Come passare avanti e indietro tra due posizioni in un buffer


38

A volte mi trovo a alternare frequentemente tra due funzioni che sto modificando insieme. In queste situazioni, è noioso e doloroso continuare a fare un C-s <functionname>passaggio all'altra funzione e quindi trovare il posto esatto che stavo modificando in precedenza.

Come posso impostare i marker e poi saltare avanti e indietro tra due posizioni nel buffer con facilità?


3
Lo stai facendo male. Dovresti avere una vista divisa verticale in modo da vedere entrambe le funzioni contemporaneamente.
CaptainCodeman,

8
Non sono d'accordo sul fatto che OP stia "sbagliando". Mentre una finestra divisa sarebbe utile, OP dovrà comunque saltare avanti e indietro tra le finestre durante la modifica di entrambe le funzioni. Oltre a ciò, la domanda è più generale del caso d'uso specifico: OP vuole essere in grado di saltare rapidamente a diverse posizioni in un buffer. Molte risposte di seguito forniscono una serie di modi utili per farlo.
Dan

@Dan È un figo, e sono d'accordo con te, ma la mia risposta non ha lo scopo di risolvere il suo problema, ma solo per sottolineare che esiste un modo alternativo.
CaptainCodeman,

4
@CaptainCodeman, va bene, anche se la risposta di T. Vernon in basso fornisce l'alternativa a finestra divisa. Ti preghiamo di considerare il mio commento come una richiesta più generale di linguaggio proattivo nei post.
Dan

1
@CaptainCodeman Hai perfettamente ragione. Non sapevo che emacs supportasse una vista divisa verticale. Come tale, ho accettato la risposta che descrive in dettaglio l'utilizzo di queste viste divise verticali.
Vedaad Shakib,

Risposte:


20

Emacs windows

C-x 2aprirà un'altra finestra (= dividere il frame) sotto quella corrente, collegata allo stesso buffer. Puoi spostare il punto in entrambe le finestre senza influire sull'altra.

Puoi spostarti da una finestra all'altra usando C-x o. La libreria integrata windmove offre alcune funzioni che facilitano la navigazione tra le finestre.

Se questo metodo fa al caso tuo, potresti anche dare un'occhiata ai buffer indiretti .

inserisci qui la descrizione dell'immagine


Forse dovresti aggiungere qualche altra riga sull'uso dei buffer indiretti: è davvero più utile (e solo un po 'più complesso) rispetto all'utilizzo di un'altra finestra.
ffevotte,

