Subject: bug#65449: 30.0.50; [PATCH] strokes: Support running other function when no stroke matches

From: Liu Hui <[email-masked]>
Date: Tue, 22 Aug 2023 14:25:24 +0800

Hi,

This patch allows users to call another function when no stroke
matches, instead of signaling an error. I bind down-mouse-3 to
strokes-do-stroke, and would like to pop up the context menu when no
stroke matches. In addition, two arguments stroke and match can be
passed to the function for other uses (e.g. making the error message
more informative).
From b507a99e55709600dc17780d35efcd52236c7833 Mon Sep 17 00:00:00 2001
From: Liu Hui <[email-masked]>
Date: Tue, 22 Aug 2023 13:52:03 +0800
Subject: [PATCH] strokes: Support running other function when no stroke
 matches

* lisp/strokes.el (strokes-no-match-function): New variable.
(strokes-no-match-default): New function.
(strokes-execute-stroke): Run `strokes-no-match-function' when no
stroke matches.
---
 lisp/strokes.el | 20 +++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/lisp/strokes.el b/lisp/strokes.el
index 293bdf0f369..3537e4ff2ed 100644
--- a/lisp/strokes.el
+++ b/lisp/strokes.el
@@ -266,6 +266,9 @@ strokes-use-strokes-buffer
 the delay in switching to the strokes buffer."
   :type 'boolean)
 
+(defvar strokes-no-match-function 'strokes-no-match-default
+  "Function run when no stroke matches.")
+
 ;;; internal variables...
 
 (defvar strokes-window-configuration nil
@@ -838,14 +841,16 @@ strokes-read-complex-stroke
 	    (goto-char (point-min))
 	    (bury-buffer)))))))
 
+(defun strokes-no-match-default (&rest _)
+  "Signal an error when no stroke matches."
+  (error
+   "No stroke matches; see variable `strokes-minimum-match-score'"))
+
 (defun strokes-execute-stroke (stroke)
   "Given STROKE, execute the command which corresponds to it.
 The command will be executed provided one exists for that stroke,
-based on the variable `strokes-minimum-match-score'.
-If no stroke matches, nothing is done and return value is nil."
-  ;; FIXME: Undocument return value.  It is not documented for all cases,
-  ;; and doesn't allow differentiating between no stroke matches and
-  ;; command-execute returning nil, anyway.
+based on the variable `strokes-minimum-match-score'.  If no
+stroke matches, `strokes-no-match-function' is called."
   (let* ((match (strokes-match-stroke stroke strokes-global-map))
 	 (command (car match))
 	 (score (cdr match)))
@@ -859,10 +864,7 @@ strokes-execute-stroke
 				     strokes-file))
 		    (strokes-load-user-strokes))
 	     (error "No strokes defined; use `strokes-global-set-stroke'")))
-	  (t
-	   (error
-	    "No stroke matches; see variable `strokes-minimum-match-score'")
-	   nil))))
+	  (t (funcall strokes-no-match-function stroke match)))))
 
 ;;;###autoload
 (defun strokes-do-stroke (event)
-- 
2.25.1