aboutsummaryrefslogtreecommitdiff
path: root/helpful.el
diff options
context:
space:
mode:
authoryuhan0 <qythium@gmail.com>2023-06-10 18:49:41 +0800
committerWilfred Hughes <me@wilfred.me.uk>2023-08-08 08:16:26 -0700
commitacb3e335c7e1d52ac4887ff96f05b08dabf3a646 (patch)
tree363a1b31867151df7d6a2b31b62faf43034ca25e /helpful.el
parent6f8991a72c83d904725a9d6c00de2cabbef32de9 (diff)
Improve user-friendliness of disambiguation prompt
Uses read-char-choice for selecting between callable (press "c") and variable (press "v") when the symbol is ambiguous, eg. `buffer-file-name'. Less mental effort required than parsing a y-or-n-p prompt and answering in the negative to "show variable?" to show help for a function.
Diffstat (limited to 'helpful.el')
-rw-r--r--helpful.el58
1 files changed, 40 insertions, 18 deletions
diff --git a/helpful.el b/helpful.el
index abf872e..acec238 100644
--- a/helpful.el
+++ b/helpful.el
@@ -2775,6 +2775,28 @@ nil if SYMBOL doesn't begin with \"F\" or \"V\"."
prefix
(s-replace "_" "-" string))))))
+(defun helpful--disambiguate (sym choices)
+ "Prompt the user to disambiguate SYM via a `read-char-choice' selection.
+
+CHOICES is a list of tuples of the form (FN DESC CHAR), where
+
+ CHAR is the input character associated with the choice
+ DESC is a short description of the choice to display in the prompt.
+ FN is the function being chosen, which takes SYM as an argument.
+
+For instance, the choice (#'helpful-variable \"[v]ariable\" ?v)
+calls (helpful-variable SYM) when the key `v' is pressed in the prompt."
+ (let* ((prompt (format "%s is ambiguous: describe %s ?"
+ (propertize (symbol-name sym) 'face font-lock-keyword-face)
+ (mapconcat (-lambda ((_ desc _)) desc)
+ choices " / ")))
+ (chars (mapcar (-lambda ((_ _ char)) char)
+ choices))
+ (lookup (mapcar (-lambda ((fn _ char)) (cons char fn))
+ choices))
+ (input (read-char-choice prompt chars)))
+ (funcall (alist-get input lookup) sym)))
+
;;;###autoload
(defun helpful-symbol (symbol)
"Show help for SYMBOL, a variable, function or macro.
@@ -2785,25 +2807,25 @@ See also `helpful-callable' and `helpful-variable'."
"Symbol: "
(helpful--symbol-at-point)
#'helpful--bound-p)))
- (let ((c-var-sym (helpful--convert-c-name symbol t))
- (c-fn-sym (helpful--convert-c-name symbol nil)))
+ (let (choices)
+ (when-let (c-var-sym (helpful--convert-c-name symbol t))
+ (push (list (lambda (_) (helpful-variable c-var-sym))
+ "c-style [V]ariable" ?V)
+ choices))
+ (when-let (c-fn-sym (helpful--convert-c-name symbol nil))
+ (push (list (lambda (_) (helpful-callable c-fn-sym))
+ "c-style [F]unction" ?F)
+ choices))
+ (when (fboundp symbol)
+ (push (list #'helpful-callable "[c]allable" ?c) choices))
+ (when (boundp symbol)
+ (push (list #'helpful-variable "[v]ariable" ?v) choices))
(cond
- ((and (boundp symbol) (fboundp symbol))
- (if (y-or-n-p
- (format "%s is a both a variable and a callable, show variable?"
- symbol))
- (helpful-variable symbol)
- (helpful-callable symbol)))
- ((fboundp symbol)
- (helpful-callable symbol))
- ((boundp symbol)
- (helpful-variable symbol))
- ((and c-fn-sym (fboundp c-fn-sym))
- (helpful-callable c-fn-sym))
- ((and c-var-sym (boundp c-var-sym))
- (helpful-variable c-var-sym))
- (t
- (user-error "Not bound: %S" symbol)))))
+ ((null choices)
+ (user-error "Not bound: %S" symbol))
+ ((= 1 (length choices))
+ (funcall (caar choices) symbol))
+ (t (helpful--disambiguate symbol choices)))))
;;;###autoload
(defun helpful-variable (symbol)