Come selezionare regioni non contigue in Emacs?


31

Supponiamo che io abbia già selezionato del testo nel buffer corrente. È possibile selezionare un altro tratto di testo, mantenendo la selezione precedente (e così via)?

Aggiunto : una motivazione per questa funzionalità è la seguente: supponiamo che io abbia del testo simile al seguente:

paragraph 1 ...

paragraph 2 ...

paragraph 3 ...

paragraph 4 ...

paragraph 5 ...

Vorrei rimuovere alcuni paragrafi (ad esempio 2, 4 e 6) e inserirli prima del paragrafo 1.



2
Esiste un pacchetto multi- selezione: skamphausen.de/cgi-bin/ska/multiselect Sembra un po 'un hack veloce.
Tobias,

A seconda delle dimensioni di ciò che stai selezionando e perché, multiple-cursorspotrebbe darti una soluzione.
Jordon Biondo,

@wasamasa Ho seguito le istruzioni fornite nel link che hai fornito. Dopo la prima selezione, ho selezionato la seconda regione mantenendo il tasto Meta. È stato selezionato, ma ci sono due problemi: (1) la seconda selezione sembra non essere una vera selezione, poiché la copia o l'eliminazione non funzionano. (2) non è possibile selezionare una terza selezione in questo modo.
Nome

1
La Wiki di Emacs ha una buona sezione sulla selezione secondaria . Vari miglioramenti lo rendono più utilizzabile dalla tastiera, ad esempio.
Disegnò

Risposte:


43

È possibile utilizzare append-next-kill(associato per C-M-wimpostazione predefinita) per accumulare il testo che si desidera inserire sopra paragraph 1:

  1. Uccidi paragraph 2come faresti normalmente.

  2. Segna paragraph 4e premi C-M-wprima di ucciderlo. Ripeti questo passaggio per tutti i paragrafi che desideri spostare prima paragraph 1.

Al termine, è possibile strappare prima il testo accumulato paragraph 1.


5
Anche con le cose di base, ci sono sempre alcune cose nuove da imparare! Questo è piuttosto utile, poiché di solito spreco un sacco di pressione dei tasti viaggiando sull'anello di uccisione quando devo farlo. Vorrei poter votare ancora un po '...
Nome utente significativo

9

È possibile utilizzare i registri combinati con l'anello di marcatura. Premere i segni correnti con C-<SPC> C-<SPC>, recuperarli in seguito con C-u C-<SPC>o salvarli in un registro, ad esempio btramite C-x r <SPC> b, e tornare indietro con C-x r j b.

Ora segna un'altra regione. C-u C-x r s acopierà la regione contrassegnata per registrarsi aed eliminerà il testo. Quindi contrassegnare la regione successiva e C-u C-x r + aaggiungere un'altra selezione a quel registro aed eliminarla.

È quindi possibile inserire i contenuti con C-x r i a.

Vedi la sezione "Salvataggio del testo nei registri" del manuale di Emacs.


5

Il nuovo supporto per regioni rettangolari in Emacs-24.4 ha effettivamente introdotto (gran parte) dell'infrastruttura necessaria per questa funzionalità [dopo tutto, una regione rettangolare è una regione non contigua].

Quindi, ora dovrebbe essere possibile implementare un pacchetto "split-region" che fornisce solo la funzionalità che stai chiedendo.

Certo, molti comandi Emacs non sono ancora stati adattati per utilizzare la nuova infrastruttura (ad esempio comandi come upcase-region, o undo-in-region, query-replace, ...) e quindi non funzionano ancora correttamente sui rettangoli (quindi non funzionerebbero correttamente su una "regione divisa"), ma questi sono bug che dovrebbero essere corretti nel tempo.


4

Installa browse-kill-ring.el

copia e uccidi tutte le regioni di interesse.

Devo indicare dove dovrebbe iniziare il reinserimento.

M-x browse-kill-ring RET aprirà un buffer e posizionerà il cursore al suo interno.

Digitare nper viaggiare pezzi.

RET inserirà il blocco nel punto nel buffer originale / altro.


3

Se le linee che vuoi manipolare possono essere distinte tramite una corrispondenza regex, puoi utilizzare la modalità di occorrenza per visualizzarle in una nuova finestra. È quindi possibile utilizzare la modalità di modifica occorrenza per modificarli, con il buffer originale che riflette le modifiche apportate nel buffer Occur.