@Francesco Capisco cosa intendi ora (con l'altra risposta sui buffer indiretti), anzi è anche un'opzione molto facile da usare. Questo non è l'uso che avevo in mente: il mio uso di buffer indiretti non sostituisce l'utilizzo di una finestra diversa, ma consente di modificare la vista con il restringimento, ad esempio. Aggiungerò alcune parole alla risposta quando trovo il tempo.
T. Verron,

56

registri:

C-xrSPCcorre point-to-register
C-xrjcorrejump-to-register

Digitare qualsiasi carattere per specificare un registro quando richiesto. 1

segnalibri:

C-xrmcorre bookmark-set
C-xrbcorrebookmark-jump

Mark ring:

C-SPCC-SPCspinge la posizione corrente sull'anello di marcatura (senza lasciarlo attivo).
C-uC-SPCfa scattare l'anello del segno, saltando alla posizione precedente. Puoi usarlo ripetutamente per navigare attraverso l'intero anello.

Nota che alcuni comandi (in particolare quelli che potrebbero spostarti di una distanza sconosciuta o arbitraria dalla tua posizione originale) spingeranno automaticamente verso l'anello di marcatura in modo che tu possa usare C-uC-SPCper tornare in seguito. Questo include isearch, quindi dopo aver usato C-sper andare da qualche parte, puoi facilmente tornare indietro di nuovo.

Scambia il punto e segna:

E come commenta Tu Do, C-xC-xcorre exchange-point-and-markche è molto utile per saltare tra due posizioni. Attiva anche il segno / la regione, ma puoi usare C-SPCper cancellare l'evidenziazione.


1 Se stai sfruttando la funzionalità di registrazione in elisp, usa alcuni simboli non in conflitto per il nome, piuttosto che un carattere, in modo da non poter entrare in conflitto con i registri impostati in modo interattivo (a meno che, ovviamente, non vuoi fare quella).


2
Dovresti anche aggiungere C-x C-x, poiché può saltare avanti e indietro tra due posizioni. C-u C-SPCfa scattare l'anello di marcatura ed eseguirlo di nuovo sposta il punto altrove.
Tu Do,

18

Oltre alla risposta di phils, ci sono alcune altre opzioni:

  • helm-all-mark-rings : ti permette di visualizzare il contenuto degli anelli di marcatura sia locali che globali in un'interfaccia amichevole, in modo da poter sempre tornare indietro dove eri. Puoi spingere il segno con C-SPC C-SPC. demo:

timone-all-mark-ring

  • helm-semantic-or-imenu : elenca tutte le definizioni disponibili nel file corrente. Se il cursore si trova all'interno di una definizione, quando si attiva l'evidenziatore preseleziona tale definizione.

  • sr-speedbar : un browser di file che elenca le sue definizioni in ciascun file. È simile all'albero del contorno in IDE.


9

Oltre ai registri e ai marcatori (vedi la risposta di @ phils su entrambi e il mio, Icicles risponde sui marcatori), i segnalibri , in particolare i segnalibri autonominati o temporanei, possono essere utili per questo. È necessaria la libreria Segnalibro + per questi tipi di segnalibri speciali.

  • Un autonamed segnalibro è uno che non è necessario dare un nome. È veloce da creare ed eliminare: basta premere un tasto. La stessa chiave crea o elimina un segnalibro nel punto. (Per impostazione predefinita, questo è legato a C-x p RET, ma puoi ovviamente usare qualsiasi tasto.)

  • I segnalibri con nome automatico sono, come i segnalibri in generale, persistenti. Ma puoi facoltativamente farli eliminare automaticamente.

  • È inoltre possibile creare segnalibri temporanei o rendere temporanei i segnalibri esistenti. Ad esempio, puoi scegliere di rendere i segnalibri con nome automatico automaticamente temporanei.

  • È possibile scorrere rapidamente tra un determinato set di segnalibri. Ad esempio, per scorrere tra i segnalibri con nome automatico, utilizzare i comandi bmkp-next-autonamed-bookmark-repeate bmkp-previous-autonamed-bookmark-repeat( associandoli ai tasti).

  • È possibile evidenziare le posizioni dei segnalibri in diversi modi, quindi è facile individuarli.


7

Per quanto riguarda i buffer indiretti menzionati nella risposta accettata ...

M-x clone-indirect-buffercreerà un buffer indiretto per il buffer corrente. Al nome del nuovo buffer verrà aggiunto '<2>' (o un numero maggiore se hai già nomi di buffer duplicati). Il nuovo buffer viene aperto in una nuova finestra. È possibile tornare a una singola finestra utilizzando C-x 0o C-x 1.

Con M-x winner-modete puoi passare facilmente tra le due posizioni. C-c <left>/ M-x winner-undoe C-c <right>/ M-x winner-redopassa da una configurazione di finestra all'altra. In questo caso le configurazioni saranno posizioni nei due buffer che visualizzano un file.

Nota: le funzioni winner-undoe winner-redofunzionano su un elenco di configurazioni. Se la configurazione viene modificata, ad es. Punto mobile, la configurazione corrente diventa la testa dell'elenco e winner-redonon è valida, in questo caso winner-undoriporterà la posizione precedente.

Per la situazione del PO ciò porta al seguente processo;

  1. Attiva la modalità vincitore M-x winner-mode
  2. Visita il file (nome file: File1.txt, nome buffer: File1.txt)
  3. M-x clone-indirect-buffer (nuovo nome del buffer indiretto: File1.txt <2>)
  4. Rendi la finestra corrente l'unica finestra C-x 1
  5. Trova la prima posizione di modifica, apporta le modifiche.
  6. Passa al file di visita del buffer originale, C-x b(il valore predefinito sarà il buffer originale a meno che non sia stato effettuato un passaggio a un altro buffer dal passaggio 3). Questo crea una nuova configurazione per il vincitore a cui tornare.
  7. Trova una posizione di modifica alternativa, apporta modifiche.

Un passaggio alla posizione di modifica precedente (configurazione della finestra) dipende dal fatto che venga effettuata una modifica alla configurazione della finestra tra gli interruttori;

  • Se viene apportata una modifica, passare utilizzando C-c <left>/ M-x winner-undo.
  • Se non viene apportata alcuna modifica, utilizzare C-c <left>/ M-x winner-undoper indietro e C-c <right>/ M-x winner-redoper avanti.

Un cambiamento è diverso da un altro winner-undoo winner-redo.


3

se usi evil-mode, il livello vim, quindi C-oe C-ifunzionerà allo stesso modo.

Eseguono i comandi evil-jump-backward/ forward. C-opassa alla posizione precedente nell'elenco dei salti, che viene impostato automaticamente (i segni sono impostati sui comandi di movimento). C-iva al contrario. Possiamo anche usare TABdopo a C-oinvece di C-i. Quindi l'utilizzo di entrambe le funzioni ti porterà avanti e indietro nel tuo buffer corrente.

Se vuoi che questa funzione sia cross-buffer, dai un'occhiata a evil-jumpers: http://melpa.org/#/evil-jumper

«
Evil-jumper è un componente aggiuntivo per evil-mode che sostituisce l'implementazione della jump list in modo tale da imitare più da vicino il comportamento di Vim. In particolare, salterà oltre i limiti del buffer e, se necessario, ripristinerà i dead buffer. La jump list può anche essere mantenuta in un file e ripristinata tra le sessioni. »

Nota: l'ho imparato su questo wiki


Questo non fornisce una risposta alla domanda. Per criticare o richiedere chiarimenti a un autore, lascia un commento sotto il suo post.
Dan

1
D'oh, e con quel commento automatizzato, intendo davvero che la risposta sembra essere destinata a essere un commento su un'altra risposta. Se intendessi che questa fosse una risposta a sé stante, potresti espandere un po 'su cosa C-oe cosa C-ifare?
Dan

Hai ragione ! fatto.
Ehvince,

2

Se usi Icicle , puoi navigare rapidamente tra i marker in mark-ringdi ciascun buffer o global-mark-ring(che ha un singolo marker in ciascun buffer).

Puoi farlo usando multi-comando C-- C-SPC (per un buffer mark-ring) o C-- C-x C-SPC(per il global-mark-ring). Dopo aver premuto il tasto una volta, usi i soliti tasti per ciclismo Icicles ecc., Per spostarti tra i marcatori dell'anello.

(Le stesse chiavi senza un prefisso arg impostano il segno ( set-mark-command) e pop il segno globale ( pop-global-mark), rispettivamente, proprio come fanno in Emacs alla vaniglia.)

Il testo della linea di ciascun marcatore viene utilizzato come candidato per il completamento. Durante la digitazione, l'input del minibuffer restringe i candidati a quelli corrispondenti (ad es. Sottostringa o corrispondenza regexp). Puoi scorrere rapidamente tra gli indicatori corrispondenti o visitare direttamente uno qualsiasi di essi. Puoi anche cambiare l'ordinamento ( C-,) per il ciclismo.


2

Una possibilità minima ma spesso utile - quando vuoi solo sbirciare l'altra funzione - è l'impostazione

(setq scroll-preserve-screen-position t)

che ti riporta alla posizione esatta del cursore iniziale quando passi da C-ve a M-v.


1

evil-modeimplementa marcatori in stile Vim . Puoi impostare i marker con ( m, cioè evil-set-marker) , e saltare al segno con il backtick `( evil-goto-mark) o alla linea del segno '( evil-goto-mark-line).

Quindi, è possibile creare il segno "a" nella prima posizione con ma, creare il segno "b" nella seconda posizione con ma, quindi 'asaltare per contrassegnare "a" e 'bsaltare per contrassegnare "b".


1

usa imenu e sotto il codice

(defvar rimenu-position-pair nil "positions before and after imenu jump")
(add-hook 'imenu-after-jump-hook
          (lambda ()
            (let ((start-point (marker-position (car mark-ring)))
                  (end-point (point)))
              (setq rimenu-position-pair (list start-point end-point)))))

(defun rimenu-jump ()
  "jump to the closest before/after position of latest imenu jump"
  (interactive)
  (when rimenu-position-pair
    (let ((p1 (car rimenu-position-pair))
          (p2 (cadr rimenu-position-pair)))

      ;; jump to the far way point of the rimenu-position-pair
      (if (< (abs (- (point) p1))
             (abs (- (point) p2)))
          (goto-char p2)
          (goto-char p1))
      )))

1

Negli ultimi 20 anni ho usato queste due gemme:

(defun ska-point-to-register ()
  "Store cursorposition _fast_ in a register. Use ska-jump-to-register
to jump back to the stored position."
  (interactive)
  (point-to-register 8))

(defun ska-jump-to-register ()
  "Switches between current cursorposition and position
that was stored with ska-point-to-register."
  (interactive)
  (let ((tmp (point-marker)))
    (jump-to-register 8)
    (set-register 8 tmp)))

Li lego a C-. e C-, rispettivamente, e li usano costantemente senza accorgersene più.

Sì, i registri, i marcatori e simili sono molto più flessibili e potenti, ma comunque, questo è uno di quei piccoli, rapidi aiutanti che mi rendono impossibile passare ad altri editor.


1
Wow, lo stai usando da più tempo di quanto non fossi vivo.
Vedaad Shakib,

Immagino che questo non accadrà ancora nel mondo del Node o del Codice di Visual Studio, ma chissà ... :-) Sono contento di vedere persone giovani e intelligenti che raccolgono ancora Emacs. Oh, e, non ho ancora 50 anni ;-)
Stefan Kamphausen,

Questo è davvero fantastico. Ho cercato di trovare un modo per passare tra due posizioni arbitrarie con la modalità contrassegno transitorio abilitata e questo risolve il problema davvero bene :) Grazie.
PlagueHammer,

0

Puoi anche sfruttare le macro, poiché possono essere rapidamente associate a tasti convenienti.

Ad esempio, registrare un salto nella posizione N usando <F3> M-g g N <F4>e assegnarlo al tasto F5 con C-x C-k b <F5>. Quindi fai lo stesso con le posizioni M e F6. Da ora in poi puoi semplicemente alternare F5 e F6 per saltare tra N e M.

Ancora più semplice, poiché <F4>esegue l'ultima macro registrata e <C-u> F4la successiva all'ultima, è possibile saltare la fase di associazione dei tasti e semplicemente alternare le posizioni usando <F4>e <C-u> F4.


Un'altra possibilità piuttosto radicale è quella di creare un buffer indiretto in un'altra finestra con <C-x> 4 c. Questo buffer ha gli stessi contenuti ma può avere una posizione del punto diversa. Ora basta semplicemente alternare tra Windows con <C-x> oil solito modo.

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.