簡體   English   中英

如何讓Lisp函數在知道包時調用java?

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

在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稱為java pkg.file從包含目錄PKG(其中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中包結構應該反映目錄結構,您可以使用上面代碼確定的包信息來確定源代碼的基本目錄:

(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 IDE(如果定期執行此操作,最終將使用)或讀取文件以解析包行。

另請注意,您很可能還需要指定編譯根文件夾(或cd到它)才能正確設置類路徑。

用於派生實際的類名,讀取文件並搜索“package(。*);” (匹配換行)也很可能足夠好。

坦率地說,當我需要像這樣工作時,我會編寫一個小腳本(在WIndows下的bat文件),它可以滿足我的需求。 原因是我通常在類路徑上也需要很多jar文件,這最終歸結為我需要指定整個命令行。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM