5

Есть ли какой-нибудь emacs lisp-код, который бы автоматически находил пути к файлам /nfs в буфере и выделял / ссылался на них? Значит, щелкнув по ним, вы откроете этот файл?

Пример пути:/nfs/foo/bar/file.txt

3 ответа3

7

Вероятно, есть пакет, который уже делает это, но я не знаю об этом.

Этот фрагмент кода добавляет кнопки к тексту, который, по его мнению, выглядит как путь к файлу. Вы можете добавить функцию '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
4

Попробуйте встроенный пакет ffap (найдите файл в точке):

http://www.emacswiki.org/emacs/FindFileAtPoint

http://www.gnu.org/software/emacs/manual/html_node/emacs/FFAP.html

Я не пользуюсь второстепенным режимом, вместо этого привязываю ключ к ffap который я нажимаю при вводе имени файла.

1

Отличное решение. Но я согласен с использованием 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)

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .