diff options
| author | Basil L. Contovounesios <basil@contovou.net> | 2026-02-13 11:12:56 +0100 |
|---|---|---|
| committer | Basil L. Contovounesios <basil@contovou.net> | 2026-02-13 12:57:49 +0100 |
| commit | 11649c347107cba5f7ef8fd67ad8e77bc3b2472c (patch) | |
| tree | 6554a7b53ed16e66dbdb8a0c96feb03b0e07c938 | |
| parent | 4defb814ce00fbbc2cf2ad626e630a39f4da1456 (diff) | |
Fix counsel-M-x regression with amx/smex
Historically counsel-M-x transformed the amx and smex collections
into something that could be manipulated uniformly with the default
obarray candidates.
Recently this was refactored and opened up via the user option
counsel-M-x-collection to arbitrary completion tables.
The counsel-M-x :predicate was adapted accordingly, but I forgot to
check other relevant actions and key bindings.
This patch tries to introduce a bit more uniformity in action
argument handling, at least as is relevant to counsel-M-x.
* ivy.el (ivy--action-cand-to-str): New convenience function.
(ivy--action-insert, ivy--action-copy):
* counsel.el (counsel--info-lookup-symbol, counsel--find-symbol):
Use it to handle symbol-keyed alists.
(counsel--action-cand-to-interned): New convenience function,
similar in spirit but opposite to ivy--action-cand-to-str.
(counsel--describe-function): Use it to handle alists.
(counsel-M-x-action): Handle alists (#3078) and as yet unknown atoms
for flexibility.
(counsel-descbinds-action-find): Simplify now that
counsel--find-symbol takes symbols.
(counsel-descbinds-action-info): Simplify;
counsel-info-lookup-symbol takes both symbols and strings.
Fixes #3078.
| -rw-r--r-- | counsel.el | 36 | ||||
| -rw-r--r-- | ivy.el | 27 |
2 files changed, 44 insertions, 19 deletions
@@ -477,7 +477,9 @@ Used by commands `counsel-describe-symbol', (defun counsel--info-lookup-symbol () "Lookup the current symbol in the info docs." (interactive) - (ivy-exit-with-action #'counsel-info-lookup-symbol)) + (ivy-exit-with-action + (lambda (x) + (counsel-info-lookup-symbol (ivy--action-cand-to-str x))))) (ivy--no-M-x #'counsel--info-lookup-symbol #'ivy--minibuffer-p) (defun counsel--push-xref-marker (&optional m) @@ -497,10 +499,11 @@ Used by commands `counsel-describe-symbol', (ring-insert find-tag-marker-ring (or m (point-marker))))) (defun counsel--find-symbol (x) - "Find symbol definition that corresponds to string X." + "Find symbol definition that corresponds to action candidate X." (with-ivy-window (counsel--push-xref-marker) - (let ((full-name (get-text-property 0 'full-name x))) + (let* ((x (ivy--action-cand-to-str x)) + (full-name (get-text-property 0 'full-name x))) (if full-name (find-library full-name) (let ((sym (read x))) @@ -586,9 +589,16 @@ Variables declared using `defcustom' are highlighted according to (function-item ivy-thing-at-point) (function-item ivy-function-called-at-point))) +;; FIXME: Use this more in place of `intern'. +(defun counsel--action-cand-to-interned (x) + "Try to return Ivy action argument X as an existing symbol. +Not quite the dual of `ivy--action-cand-to-str'." + (intern-soft (if (consp x) (car x) x))) + (defun counsel--describe-function (candidate) "Pass string CANDIDATE to `counsel-describe-function-function'." - (funcall counsel-describe-function-function (intern candidate))) + (funcall counsel-describe-function-function + (counsel--action-cand-to-interned candidate))) ;;;###autoload (defun counsel-describe-function () @@ -995,9 +1005,17 @@ that returns a completion table suitable for `ivy-read'." "History for `counsel-M-x'.") (defun counsel-M-x-action (cmd) - "Execute CMD." - (setq cmd (intern - (subst-char-in-string ?\s ?- (string-remove-prefix "^" cmd)))) + "Execute CMD from `counsel-M-x'." + ;; Currently CMD is a string either following `ivy-immediate-done', + ;; or for all collection types but alist, where CMD is the original + ;; cons. There is no harm in allowing other atoms through. + (setq cmd (cond ((stringp cmd) + ;; For the benefit of `ivy-immediate-done'. + ;; FIXME: Check `intern-soft'? + (intern (subst-char-in-string + ?\s ?- (string-remove-prefix "^" cmd)))) + ((atom cmd) cmd) + ((intern-soft (car cmd))))) (counsel--M-x-extern-rank cmd) ;; As per `execute-extended-command'. (setq this-command cmd) @@ -1237,13 +1255,13 @@ See `execute-extended-command' for further information." "Find symbol definition of candidate X. See `counsel--find-symbol' for further information." (let ((cmd (cddr x))) - (counsel--find-symbol (symbol-name cmd)))) + (counsel--find-symbol cmd))) (defun counsel-descbinds-action-info (x) "Display symbol definition of candidate X, as found in the relevant manual. See `info-lookup-symbol' for further information." (let ((cmd (cddr x))) - (counsel-info-lookup-symbol (symbol-name cmd)))) + (counsel-info-lookup-symbol cmd))) ;;;###autoload (defun counsel-descbinds (&optional prefix buffer) @@ -4796,25 +4796,32 @@ Otherwise, forward to `ivy-kill-line'." (ivy-set-actions t - '(("i" ivy--action-insert "insert") - ("w" ivy--action-copy "copy"))) + `(("i" ,#'ivy--action-insert "insert") + ("w" ,#'ivy--action-copy "copy"))) (defun ivy--trim-grep-line-number (x) (if (string-match ":[0-9]+:" x) (substring x (match-end 0)) x)) +(defun ivy--action-cand-to-str (x) + "Try to return Ivy action argument X as a string." + (let ((x (if (consp x) (car x) x))) + (if (symbolp x) (symbol-name x) x))) + (defun ivy--action-insert (x) - (insert - (if (stringp x) - (ivy--trim-grep-line-number x) - (car x)))) + "Insert completion candidate X into current buffer at point." + (insert (funcall (if (stringp x) + #'ivy--trim-grep-line-number + #'ivy--action-cand-to-str) + x))) (defun ivy--action-copy (x) - (kill-new - (if (stringp x) - (ivy--trim-grep-line-number x) - (car x)))) + "Add completion candidate X to the kill ring." + (kill-new (funcall (if (stringp x) + #'ivy--trim-grep-line-number + #'ivy--action-cand-to-str) + x))) (defun ivy--switch-buffer-matcher (regexp candidates) "Return REGEXP matching CANDIDATES. |
