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

для контекста я что-то вроде Новичка emacs. Я не использовал его очень долго, но использую его все больше и больше (мне это очень нравится). Также мне комфортно с lisp, но не очень хорошо знаком с elisp.

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

что я делал:

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

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

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

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

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


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

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


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

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

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

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

4 ответов


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

пример:

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.


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

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

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


@Justin:

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

действительно классная вещь о макросах emacs-это то, что он остановится, когда увидит звонок... что происходит, когда вы не соответствуете инкрементальному поиску (среди прочего). Таким образом, вышеуказанный макрос, вы можете сделать c-u 1000 C-x e, который выполнит макрос 1000 раз... но так как вы сделали поиск, он будет копировать только 1000 строк, или пока поиск не завершится неудачей! Это означает, что если есть 100 совпадений, он будет выполнять только макрос 100 раз.

EDIT: Проверьте c-HF highlight-lines-matching-regexp, который покажет помощь команды, которая выделяет все, что соответствует регулярному выражению... Я не знаю, как отменить выделение... в любом случае вы можете использовать сохраненный макрос, чтобы выделить все соответствующие регулярному выражению, а затем другой макрос, чтобы найти следующий...?

дальнейшее редактирование: 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 определяет функцию-use C-h f defun для получения более конкретной информации. The (interactive) на самом деле нет вызова функции; он сообщает компилятору, что это нормально для функции, вызываемой пользователем с помощью M-x function-name и через keybindings.

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