all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Jonas Bernoulli <jonas@bernoul.li>
To: 61176@debbugs.gnu.org
Subject: bug#61176: post-command-hook is not run if minibuffer input is aborted
Date: Mon, 30 Jan 2023 16:07:30 +0100	[thread overview]
Message-ID: <87y1pk2h8t.fsf@bernoul.li> (raw)


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





             reply	other threads:[~2023-01-30 15:07 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-01-30 15:07 Jonas Bernoulli [this message]
2023-02-01 23:06 ` bug#61176: post-command-hook is not run if minibuffer input is aborted 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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87y1pk2h8t.fsf@bernoul.li \
    --to=jonas@bernoul.li \
    --cc=61176@debbugs.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

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

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.