Как связать регулярное выражение с комбинацией клавиш в emacs?

Для контекста, я новичок в Emacs. Я не использовал его очень долго, но использую его все больше и больше (мне это очень нравится). Также я доволен LISP, но не очень хорошо знаком с Elisp.

Что мне нужно сделать, так это связать регулярное выражение с комбинацией клавиш, потому что я так часто использую это регулярное выражение.

Что я делал:

M-C-s ^.*Table\(\(.*\n\)*?GO\)

Обратите внимание, что я использовал новую строку выше, но я обнаружил, что для isearch-forward-regexp, вам действительно нужно заменить \nрегулярное выражение на результат C-q Q-j. При этом вставляется буквальный символ новой строки (без завершения команды), что позволяет мне вставить новую строку в выражение и сопоставить ее между строками.

Как я могу связать это с комбинацией клавиш?

Я смутно понимаю, что мне нужно создать функцию elisp, которая выполняется isearch-forward-regexpс выражением, но я не совсем уверен в деталях. Я искал в Google и обнаружил, что большая часть документации немного запутана.

Как я могу связать регулярное выражение с комбинацией клавиш в Emacs?


У Майка Стоуна был лучший ответ - не совсем то , что я искал, но это сработало для того, что мне было нужно

Редактировать - это вроде работало, но после сохранения макроса, когда я вернулся, чтобы использовать его позже, я не мог использовать его с C-x e. (то есть, если я перезагружаю emacs, а затем набираю M-x macro-name, а затем C-x eя получаю сообщение в минибуфере типа «нет последнего макроса kbd» или что-то подобное)


@ Майк Стоун - Спасибо за информацию. Я попытался создать макрос так:

C-x( M-C-s ^.*Table\(\(.*C-q C-J\)*?GO\) C-x)

Это создало мой макрос, но когда я выполнил свой макрос, я не получил ту же подсветку, которую обычно получаю при использовании isearch-forward-regexp. Вместо этого он просто перепрыгнул в конец следующего совпадения выражения. Так что это на самом деле не работает для того, что мне нужно. Есть идеи?

Изменить: Похоже, я могу использовать макросы, чтобы делать то, что я хочу, я просто должен думать за пределами коробки isearch-forward-regexp. Я попробую то, что вы предложили.

13.08.2008 18:15:09
4 ОТВЕТА
РЕШЕНИЕ

Вы можете использовать макросы, просто сделайте, C-x (затем сделайте все для макроса, затем C-x )завершите макрос C-x eи выполните последний определенный макрос. Затем вы можете назвать его, используя, M-x name-last-kbd-macroчто позволяет вам присвоить ему имя, которое затем можно вызвать M-x TESTIT, затем сохранить определение, с помощью M-x insert-kbd-macroкоторого макрос будет помещен в ваш текущий буфер, а затем вы можете сохранить его в своем .emacsфайле.

Пример:

C-x( abc *return* C-x)

Определим макрос для типа «abc» и нажмите return.

C-xeee

Выполняет вышеупомянутый макрос немедленно, 3 раза (сначала e выполняет его, затем следующие 2 e выполнит его еще два раза).

M-x name-last-kbd-macro testit

Называет макрос "testit"

M-x testit

Выполняет только что названный макрос (печатает «abc», затем возвращает).

M-x insert-kbd-macro

Помещает следующее в ваш текущий буфер:

(fset 'testit
   [?a ?b ?c return])

Который затем можно сохранить в вашем .emacsфайле, чтобы использовать названный макрос снова и снова после перезапуска Emacs.

6
23.01.2013 22:12:10

@Justin:

При выполнении макроса все немного по-другому ... инкрементальный поиск будет происходить только один раз, и вам придется выполнить макрос еще раз, если вы хотите выполнить поиск снова. Вы можете делать более мощные и сложные вещи, такие как поиск по ключевому слову, переход к началу строки, пометка, переход к концу строки, Mw (для копирования), затем переход к другому буферу, затем Cy (вставка) ), затем вернитесь к другому буферу и завершите свой макрос. Затем при каждом выполнении макроса вы будете копировать строку в следующий буфер.

