How to make a Lisp function call java while being aware of packages?

拥有回忆 提交于 2019-12-05 21:11:39

Try the following code to search the current file for a package declaration:

(save-excursion
  (goto-char (point-min))
  (when (re-search-forward "^\\s *package\\s +\\(.*\\);" (point-max) t)
    (match-string 1)))

This will return the value between a package declaration and the semi-colon. It will return nil if no such declaration is found.

(Beware that this might fail if there is a commented-out package declaration somewhere before the actual package declaration, in a C-style, multi-line comment (/* ... */).)

In order to change the directory from which a shell command is run, use the cd function. Since in Java the package structure should reflect the directory structure, you can use the package information determined by the above code to figure out the base directory of your source code:

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

You may use this code to extend your function like so:

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

Either use a proper Java IDE (you will eventually if you do this on a regular basis) or read the file to parse the package line.

Also note that you will most likely also need to specify the compilation root folder (or cd to it) to be able to set the class path properly.

For deriving the actual class name, reading the file and searching for "package (.*);" (matching newlines too) would most likely be good enough.

To be frank, when I need to work like this, I write a small script (bat-file under WIndows) which does what I need. The reason is that I usually need a lot of jarfiles on the classpath too, which eventually boils down to me needing to specify the whole command line anyway.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!