我使用一个 Lisp 函数来编译当前的 Java 文件并使用另一个来运行它。这两个函数使用相同的功能来获取包名称和适当的目录来编译/运行(这个功能是作为另一个问题的答案发布的)。我想将这些功能的通用功能模块化,即 from (let*
to 但不包括(cd
. 我怎样才能做到这一点?
作为奖励,我想撤消对目录(cd
:ing)的更改,因为这些功能已完成以避免意外行为,例如C-x C-f
从 parten 目录开始查找文件()。有人建议,这可以通过unwind-protect
.
(add-hook 'java-mode-hook
(lambda ()
(defun java-compile-current-file ()
"Compiles the current file with javac"
(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)
(compile
(concat "javac -Xlint:all " ; Tog bort -Werror från
; argumenten. För
; gnälligt!
(if package (concat package "/") "")
(file-name-nondirectory (buffer-file-name))))))
(local-set-key [(f8)] 'java-compile-current-file)
;; https://stackoverflow.com/a/12548762/789593
(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)))))))
(local-set-key [(f7)] 'java-run-current-file)))