java - 如何在知道包的情况下使 Lisp 函数调用 java?

标签 java emacs lisp

在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. java 的参数必须以包名和一个点为前缀,并且
  2. java 必须从包含包的目录运行。

例如,如果文件是 file.java 并且包名称是 pkg java 从包含目录 pkg 的目录中调用 java pkg.file( file.java所在目录的父目录)。

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

package pkg;

如果它找到一个,它会使用该包名称适本地调用 java

最佳答案

尝试使用以下代码在当前文件中搜索包声明:

(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 中包结构应该反射(reflect)目录结构,您可以使用上面代码确定的包信息来确定源代码的基本目录:

(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)))))))

关于java - 如何在知道包的情况下使 Lisp 函数调用 java?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12546437/

相关文章:

java - 如何修复 Android 中的 NetworkonMainThreadException?

java - 允许安全性较低的应用程序 : ON But Heroku still generating that error

java - 从 TextField 动态更新 ListView (JavaFX)

templates - 如何使用 Emacs+AUCTeX 创建(自动插入)LaTeX 模板?

lisp - 如何在 Lisp 变量中保存追加返回?

LISP 列表项的总和

java - 从 Java 中的 ProcessBuilder 调用时 EXE 崩溃

emacs - Emacs:创建新框架时,set-frame-height不起作用

emacs - isearch 中的关键和弦

lisp - 它是闭括号、闭括号还是闭括号?