2009-02-17 7 views
12

EDIT: Capisco che vi è un tasto di uscita da tastiera (che normalmente è associato a C-g); ma sono più interessato a sapere come si gestiscono le funzioni di editing fornite con Emacs (come in questo caso). Mi imbatto in questo tipo di situazioni di volta in volta quando voglio cambiare solo un po 'di alcune funzioni built-in.in Emacs, qual è il modo migliore per tastiera-escape-quit non distruggere altre finestre?

In emacs, quando si preme M-ESC ESC (o ESC tre volte), è possibile uscire da un sacco di situazioni come il segno transitorio, ecc. Ma di solito prendo la chiave di escape (in realtà rimappino questo in un singolo colpo della chiave di escape) più di quanto intendessi, e questo finisce per uccidere la mia configurazione di Windows, che è abbastanza fastidiosa. La funzione della tastiera-escape-quit è definita in simple.el:

(defun keyboard-escape-quit() 
    "Exit the current \"mode\" (in a generalized sense of the word). 
This command can exit an interactive command such as `query-replace', 
can clear out a prefix argument or a region, 
can get out of the minibuffer or other recursive edit, 
cancel the use of the current buffer (for special-purpose buffers), 
or go back to just one window (by deleting all but the selected window)." 
    (interactive) 
    (cond ((eq last-command 'mode-exited) nil) 
    ((> (minibuffer-depth) 0) 
    (abort-recursive-edit)) 
    (current-prefix-arg 
    nil) 
    ((and transient-mark-mode mark-active) 
    (deactivate-mark)) 
    ((> (recursion-depth) 0) 
    (exit-recursive-edit)) 
    (buffer-quit-function 
    (funcall buffer-quit-function)) 
    ((not (one-window-p t)) 
    (delete-other-windows)) 
    ((string-match "^ \\*" (buffer-name (current-buffer))) 
    (bury-buffer)))) 

e posso vedere che non voglio che le linee:

((not (one-window-p t)) 
    (delete-other-windows)) 

ma qual è il modo migliore per modificare questo funzione? Posso vedere solo due modi: 1) modificare simple.el 2) copiare questa funzione nel mio file .emacs e fare le modifiche lì. Entrambi i modi non sono in realtà buono; idealmente mi piacerebbe vedere qualcosa sulla linea di defadvice, ma non riesco a vedere come posso farlo in questo caso.

risposta

14

si potrebbe usare intorno consigli e ridefinire la funzione incriminata di fare ciò che si vuole (vale a dire un-window-p deve sempre tornare t):

(defadvice keyboard-escape-quit (around my-keyboard-escape-quit activate) 
    (let (orig-one-window-p) 
    (fset 'orig-one-window-p (symbol-function 'one-window-p)) 
    (fset 'one-window-p (lambda (&optional nomini all-frames) t)) 
    (unwind-protect 
     ad-do-it 
     (fset 'one-window-p (symbol-function 'orig-one-window-p))))) 

Questo tipo di atti come a (let ...) ma deve essere più complicato perché è necessario sovrascrivere una funzione per un ambito limitato anziché una variabile.

+4

Una migliore versione one-liner utilizzando flet (cioè la versione funzione del LET): (defadvice tastiera-fuga-quit (intorno al mio-tastiera-escape-smettere di attivare) (flet ((one-window-p (& nomini all-frame opzionali) t)) ad-do-it)) – polyglot

+0

L'estensione cl è necessaria per il funzionamento di flet. – Alan

+0

Potrebbe anche essere necessario cambiare 'flet' in' cl-flet'. – Alan

7

Di solito trovo che "keyboard-quit (C-g) funziona per uscire da tutte queste situazioni.

Tuttavia, se si vuole davvero avere una variante di questa funzione, penso che copi nel tuo file .emacs (e rinominando, di solito ho usato un prefisso di bp) e fare le modifiche lì è probabilmente l'opzione migliore.

EDIT, in risposta alla modifica: In generale, ogni volta che voglio una versione modificata di una funzione emacs, la scrivo da sola, oppure la copia sul mio .emacs, la rinominano bp-whotever e poi apporto le modifiche appropriate.

Il lato negativo di questo è che il mio .emacs è ENORME, e probabilmente extra-crufty con funzioni antiche che non sono più utilizzate ... il lato positivo è che ogni volta che ho bisogno di scrivere qualcosa di nuovo, ho tonnellate di campione il codice di guardare ...

0

Una singola pressione del tasto Esc, per impostazione predefinita, funge da prefisso Meta; cioè, una combinazione di tasti che coinvolge la chiave Meta.

Premendo tre volte il tasto Esc si eseguirà keyboard-escape-quit, che è simile a keyboard-quit ma con più di un comportamento "do what I mean".

Questo codice può essere d'aiuto nel caso d'uso.È possibile utilizzare questo nel file di inizializzazione di Emacs:

;;; esc always quits 
(define-key minibuffer-local-map [escape] 'minibuffer-keyboard-quit) 
(define-key minibuffer-local-ns-map [escape] 'minibuffer-keyboard-quit) 
(define-key minibuffer-local-completion-map [escape] 'minibuffer-keyboard-quit) 
(define-key minibuffer-local-must-match-map [escape] 'minibuffer-keyboard-quit) 
(define-key minibuffer-local-isearch-map [escape] 'minibuffer-keyboard-quit) 
(global-set-key [escape] 'keyboard-quit) 
1

Ecco un altro pezzo semplice consiglio che sfrutta il fatto che keyboard-escape-quit chiamate buffer-quit-function prima che le finestre di chiusura:

(defadvice keyboard-escape-quit 
    (around keyboard-escape-quit-dont-close-windows activate) 
    (let ((buffer-quit-function (lambda()()))) 
    ad-do-it)) 

Funziona con Emacs 25.1. (I originariamente utilizzato @ consiglio di scottfrazer, ma è infelice in 25.1. Non ho ancora preso la briga di debug.)

1

Sono più interessato a sapere di come uno si occupa di funzioni di editing che vengono con Emacs (come in questo Astuccio). Mi imbatto in questo tipo di situazioni di volta in volta quando voglio cambiare solo un po 'di alcune funzioni built-in.

Questo è esattamente lo scopo per cui ho creato la libreria el-patch. Si potrebbe mettere questo nel file init-file:

(el-patch-defun keyboard-escape-quit() 
    "Exit the current \"mode\" (in a generalized sense of the word). 
This command can exit an interactive command such as `query-replace', 
can clear out a prefix argument or a region, 
can get out of the minibuffer or other recursive edit, 
cancel the use of the current buffer (for special-purpose buffers), 
or go back to just one window (by deleting all but the selected window)." 
    (interactive) 
    (cond ((eq last-command 'mode-exited) nil) 
    ((> (minibuffer-depth) 0) 
    (abort-recursive-edit)) 
    (current-prefix-arg 
    nil) 
    ((and transient-mark-mode mark-active) 
    (deactivate-mark)) 
    ((> (recursion-depth) 0) 
    (exit-recursive-edit)) 
    (buffer-quit-function 
    (funcall buffer-quit-function)) 
    (el-patch-remove 
     ((not (one-window-p t)) 
     (delete-other-windows))) 
    ((string-match "^ \\*" (buffer-name (current-buffer))) 
    (bury-buffer)))) 
Problemi correlati