4

在 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从文件所在路径运行的参数来工作。这种方法的问题在于,如果当前文件是包的一部分,那么

  1. to 的参数java必须以包名和一个点作为前缀,并且
  2. java必须从包含包的目录运行。

因此,例如,如果文件是 file.java 并且包名称是 pkg javajava pkg.file则从包含目录 pkg 的目录(放置 file.java 的目录的父目录)中调用。

如何修改函数以了解包并java相应地构造参数?我想可以通过在当前文件中搜索包声明来解决这个问题,例如

package pkg;

如果找到它,它会使用该包名称进行java适当的调用。

4

2 回答 2

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)))))))
于 2012-09-23T00:25:35.917 回答
0

要么使用适当的 Java IDE(如果你经常这样做,你最终会这样做)或读取文件以解析包行。

另请注意,您很可能还需要指定编译根文件夹(或 cd 到它)才能正确设置类路径。

为了派生实际的类名,读取文件并搜索“package (.*);” (也匹配换行符)很可能就足够了。

坦率地说,当我需要像这样工作时,我会编写一个小脚本(Windows 下的 bat 文件)来满足我的需要。原因是我通常在类路径上也需要很多 jarfile,最终归结为我需要指定整个命令行。

于 2012-09-22T18:15:49.593 回答