Emacs Modos: “Command tentou usar minibuffer enquanto em minibuffer”
-
03-07-2019 - |
Pergunta
Cenário:
- eu começo a digitar M-x para digitar um comando
- eu mudar para outra janela emacs / tampão porque eu percebo que estou executando o comando na janela errada
- eu começo a digitar M-x novamente para executar o comando na janela correta ??li>
Resultado: eu recebo o temido "Command tentou usar minibuffer enquanto em minibuffer"
Esta me acontece várias vezes por dia, enquanto usando emacs, e não apenas neste cenário. Este comportamento é altamente user-hostil (ref. Modos e Pseudo-modos em The Humane Interface
por Jef Raskin)
Existe uma maneira de comportamento personaliza emacs de modo que em vez de dar esse erro, ele simplesmente cancela o primeiro minibuffer e substitui-lo por um novo?
Solução
Na verdade, este "recurso" emacs é agressivo e irritante. Eu encontrei este para ser a resposta certa para o problema .Most provável que você perdeu o foco do minibuffer porque você trocou janelas com o mouse e não uma ordem minibuffer. Assim, sempre que você perde o foco usando o mouse, o minibuffer serão apagados. Confira este post. Ele funciona para mim e é muito melhor do que minibuffers recursiva que irá causar uma dor de cabeça
http: // trey- jackson.blogspot.com/2010/04/emacs-tip-36-abort-minibuffer-when.html
Outras dicas
Você pode definir o enable-recursive-minibuffers
variável, o que impedirá que a mensagem de erro a partir chegando. Mas isso só permite que várias chamadas para o minibuffer - não redirecionar o comando do minibuffer atual para o novo buffer. Você pode tentar dar um presente, mas eu acho que vai ser mais confuso porque a ação original ainda está pendente ...
M-x
é obrigado a 'execute-extended-command
, e re-hospedagem (mudando o tampão original) para esse comando é como a programação com continuação. ou seja, você chamar uma sub-rotina do local X, mas em vez de voltar para X quando feito, você retornar ao Y. Eu, pessoalmente, acho que ele iria abrir mais confusão do que ele iria resolver. Mas eu entendo a frustração (e conhecer outras pessoas que têm a mesma frustração).
Eu não tenho certeza se é que existe tal personalização um, mas a maneira que eu evitar isso é bater Ctrl - g para cancelar o comando eu estava no meio da escrevendo no minibuffer.
Desde a minha primeira resposta não dar-lhe diretamente o que você quiser, eu pensei que eu ia chegar a uma solução real. Isto é o que eu tenho:
(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)))))
Eu testei-lo desta forma. I ligou-o a uma chave (F10
no meu caso b / c eu não queria perder M-x
). Em seguida, com duas janelas, cada um mostrando um buffer diferente (digamos, A e B):
- Na janela mostrando tampão A:
F10 isearch-for
- Mudar de minibuffer a janela mostrando A:
C-x o
- Mudar de janela mostrando à que mostrando B:
C-x o
- "re-host" o comando de tampão B:
F10
- Agora, de volta na minibuffer, terminar o
ward RET
comando
Quando eu comecei a digitar um termo de busca, a pesquisa aplicada ao tampão B.
Isso só substitui a funcionalidade M-x
, não os comandos invocados a partir M-x
. Além disso, esta versão não suporta o argumento prefixo.
Esperamos que este é o que você quer.
Alguém pode melhorar o seguinte?
Eu desisti e só quero conjunto \ C-w de cancelar qualquer minibuffer anterior antes de abrir uma nova (como fazer \ C-g \ C-w)
Até agora, graças à Trey eu tenho:
(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)
O comando que eu deveria usar no lugar de exit-minibuffer
acima?
Eu tentei
keyboard-escape-quit
exit-minibuffer
keyboard-quit
Aqui vai:
;; 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)