¿Cómo seleccionar regiones no contiguas en Emacs?

31

Supongamos que ya he seleccionado algún texto en el búfer actual. ¿Es posible seleccionar otro tramo de texto, manteniendo la selección anterior (y así sucesivamente)?

Agregado : Una motivación para esta funcionalidad es la siguiente: Suponga que tengo un texto que se ve así:

paragraph 1 ...

paragraph 2 ...

paragraph 3 ...

paragraph 4 ...

paragraph 5 ...

Me gustaría eliminar algunos párrafos (por ejemplo, 2, 4 y 6) e insertarlos antes del párrafo 1.

Nombre
fuente
1
Hay una selección secundaria .
wasamasa
2
Hay un paquete de selección múltiple : skamphausen.de/cgi-bin/ska/multiselect Se parece un poco a un truco rápido.
Tobias
Dependiendo del tamaño de lo que esté seleccionando y por qué, multiple-cursorspuede darle una solución.
Jordon Biondo
@wasamasa Seguí las instrucciones dadas en el enlace que proporcionaste. Después de la primera selección, seleccioné la segunda región donde mantengo la tecla Meta. Se seleccionó, pero hay dos problemas: (1) la segunda selección parece no ser una selección real, ya que copiar o eliminar no funcionan. (2) no es posible seleccionar una tercera selección de esta manera.
Nombre
1
El Wiki de Emacs tiene una buena sección sobre la selección secundaria . Varias mejoras lo hacen más utilizable desde el teclado, por ejemplo.
Dibujó

Respuestas:

43

Puede usar append-next-kill(vinculado C-M-wde forma predeterminada) para acumular el texto que desea insertar arriba paragraph 1:

  1. Mata paragraph 2como lo harías normalmente.

  2. Marca paragraph 4y presiona C-M-wantes de matarlo. Repita este paso para todos los párrafos que le gustaría mover antes paragraph 1.

Cuando haya terminado, puede tirar del texto acumulado antes paragraph 1.

itsjeyd
fuente
55
Incluso con las cosas básicas, ¡siempre hay algunas cosas nuevas que aprender! Esto es bastante útil, ya que generalmente malgasto muchas teclas presionando viajando por el anillo de matar cuando necesito hacer esto. Ojalá pudiera votar esto un poco más ...
Nombre de usuario significativo
9

Puede usar registros combinados con el anillo de marca. Empuje las marcas actuales con C-<SPC> C-<SPC>, recupérelas más tarde con C-u C-<SPC>, o guárdelas en un registro, digamos b, vía C-x r <SPC> b, y salte más tarde con C-x r j b.

Ahora marque otra región. C-u C-x r s acopiará la región marcada para registrar ay eliminar el texto. Luego marque la siguiente región y C-u C-x r + aagregará otra selección a ese registro ay la eliminará.

Luego puede insertar el contenido con C-x r i a.

Consulte la sección "Guardar texto en registros" del manual de Emacs.

Andrew Swann
fuente
5

El nuevo soporte de región rectangular en Emacs-24.4 realmente introdujo (una gran parte de) la infraestructura necesaria para esta funcionalidad [después de todo, una región rectangular es una región no contigua].

Por lo tanto, ahora debería ser posible implementar un paquete de "región dividida" que proporcione la funcionalidad que está solicitando.

Es cierto que muchos comandos de Emacs todavía no se han adaptado para usar la nueva infraestructura (por ejemplo, comandos como upcase-region, odo-in-region, query-replace, ...) y, por lo tanto, todavía no funcionan correctamente en rectángulos (para que tampoco funcionen correctamente en una "región dividida"), pero estos son errores que, con suerte, deberían solucionarse con el tiempo.

Stefan
fuente
4

Instalar browse-kill-ring.el

copiar y matar todas las regiones de interés.

Tengo que señalar dónde debería comenzar la reinsertar.

M-x browse-kill-ring RET abrirá un búfer y colocará el cursor en él.

Escriba npara viajar en trozos.

RET insertará el fragmento en el punto en el búfer original / otro.

Andreas Röhler
fuente
3

Si las líneas que desea manipular se pueden distinguir mediante una coincidencia de expresiones regulares, puede usar el modo de aparición para verlas en una nueva ventana. Luego puede usar el modo de edición de ocurrencia para editarlos, con el búfer original que refleja los cambios que realiza en el búfer de ocurrencia.

