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

StackOverflow https://stackoverflow.com/questions/10149

  •  08-06-2019
  •  | 
  •  

Вопрос

Для контекста: я что-то вроде новичка в 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 е.(т. е. если я перезагружаю emacs и затем набираю M-x имя макроса, а потом C-x е, я получаю сообщение в минибуфере типа «нет последнего макроса kbd» или что-то подобное)


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

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

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

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

Это было полезно?

Решение

Вы можете использовать макросы, просто сделайте С-х ( затем сделайте все для макроса, затем С-х) чтобы завершить макрос, затем C-x е выполнит последний определенный макрос.Затем вы можете назвать его, используя M-x имя-фамилия-kbd-макрос который позволяет вам присвоить ему имя, которое вы затем можете вызвать с помощью М-х ТЕСТИТ, затем сохраните определение, используя M-x вставка-kbd-макрос который поместит макрос в ваш текущий буфер, а затем вы сможете сохранить его в своем .emacs файл.

Пример:

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

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

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.

Другие советы

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

(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")

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

@Джастин:

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

Самое замечательное в макросах emacs то, что они останавливаются, когда видят колокольчик...что происходит, когда вам не удается найти совпадение с инкрементным поиском (среди прочего).Итак, приведенный выше макрос: вы можете выполнить C-u 1000 C-x e, который выполнит макрос 1000 раз...но раз уж вы сделали поиск, то он скопирует только 1000 строк, ИЛИ ПОКА ПОИСК НЕ ПРОЙДЕТ!Это означает, что если совпадений 100, макрос выполнится только 100 раз.

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

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

В общем, чтобы определить пользовательскую привязку клавиш в 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 модуль, похоже, на самом деле не настроен для того, что вы пытаетесь сделать.Но вы можете использовать это, чтобы сделать что-то подобное.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top