Действительно классная вещь в макросах emacs - он останавливается, когда видит колокол ... что происходит, когда вы не соответствуете инкрементальному поиску (среди прочего). Таким образом, вышеупомянутый макрос, вы можете сделать Cu 1000 Cx e, который будет выполнять макрос 1000 раз ... но так как вы выполнили поиск, он скопирует только 1000 строк, ИЛИ ДО СБОТА ПОИСКА! Это означает, что если есть 100 совпадений, он будет выполнять макрос только 100 раз.

РЕДАКТИРОВАТЬ: Проверьте C-HF Highlight-Lines-Match-Regexp, которая покажет помощь команды, которая выделяет все, что соответствует регулярному выражению ... Я не знаю, как отменить выделение, хотя ... в любом случае вы могли бы использовать сохраненный макрос для выделения всех соответствующих регулярных выражений, а затем еще один макрос для поиска следующего ...?

ДОПОЛНИТЕЛЬНОЕ РЕДАКТИРОВАНИЕ: Mx unhighlight-regexp отменит выделение, хотя вы должны ввести последнее регулярное выражение (но по умолчанию используется регулярное выражение, которое вы использовали для выделения)

1
13.08.2008 19:09:31

В общем, чтобы определить пользовательскую привязку клавиш в Emacs, вы должны написать

(define-key global-map (kbd "C-c C-f") 'function-name)

define-keyнеудивительно, что это функция для определения нового ключа. global-mapявляется глобальной картой ключей, в отличие от отдельных карт для каждого режима. (kbd "C-c C-f")возвращает строку, представляющую последовательность клавиш C-c C-f. Есть и другие способы сделать это, включая непосредственный ввод строки, но обычно это самый простой способ, поскольку он принимает нормальное письменное представление. 'function-nameэто символ, который является названием функции.

Теперь, если ваша функция уже не определена, вы захотите определить ее, прежде чем использовать это. Для этого напишите

(defun function-name (args)
  (interactive)
  stuff
  ...)

defunопределяет функцию - используйте C-h f defunдля более конкретной информации. (interactive)Есть на самом деле не вызов функции; он сообщает компилятору, что функция может вызываться пользователем с помощью M-x function-nameи с помощью сочетаний клавиш.

Теперь, в частности, для интерактивного поиска это сложно; isearchмодуль не действительно , кажется, создана для того, что вы пытаетесь сделать. Но вы можете использовать это, чтобы сделать что-то подобное.

1
24.08.2008 08:12:16

Я начал с решения вашей проблемы буквально,

(defun search-maker (s)
  `(lambda ()
     (interactive)
     (let ((regexp-search-ring (cons ,s regexp-search-ring)) ;add regexp to history
           (isearch-mode-map (copy-keymap isearch-mode-map)))
       (define-key isearch-mode-map (vector last-command-event) 'isearch-repeat-forward) ;make last key repeat
       (isearch-forward-regexp)))) ;`

(global-set-key (kbd "C-. t") (search-maker "^.*Table\\(\\(.*\\n\\)*?GO\\)"))
(global-set-key (kbd "<f6>") (search-maker "HELLO WORLD"))

Последовательность клавиатуры от (kbd ...)запускает новый пустой поиск. Чтобы на самом деле найти вашу строку, вы нажимаете последнюю клавишу снова столько раз, сколько вам нужно. Так C-. t t tили <f6> <f6> <f6>. Решение в основном взломать, но я оставлю это здесь, если вы хотите поэкспериментировать с ним.

Следующее, вероятно, ближе всего к тому, что вам нужно,

(defmacro define-isearch-yank (key string)
  `(define-key isearch-mode-map ,key 
     (lambda ()
       (interactive) 
       (isearch-yank-string ,string)))) ;`

(define-isearch-yank (kbd "C-. t") "^.*Table\\(\\(.*\\n\\)*?GO\\)")
(define-isearch-yank (kbd "<f6>") "HELLO WORLD")

Комбинации клавиш теперь работают только в режиме поиска. Вы начинаете поиск как обычно, а затем нажимаете комбинации клавиш, чтобы вставить предварительно заданную строку.

2
13.09.2008 00:34:28