branch: externals/vertico commit 95d0d4c9aa0d13e4333cec0fdfdf19487e282a28 Author: Daniel Mendler <m...@daniel-mendler.de> Commit: Daniel Mendler <m...@daniel-mendler.de>
Guard Vertico hooks to automatically show stack traces --- CHANGELOG.org | 5 +++++ README.org | 20 +++----------------- vertico.el | 35 +++++++++++++++++++++++++++++------ 3 files changed, 37 insertions(+), 23 deletions(-) diff --git a/CHANGELOG.org b/CHANGELOG.org index 8d15a5967c..4d6e1a23de 100644 --- a/CHANGELOG.org +++ b/CHANGELOG.org @@ -2,6 +2,11 @@ #+author: Daniel Mendler #+language: en +* Development + +- Guard Vertico hooks to automatically print stack traces in order to ease + debugging. + * Version 2.1 (2025-04-19) - =vertico-flat-format=: Customizable =:spacer= string. diff --git a/README.org b/README.org index 9e8381e57b..2fa61ce9ed 100644 --- a/README.org +++ b/README.org @@ -502,23 +502,9 @@ assignment to the FSF. * Debugging Vertico -When you observe an error in the =vertico--exhibit= post command hook, you should -install an advice to enforce debugging. This allows you to obtain a stack trace -in order to narrow down the location of the error. The reason is that post -command hooks are automatically disabled (and not debugged) by Emacs. Otherwise -Emacs would become unusable, given that the hooks are executed after every -command. - -#+begin_src emacs-lisp -(setq debug-on-error t) - -(defun force-debug (func &rest args) - (condition-case e - (apply func args) - ((debug error) (signal (car e) (cdr e))))) - -(advice-add #'vertico--exhibit :around #'force-debug) -#+end_src +Vertico will automatically print a stack trace to the =*Messages*= buffer when an +error is detected. The stack trace allows you to narrow down the exact code +location which caused the error. * Problematic completion commands diff --git a/vertico.el b/vertico.el index efab3dca23..6c97e9a3d4 100644 --- a/vertico.el +++ b/vertico.el @@ -463,14 +463,37 @@ The value should lie between 0 and vertico-count/2." (put-text-property beg next 'face (remq face (ensure-list val)) obj)) (setq beg next)))) +(defun vertico--debug (&rest _) + "Debugger used by `vertico--guard'." + (require 'backtrace) + (declare-function backtrace-to-string "backtrace") + (declare-function backtrace-get-frames "backtrace") + (let ((inhibit-message t)) + (message "Vertico detected an error:\n%s" + (backtrace-to-string (backtrace-get-frames #'vertico--debug)))) + (let (message-log-max) + (message "%s %s" + (propertize "Vertico detected an error:" 'face 'error) + (substitute-command-keys "Press \\[view-echo-area-messages] to see the stack trace"))) + nil) + +(defmacro vertico--guard (&rest body) + "Guard BODY showing a stack trace on error." + `(condition-case nil + (let ((debug-on-error t) + (debugger #'vertico--debug)) + ,@body) + ((debug error) nil))) + (defun vertico--exhibit () "Exhibit completion UI." - (let ((buffer-undo-list t)) ;; Overlays affect point position and undo list! - (vertico--update 'interruptible) - (vertico--prompt-selection) - (vertico--display-count) - (vertico--display-candidates (vertico--arrange-candidates)) - (vertico--resize))) + (vertico--guard + (let ((buffer-undo-list t)) ;; Overlays affect point position and undo list! + (vertico--update 'interruptible) + (vertico--prompt-selection) + (vertico--display-count) + (vertico--display-candidates (vertico--arrange-candidates)) + (vertico--resize)))) (defun vertico--goto (index) "Go to candidate with INDEX."