2

プロジェクト ファイルを次の形式で設定しています。

/home/user/proj/source
/home/user/proj/source/src1
/home/user/proj/source/src1
/home/user/proj/header ...etc

ソースファイルを表示するときにプロジェクトパスを見つける方法があります

"/home/user/proj"

また、(buffer-file-name) は、指定されたソース ファイルの完全な絶対パスを示します。

ソースファイルの相対パスを抽出する Lisp 関数の書き方は?

つまり、私が見ている場合

/home/user/proj/source/src1/file.c

パスが欲しい

"source/src1/file.c"

次の関数は、プロジェクト パスを提供します。

(defun upward-find-file (filename &optional startdir)
  (let ((dirname (expand-file-name
          (if startdir startdir ".")))
    (found nil) ; found is set as a flag to leave loop if we find it
    (top nil))  ; top is set when we get
            ; to / so that we only check it once
    ; While we've neither been at the top last time nor have we found
    ; the file.
    (while (not (or found top))
      ; If we're at / set top flag.
      (if (string= (expand-file-name dirname) "/")
      (setq top t))
      ; Check for the file
      (if (file-exists-p (expand-file-name filename dirname))
      (setq found t)
    ; If not, move up a directory
    (setq dirname (expand-file-name ".." dirname))))
    ; return statement
    (if found (concat dirname "/") nil)))

メインのプロジェクトフォルダには常に「Makefile」があるので、

(setq dirname (upward-find-file "Makefile" startdir))

それを大事にします。

4

4 に答える 4

5

と を試してlocate-dominating-fileくださいfile-relative-name

(let ((fname (buffer-file-name)))
  (file-relative-name fname (locate-dominating-file fname "Makefile")))

何も見つからない場合、NBlocate-dominiating-fileは戻ります。nil

于 2013-08-21T22:55:02.810 に答える
0

必要に応じてこのコードを微調整できます。

(defun java-package-name (file)
  "Generates package name for FILE, based on path."
  (let* ((f (file-name-directory file))
         (rem
          (car
           (sort
            (delq nil
                  (mapcar
                   (lambda(x)
                     (and (string-match (expand-file-name x) f) 
                          (substring f (match-end 0))))
                   (parse-colon-path (getenv "CLASSPATH"))))
            (lambda (a b) (< (length a) (length b)))))))
    (cond
     ((null rem)
      "Not on CLASSPATH.")
     ((= 0 (length rem))
      "At root of CLASSPATH")
     (t
      (mapconcat
       #'downcase
       (delete "" (split-string rem "[\\\\/]"))
       ".")))))
于 2013-08-21T20:23:27.203 に答える