Режимы Emacs: "Команда попыталась использовать минибуфер в минибуфере"
Сценарий:
- Я начинаю вводить M-x для ввода команды
- Я переключаюсь на другое окно/буфер emacs, потому что понимаю, что я выполняю команду в неправильном окне
- Я снова начинаю вводить M-x для выполнения команды в правильном окне
Результат: я получаю страшную команду "Команда пыталась использовать минибуфер в минибуфере"
Это происходит со мной несколько раз в день при использовании emacs, а не только в этом сценарии. Это поведение очень враждебно-враждебно (Режимы и псевдорежимы в The Humane Interface
от Jef Raskin)
Есть ли способ настроить поведение emacs, чтобы вместо того, чтобы давать эту ошибку, он просто отменяет первый минибуфер и заменяет его новым?
Ответы
Ответ 1
Действительно, эта особенность emacs является агрессивной и раздражающей.
Я нашел, что это правильный ответ на проблему. Вероятно, вы потеряли фокус минибуфера, потому что вы переключили окна с помощью мыши и НЕ команду минибуфера. Поэтому, когда вы теряете фокус с помощью мыши, минибуфер будет очищен. Проверьте этот пост. Это работает для меня, и это лучше, чем рекурсивные минибуферы, которые вызывают головную боль.
http://trey-jackson.blogspot.com/2010/04/emacs-tip-36-abort-minibuffer-when.html
Ответ 2
Вы можете установить переменную enable-recursive-minibuffers
, которая предотвратит появление этого сообщения об ошибке. Но он просто включает несколько вызовов минибуфера - он не перенаправляет текущую команду минибуфера в новый буфер. Вы можете попробовать, но я думаю, что это будет более запутанным, потому что исходное действие все еще ожидается...
M-x
привязан к 'execute-extended-command
, а повторный хостинг (изменение исходного буфера) для этой команды похож на программирование с продолжением. т.е. вы вызываете подпрограмму из местоположения X, но вместо того, чтобы вернуться к X, когда вы закончите, вы вернетесь к Y. Я лично считаю, что это откроет больше путаницы, чем это решит. Но я понимаю разочарование (и знаю других, у кого такое же расстройство).
Ответ 3
Я не уверен, есть ли такая настройка, но способ избежать этого - нажать ctrl - g, чтобы отменить команду, которую я был в середине записи в минибуфере.
Ответ 4
Поскольку мой первый ответ прямо не дает вам то, что вы хотите, я думал, что придумаю реальное решение. Это то, что у меня есть:
(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
). Затем, при открытии двух окон, каждый из которых показывает другой буфер (например, A и B):
- Из окна, показывающего буфер A:
F10 isearch-for
- Переключение с минибуфера на окно с изображением A:
C-x o
- Переключиться из окна, показывающего A, с изображением B:
C-x o
- "повторить" команду из буфера B:
F10
- Теперь вернитесь в минибуфер, завершите команду
ward RET
Когда я начал вводить поисковый запрос, поиск применялся к буферам B.
Это заменяет функциональность M-x
, а не команды, вызываемые из M-x
. Кроме того, эта версия не поддерживает аргумент префикса.
Надеюсь, это то, что вы хотите.
Ответ 5
Может ли кто-нибудь улучшить следующее:
Я отказался и просто хочу установить \C-w, чтобы отменить любой предыдущий минибуфер, прежде чем открывать новый (например, делать \C-g\C-w)
Пока благодаря Трей я получил:
(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
Ответ 6
Здесь вы идете:
;; 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)