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. への引数にjavaは、パッケージ名とドットをプレフィックスとして付ける必要があります。
  2. javaパッケージを含むディレクトリから実行する必要があります。

たとえば、ファイルが file.java でパッケージ名が pkg の場合、ディレクトリ pkg を含むディレクトリ (file.java が配置されているディレクトリの親ディレクトリ) からpkgjavaが呼び出されます。java pkg.file

関数を変更してパッケージを認識し、それに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 スタイルの複数行コメント ( ) で、実際のパッケージ宣言の前にコメントアウトされた宣言がある場合、これは失敗する可能性があることに注意してください/* ... */)。

シェル コマンドを実行するディレクトリを変更するには、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 ではバッチ ファイル) を作成します。その理由は、通常、クラスパスにも多くの jar ファイルが必要であり、最終的にはコマンド ライン全体を指定する必要があるからです。

于 2012-09-22T18:15:49.593 に答える