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

Для контекста, я новичок в 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 macro-name , а затем Cx e , я получаю сообщение в минибуфере вроде «no last kbd macro» или что-то подобное)


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

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

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

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

Ответы [ 4 ]

6 голосов
/ 13 августа 2008

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

2 голосов
/ 13 сентября 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")

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

1 голос
/ 24 августа 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, похоже, на самом деле не настроен на то, что вы пытаетесь сделать. Но вы можете использовать это, чтобы сделать нечто подобное.

1 голос
/ 13 августа 2008

@ Джастин:

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

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

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

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

...