Como vinculo uma expressão regular a uma combinação de teclas no emacs?
Pergunta
Para contextualizar, sou um novato em emacs.Faz muito tempo que não uso, mas tenho usado cada vez mais (gosto muito).Além disso, estou confortável com o lisp, mas não estou muito familiarizado com o elisp.
O que preciso fazer é vincular uma expressão regular a uma combinação de teclado porque uso esse regex específico com frequência.
O que tenho feito:
M-C-s ^.*Table\(\(.*\n\)*?GO\)
Observe que usei nova linha acima, mas descobri que para isearch-forward-regexp
, você realmente precisa substituir o \n
na expressão regular com o resultado de C-q Q-j.Isso insere uma nova linha literal (sem finalizar o comando), permitindo-me colocar uma nova linha na expressão e fazer a correspondência entre as linhas.
Como posso vincular isso a uma combinação de teclas?
Entendo vagamente que preciso criar uma função elisp que execute isearch-forward-regexp
com a expressão, mas estou confuso com os detalhes.Pesquisei no Google e achei a maior parte da documentação um pouco confusa.
Como posso vincular uma expressão regular a uma combinação de teclas no emacs?
Mike Stone teve a melhor resposta até agora - não exatamente o que eu procurava, mas funcionou para o que eu precisava
Editar - isso meio que funcionou, mas depois de armazenar a macro, quando voltei a usá-la mais tarde, não consegui usá-la com Cx e.(ou seja, se eu reiniciar o emacs e digitar Nome da macro M-x, e então Cx e, recebo uma mensagem no minibuffer como 'no last kbd macro' ou algo semelhante)
@Mike Stone - Obrigado pela informação.Tentei criar uma macro assim:
C-x( M-C-s ^.*Table\(\(.*C-q C-J\)*?GO\) C-x)
Isso criou minha macro, mas quando a executei não obtive o mesmo destaque que normalmente recebo quando uso isearch-forward-regexp
.Em vez disso, simplesmente saltou para o final da próxima correspondência da expressão.Então isso realmente não funciona para o que eu preciso.Alguma ideia?
Editar:Parece que eu pode usar macros para fazer o que eu quero, só preciso pensar fora da caixa isearch-forward-regexp
.Vou tentar o que você sugeriu.
Solução
Você pode usar macros, basta fazer Cx ( então faça tudo para a macro, então Cx) para finalizar a macro, então Cx e executará a última macro definida.Então, você pode nomeá-lo usando MX nome-último-kbd-macro que permite atribuir um nome a ele, que você pode invocar com M-x TESTE, e armazene a definição usando Mx inserir-kbd-macro que colocará a macro em seu buffer atual, e então você poderá armazená-la em seu .emacs
arquivo.
Exemplo:
C-x( abc *return* C-x)
Irá definir uma macro para digitar "abc" e pressionar Enter.
C-xeee
Executa a macro acima imediatamente, 3 vezes (primeiro e a executa, depois os 2 e's irão executá-la mais duas vezes).
M-x name-last-kbd-macro testit
Nomeia a macro como "testit"
M-x testit
Executa a macro recém-nomeada (imprime "abc" e depois retorna).
M-x insert-kbd-macro
Coloca o seguinte no seu buffer atual:
(fset 'testit
[?a ?b ?c return])
Que pode então ser salvo em seu .emacs
arquivo para usar a macro nomeada repetidamente após reiniciar o emacs.
Outras dicas
Comecei resolvendo seu problema literalmente,
(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"))
A sequência de teclado de (kbd ...)
inicia uma nova pesquisa em branco.Para realmente pesquisar sua string, você pressiona última chave novamente quantas vezes você precisar.Então C-. t t t
ou <f6> <f6> <f6>
.A solução é basicamente um hack, mas deixarei aqui se você quiser experimentar.
O seguinte é provavelmente o mais próximo do que você precisa,
(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")
As combinações de teclas agora funcionam apenas no modo isearch.Você inicia a pesquisa normalmente e, em seguida, pressiona combinações de teclas para inserir sua string predefinida.
@Justino:
Ao executar uma macro, é um pouco diferente...pesquisas incrementais acontecerão apenas uma vez e você terá que executar a macro novamente se quiser pesquisar novamente.Você pode fazer coisas mais poderosas e complexas, como pesquisar uma palavra-chave, pular para o início da linha, marcar, ir para o final da linha, Mw (para copiar), depois pular para outro buffer e depois C-y (colar ), volte para o outro buffer e encerre sua macro.Então, cada vez que você executar a macro, você copiará uma linha para o próximo buffer.
O que é realmente legal sobre as macros do emacs é que elas param quando a campainha toca...o que acontece quando você não consegue corresponder a uma pesquisa incremental (entre outras coisas).Portanto, a macro acima, você pode fazer C-u 1000 C-x e que executará a macro 1000 vezes...mas como você fez uma pesquisa, ela copiará apenas 1000 linhas, OU ATÉ A PESQUISA FALHAR!O que significa que se houver 100 correspondências, a macro será executada apenas 100 vezes.
EDITAR:Confira C-hf Highlight-lines-matching-regexp que mostrará a ajuda de um comando que destaca tudo que corresponde a uma regex...Não sei como desfazer o realce...de qualquer forma, você poderia usar uma macro armazenada para destacar todas as correspondências com o regex e, em seguida, outra macro para encontrar a próxima...?
EDIÇÃO ADICIONAL:M-x unhighlight-regexp irá desfazer o destaque, mas você deve inserir o último regex (mas o padrão é o regex que você usou para destacar)
Em geral, para definir um atalho de teclado personalizado no Emacs, você escreveria
(define-key global-map (kbd "C-c C-f") 'function-name)
define-key
é, sem surpresa, a função para definir uma nova chave. global-map
é o mapa de teclado global, em oposição aos mapas individuais para cada modo. (kbd "C-c C-f")
retorna uma string representando a sequência de teclas C-c C-f
.Existem outras maneiras de fazer isso, incluindo inserir a string diretamente, mas geralmente é a mais direta, pois utiliza a representação escrita normal. 'function-name
é um símbolo que é o nome da função.
Agora, a menos que sua função já esteja definida, você desejará defini-la antes de usar isto.Para fazer isso, escreva
(defun function-name (args)
(interactive)
stuff
...)
defun
define uma função - use C-h f defun
para informações mais específicas.O (interactive)
não há realmente uma chamada de função;diz ao compilador que não há problema em a função ser chamada pelo usuário usando M-x function-name
e por meio de atalhos de teclado.
Agora, para pesquisas interativas em particular, isso é complicado;o isearch
O módulo realmente não parece estar configurado para o que você está tentando fazer.Mas você pode usar isso para fazer algo semelhante.