![如何让 emacs 高亮并链接文件路径](https://linux22.com/image/1247330/%E5%A6%82%E4%BD%95%E8%AE%A9%20emacs%20%E9%AB%98%E4%BA%AE%E5%B9%B6%E9%93%BE%E6%8E%A5%E6%96%87%E4%BB%B6%E8%B7%AF%E5%BE%84.png)
是否有一些 emacs lisp 代码可以自动在缓冲区中查找 /nfs 文件路径并突出显示/链接到它们?那么单击它们会打开该文件吗?
示例路径:/nfs/foo/bar/file.txt
答案1
可能已经有一个可以执行此操作的包,但是我不知道。
这段代码会将按钮添加到它认为看起来像文件路径的文本中。您可以手动(或有条件地)添加或运行该'buttonize-buffer
函数。find-file-hooks
(define-button-type 'find-file-button
'follow-link t
'action #'find-file-button)
(defun find-file-button (button)
(find-file (buffer-substring (button-start button) (button-end button))))
(defun buttonize-buffer ()
"turn all file paths into buttons"
(interactive)
(save-excursion
(goto-char (point-min))
(while (re-search-forward "/[^ \t]*" nil t)
(make-button (match-beginning 0) (match-end 0) :type 'find-file-button))))
; (add-hook 'find-file-hook 'buttonize-buffer) ; uncomment to add to find file
答案2
尝试内置包 ffap(在点处查找文件):
http://www.emacswiki.org/emacs/FindFileAtPoint
http://www.gnu.org/software/emacs/manual/html_node/emacs/FFAP.html
我不使用次要模式,而是将一个键绑定到ffap
我在文件名上按下的键上。
答案3
很好的解决方案。我同意使用ffap
,它是 GNU Emacs 的一部分。ffap
解决了许多微妙的问题,它扩展了环境变量并捕获了 URL。
但是,ffap
不能从自己的 Lisp 中轻松使用。我的重新实现buttonize-buffer
基于ffap-next-regexp
和ffap-guesser
。困难的部分是解决下面提到的错误,并获取文件或 URL 的起点,但ffap-guesser
并未提供。
解析器扫描当前缓冲区并将详细信息打印到消息缓冲区中;在那里您可以看到哪些字符串被猜测是文件,哪些匹配,哪些是按钮化的。
(defun buttonize-buffer ()
"Turn all file paths and URLs into buttons."
(interactive)
(require 'ffap)
(deactivate-mark)
(let (token guess beg end reached bound len)
(save-excursion
(setq reached (point-min))
(goto-char (point-min))
(while (re-search-forward ffap-next-regexp nil t)
;; There seems to be a bug in ffap, Emacs 23.3.1: `ffap-file-at-point'
;; enters endless loop when the string at point is "//".
(setq token (ffap-string-at-point))
(unless (string= "//" (substring token 0 2))
;; Note that `ffap-next-regexp' only finds some "indicator string" for a
;; file or URL. `ffap-string-at-point' blows this up into a token.
(save-excursion
(beginning-of-line)
(when (search-forward token (point-at-eol) t)
(setq beg (match-beginning 0)
end (match-end 0)
reached end))
)
(message "Found token %s at (%d-%d)" token beg (- end 1))
;; Now let `ffap-guesser' identify the actual file path or URL at
;; point.
(when (setq guess (ffap-guesser))
(message " Guessing %s" guess)
(save-excursion
(beginning-of-line)
(when (search-forward guess (point-at-eol) t)
(setq len (length guess) end (point) beg (- end len))
;; Finally we found something worth buttonizing. It shall have
;; at least 2 chars, however.
(message " Matched at (%d-%d]" beg (- end 1))
(unless (or (< (length guess) 2))
(message " Buttonize!")
(make-button beg end :type 'find-file-button))
)))
;; Continue one character after the guess, or the original token.
(goto-char (max reached end))
(message "Continuing at %d" (point))
)))))
要永久安装该功能:
(add-hook 'find-file-hook 'buttonize-buffer)
一个更好的解决方案是偷懒:
(defun buttonize-current-buffer-on-idle (&optional secs)
"Idle-timer (see \\[run-with-idle-timer]) that buttonizes filenames and URLs.
SECS defaults to 60 seconds idle time."
(interactive)
(run-with-idle-timer (or secs 60) t 'buttonize-buffer))
(add-hook 'after-init-hook 'buttonize-current-buffer-on-idle)