Modalità Emacs: "Il comando ha tentato di utilizzare il minibuffer mentre era nel minibuffer"

StackOverflow https://stackoverflow.com/questions/812135

  •  03-07-2019
  •  | 
  •  

Domanda

Scenario:

  • Comincio a digitare M-x per digitare un comando
  • Passo a un'altra finestra / buffer di emacs perché mi rendo conto che sto eseguendo il comando nella finestra sbagliata
  • Comincio a digitare nuovamente M-x per eseguire il comando nella finestra corretta

Risultato: ottengo il temuto comando "quot" tentato di usare il minibuffer mentre si trova nel minibuffer "

Questo mi succede più volte al giorno mentre utilizzo emacs e non solo in questo scenario. Questo comportamento è altamente ostile all'utente (rif. Modalità e Pseudo-modalità in The Humane Interface di Jef Raskin)

C'è un modo per personalizzare il comportamento di emacs in modo che invece di dare questo errore, annulli semplicemente il primo minibuffer e lo sostituisca con uno nuovo?

È stato utile?

Soluzione

In effetti questa emacs "caratteristica" è aggressivo e fastidioso. Ho trovato che questa era la risposta giusta al problema. Molto probabilmente hai perso la concentrazione del minibuffer perché hai cambiato Windows con il mouse e NON un comando di minibuffer. Quindi ogni volta che perdi la messa a fuoco con il mouse, il minibuffer verrà cancellato. Controlla questo post. Funziona per me ed è molto meglio dei minibuffer ricorsivi che causeranno mal di testa

http: // trey- jackson.blogspot.com/2010/04/emacs-tip-36-abort-minibuffer-when.html

Altri suggerimenti

Puoi impostare la variabile enable-recursive-minibuffers , che impedirà la comparsa di quel messaggio di errore. Ma consente solo più chiamate al minibuffer - non reindirizza il comando del minibuffer corrente al nuovo buffer. Puoi provarlo, ma penso che sarà più confuso perché l'azione originale è ancora in sospeso ...

M-x è associato a 'execute-extended-command , e il re-hosting (modifica del buffer originale) per quel comando è un po' come una programmazione con continuazione. vale a dire che si chiama una subroutine dalla posizione X, ma invece di tornare a X una volta terminato, si torna a Y. Personalmente penso che creerebbe più confusione di quanto non risolva. Ma capisco la frustrazione (e conosco altri che hanno la stessa frustrazione).

Non sono sicuro che ci sia una tale personalizzazione, ma il modo in cui lo evito è premere ctrl - g per annullare il comando che mi trovavo nel mezzo di scrivendo nel minibuffer.

Poiché la mia prima risposta non ti dà direttamente quello che vuoi, ho pensato di trovare una soluzione reale. Questo è quello che ho:

(defvar my-execute-extended-command-source-buffer nil
  "var holding the buffer to which the extended-execute-command should apply")
(defvar in-my-execute-extended-command nil
  "internal use - indicates whether we're in a 'recursive edit' of sorts")
(defun my-execute-extended-command (command)
  "home-grown version of execute-extended-command that supports re-hosting the buffer"
  (interactive (list (if in-my-execute-extended-command
                   nil
                 (let ((in-my-execute-extended-command t))
                   (setq my-execute-extended-command-source-buffer (current-buffer))
                   (completing-read "My-x " obarray 'commandp t nil 'extended-command-history nil nil)))))
  (if in-my-execute-extended-command
      (progn (setq my-execute-extended-command-source-buffer (current-buffer))
             (select-window (minibuffer-window)))
    (switch-to-buffer my-execute-extended-command-source-buffer)
    (call-interactively (symbol-function (intern command)))))

L'ho provato in questo modo. L'ho associato a una chiave ( F10 nel mio caso b / c non volevo perdere M-x ). Quindi, con due finestre aperte, ognuna con un buffer diverso (diciamo A e B):

  1. Dalla finestra che mostra il buffer A: F10 isearch-for
  2. Passa dal minibuffer alla finestra che mostra A: C-x o
  3. Passa dalla finestra che mostra A a quella che mostra B: C-x o
  4. " re-host " il comando dal buffer B: F10
  5. Ora nel minibuffer, finisci il comando ward RET

Quando ho iniziato a digitare un termine di ricerca, la ricerca si applicava al buffer B.

Sostituisce solo la funzionalità M-x , non i comandi invocati da M-x . Inoltre, questa versione non supporta l'argomento prefisso.

Speriamo che sia quello che vuoi.

Qualcuno può migliorare quanto segue?

Ho rinunciato e voglio solo impostare \ C-w per annullare qualsiasi precedente minibuffer prima di aprirne uno nuovo (come fare \ C-g \ C-w)

Finora grazie a Trey ho:

(defun cancel-completing-read ()
  (if (> (minibuffer-depth) 0) (exit-minibuffer))
   (completing-read "My-x " obarray 'commandp t nil 'extended-command-history nil nil))

(defun cancel-and-execute-command (command)
  (interactive (list (cancel-completing-read)))
  (call-interactively (symbol-function (intern command))))

(global-set-key "\M-x" 'cancel-and-execute-command)

Quale comando devo usare al posto di exit-minibuffer sopra?

Ho provato

keyboard-escape-quit
exit-minibuffer
keyboard-quit

Ecco qua:

;; automatically cancel the minibuffer when you switch to it, to avoid
;; "attempted to use minibuffer" error.
;; cy was here

(provide 'cancel-minibuffer)

(defun cancel-minibuffer-first (sub-read &rest args)
    (let ((active (active-minibuffer-window)))
        (if active
                (progn
                    ;; we have to trampoline, since we're IN the minibuffer right now.
                    (apply 'run-at-time 0 nil sub-read args)
                    (abort-recursive-edit))
            (apply sub-read args))))

(advice-add 'read-from-minibuffer :around #'cancel-minibuffer-first)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top