在Emacs中使用Lisp函数来运行当前文件对应的Java程序。
(defun java-run-current-file ()
"Runs the java program the current file correspond to"
(interactive)
(shell-command
(concat "java "
(file-name-sans-extension
(file-name-nondirectory (buffer-file-name))))))
它的工作原理是剥离其路径和扩展名的当前文件名,并将其用作java
的参数,该参数从文件所在的路径运行。这种方法的问题是,如果当前文件是包的一部分,那么
java
的参数必须以包名和点为前缀,并且java
必须从包含该包的目录运行。因此,例如,如果文件是file.java,并且包名称是pkg java
,则从包含目录pkg的目录(作为file.java的目录的父目录)调用java pkg.file
放置)。
如何修改函数以了解包并相应地构造java
的参数?我想有人可以通过在当前文件中搜索包声明来解决这个问题,例如
package pkg;
如果找到一个,则使用该包名称来适当地调用java
。
答案 0 :(得分:2)
尝试使用以下代码在当前文件中搜索包声明:
(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)))))))
答案 1 :(得分:-1)
使用适当的Java IDE(如果定期执行此操作,最终会使用)或读取文件以解析包行。
另请注意,您很可能还需要指定编译根文件夹(或cd到它)才能正确设置类路径。
用于派生实际的类名,读取文件并搜索“package(。*);” (也匹配换行)很可能就足够了。
坦率地说,当我需要像这样工作时,我会编写一个小脚本(在WIndows下的bat文件)来完成我需要的工作。原因是我通常在类路径上也需要很多jar文件,最终归结为我需要指定整个命令行。