簡體   English   中英

查找項目中文件的相對路徑

[英]Find the relative path of a file in a project

我將項目文件設置為以下格式:

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

照顧的。

嘗試locate-dominating-filefile-relative-name

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

注意如果找不到任何內容, locate-dominiating-file返回nil

這個怎么樣:

(defun file-name-make-relative (filename reference)
  (interactive)
  (let ((reduced-path-reference)
        (common-pos 0)
        (depth 0)
        (pos 0)
        (retval ""))
    (while (eq (aref filename common-pos) (aref reference common-pos))
      (setq common-pos (+ common-pos 1)))
    (setq reduced-path-reference (substring reference (+ common-pos 1)))
    (while (< pos (length (substring reference (+ common-pos 1))))
      (if (eq (aref reduced-path-reference pos) (aref "/" 0))
          (setq depth (+ depth 1)))
      (setq pos (+ pos 1)))
    (dotimes (i depth)
      (setq retval (concat retval "../")))
    (setq retval (concat retval (substring filename common-pos)))
    retval))

它沒有經過非常徹底的測試,但是,在我的簡單測試用例中,它按預期工作。 給定文件filename和引用目錄reference (必須帶有斜杠,我不記得是哪個函數自動執行,有人可以注釋嗎?),該函數將計算從referencefilename的相對路徑。

例:

(file-name-make-relative "/usr/local/bin/exec" "/usr/local/root/bin/")

結果:

"../../bin/exec"

安裝f.el ,一個全面的文件和目錄操作庫。 然后運行f-relative函數:

(f-relative "some/path/is/long" "some/path/was/short") ; => "../../is/long"

您可以根據需要調整此代碼:

(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 "[\\\\/]"))
       ".")))))

暫無
暫無

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

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