2013-01-14 14 views
7

Mi piacerebbe fare una semplice modifica a Emacs in modo che i next-buffer e previous-buffer comandi (che ho legati a C-x <RIGHT> e C-x <LEFT> potranno saltare il buffer *Messages*.Fai emacs prossima buffer di saltare i messaggi * * tampone

sto usando Emacs 24 e il Emacs Starter Kit

ho letto le seguenti domande e relative risposte, ma non sono quello che voglio:.

Ecco alcuni dei motivi per cui non funzionano:

  • mi piacerebbe tenerlo il più semplice possibile. Meno modifiche alla configurazione sono migliori.
  • Non voglio uccidere o impedire del tutto *Messages*.
  • (add-to-list 'ido-ignore-buffers "^\*Messages\*" aiuta con il mio C-x b (ido-switch-buffer) ma non modifica il comportamento di next-buffer e previous-buffer.
+0

Penso che dovresti dare un'occhiata a IDO. Non è una risposta, ma una raccomandazione, perché (C-x ) xN è molto meno conveniente di C-x b xN. – desudesudesu

+0

Suggerisco che i lettori si riferiscono invece a http://emacs.stackexchange.com/q/17687/454 (che è più recente). – phils

risposta

6

Il modo più semplice a cui posso pensare è definire un consiglio per entrambe le funzioni. Qui è per next-buffer. Allo stesso modo sarebbe per previous-buffer. Si può anche definire una variabile di configurazione per abilitare/disabilitare il comportamento (o l'attivazione/disattivazione del consiglio):

(defadvice next-buffer (after avoid-messages-buffer-in-next-buffer) 
    "Advice around `next-buffer' to avoid going into the *Messages* buffer." 
    (when (string= "*Messages*" (buffer-name)) 
    (next-buffer))) 

;; activate the advice 
(ad-activate 'next-buffer) 

Forse è possibile confrontare i buffer in qualche altro modo, invece del suo nome stringa, ma che funzionerà. Il codice per il buffer precedente è quasi lo stesso. Non so neanche se ci sia un modo di chiamare la funzione originale senza attivare il consiglio una volta all'interno del consiglio stesso, ma ancora una volta, il codice funzionerà anche se il nome del buffer viene testato in seguito (fallirà se hai appena un buffer, ed è il buffer dei messaggi, alcuni codici possono controllare se c'è un solo buffer e non chiamare di nuovo next-buffer).

Se si desidera utilizzare una funzione autonoma che fa la stessa cosa:

(defun my-next-buffer() 
    "next-buffer, only skip *Messages*" 
    (interactive) 
    (next-buffer) 
    (when (string= "*Messages*" (buffer-name)) 
     (next-buffer))) 

(global-set-key [remap next-buffer] 'my-next-buffer) 
(global-set-key [remap previous-buffer] 'my-next-buffer) 
+5

Eviterei di usare 'defadvice' per funzioni in cui non si ha il controllo su chi le chiamerebbe. In questo caso, definirei nuove funzioni e le legheremo alle chiavi in ​​questione, in questo modo si sarebbe certi che non ci saranno effetti collaterali indesiderati. – Lindydancer

+0

Mmm ... forse hai ragione, sì, ma l'OP ha chiesto specificamente di cambiare il funzionamento di queste funzioni. Anche questo è ciò che è "defadvice", giusto? In ogni caso, sì, ridefinire i legami chiave è un'altra opzione praticabile, ovviamente. –

+0

Sarei felice di adattare le combinazioni di tasti per puntare a nuove funzioni. –

4

questo è quello che sto usando, in base alla risposta di Diego:

(setq skippable-buffers '("*Messages*" "*scratch*" "*Help*")) 

(defun my-next-buffer() 
    "next-buffer that skips certain buffers" 
    (interactive) 
    (next-buffer) 
    (while (member (buffer-name) skippable-buffers) 
    (next-buffer))) 

(defun my-previous-buffer() 
    "previous-buffer that skips certain buffers" 
    (interactive) 
    (previous-buffer) 
    (while (member (buffer-name) skippable-buffers) 
    (previous-buffer))) 

(global-set-key [remap next-buffer] 'my-next-buffer) 
(global-set-key [remap previous-buffer] 'my-previous-buffer) 

Non è ancora grande , perché si bloccherà se non ci sono buffer diversi dall'elenco skippable-buffers I. Io uso C-g per interrompere il ciclo quando accade come un hackaround.

+0

questa risposta dovrebbe essere accettata in quanto gestisce l'elenco dei buffer ignorabili – rkm

13

questo modo si può evitare il ciclo infinito:

(defun next-code-buffer() 
    (interactive) 
    (let ((bread-crumb (buffer-name))) 
    (next-buffer) 
    (while 
     (and 
     (string-match-p "^\*" (buffer-name)) 
     (not (equal bread-crumb (buffer-name)))) 
     (next-buffer)))) 
(global-set-key [remap next-buffer] 'next-code-buffer) 

Questo codice loop tra i respingenti non-stellati ("^\*").Per il vostro caso (solo evitare *Messages*) sarebbe:

(defun next-code-buffer() 
    (interactive) 
    (let ((bread-crumb (buffer-name))) 
    (next-buffer) 
    (while 
     (and 
     (equal "*Messages*" (buffer-name)) 
     (not (equal bread-crumb (buffer-name)))) 
     (next-buffer)))) 
(global-set-key [remap next-buffer] 'next-code-buffer) 

È possibile scrivere previous-code-buffer semplicemente sostituendo ogni next-buffer con previous-buffer.

+2

Grazie, i buffer di \ * Helm ... \ * mi fanno davvero incazzare. – CodyChan

2

Come sottolinea la risposta di RubenCaro, le altre risposte possono inserire loop infiniti. Ho pensato che l'approccio di David James su una lista dei buffer ignorabili fosse un po 'più bello, quindi ecco una variante di questo.

(setq my-skippable-buffers '("*Messages*" "*scratch*" "*Help*")) 

(defun my-change-buffer (change-buffer) 
    "Call CHANGE-BUFFER until current buffer is not in `my-skippable-buffers'." 
    (let ((initial (current-buffer))) 
    (funcall change-buffer) 
    (let ((first-change (current-buffer))) 
     (catch 'loop 
     (while (member (buffer-name) my-skippable-buffers) 
      (funcall change-buffer) 
      (when (eq (current-buffer) first-change) 
      (switch-to-buffer initial) 
      (throw 'loop t))))))) 

(defun my-next-buffer() 
    "`next-buffer' that skips `my-skippable-buffers'." 
    (interactive) 
    (my-change-buffer 'next-buffer)) 

(defun my-previous-buffer() 
    "`previous-buffer' that skips `my-skippable-buffers'." 
    (interactive) 
    (my-change-buffer 'previous-buffer)) 

(global-set-key [remap next-buffer] 'my-next-buffer) 
(global-set-key [remap previous-buffer] 'my-previous-buffer) 
+0

Riprodotto in forma leggermente migliorata su http://emacs.stackexchange.com/a/17694/454 - usa questa versione invece di questa (e in generale probabilmente stai meglio usare quella * domanda * invece di questa, come molte delle risposte qui, compresa la risposta accettata, sono piuttosto errate). – phils

Problemi correlati