Emacs org-mode: текстовая ссылка на файл: строка


Я использую org-mode в Emacs для документирования моей деятельности по развитию. Одна из задач, которую я должен постоянно выполнять вручную, заключается в описании областей кода. Emacs имеет очень хороший список закладок : создайте закладку с помощью CTRL-x r m , перечислите их с помощью CTRL-x r l . Это очень полезно, но не совсем то, что мне нужно.

Org-mode имеет понятие link, и команда org-store-link запишет a ссылка на текущую позицию в любом файле, который можно вставить в орг-файл. Проблема с этим двоякая:

  • он хранится как орг-ссылка, и связанная позиция непосредственно не видна (только описание).
  • он хранится в формате file/search, а это не то, что я хочу.

Мне нужно иметь закладку в текстовой форме, чтобы я мог скопировать вставить ее в орг-режим, закончить редактировать ее, если это необходимо, с помощью простого формата, такого как:

absolute-file-path:line

И это должно быть получено из текущего положения точки. Рабочий процесс будет таким же простым, как:

  • перейти к позиции, которую я хочу записать
  • вызов функции: position-to-kill-ring (я бы привязал это к сочетанию клавиш)
  • перейдите в буфер org-mode.
  • дерните за позицию.
  • редактировать при необходимости (иногда мне нужно изменить абсолютные пути на относительные пути, так как мой код находится в другом месте на разных машинах)

К сожалению, мой lisp не существует, поэтому я не знаю, как это сделать. Есть ли простое решение моей проблемы?

4 8

4 ответа:

(defun position-to-kill-ring ()
  "Copy to the kill ring a string in the format \"file-name:line-number\"
for the current buffer's file name, and the line number at point."
  (interactive)
  (kill-new
   (format "%s:%d" (buffer-file-name) (save-restriction
                                        (widen) (line-number-at-pos)))))

Вы хотите использовать крючки org-create-file-search-functions и org-execute-file-search-functions.

Например, если вам нужен поиск, который вы описываете для текстовых файлов, используйте следующее:

(add-hook 'org-create-file-search-functions
      '(lambda ()
         (when (eq major-mode 'text-mode)
           (number-to-string (line-number-at-pos)))))

(add-hook 'org-execute-file-search-functions
      '(lambda (search-string)
         (when (eq major-mode 'text-mode)
           (goto-line (string-to-number search-string)))))

Тогда M-x org-store-link RET поступит правильно (сохранит номер строки в качестве строки поиска) и C-c-o (т. е. M-x org-open-at-point RET) откроет файл и перейдет к этому номеру строки.

Вы, конечно, можете проверить наличие других режимов и / или условий.

Начинающий elisp сам я думал об этом как о хорошем упражнении et voila:

Edit: переписал его, используя формат methode, но я все еще думаю, что не хранить его в kill-ring менее навязчиво в моем рабочем процессе (не знаю, как вы). Также я добавил возможность добавлять позицию столбца.

(defvar current-file-reference ""  "Global variable to store the current file reference")

(defun store-file-line-and-col ()
  "Stores the current file, line and column point is at in a string in format \"file-name:line-number-column-number\". Insert the string using \"insert-file-reference\"."
  (interactive)
  (setq current-file-reference (format "%s:%d:%d" (buffer-file-name) (line-number-at-pos) (current-column))))
(defun store-file-and-line ()
  "Stores the current file and line oint is at in a string in format \"file-name:line-number\". Insert the string using \"insert-file-reference\"."
  (interactive)
 (setq current-file-reference (format "%s:%d" (buffer-file-name) (line-number-at-pos))))

(defun insert-file-reference ()
  "Inserts the value stored for current-file-reference at point."
  (interactive)
  (if (string= "" current-file-reference)
      (message "No current file/line/column set!")
    (insert current-file-reference)))

Не испытано экстенсивно, но работает на меня. Просто нажмите store-file-and-line или store-file-line-and-col, чтобы сохранить текущее местоположение и insert-file-reference для вставки сохраненного значения в точку.

Кстати, если вы хотите что-то лучше, чем FILE:LINE, вы можете попробовать использовать add-log-current-defun (в add-log.el), который должен возвращать имя текущей функции.