Fundamentos de múltiples cursores


55

Hace poco me enteré multiple-cursorsy parece un paquete muy útil. Revisé la documentación del repositorio original , pero los comandos aún me parecen un poco oscuros.

Luego vi el video en Emacs Rocks !, y el video es excelente, pero se enfoca principalmente en lo que multiple-cursorses capaz de hacer, en lugar de cómo hacerlo.

¿Hay tutoriales, tutoriales o ejemplos que ilustren su funcionalidad más básica?


44
Pude ponerme en marcha multiple-cursorsmuy rápidamente con solo leer el archivo README. Mi recomendación es simplemente aprender mc/mark-next-like-this. Pruébelo y familiarícese con lo que hace. A partir de ahí, consulte el archivo README cada vez que tenga una pregunta que comience con "Me pregunto si los cursores múltiples pueden hacer ..." Dicho todo esto, creo que es una introducción más básica que las rocas Emacs. El video sería útil para los principiantes.
nispio

¡Totalmente de acuerdo! Absolutamente no está claro cómo usarlo. Acabo de enmascarar líneas y luego hago mc / edit-lines con KBD enlazado (no a través de Mx como se indica en Github) Luego veo múltiples cursores pero desaparecen después de cualquier entrada de texto
Dima Fomin

Respuestas:


19

Además de los usos que describe @bastibe, utilizo múltiples cursores para agregar o eliminar texto del principio / final de un grupo de líneas:

  1. Mover el punto al principio o al final del área de interés.
  2. llamada set-rectangular-region-anchor(vinculada a la clave que desee, creo que la sugerencia de Magnars fue H-space, si tiene una hiperclave)
  3. Movió el punto hacia adelante o hacia atrás por línea ( C-ny C-p) hasta que tenga un cursor en cada línea que desea editar
  4. Inserte o elimine el texto según sea necesario, opcionalmente moviéndose al final de la línea ( C-e) para realizar cambios allí.

Puede usar forward-word, forward sentenceetc. para moverse hacia adelante y hacia atrás a lo largo de las líneas, lo que le permite editar la cuarta palabra en cada línea, incluso si el texto en cada línea no es idéntico.

Como ejemplo, hago este tipo de trabajo todo el tiempo:

  • C-u M-!ls / test-dat / pp5 / * fsaRETURN

    Esto inserta los contenidos del directorio pp5 en el búfer. Coloco el punto !al comienzo del listado:

!/test-dat/pp5/ONAB-6-5_Frag#89.fsa
/test-dat/pp5/QCJB-22-5_Frag#90.fsa
/test-dat/pp5/ONGL-1-5_Frag#102.fsa
/test-dat/pp5/ONGL-1-5_Frag#78.fsa
  • Añadir cursores para cada línea con H-space, C-nx 4
  • duplicar cada línea con C-k C-y space C-y C-a

!/test-dat/pp5/ONAB-6-5_Frag#89.fsa /test-dat/pp5/ONAB-6-5_Frag#89.fsa
!/test-dat/pp5/QCJB-22-5_Frag#90.fsa /test-dat/pp5/QCJB-22-5_Frag#90.fsa
!/test-dat/pp5/ONGL-1-5_Frag#102.fsa /test-dat/pp5/ONGL-1-5_Frag#102.fsa
!/test-dat/pp5/ONGL-1-5_Frag#78.fsa /test-dat/pp5/ONGL-1-5_Frag#78.fsa
  • recorte la primera sección en nombres de variables con M-dx 3 C-d C-fx3 M-dx3 <-

ONAB-6-5 <-! /test-dat/pp5/ONAB-6-5_Frag#89.fsa
QCJB-22-5 <-! /test-dat/pp5/QCJB-22-5_Frag#90.fsa
ONGL-1-5 <-! /test-dat/pp5/ONGL-1-5_Frag#102.fsa
ONGL-1-5 <-! /test-dat/pp5/ONGL-1-5_Frag#78.fsa
  • luego ajuste el nombre del archivo real en la función para cargarlo: read.file ( C-d" C-e")RETURN

ONAB-6-5 <- read.file("/test-dat/pp5/ONAB-6-5_Frag#89.fsa")
QCJB-22-5 <- read.file("/test-dat/pp5/QCJB-22-5_Frag#90.fsa")
ONGL-1-5 <- read.file("/test-dat/pp5/ONGL-1-5_Frag#102.fsa")
ONGL-1-5 <- read.file("/test-dat/pp5/ONGL-1-5_Frag#78.fsa")

Y listo, ha convertido una lista de archivos en el código para leer esa lista. ¡En realidad es mucho más difícil de describir que realmente hacer!


3
Si hace lo mismo con frecuencia, puede envolverlo en una macro de teclado. Las macros de teclado y multiple-cursorspueden hacer una combinación realmente poderosa.
nispio

@nispio estuvo de acuerdo! A veces estoy repitiendo el mismo proceso y una macro sería útil. Sin embargo, a menudo, hay pequeñas diferencias en el medio del flujo de trabajo que requieren ligeros cambios que 'romperían' una macro.
Tyler

1
A menudo puede describir con precisión la ubicación a la que desea que salte el cursor usando una expresión regular. En tales casos, el uso phi-searchpuede ser más robusto que navegar con comandos comoM-f (x3)
nispio

