【问题标题】:Highlight which of the file names in emacs buffer are missing突出显示 emacs 缓冲区中缺少哪些文件名
【发布时间】:2012-06-04 09:31:56
【问题描述】:

在 GNU Emacs 中,我可以使用假设的“flyexist.el”之类的东西——我有一个缓冲区,其中包含绝对 (Unix) 文件名(加上一些额外的文本)。这些文件中的大多数都存在,但有些文件丢失了。我想运行一个函数来突出显示丢失的文件(可能带有红色覆盖)。此函数需要确定缓冲区中的哪些文本看起来像文件名(一些误报是可以的),然后使用 file-exists-p 处理它。

例如,假设我的缓冲区包含

Some random text mentioning /file/that/does/exist.txt, 
some more random text, and a /file/that/does/not-exist.txt

我想突出显示第二个文件。

这样的东西已经存在了吗?

【问题讨论】:

  • 您需要代码来确定/file/that/does/exist.txt 存在,即使/file/that/does/exist.txt,(大概)不存在?如果存在/file/that/does/not-exist.tx,也不要突出显示?
  • 好吧,如果一个文件存在,它不应该被突出显示(或以不同的颜色,例如绿色),但我想快速查看不存在的文件。
  • @cmarqu:+1...我觉得这也很方便。解决 /path/to/file~/path/to/file 并以红色突出显示丢失的文件将非常有用:)

标签: emacs overlay elisp highlighting


【解决方案1】:

我是 emacs hacking 的新手...这是我的“次要模式”版本。

(defvar filehi-path-re "\\([/$][[:alnum:]$-_.]+\\)+"
  "Regexp used for path matching.")


(defface filehi-file-existing
  '((t (:foreground "White" :background "Green")))
  "Face for existing files.")

(defface filehi-file-missing
  '((t (:foreground "Yellow" :background "Red")))
  "Face for missing files.")

(defun filehi-check-and-highlight (start end)
  "Check if substring is existing file path and highlight it."
    (remove-overlays start end 'name 'filehi-highlight)
    (let ((overlay (make-overlay start end)))
      (overlay-put overlay 'name 'filehi-highlight)
      (overlay-put overlay 'face (if (file-exists-p (substitute-in-file-name
                                                     (buffer-substring start end)))
                                     'filehi-file-existing
                                   'filehi-file-missing))))


(defun filehi-highlight-file-paths (&optional start end _ignore)
   "Run through the buffer and highliht file paths."
    (save-excursion
      (save-match-data ; fixes problem with dabbrev (and may be more...)
        (remove-overlays (point-min) end 'name 'filehi-highlight)
        (let ((prev-end (point-min)))
          (goto-char (point-min)) ; FIXME use something like greedy
                                        ; search-backward
          (while (and (<= (point) end)
                      (re-search-forward filehi-path-re nil t))
            (filehi-check-and-highlight (match-beginning 0) (match-end 0)))))))


(define-minor-mode filehi-mode
  "Minor mode for highlighting existing file paths.
May conflict with other modes..."
  nil " Filehi" nil
  (if filehi-mode
      (progn ; enable mode
        (make-local-hook 'after-change-functions)
        (filehi-highlight-file-paths (point-min) (point-max))
        (add-hook 'after-change-functions 'filehi-highlight-file-paths nil t))
    ; disable mode
    (remove-hook 'after-change-functions 'filehi-highlight-file-paths t)
    (remove-overlays (point-min) (point-max) 'name 'filehi-highlight)))

【讨论】:

  • 谢谢,太棒了。由于您的解决方案立即有用且最完整,因此我“接受”它作为答案。您是否考虑在例如托管该代码? github,有适当的许可等?
  • 扩展环境变量很容易——只需添加一个函数调用(参见差异)并更改正则表达式。 Elisp 参考是您的朋友!至于托管和许可,您可以随意使用此代码。我不想维护它:)
  • 我已经稍微修改了正则表达式,以便它也支持本地文件名 - 它希望至少找到一个斜杠 (/)。 (defvar filehi-path-re "\\([[:alnum:]$_.-]+/[[:alnum:]$_.\\*/-]+\\)" "Regexp used for path matching.")
【解决方案2】:

试试这个(不过你必须手动触发它,或者将它合并到其他一些定期例程中):

(defun x-mark-missing-files ()
  (interactive)
  (save-excursion
   (while (search-forward-regexp "~?/[A-Za-z./-]+")
     (when (not (file-exists-p (match-string 0)))
       (overlay-put
        (make-overlay (match-beginning 0) (match-end 0))
        'face '(:background "red"))))))

对文件名正则表达式进行一些操作,以使其正确。

【讨论】:

  • 也谢谢你,我在正则表达式中添加了 0-9 和 _ 并且效果也很好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-06
相关资源
最近更新 更多