2012-04-30 8 views
5

A menudo me resulta necesario realizar varias operaciones de consulta y reemplazo seguidas porque, por ejemplo, deseo cambiar todas las ocurrencias de 23 a 24 en una línea, luego de 24 a 25 en la línea siguiente, y así sucesivamente (generalmente porque escribo una expresión en una línea que doblo varias veces en las líneas siguientes y necesito modificarlo ligeramente) ...Cómo agregar un toque dinámico a las macros de emacs y/o a las sustituciones de las consultas?

Una macro con Cx q o una tarea normal que hace varias consultas para reemplazar no parece ser lo suficientemente potente en situaciones como estas ¿Hay algo más general/flexible para manejar las sustituciones de variables o variaciones de macro variables como esta que puedo examinar? Creo que una vez me encontré con un ejemplo en la web donde las expresiones de lisp se introdujeron en ciertos comandos para ser más poderoso pero no recuerdo esto o donde lo leí ...

+5

Puede que esté pensando en esta página web, que describe algunas funciones de búsqueda/reemplazo muy potentes: http://steve-yegge.blogspot.com/2006/06/shiny-and-new-emacs-22.html – Tyler

+0

Sí , parece que estás buscando la expresión elisp en buscar/reemplazar que se describe en esa publicación del blog. Otra cosa muy útil para probar es una combinación de macros de teclado y elisp: crea una macro que escribe una expresión y luego la evalúa, muy útil para contadores y demás. –

+0

Ah sí, ese es el blog que había visto, ¡increíble! Gracias. –

Respuesta

6

No estoy seguro de esto por completo responde su pregunta, pero he encontrado que los registros son una herramienta útil para crear macros potentes. Las funciones más importantes son:

  • Cx rnnumber-to-register copiar el número en el punto en un registro
  • Cx r +increment-register incrementa el valor almacenado en un registro
  • Cx riinsert-register inserta el valor del registro en el buffer

El uso de estas funciones, se podría resolver el problema de la sustitución de los números que se incrementan en cada línea con:

  • semilla el primer número en un registro con number-to-register
  • iniciar la definición de macro
  • seleccionar una línea
  • replace-string , insert-register, increment-register, insert-register
  • va al principio de la siguiente línea
  • extremo macro definición

Hay más información sobre los registros del manual de emacs: https://www.gnu.org/software/emacs/manual/html_node/emacs/Registers.html

3

así como los usos ordenadas de comandos existentes, tales como la que se muestra por ataylor, macros de teclado se puede utilizar para llevar a cabo comportamientos casi arbitrariamente complejos y dinámicos.

De particular interés, CuM-: se inserte en la corriente amortiguar el resultado de cualquier forma elisp entras - una forma que puede, por supuesto, ser construido como parte de la macro - por lo incluso cuando no existe un comando para una operación en particular, es poco probable que se le impida usar macros para lograr sus objetivos.

(Y por supuesto si elisp no es la respuesta, C-uM- y C-uM- |! le dará un fácil acceso a la incorporación de la salida del comando shell también.

Naturalmente, hay casos en los que una solución más específica está disponible y una macro es más problemática de lo que vale (la técnica de "buscar y reemplazar con evaluación elisp" vinculada en los comentarios también es increíblemente poderosa, y solución ideal); Sin embargo, las macros de teclado también ofrecen una increíble cantidad de energía para un esfuerzo increíblemente pequeño, y pueden hacer algunas cosas con facilidad que de lo contrario podrías tener dificultades para implementar.

Uno de mis ejemplos favoritos es usar datos de mapeo "antiguos -> nuevos" en un búfer (en prácticamente cualquier formato imaginable) y usarlos para realizar una búsqueda y reemplazo de esos valores en otro búfer. La velocidad con la que puede hacer este tipo de cosas ad-hoc con nada más que simples movimientos y pulsaciones de teclas de edición es increíble.

El editor de macros también facilita la modificación de su macro si no es correcta la primera vez, sin la necesidad de volver a registrar todos los pasos.

Leí algunos consejos útiles una vez, que era simplemente intentar siempre pensar si se podía lograr una tarea con macros de teclado cada vez que encontraba algo no trivial. Cuanto más los use, más se dará cuenta de las diferentes formas en que puede usarlos, y pronto tendrá una nueva herramienta indispensable en su caja de herramientas.

2

La situación específica sobre la que pregunta es el lugar perfecto para usar query-replace-regexp.

M-x query-replace-regexp 
Regexp: \([0-9]+\) 
Replace with: \,(+ 1 (string-to-number \1)) 

que el uso encontrarán todos los conjuntos de uno o más dígitos (expresiones regulares Emacs no son compatibles con \d) y reemplazarlos con su incremento, provocando cada vez.

Los puntos clave son:

  • grupos capturados son cadenas que se puede llamar en la operación de sustitución
  • puede unir código arbitrario en la operación de sustitución con \,
  • puede utilizar grupos capturados como argumentos en cualquier código que cose de esta manera
1

Aquí hay otra posible solución a su problema planteado, utilizando un reemplazo de elisp y el contador de macro del teclado, que puede sembrar con un argumento de prefijo numérico.

(no voy a decir que es mejor , pero demuestra otra opción disponible.)

Así que asumiendo que el 23 fue el número inicial, se podría definir la macro siguiente, comenzando con:

C-2C-3F3

C-SPC  ;; set-mark-command 
C-e   ;; move-end-of-line 
<<replace-regexp>> ;; replace-regexp 
<f3>  ;; kmacro-start-macro-or-insert-counter 
C--   ;; negative-argument 
[email protected]   ;; mark-word 
M-w   ;; kill-ring-save 
RET   ;; indent-new-comment-line 
\   ;; self-insert-command 
,(1+  ;; self-insert-command * 4 
SPC   ;; self-insert-command 
C-y   ;; yank 
)   ;; self-insert-command 
RET   ;; indent-new-comment-line 

y F4 para detener la grabación.

(n.b. esta macro asume que cada línea en la región contiene un valor en la secuencia.)

Entonces resaltar las líneas restantes y utilizar C-xC-kr para actualizar todas las líneas en la región.

Se puede volver a poner el contador macro a cualquier valor deseado con C-xC-kC-c para volver a reproducir la macro sobre otra región.

Y dependiendo de cómo se vean sus datos en realidad, probablemente podría simplificarlo considerablemente eliminando por completo el replace-regexp, y simplemente moviéndose a donde sabe el número, eliminando el número existente e insertando el valor del contador en su lugar.

Cuestiones relacionadas