Есть ли какой-нибудь emacs lisp-код, который бы автоматически находил пути к файлам /nfs в буфере и выделял / ссылался на них? Значит, щелкнув по ним, вы откроете этот файл?
Пример пути:/nfs/foo/bar/file.txt
Вероятно, есть пакет, который уже делает это, но я не знаю об этом.
Этот фрагмент кода добавляет кнопки к тексту, который, по его мнению, выглядит как путь к файлу. Вы можете добавить функцию '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
Попробуйте встроенный пакет ffap (найдите файл в точке):
http://www.emacswiki.org/emacs/FindFileAtPoint
http://www.gnu.org/software/emacs/manual/html_node/emacs/FFAP.html
Я не пользуюсь второстепенным режимом, вместо этого привязываю ключ к ffap
который я нажимаю при вводе имени файла.
Отличное решение. Но я согласен с использованием 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)