Esto funciona de maravilla, por ejemplo, en combinación con el modo de cursores múltiples : debido a que las líneas que ha seleccionado para aparecer en el búfer Occur se muestran de forma contigua, independientemente de qué tan lejos estén en el búfer original, puede marcarlas todas o un subconjunto y luego activarlos mc/edit-linesy editarlos todos a la vez. (Sí, sé que los cursores múltiples pueden hacer esto por sí solos mc/mark-all-like-this, pero es bueno tener opciones).

Cualquier otra operación de edición que se haría más fácilmente si estuviera viendo solo las líneas en las que desea trabajar, como configurar una búsqueda y reemplazo de expresiones regulares complicadas, o una macro que necesita ejecutarse en cada línea de un búfer a su vez, También se puede hacer de esta manera.

dodgethesteamroller
fuente
3

Esto responde a su pregunta general, pero no particularmente al caso de uso que menciona (mover partes de código).

Emacs ahora tiene lo que llama una región no contigua , que es el tipo de selección que está preguntando. Vanilla Emacs no proporciona ninguna forma especial de crear una región no contigua, excepto si es un rectángulo . Pero las Zonas de la biblioteca sí.

Library Zones le permite definir múltiples zonas en su búfer. Una lista de zonas es una región no contigua . También puede considerarlo como múltiples regiones, dependiendo de cómo quiera utilizarlo. Puede tener múltiples listas de zonas definidas en cualquier momento, cada una asignada a una variable de zonas diferente, y puede cambiar entre ellas.

Si también usa la biblioteca Bookmark + , puede guardar listas de zonas de forma persistente y restaurarlas en sesiones posteriores de Emacs. Bookmark + también le permite asignar etiquetas arbitrarias a un marcador. Esto significa que puede etiquetar una lista de zonas.

Las zonas en una lista de zonas dada generalmente están en el mismo búfer, pero no es necesario que estén. En esto, una lista de zonas es más general que una región no contigua. También es más general porque cada zona puede contener información adicional, además de los límites de la zona, y puede tener un identificador.

Hay varias formas de crear una zona. Una de las más fáciles de usar C-x n aes que define una zona de la región activa y la agrega al conjunto de zonas actual. ( C-x n n( narrow-to-region) también hace esto, además de reducir).

Estas son algunas de las cosas que puede hacer con un conjunto (lista) de zonas:

  • Clasifícalos.
  • Unir (fusionar) zonas adyacentes o superpuestas (lo que incluye ordenarlas).
  • Entrecruzarlos.
  • Limite el búfer a una zona en la lista. Ciclo entre estrechamientos. Ver Estrechamiento múltiple .
  • Seleccione una zona en la lista como la región activa. Ciclo entre regiones.
  • Búscalos (se unen automáticamente primero). Para esto necesitas la biblioteca Isearch + .
  • Consulta-reemplazar sobre ellos.
  • Resaltar y resaltarlos. (Para esto necesita biblioteca Highlight o library facemenu+.el.

Consulte también Narrow Indirect , que le permite crear buffers indirectos que son clones de un buffer determinado y que se reducen a diferentes partes del mismo.

Dibujó
fuente
2

Otra opción: transponer párrafos

En aras de la integridad, puede lograr la reordenación de los párrafos (secuencialmente) con regiones marcadas y M-0 M-x transpose-paragraph(el argumento cero hace tra-parintercambiar los párrafos donde están el punto y la marca, es decir, la región comienza y termina).

Por cierto, esto funciona para todos los transpose-.*comandos (-words, -sexp, -sentences, ...) y es extremadamente útil en muchas situaciones.

Dieter.Wilhelm
fuente
2

Otra forma es usar el paquete objed (soy el autor). Puede marcar cualquier objeto de texto con mel punto que se mueve automáticamente al siguiente objeto del tipo actual. Desmarca cualquier objeto navegando hacia él y presiona m nuevamente. Aquí hay un screencast de ejemplo (muestra líneas de marcado pero también funciona para otros objetos como párrafos, defun ...):

ingrese la descripción de la imagen aquí

clemera
fuente
Cuando intento instalar este paquete desde Melpa me sale el error package-install-from-archive: http://melpa.milkbox.net/packages/objed-20181201.1346.tar: Not found.
Nombre el
@Name Eso suena como la necesidad de actualizar su lista de paquetes. Intenta M-x package-refresh-contentsy luego M-x package-install.
clemera
@ Nombre ¿Funciona ahora? Avíseme si tiene más preguntas.
clemera
Pude instalar el paquete. Parece funcionar bien, no he probado todas sus características. Gracias.
Nombre