¿Cómo vinculo una expresión regular a una combinación de teclas en emacs?

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

  •  08-06-2019
  •  | 
  •  

Pregunta

Por contexto, soy algo así como un novato en emacs.Hace poco que lo uso, pero cada vez lo uso más (me gusta mucho).También me siento cómodo con lisp, pero no muy familiarizado con elisp.

Lo que tengo que hacer es vincular una expresión regular a una combinación de teclado porque uso esta expresión regular en particular con mucha frecuencia.

Lo que he estado haciendo:

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

Tenga en cuenta que utilicé una nueva línea arriba, pero descubrí que para isearch-forward-regexp, realmente necesitas reemplazar el \n en la expresión regular con el resultado de C-q Q-j.Esto inserta una nueva línea literal (sin finalizar el comando) lo que me permite poner una nueva línea en la expresión y hacer coincidir líneas.

¿Cómo puedo vincular esto a una combinación de teclas?

Entiendo vagamente que necesito crear una función elisp que se ejecute isearch-forward-regexp con la expresión, pero no entiendo los detalles.Busqué en Google y encontré que la mayoría de la documentación era un poco confusa.

¿Cómo puedo vincular una expresión regular a una combinación de teclas en emacs?


Mike Stone tuvo la mejor respuesta hasta el momento: no exactamente lo que buscaba pero funciono para lo que necesitaba

Editar: esto funcionó, pero después de almacenar la macro, cuando volví a usarla más tarde, no pude usarla con C-x e.(es decir, si reinicio emacs y luego escribo Nombre de macro M-x, y luego C-x e, aparece un mensaje en el minibúfer como "no hay última macro kbd" o algo similar)


@Mike Stone: gracias por la información.Intenté crear una macro como esta:

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

Esto creó mi macro, pero cuando la ejecuté no obtuve el mismo resaltado que normalmente obtengo cuando uso isearch-forward-regexp.En lugar de eso, simplemente saltó al final de la siguiente coincidencia de la expresión.Entonces eso realmente no funciona para lo que necesito.¿Algunas ideas?

Editar:parece que yo poder uso macros para hacer lo que quiero, sólo tengo que pensar fuera de la caja de isearch-forward-regexp.Probaré lo que me sugeriste.

¿Fue útil?

Solución

Puedes usar macros, solo hazlo. C-x ( luego haz todo para la macro, luego C-x) para finalizar la macro, entonces C-x e ejecutará la última macro definida.Luego, puedes nombrarlo usando M-x nombre-apellido-kbd-macro que le permite asignarle un nombre, que luego puede invocar con PRUEBA M-x, luego almacene la definición usando M-x insertar-kbd-macro lo que pondrá la macro en su búfer actual, y luego podrá almacenarla en su .emacs archivo.

Ejemplo:

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

Definirá una macro para escribir "abc" y presionará Enter.

C-xeee

Ejecuta la macro anterior inmediatamente, 3 veces (primero e la ejecuta, luego las siguientes 2 e la ejecutarán dos veces más).

M-x name-last-kbd-macro testit

Nombra la macro para "probar"

M-x testit

Ejecuta la macro recién nombrada (imprime "abc" y luego regresa).

M-x insert-kbd-macro

Pone lo siguiente en su buffer actual:

(fset 'testit
   [?a ?b ?c return])

Que luego se puede guardar en su .emacs archivo para usar la macro nombrada una y otra vez después de reiniciar emacs.

Otros consejos

Empecé resolviendo tu 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"))

La secuencia del teclado de (kbd ...) inicia una nueva búsqueda en blanco.Para buscar realmente su cadena, presione última clave nuevamente tantas veces como necesites.Entonces C-. t t t o <f6> <f6> <f6>.La solución es básicamente un truco, pero la dejaré aquí si quieres experimentar con ella.

Lo siguiente es probablemente lo más cercano a lo que necesita,

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

Las combinaciones de teclas ahora sólo funcionan en modo isearch.Inicia la búsqueda normalmente y luego presiona combinaciones de teclas para insertar su cadena predefinida.

@Justin:

Al ejecutar una macro, es un poco diferente...Las búsquedas incrementales solo se realizarán una vez y tendrás que ejecutar la macro nuevamente si deseas buscar nuevamente.Sin embargo, puedes hacer cosas más poderosas y complejas, como buscar una palabra clave, saltar al principio de la línea, marcar, ir al final de la línea, M-w (para copiar), luego saltar a otro buffer, luego C-y (pegar). ), luego regrese al otro búfer y finalice su macro.Luego, cada vez que ejecute la macro, copiará una línea al siguiente búfer.

Lo realmente bueno de las macros de emacs es que se detendrán cuando vea la campana...lo que sucede cuando no coincide con una búsqueda incremental (entre otras cosas).Entonces, la macro anterior, puedes hacer C-u 1000 C-x e que ejecutará la macro 1000 veces...pero como hiciste una búsqueda, solo copiará 1000 líneas, ¡O HASTA QUE LA BÚSQUEDA FALLE!Lo que significa que si hay 100 coincidencias, sólo ejecutará la macro 100 veces.

EDITAR:Consulte C-hf highlights-lines-matching-regexp que mostrará la ayuda de un comando que resalta todo lo que coincida con una expresión regular...Aunque no sé cómo deshacer el resaltado...de todos modos, ¿podrías usar una macro almacenada para resaltar todas las que coincidan con la expresión regular, y luego otra macro para encontrar la siguiente...?

EDICIÓN ADICIONAL:M-x unhighlight-regexp deshará el resaltado, aunque debes ingresar la última expresión regular (pero de manera predeterminada es la expresión regular que usaste para resaltar)

En general, para definir una combinación de teclas personalizada en Emacs, escribirías

(define-key global-map (kbd "C-c C-f") 'function-name)

define-key es, como era de esperar, la función para definir una nueva clave. global-map es el mapa de teclas global, a diferencia de los mapas individuales para cada modo. (kbd "C-c C-f") devuelve una cadena que representa la secuencia de claves C-c C-f.Hay otras formas de hacer esto, incluida ingresar la cadena directamente, pero esta suele ser la más sencilla ya que toma la representación escrita normal. 'function-name es un símbolo que es el nombre de la función.

Ahora, a menos que su función ya esté definida, querrá definirla antes de usarla.Para ello escribe

(defun function-name (args)
  (interactive)
  stuff
  ...)

defun define una función - uso C-h f defun para información más específica.El (interactive) en realidad no hay una llamada a función;le dice al compilador que está bien que el usuario llame a la función usando M-x function-name y mediante combinaciones de teclas.

Ahora bien, para la búsqueda interactiva en particular, esto es complicado;el isearch El módulo realmente no parece estar configurado para lo que estás intentando hacer.Pero puedes usar esto para hacer algo similar.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top