尝试使用以下代码在当前文件中搜索包声明:
(save-excursion
(goto-char (point-min))
(when (re-search-forward "^\\s *package\\s +\\(.*\\);" (point-max) t)
(match-string 1)))
这将返回package
声明和分号之间的值。nil
如果没有找到这样的声明,它将返回。
(请注意,如果在实际包声明之前的某处有一个注释掉的package
声明,在 C 风格的多行注释 ( /* ... */
) 中,这可能会失败。)
要更改运行 shell 命令的目录,请使用该cd
函数。由于在 Java 中包结构应该反映目录结构,因此您可以使用上述代码确定的包信息来确定源代码的基本目录:
(let ((directory (file-name-directory (buffer-file-name)))
(sub-dirs (reverse (split-string package "\\."))))
(while sub-dirs
(if (string-match (concat "^\\(.*/\\)" (regexp-quote (car sub-dirs)) "/$") directory)
(setq directory (match-string 1 directory)
sub-dirs (cdr sub-dirs))
(error "Package does not match directory structure")))
(cd directory))
您可以使用此代码来扩展您的功能,如下所示:
(defun java-run-current-file ()
"Runs the java program the current file corresponds to"
(interactive)
(let* ((package (save-excursion
(goto-char (point-min))
(when (re-search-forward "^\\s *package\\s +\\(.*\\);" (point-max) t)
(match-string 1))))
(directory (file-name-directory (buffer-file-name)))
sub-dirs)
(if directory
(setq directory (file-truename directory))
(error "Current buffer is not visiting a file"))
(when package
(setq sub-dirs (reverse (split-string package "\\.")))
(while sub-dirs
(if (string-match (concat "^\\(.*/\\)" (regexp-quote (car sub-dirs)) "/$") directory)
(setq directory (match-string 1 directory)
sub-dirs (cdr sub-dirs))
(error "Package does not match directory structure"))))
(cd directory)
(shell-command
(concat "java "
(if package (concat package ".") "")
(file-name-sans-extension
(file-name-nondirectory (buffer-file-name)))))))