Как связать регулярное выражение с комбинацией клавиш в 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, а затем набираю Mx имя-макроса, а затем Cx e, я получаю сообщение в минибуфере типа "нет последнего макроса kbd" или что-то в этом роде. похожий)


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

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

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

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


person Justin Standard    schedule 13.08.2008    source источник


Ответы (4)


Вы можете использовать макросы, просто выполните Cx (, затем сделайте все для макроса, затем Cx ), чтобы завершить макрос, затем Cx e будет выполнено последний определенный макрос. Затем вы можете назвать его с помощью Mx name-last-kbd-macro, который позволяет вам присвоить ему имя, которое вы затем можете вызвать с помощью Mx TESTIT, а затем сохранить определение с помощью Mx insert-kbd-macro, который поместит макрос в ваш текущий буфер, а затем вы сможете сохранить его в файле .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.

person Mike Stone    schedule 13.08.2008

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

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

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

person Community    schedule 13.09.2008

@Джастин:

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

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

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

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

person Mike Stone    schedule 13.08.2008

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

person Natalie Weizenbaum    schedule 24.08.2008