Need a recipe for annotating consult-line
( consult-grep
etc) candidte buffer with which-function
#993
Replies: 13 comments 8 replies
-
Hi! I am not a which-function user since it turned out to be quite slow in my profiling, but this was years ago. Iirc it repeatedly loads and traverses the Imenu internally, which can be expensive depending on the backend. Nevertheless it would be good if we could ensure that Consult interacts nicely with this mode. There is also the new Breadcrumb as an alternative, which you may want to take a look at? |
Beta Was this translation helpful? Give feedback.
-
I haven't explored If the provider builds a pre-built symbols database, then mapping file + line + column to a context should be an easy job. (Leaving aside what the provider is and how performant it is, I would really like to hear about what hooks are provided by consult to update the mode line. IOW, if I would like to add a "update mode line" or "do a redisplay" of the preview window, what places I need to hook to. ) I am looking in to some leads, so that I can dig in to the
Let me see. |
Beta Was this translation helpful? Give feedback.
-
For a quick draft this works for (add-hook 'consult-after-jump-hook 'which-func-update) To the next question ...
Give me a clue or a starting point, and I can figure out the rest. |
Beta Was this translation helpful? Give feedback.
-
When doing (Note that my earlier screenshots of As a site note, the I would assume that |
Beta Was this translation helpful? Give feedback.
-
One of the places where it would be helpful, is to look for commands in a 3rd party package. IMHO, doing Using (I understand that the way As I write this comment, I wonder if this a way for Using (It appears that having I appreciate any recipe, or quick start hints to accomplish the tasks captured in the screenshots above |
Beta Was this translation helpful? Give feedback.
-
For single buffer functions like For multi-file functions like consult-grep, the cost of parsing the (possibly many) files is going to much higher than the cost of merely searching them so you're going to want a separate command anyway. See orderless issue 170 for the current state of annotation matching. Note also that which-function and imenu are useful in not just elisp buffers as are the mentioned consult commands. So any changes to consult for this would have to work in more contexts (do you want full headers in the annotations for text files?) |
Beta Was this translation helpful? Give feedback.
-
To get this or this use this (defun consult--candidate-consult-location-which-function (cand)
(let ((prop 'consult-location))
(pcase (get-text-property 0 prop cand)
((or (and (or (and `(,(and (pred markerp) marker) . ,line)
(let `(,buffer . ,point-at-bol)
(cons (marker-buffer marker)
(marker-position marker))))
`((,buffer . ,point-at-bol) . ,line))
(let ctx
(with-current-buffer buffer
(save-excursion
(goto-char point-at-bol)
(substring-no-properties
(or (which-function)
""))))))
(app (format "%S") ctx))
ctx))))
(defun consult--candidate-consult-location-lisp (cand)
(let ((prop 'consult-location))
(pcase (get-text-property 0 prop cand)
((app (format "%S") ctx)
ctx))))
(defun consult--candidate-consult-location-line-no (cand)
(pcase (get-text-property 0 'consult-location cand)
(`(,_ . ,line)
line)))
(defun consult--line-prefix (&optional curr-line)
(lexical-let* ((display-style
'prefix
;; 'suffix
)
(consult--candidate-to-context
;; #'consult--candidate-consult-location-line-no
#'consult--candidate-consult-location-which-function
;; #'consult--candidate-consult-location-lisp
))
(pcase display-style
(`prefix
(lambda (cand)
(list cand
(thread-last cand
(funcall (lambda (cand)
(->> cand
(funcall consult--candidate-to-context)
(format "%-50s| ") ; FIXME
(funcall (-rpartial #'propertize 'face 'marginalia-symbol))))))
"")))
(`suffix
(lambda (cand)
(consult--annotate-align cand
(->> cand
(funcall consult--candidate-to-context)
(funcall (-rpartial #'propertize 'face 'font-lock-warning-face)))))))))
|
Beta Was this translation helpful? Give feedback.
-
Apropos #993 (comment), I would have liked to see a IIUC how Regarding the performance hit of using So, the bottleneck in "the search and make sense of a 3rd party library" may not the be software that provides the context, but the human who has to exercise his cognitive functions ... I wonder how |
Beta Was this translation helpful? Give feedback.
-
To get this
or this
do this diff --git a/consult.el b/consult.el
index ad77917..d74dbe3 100644
--- a/consult.el
+++ b/consult.el
@@ -2557,7 +2557,8 @@ PREVIEW-KEY are the preview keys."
(cl-defun consult--read-1 (table &key
prompt predicate require-match history default
keymap category initial narrow add-history annotate
- state preview-key sort lookup group inherit-input-method)
+ state preview-key sort lookup group inherit-input-method
+ &allow-other-keys)
"See `consult--read' for the documentation of the arguments."
(consult--minibuffer-with-setup-hook
(:append (lambda ()
and this (defun consult--grep-which-function (cand &optional find-file)
(when cand
(let* ((file-end (next-single-property-change 0 'face cand))
(line-end (next-single-property-change (1+ file-end) 'face cand))
(matches (consult--point-placement cand (1+ line-end) 'consult-grep-context))
(file (substring-no-properties cand 0 file-end))
(line (string-to-number (substring-no-properties cand (+ 1 file-end) line-end)))
;; Hide line numbers and the separator that follows in candidates
(_ (add-text-properties (+ 1 file-end ) (+ 1 line-end)
(list 'invisible t)
cand))
(buffer (funcall (or find-file #'find-file-noselect) file))
(column (or (car matches) 0))
(which-function (when (buffer-live-p buffer)
(with-current-buffer buffer
(save-excursion
(without-restriction
(goto-char (point-min))
;; Location data might be invalid by now!
(ignore-errors
(forward-line (1- line))
(goto-char (min (+ (point) column) (pos-eol))))
(point-marker)
(substring-no-properties
(or (which-function) ""))))))))
(format "%-50s|"
(format "%s (%s)"
(propertize (file-name-nondirectory file) 'face 'marginalia-file-name)
(propertize which-function 'face 'marginalia-symbol)
)))))
;; To push an `:annotate' property to `consult-grep' command, do
;; `&allow-other-keys' in `consult--read-1'
(consult-customize consult-grep
:annotate
(lambda (cand)
(let ((display-style
'prefix
;; 'suffix
))
(pcase display-style
(`suffix
(consult--annotate-align cand
(consult--grep-which-function cand)))
(`prefix
(list cand (consult--grep-which-function cand) ""))))))
|
Beta Was this translation helpful? Give feedback.
-
Apropos #993 (comment) , how open you will be in adding IOW, I need some way to push an If the "push new property" is in place for (Note that I am the author of |
Beta Was this translation helpful? Give feedback.
-
Do you think there is a scope for improvement in how prefixes and suffixes are "aligned"? Screenshots created with recipe shared in #993 (comment) (The screenshots below are self-explanatory) Any way Any way (Artefact 1) and ... |
Beta Was this translation helpful? Give feedback.
-
To get this FILE + WHICH-FUNCTION as "prefix" annotation of `M-x consult-grep' (Note that the FILE + WHICH-FUNCTION annotation and the SEARCH HITS always start at the same column) do this diff --git a/consult.el b/consult.el
index ad77917..134ddee 100644
--- a/consult.el
+++ b/consult.el
@@ -2557,7 +2557,8 @@ PREVIEW-KEY are the preview keys."
(cl-defun consult--read-1 (table &key
prompt predicate require-match history default
keymap category initial narrow add-history annotate
- state preview-key sort lookup group inherit-input-method)
+ state preview-key sort lookup group inherit-input-method
+ &allow-other-keys)
"See `consult--read' for the documentation of the arguments."
(consult--minibuffer-with-setup-hook
(:append (lambda ()
@@ -4728,6 +4729,11 @@ BUILDER is the command line builder function."
(setq content (substring content 0 consult-grep-max-columns)))
(when highlight
(funcall highlight content))
+
+ ;; Hide leading white space in file text
+ (when (string-match (rx (and bos (one-or-more (any " " "\t")))) content)
+ (add-text-properties 0 (match-end 0) '(invisible t) content))
+
(setq str (concat file sep line sep content))
;; Store file name in order to avoid allocations in `consult--prefix-group'
(add-text-properties 0 file-len `(face consult-file consult--prefix-group ,file) str) and this ;; `which-function' annotation for `M-x consult-grep'
(custom-set-variables
`(vertico-count 5))
(custom-set-faces
'(consult-grep-context ((t ( :background "whitesmoke"
:box (:line-width (2 . 2) :color "grey75" :style released-button)
:height 1.01
)))))
(defface consult-annotate-face
'((t (
:box ( :line-width (2 . 2)
:style flat-button
)
:overline t
:weight bold
:height 1.01
)))
"Annotate face."
:group 'faces)
(defface consult-annotate-file-name-face
'((t ( :inherit (consult-annotate-face font-lock-function-name-face))))
"Annotate file name face."
:group 'faces)
(defface consult-annotate-which-function-face
'((t ( :inherit (consult-annotate-face font-lock-comment-face))))
"Annotate which function face."
:group 'faces)
(defface consult-annotate-indent-face
'((t ( :background "gray97")))
"Annotate indent face."
:group 'faces)
(defun consult--grep-which-function (cand &optional find-file)
(when cand
(let* ((file-end (next-single-property-change 0 'face cand))
(line-end (next-single-property-change (1+ file-end) 'face cand))
(matches (consult--point-placement cand (1+ line-end) 'consult-grep-context))
(file (substring-no-properties cand 0 file-end))
(line (string-to-number (substring-no-properties cand (+ 1 file-end) line-end)))
;; Hide line numbers and the separator that follows in candidates
(_ (add-text-properties (+ 1 file-end) (+ 1 line-end)
(list 'invisible t)
cand))
(buffer (funcall (or find-file #'find-file-noselect) file))
(column (or (car matches) 0))
(which-function (when (buffer-live-p buffer)
(with-current-buffer buffer
(save-excursion
(without-restriction
(goto-char (point-min))
;; Location data might be invalid by now!
(ignore-errors
(forward-line (1- line))
(goto-char (min (+ (point) column) (pos-eol))))
(point-marker)
(substring-no-properties
(or (which-function) ""))))))))
(concat
(propertize (format "%s" which-function) 'face 'consult-annotate-which-function-face)
(propertize (format " [%s]" (file-name-nondirectory file)) 'face 'consult-annotate-file-name-face)))))
;; To push an `:annotate' property to `consult-grep' command, do
;; `&allow-other-keys' in `consult--read-1'
(consult-customize consult-grep
:annotate
(lambda (cand)
(list
;; Candidate
(progn
(add-face-text-property 0 (length cand) 'consult-grep-context 'append cand)
cand)
;; Prefix
(format "%s\n%s"
(consult--grep-which-function cand)
(propertize "\t\t" 'face 'consult-annotate-indent-face))
;; Suffix
""))
) |
Beta Was this translation helpful? Give feedback.
-
In iteration shown at #993 (comment), the significant improvement is
FWIW, I like this implementation. The only drawback is the number of hits (= |
Beta Was this translation helpful? Give feedback.
-
Provide
which-function
(= "context of the hit") as an annotation to the search hits.Even without preview turned on, simply having the
which-function
in completions buffer (either asmarginalia
annotation or "in place" annotation) would help a lot.See screenshot for where I imagine the
which-function
annotation will be displayed. I don't look at the line numbers, and I would be happy if the line numbers of the hits are elided, andwhich-function
is displayed inside.Recipe for annotating
consult-line
(consult-grep
etc) withwhich-function
Beta Was this translation helpful? Give feedback.
All reactions