unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#61176: post-command-hook is not run if minibuffer input is aborted
@ 2023-01-30 15:07 Jonas Bernoulli
  2023-02-01 23:06 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 1 reply; 4+ messages in thread
From: Jonas Bernoulli @ 2023-01-30 15:07 UTC (permalink / raw)
  To: 61176


> -- Variable: post-command-hook
>     This normal hook is run by the editor command loop after it
>     executes each command (including commands terminated prematurely by
>     quitting or by errors).  At that time, ‘this-command’ refers to the
>     command that just ran, and ‘last-command’ refers to the command
>     before that.
>
>     This hook is also run when Emacs first enters the command loop (at
>     which point ‘this-command’ and ‘last-command’ are both ‘nil’).

- post-command-hook is run even if a command is "terminated prematurely
  by quitting or by errors".  This is very useful when it is crucial
  that some cleanup is run even when something goes wrong.

- When a command uses the minibuffer, then post-command-hook is
  additionally run when the minibuffer is setup, with this-command
  being the command that uses the minibuffer.  This happens before
  minibuffer-setup-hook is run.

  This is surprising, because undocumented, but easy to detect, because
  at this time this-command-keys-vector returns an empty vector.  Never-
  the-less this should be documented (instead of being "fixed"; I depend
  on this behavior, and so might others).

- However, when the command reads from the minibuffer and the user
  aborts that, then post-command-hook is NOT run a second time AFTER
  the command.

  This is extremely inconvenient.  IMO, the fact that this hook is
  documented to run even if the command "terminated prematurely by
  quitting or by errors", implies that the hook is run even if the
  quitting is done intentionally by the user.

  This could be fixed simply by running post-command-hook in this case
  as well.  If that is considered a dangerous change in behavior, then
  maybe a very similar hook --say unwind-command-hook-- could be added.

Cheers,
Jonas

Oh -- here's some code that can be used to observe this behavior:

(keymap-global-set "<f1>" '-command)
(keymap-global-set "<f2>" '-prepare)
(keymap-global-set "<f3>" '-cleanup)

(defun -prepare ()
  (interactive)
  (add-hook 'post-command-hook '-post)
  (add-hook 'minibuffer-setup-hook '-setup)
  (add-hook 'minibuffer-exit-hook '-exit))

(defun -cleanup ()
  (interactive)
  (remove-hook 'post-command-hook '-post)
  (remove-hook 'minibuffer-setup-hook '-setup)
  (remove-hook 'minibuffer-exit-hook '-exit))

(defun -post ()
  (message ";; -post    (%-10s %s)" (this-command-keys-vector) this-command))

(defun -setup ()
  (message ";; -setup   (%-10s %s)" (this-command-keys-vector) this-command))

(defun -exit ()
  (message ";; -exit    (%-10s %s)" (this-command-keys-vector) this-command))

(defun -command ()
  (interactive)
  (message ";; -command"))

;; -command
;; -post    ([f1]       -command)

(defun -command ()
  (interactive)
  (message ";; -command")
  (error "error in command"))

;; -command
;; -command: error in command
;; -post    ([]         -command)

(defun -command ()
  (interactive (error "error in interactive"))
  (message ";; -command"))

;; call-interactively: error in interactive
;; -post    ([]         -command)

(defun -command (arg)
  (interactive (list (read-string ": ")))
  (message ";; -command"))

;; -setup   ([f1]       -command)
;; -post    ([]         -command)
;; -post    ([97]       self-insert-command)
;; -exit    ([return]   exit-minibuffer)
;; -command
;; -post    ([f1]       -command)

;; -setup   ([f1]       -command)
;; -post    ([]         -command)
;; -exit    ([7]        abort-minibuffers)
;; Quit
;; -post    ([]         abort-minibuffers)

(defun -command ()
  (interactive)
  (message ";; -command")
  (read-string "-command: "))

;; -setup   ([f1]       -command)
;; -post    ([]         -command)
;; -post    ([97]       self-insert-command)
;; -exit    ([return]   exit-minibuffer)
;; -post    ([f1]       exit-minibuffer)

;; -setup   ([f1]       -command)
;; -post    ([]         -command)
;; -exit    ([return]   exit-minibuffer)
;; -post    ([f1]       exit-minibuffer)

(defun -command (arg)
  (interactive
   (list (read-from-minibuffer
	  ": " nil (let ((map (make-sparse-keymap)))
		     (set-keymap-parent map minibuffer-local-map)
		     (define-key map "a"
		       (lambda () (interactive)
			 (error "error in minibuffer")))
		     map))))
  (message ";; -command"))

;; -setup   ([f1]       -command)
;; -post    ([]         -command)
;; (lambda nil (interactive) (error error in minibuffer)): error in minibuffer
;; -post    ([]         (lambda nil (interactive) (error error in minibuffer)))
;; -exit    ([return]   exit-minibuffer)
;; -command
;; -post    ([f1]       -command)





^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2023-02-05 14:47 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-01-30 15:07 bug#61176: post-command-hook is not run if minibuffer input is aborted Jonas Bernoulli
2023-02-01 23:06 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-02-02 14:36   ` Jonas Bernoulli
2023-02-05 14:47     ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).