Modos de Emacs: "El comando intentó usar el minibúfer mientras estaba en el minibúfer"

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

  •  03-07-2019
  •  | 
  •  

Pregunta

Escenario:

  • Comienzo a escribir M-x para escribir un comando
  • Me cambio a otra ventana / búfer de emacs porque me doy cuenta de que estoy ejecutando el comando en la ventana incorrecta
  • Comienzo a escribir M-x nuevamente para ejecutar el comando en la ventana correcta

Resultado: me sale el temido " El comando intentó usar el minibúfer mientras estaba en el minibúfer "

Esto me sucede varias veces al día mientras uso emacs, y no solo en este escenario. Este comportamiento es altamente hostil para el usuario (modos de ref. Y pseudo modos en The Humane Interface de Jef Raskin)

¿Hay alguna manera de personalizar el comportamiento de emacs para que, en lugar de dar este error, simplemente cancele el primer minibúfer y lo reemplace por uno nuevo?

¿Fue útil?

Solución

De hecho, esta emacs " característica " Es agresivo y molesto. Descubrí que esta es la respuesta correcta al problema. Lo más probable es que hayas perdido el foco del minibúfer porque cambiaste las ventanas con el mouse y NO con un comando de minibúfer. Entonces, cuando pierdas el foco con el mouse, el minibúfer se borrará. Revisa esta publicación. Funciona para mí y es mucho mejor que los minibuffers recursivos que causan un dolor de cabeza

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

Otros consejos

Puedes configurar la variable enable-recursive-minibuffers , lo que evitará que aparezca ese mensaje de error. Pero solo habilita múltiples llamadas al minibúfer, no redirige el comando del minibúfer actual al nuevo búfer. Puedes intentarlo, pero creo que será más confuso porque la acción original aún está pendiente ...

M-x está vinculado a 'execute-extended-command , y el realojamiento (cambio del búfer original) para ese comando es algo así como una programación con continuación. es decir, llama a una subrutina desde la ubicación X, pero en lugar de volver a X cuando termina, vuelve a Y. Personalmente, creo que esto generaría más confusión de la que resolvería. Pero entiendo la frustración (y conozco a otros que tienen la misma frustración).

No estoy seguro de si existe tal personalización, pero la forma en que evito esto es golpear ctrl - g para cancelar el comando que estaba en el medio de escribiendo en el minibúfer.

Ya que mi primera respuesta no te da directamente lo que quieres, pensé que encontraría una solución real. Esto es lo que tengo:

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

Lo he probado de esta manera. Lo vinculé a una clave ( F10 en mi caso b / c no quería perder M-x ). Luego, con dos ventanas abiertas, cada una muestra un búfer diferente (por ejemplo, A y B):

  1. Desde la ventana que muestra el búfer A: F10 isearch-for
  2. Cambie de minibúfer a la ventana que muestra A: C-x o
  3. Cambie de la ventana que muestra A a la que muestra B: C-x o
  4. " re-host " el comando del búfer B: F10
  5. Ahora, nuevamente en el minibúfer, finalice el comando ward RET

Cuando comencé a escribir un término de búsqueda, la búsqueda se aplicó al búfer B.

Esto solo reemplaza la funcionalidad M-x , no los comandos invocados desde M-x . Además, esta versión no admite el argumento de prefijo.

Espero que esto sea lo que quieres.

¿Puede alguien mejorar lo siguiente?

Me he rendido y solo quiero configurar \ C-w para cancelar cualquier minibúfer anterior antes de abrir uno nuevo (como hacer \ C-g \ C-w)

Hasta ahora, gracias a 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)

¿Qué comando debo usar en lugar del exit-minibuffer anterior?

Lo he intentado

keyboard-escape-quit
exit-minibuffer
keyboard-quit

Aquí tienes:

;; 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 bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top