Funziona meravigliosamente, ad esempio, in combinazione con la modalità a cursori multipli : poiché le linee che hai selezionato per apparire nel buffer Occur vengono visualizzate in modo contiguo indipendentemente da quanto si trovano nel buffer originale, puoi contrassegnarle tutte o un sottoinsieme e quindi attivarli mc/edit-linese modificarli tutti in una volta. (Sì, so che più cursori possono fare tutto da soli con mc/mark-all-like-this, ma è bello avere opzioni.)

Qualsiasi altra operazione di modifica che verrebbe eseguita più facilmente se si vedessero solo le righe su cui si desidera lavorare, come l'impostazione di una ricerca regex complicata e la sostituzione, o una macro che deve essere eseguita a turno su ciascuna riga di un buffer, può anche essere fatto in questo modo.


3

Questo risponde alla tua domanda generale, ma non in particolare al caso d'uso menzionato (spostando frammenti di codice).

Emacs ora ha quella che chiama una regione non contigua , che è il tipo di selezione che stai chiedendo. Vanilla Emacs non fornisce alcun modo speciale per creare una regione non contigua, tranne se si tratta di un rettangolo . Ma la libreria Zone lo fa.

Zone di libreria consente di definire più zone nel buffer. Un elenco di zone è una regione non contigua . Puoi anche pensarlo come più regioni, a seconda di come desideri utilizzarlo. È possibile definire più elenchi di zone in qualsiasi momento, ciascuno assegnato a una diversa variabile di zona e passare da uno all'altro.

Se usi anche la libreria Bookmark + puoi salvare gli elenchi di zone in modo persistente e ripristinarli nelle sessioni successive di Emacs. Bookmark + consente inoltre di assegnare tag arbitrari a un segnalibro. Ciò significa che è possibile taggare un elenco di zone.

Le zone in un determinato elenco di zone si trovano in genere nello stesso buffer, ma non è necessario. In questo, un elenco di zone è più generale di una regione non contigua. È anche più generale in quanto ogni zona può contenere informazioni aggiuntive, oltre ai limiti di zona, e può avere un identificatore.

Esistono diversi modi per creare una zona. Uno dei più semplici è usare C-x n a: definisce una zona dalla regione attiva e la aggiunge al set di zone corrente. ( C-x n n( narrow-to-region) fa anche questo, oltre al restringimento.)

Queste sono alcune delle cose che puoi fare con un set (elenco) di zone:

  • Ordinali.
  • Unire (unire) le zone adiacenti o sovrapposte (che include l'ordinamento).
  • Intersecali.
  • Restringere il buffer a una zona dell'elenco. Ciclo tra restringimenti. Vedi più restringimenti .
  • Seleziona una zona nell'elenco come regione attiva. Scorri tra le regioni.
  • Cerca (vengono automaticamente uniti prima). Per questo è necessaria la libreria Isearch + .
  • Interroga-sostituisci su di loro.
  • Evidenziarli e deselezionarli. (Per questo è necessario evidenziare la libreria o la libreria facemenu+.el.

Vedi anche Narrow Indirect , che consente di creare buffer indiretti che sono cloni di un determinato buffer e che sono ristretti a diverse parti di esso.


2

Un'altra opzione: trasposizione di paragrafi

Per completezza, è possibile ottenere il riordino dei paragrafi (in sequenza) con le aree contrassegnate e M-0 M-x transpose-paragraph(l'argomento zero fa tra-parscambiare i paragrafi in cui si trovano punto e segno, ovvero la regione inizia e finisce)!

A proposito, questo funziona per tutti i transpose-.*comandi (-words, -sexp, -sentences, ...) ed è estremamente utile in molte situazioni.


2

Un altro modo è usare il pacchetto objed (sono l'autore). È possibile contrassegnare qualsiasi oggetto di testo quando mil punto viene spostato automaticamente sull'oggetto successivo del tipo corrente. Deseleziona qualsiasi oggetto navigando verso di esso e premi di nuovo m. Ecco un esempio di screencast (mostra le linee di marcatura ma funziona anche per altri oggetti come paragrafi, defun ...):

inserisci qui la descrizione dell'immagine


Quando provo ad installare questo pacchetto da Melpa ricevo l'errore package-install-from-archive: http://melpa.milkbox.net/packages/objed-20181201.1346.tar: Not found.
Nome

@Nome Sembra che sia necessario aggiornare l'elenco dei pacchetti. Prova M-x package-refresh-contentse poi M-x package-install.
Clemera,

@Name Funziona ora? Fammi sapere se hai ulteriori domande.
Clemera,

Sono stato in grado di installare il pacchetto. Sembra funzionare bene, non ho testato tutte le sue funzionalità. Grazie.
Nome
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.