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

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?

Foi útil?

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):

  1. Na janela mostrando tampão A: F10 isearch-for
  2. Mudar de minibuffer a janela mostrando A: C-x o
  3. Mudar de janela mostrando à que mostrando B: C-x o
  4. "re-host" o comando de tampão B: F10
  5. 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)
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top