Emacs 查找项目中文件的相对路径

Emacs 查找项目中文件的相对路径,emacs,elisp,Emacs,Elisp,我将项目文件设置为以下格式: /home/user/proj/source /home/user/proj/source/src1 /home/user/proj/source/src1 /home/user/proj/header ...etc 在查看任何源文件时,我都可以找到项目路径 "/home/user/proj" 另外,(缓冲区文件名)给出给定源文件的完整绝对路径 如何编写lisp函数来提取源文件的相对路径 意思是,如果我正在观看 /home/user/proj/source/sr

我将项目文件设置为以下格式:

/home/user/proj/source
/home/user/proj/source/src1
/home/user/proj/source/src1
/home/user/proj/header ...etc
在查看任何源文件时,我都可以找到项目路径

"/home/user/proj"
另外,(缓冲区文件名)给出给定源文件的完整绝对路径

如何编写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))

注意这一点。

您可以根据需要调整此代码:

(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 "[\\\\/]"))
       ".")))))
(定义java包名称(文件)
根据路径为文件生成包名
(let*((f(文件名目录文件))
(雷姆
(汽车
(分类
(德尔克零
(地图车
(λ(x)
(和(字符串匹配(扩展文件名x)f)
(子字符串f(匹配结束0)))
(解析冒号路径(getenv“CLASSPATH”))
(λ(ab)(<(长度a)(长度b()()())))
(续)
((空rem)
“不在类路径上。”)
(=0(长度rem))
“在类路径的根目录下”)
(t
(mapconcat)
#“唐卡斯
(删除“”(拆分字符串rem“[\\/]”)
".")))))

您可以根据需要调整此代码:

(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 "[\\\\/]"))
       ".")))))
(定义java包名称(文件)
根据路径为文件生成包名
(let*((f(文件名目录文件))
(雷姆
(汽车
(分类
(德尔克零
(地图车
(λ(x)
(和(字符串匹配(扩展文件名x)f)
(子字符串f(匹配结束0)))
(解析冒号路径(getenv“CLASSPATH”))
(λ(ab)(<(长度a)(长度b()()())))
(续)
((空rem)
“不在类路径上。”)
(=0(长度rem))
“在类路径的根目录下”)
(t
(mapconcat)
#“唐卡斯
(删除“”(拆分字符串rem“[\\/]”)
".")))))
这个怎么样:

(定义文件名使相对(文件名引用)
(互动)
(let)((简化路径参考)
(普通位置0)
(深度0)
(位置0)
(retval“”)
(而(等式(aref文件名通用pos)(aref参考通用pos))
(setq公共位置(+公共位置1)))
(setq简化路径参考(子串参考(+公共位置1)))
(而(
它还没有经过非常彻底的测试,但是,在我的简单测试用例中,它按照预期工作。给定一个文件
filename
和一个引用目录
reference
(必须有尾随斜杠,我记不起哪个函数会自动执行此操作,是否有人可以注释?)此函数将计算从
reference
filename
的相对路径

示例:

(文件名为相对“/usr/local/bin/exec”“/usr/local/root/bin/”)
结果:

这个怎么样:

(定义文件名使相对(文件名引用)
(互动)
(let)((简化路径参考)
(普通位置0)
(深度0)
(位置0)
(retval“”)
(而(等式(aref文件名通用pos)(aref参考通用pos))
(setq公共位置(+公共位置1)))
(setq简化路径参考(子串参考(+公共位置1)))
(而(
它还没有经过非常彻底的测试,但是,在我的简单测试用例中,它按照预期工作。给定一个文件
filename
和一个引用目录
reference
(必须有尾随斜杠,我记不起哪个函数会自动执行此操作,是否有人可以注释?)此函数将计算从
reference
filename
的相对路径

示例:

(文件名为相对“/usr/local/bin/exec”“/usr/local/root/bin/”)
结果:


尝试
定位主要文件
文件相对名称

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

注意
locate dominating file
如果找不到任何内容,则返回
nil

尝试
locate dominating file
文件相对名称

(let ((fname (buffer-file-name)))
  (file-relative-name fname (locate-dominating-file fname "Makefile")))
注意
locate dominating file
如果找不到任何内容,则返回
nil

安装一个全面的文件和目录操作库。然后运行函数:

安装,一个全面的文件和目录操作库。然后运行函数:


谢谢你,伊莱马基尔。我相信你的意思是(文件名makerelative“/usr/local/root/bin/exec”“/usr/local/root/bin/”),因为这正是我基本上想要的。类似:(file name make relative(buffer file name)“/home/proj”),输出应该是:“source/src1/file.c”当添加/root/“部分时,您的代码”会在启动时出错感谢elemakil。我相信你的意思是(文件名makerelative“/usr/local/root/bin/exec”“/usr/local/root/bin/”),因为这正是我基本上想要的。类似:(file name make relative(buffer file name)“/home/proj”),输出应该是:“source/src1/file.c”当添加/root/”部分时,您的代码在启动时会出现错误谢谢abo abo。你能给我一个例子,说明你的函数的输出被赋予了一个文件名吗?我不是