Emacsモード:“コマンドはミニバッファーでミニバッファーを使用しようとしました”
-
03-07-2019 - |
質問
シナリオ:
- M-xと入力してコマンドを入力し始めます
- 間違ったウィンドウでコマンドを実行していることに気付いたため、別のemacsウィンドウ/バッファに切り替えました
- 正しいウィンドウでコマンドを実行するためにM-xを再度入力し始めます
結果:恐ろしい"コマンドはミニバッファーでミニバッファーを使用しようとしました"
これは、このシナリオだけでなく、emacsの使用中に1日に複数回発生します。この振る舞いはユーザーに対して非常に敵対的です(Jef Raskinによる The Humane Interface
のモードと擬似モードを参照)
emacsの動作をカスタマイズして、このエラーを発生させる代わりに、最初のミニバッファーをキャンセルして新しいミニバッファーに置き換える方法はありますか?
解決
確かにこのemacsの「機能」攻撃的で迷惑です。 これは問題に対する正しい答えであることがわかりました。ほとんどの場合、ミニバッファコマンドではなくマウスでウィンドウを切り替えたため、ミニバッファのフォーカスを失います。したがって、マウスを使用してフォーカスを失うと、ミニバッファーはクリアされます。この投稿を確認してください。それは私のために働いており、頭痛を引き起こす再帰的なミニバッファよりもはるかに優れています
http:// trey- jackson.blogspot.com/2010/04/emacs-tip-36-abort-minibuffer-when.html
他のヒント
変数 enable-recursive-minibuffers
を設定すると、エラーメッセージが表示されなくなります。しかし、ミニバッファーへの複数の呼び出しを有効にするだけです-現在のミニバッファーのコマンドを新しいバッファーにリダイレクトしません。これを試してみることができますが、元のアクションはまだ保留中なので、もっと混乱を招くと思います...
M-x
は 'execute-extended-command
にバインドされ、そのコマンドの再ホスト(元のバッファーの変更)は、継続を伴うプログラミングのようなものです。つまり、場所Xからサブルーチンを呼び出しますが、完了したらXに戻る代わりに、Yに戻ります。個人的には、解決するよりも混乱を招くと思います。しかし、私はフラストレーションを理解しています(そして、同じフラストレーションを持っている他の人を知っています)。
このようなカスタマイズがあるかどうかはわかりませんが、これを回避する方法は、 ctrl - g を押してコマンドをキャンセルすることですミニバッファに書き込みます。
私の最初の答えはあなたが望むものを直接あなたに与えないので、私は本当の解決策を思い付くと思いました。これは私が持っているものです:
(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)))))
この方法でテストしました。キーにバインドしました(私の場合は F10
b / c M-x
を失いたくありませんでした)。次に、2つのウィンドウを開いて、それぞれ異なるバッファーを表示します(AとBなど):
- バッファAを表示するウィンドウから:
F10 isearch-for
- ミニバッファーからAを表示するウィンドウに切り替える:
C-x o
- Aを表示しているウィンドウからBを表示しているウィンドウに切り替える:
C-x o
- "再ホスト"バッファーBからのコマンド:
F10
- ミニバッファーに戻り、コマンド
ward RET
を終了します
検索語の入力を開始すると、検索がバッファBに適用されました。
これは M-x
機能のみを置き換え、 M-x
から呼び出されたコマンドは置き換えません。また、このバージョンはプレフィックス引数をサポートしていません。
うまくいけば、これはあなたが望むものです。
次の点を改善できますか?
\これまでのところ、私が持っているTreyに感謝します:
(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)
上記の exit-minibuffer
の代わりに使用するコマンドは何ですか?
試しました
keyboard-escape-quit
exit-minibuffer
keyboard-quit
ここに行きます:
;; 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)