@nispio seguro, depende de la situación. Con nombres consistentemente estructurados es fácil moverse por palabras. No había usado la búsqueda en múltiples cursores ya que los comandos de búsqueda de emacs integrados son frágiles con mc. No sabía phi-search, ¡eso se ve genial!
Tyler

22

Básicamente tengo dos casos de uso frecuente para multiple-cursors:

  • Reemplace algunas cuerdas. Marque una instancia de una cadena, luego use mc/mark-next-like-thisy mc/mark-previous-like-thispara marcar más instancias de ella. Luego presioné inmediatamente C-wpara eliminar cada instancia, y en su lugar escribí una nueva cadena. Lo uso a menudo para cambiar el nombre de una variable en el código.
  • Edite varios lugares simultáneamente. Marque varias instancias de una cadena como antes, pero cancele la selección (pero no los cursores) inmediatamente usando C-g, o coloque la marca y el punto en la misma columna de diferentes líneas, y use mc/edit-linespara obtener un cursor por línea. Ahora puede usar comandos de edición regulares que operan en cada uno de estos cursores.

El primer caso de uso es particularmente útil con expand-region. Me he er/expand-regionunido a C-j, y mc/mark-next-like-thisy mc/mark-previous-like-thisa C->y C-<. Con eso, puedo seleccionar fácilmente el punto de palabra que está activado y marcar la aparición siguiente / anterior de esa palabra al instante.

El segundo caso de uso reemplazó la mayoría de los usos de macros para mí. En lugar de grabar una macro y luego aplicarla en varios lugares, colocaría un cursor en cada lugar y simplemente realizaría la operación en todos los lugares a la vez.


Gracias @bastibe. ¿Alguna vinculación particular que usted o multiple-cursors recomiende, por ejemplo, para mark-next-like-this& mark-previous-like-this?
Amelio Vazquez-Reina

@ user815423426 como se describe en la publicación, uso C->y C-<para mark-next-like-thisy mark-previous-like-this.
bastibe

¿Por qué no utilizar el estándar M-% para buscar y reemplazar ?
Dima Fomin

6

Me gustaría agregar algunos extras que a veces uso multiple-cursors.

He encontrado que lo siguiente es útil:

iy-go-to-char

A veces, te encuentras necesitando pasar al siguiente #o al siguiente ,o algún delimitador específico. Esto es especialmente útil cuando necesita moverse a través de diferentes números de palabras para cada cursor. Proporciona las funciones iy-go-to-chary iy-go-to-char-backward, que puede vincular y usar muy bien.

expandir-región

Esto es realmente útil por una razón similar a iy: cuando tiene líneas ligeramente diferentes debajo de cada cursor, y tal vez desee seleccionar la cadena entre comillas debajo del punto o similar.

cosas personalizadas

Estas son cosas que son solo elisp en mi configuración, pero me parecen útiles. Probablemente no escrito por mí.

Solicitud de entrada
Recibí este de Magnars en respuesta a una solicitud para poner una cadena diferente debajo de cada cursor. El código es simple, pero vincularlo a algo y usarlo para múltiples cursores es una forma práctica de insertar cosas ligeramente diferentes en cada lugar.

(defun prompt-for-insert ()
  (interactive)
  (insert (read-string "Insert: ")))

Número de incremento en el punto
Esto vino de SO o de emacswiki. No estoy seguro de cuál. Es bastante útil por sí solo, y también cuando se usa en combinación conmc/insert-numbers

(defun my-increment-number-decimal (&optional arg)
  "Increment the number forward from point by 'arg'."
  (interactive "p*")
  (save-excursion
    (save-match-data
      (let (inc-by field-width answer)
        (setq inc-by (if arg arg 1))
        (skip-chars-backward "0123456789")
        (when (re-search-forward "[0-9]+" nil t)
          (setq field-width (- (match-end 0) (match-beginning 0)))
          (setq answer (+ (string-to-number (match-string 0) 10) inc-by))
          (when (< answer 0)
            (setq answer (+ (expt 10 field-width) answer)))
          (replace-match (format (concat "%0" (int-to-string field-width) "d")
                                 answer)))))))

eval-and-replace
Esto es súper poderoso y permite algunos bits 'n' piezas realmente útiles. Evalúa cualquier sexp que esté detrás del cursor e inserta el resultado de evaluarlo.
Combínelo con, multiple-cursors-numberspor ejemplo, para insertar potencias de dos, o una serie que 0 1 2 0 1 2 0 1 2atraviesa cada línea o algo. (He hecho ambas cosas de manera útil) O úsela s.elpara escribir esas tediosas configuraciones de Java con las cosas predeterminadas. Escribes cada uno CONFIG_VALUE_VARIABLE, luego lo transformas CONFIG_VALUE_VARIABLE = "configValueVariable"corriendo s-camel-case.

(defun eval-and-replace ()
  (interactive)
  (let ((value (eval (preceding-sexp))))
    (kill-sexp -1)
    (insert (format "%s" value))))

iy-go-to-char es muy útil. Justo lo que estaba buscando.
Heinrich Hartmann

1
  1. Ve al final * de lo que deseas seleccionar.
  2. Presione C-S-bo M-S-bpara seleccionar hacia atrás hasta que seleccione una parte. También puedes usar la flecha de desplazamiento hacia la izquierda.
  3. Luego presione C->(presione Mayús si la tecla >está encima de la tecla de su teclado) hasta que seleccione más de un elemento.

* Es importante seleccionar hacia atrás o la primera selección colocará el cursor en la posición incorrecta.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.