all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* bug#74408: 30.0.92; FR: Add a function completion-list-candidate-at-point
@ 2024-11-17 21:10 Daniel Mendler via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-11-17 21:46 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 1 reply; 7+ messages in thread
From: Daniel Mendler via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-11-17 21:10 UTC (permalink / raw)
  To: 74408; +Cc: Stefan Monnier

Emacs 31 comes with the internal function
`completions--start-of-candidate-at' in simple.el, which returns the
position of the completion candidate at point in the completions buffer.
I propose to replace this function with a slightly improved version,
which returns the candidate string in addition to the candidate bounds.
It could be made part of the public API:

(defun completion-list-candidate-at-point ()
  "Return completion candidate string at point with bounds in completions buffer."
  (let (beg end)
    (when (cond
           ((and (not (eobp)) (get-text-property (point) 'completion--string))
            (setq end (point) beg (1+ (point))))
           ((and (not (bobp)) (get-text-property (1- (point)) 'completion--string))
            (setq end (1- (point)) beg (point))))
      (list (get-text-property
             (previous-single-property-change beg 'completion--string)
             'completion--string)
            beg end))))

For a few years, the GNU ELPA packages like Embark and Consult had
versions of this function. These packages need to obtain the completion
candidate at point when acting on the candidate. If
`completion-list-candidate-at-point' is made available in Emacs, I can
port it back via the GNU ELPA Compat package, such that external
packages can take advantage of the new function, and don't have to rely
on internals like the `completion--string' property.

If there is interest, I can provide a patch for simple.el which replaces
`completions--start-of-candidate-at'. Thank you for your consideration.

Daniel





^ permalink raw reply	[flat|nested] 7+ messages in thread

* bug#74408: 30.0.92; FR: Add a function completion-list-candidate-at-point
  2024-11-17 21:10 bug#74408: 30.0.92; FR: Add a function completion-list-candidate-at-point Daniel Mendler via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-11-17 21:46 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-11-18  0:06   ` Daniel Mendler via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 1 reply; 7+ messages in thread
From: Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-11-17 21:46 UTC (permalink / raw)
  To: Daniel Mendler; +Cc: 74408

> Emacs 31 comes with the internal function
> `completions--start-of-candidate-at' in simple.el, which returns the
> position of the completion candidate at point in the completions buffer.
> I propose to replace this function with a slightly improved version,
> which returns the candidate string in addition to the candidate bounds.
> It could be made part of the public API:

Sounds fine to me.


        Stefan






^ permalink raw reply	[flat|nested] 7+ messages in thread

* bug#74408: 30.0.92; FR: Add a function completion-list-candidate-at-point
  2024-11-17 21:46 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-11-18  0:06   ` Daniel Mendler via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-11-18 23:25     ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 1 reply; 7+ messages in thread
From: Daniel Mendler via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-11-18  0:06 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: 74408

[-- Attachment #1: Type: text/plain, Size: 492 bytes --]

Stefan Monnier <monnier@iro.umontreal.ca> writes:

>> Emacs 31 comes with the internal function
>> `completions--start-of-candidate-at' in simple.el, which returns the
>> position of the completion candidate at point in the completions buffer.
>> I propose to replace this function with a slightly improved version,
>> which returns the candidate string in addition to the candidate bounds.
>> It could be made part of the public API:
>
> Sounds fine to me.

Thanks. Patch attached.

Daniel


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-New-function-completion-list-candidate-at-point.patch --]
[-- Type: text/x-diff, Size: 4233 bytes --]

From 97dbfca1562b5d416617331617ebbc1594f683fd Mon Sep 17 00:00:00 2001
From: Daniel Mendler <mail@daniel-mendler.de>
Date: Mon, 18 Nov 2024 00:58:48 +0100
Subject: [PATCH] New function `completion-list-candidate-at-point'

Replace `completions--start-of-candidate-at' with the new
function `completion-list-candidate-at-point' which returns both
the candidate string and the candidate bounds.

* lisp/simple.el (completions--start-of-candidate-at): Remove.
(completion-list-candidate-at-point): New function.
(choose-completion): Use it.
* lisp/minibuffer.el (minibuffer-completion-help): Use it.
---
 lisp/minibuffer.el |  6 ++++--
 lisp/simple.el     | 41 ++++++++++++++++++++---------------------
 2 files changed, 24 insertions(+), 23 deletions(-)

diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el
index 9b498615926..ed0c5142b17 100644
--- a/lisp/minibuffer.el
+++ b/lisp/minibuffer.el
@@ -2628,8 +2628,10 @@ minibuffer-completion-help
               (when-let* ((buffer (get-buffer "*Completions*"))
                           (window (get-buffer-window buffer 0)))
                 (with-current-buffer buffer
-                  (when-let* ((beg (completions--start-of-candidate-at (window-point window))))
-                    (cons (get-text-property beg 'completion--string) (- (point) beg))))))
+                  (when-let* ((cand (save-excursion
+                                     (goto-char (window-point window))
+                                     (completion-list-candidate-at-point))))
+                    (cons (car cand) (- (point) (cadr cand)))))))
              ;; If the *Completions* buffer is shown in a new
              ;; window, mark it as softly-dedicated, so bury-buffer in
              ;; minibuffer-hide-completions will know whether to
diff --git a/lisp/simple.el b/lisp/simple.el
index 3a142ef14b3..5687c16387c 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -10246,22 +10246,22 @@ choose-completion-deselect-if-after
 
 This makes `completions--deselect' effective.")
 
-(defun completions--start-of-candidate-at (position)
-  "Return the start position of the completion candidate at POSITION."
-  (save-excursion
-    (goto-char position)
-    (let (beg)
-      (cond
-       ((and (not (eobp))
-             (get-text-property (point) 'completion--string))
-        (setq beg (1+ (point))))
-       ((and (not (bobp))
-             (get-text-property (1- (point)) 'completion--string))
-        (setq beg (point))))
-      (when beg
-        (or (previous-single-property-change
-             beg 'completion--string)
-            beg)))))
+(defun completion-list-candidate-at-point ()
+  "Return candidate string at point and bounds in completions buffer."
+  (let (beg)
+    (when (cond
+           ((and (not (eobp))
+                 (get-text-property (point) 'completion--string))
+            (setq beg (1+ (point))))
+           ((and (not (bobp))
+                 (get-text-property (1- (point)) 'completion--string))
+            (setq beg (point))))
+      (setq beg (or (previous-single-property-change
+                     beg 'completion--string)
+                    beg))
+      (list (get-text-property beg 'completion--string) beg
+            (or (next-single-property-change beg 'completion--string)
+                (point-max))))))
 
 (defun choose-completion (&optional event no-exit no-quit)
   "Choose the completion at point.
@@ -10286,11 +10286,10 @@ choose-completion
                (or (get-text-property (posn-point (event-start event))
                                       'completion--string)
                    (error "No completion here"))
-             (if-let* ((candidate-start
-                        (completions--start-of-candidate-at
-                         (posn-point (event-start event)))))
-                 (get-text-property candidate-start 'completion--string)
-               (error "No completion here")))))
+             (or (save-excursion
+                   (goto-char (posn-point (event-start event)))
+                   (car (completion-list-candidate-at-point)))
+                 (error "No completion here")))))
 
       (unless (buffer-live-p buffer)
         (error "Destination buffer is dead"))
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* bug#74408: 30.0.92; FR: Add a function completion-list-candidate-at-point
  2024-11-18  0:06   ` Daniel Mendler via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-11-18 23:25     ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-11-18 23:36       ` Daniel Mendler via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 1 reply; 7+ messages in thread
From: Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-11-18 23:25 UTC (permalink / raw)
  To: Daniel Mendler; +Cc: 74408

> Thanks. Patch attached.

Thanks, Daniel.  Minor comments below.

> @@ -2628,8 +2628,10 @@ minibuffer-completion-help
>                (when-let* ((buffer (get-buffer "*Completions*"))
>                            (window (get-buffer-window buffer 0)))
>                  (with-current-buffer buffer
> -                  (when-let* ((beg (completions--start-of-candidate-at (window-point window))))
> -                    (cons (get-text-property beg 'completion--string) (- (point) beg))))))
> +                  (when-let* ((cand (save-excursion
> +                                     (goto-char (window-point window))
> +                                     (completion-list-candidate-at-point))))
> +                    (cons (car cand) (- (point) (cadr cand)))))))
>               ;; If the *Completions* buffer is shown in a new
>               ;; window, mark it as softly-dedicated, so bury-buffer in
>               ;; minibuffer-hide-completions will know whether to

AFAICT, it's easy to make `completion-list-candidate-at-point` accept an
optional position argument (which would default to point), which would
be helpful in the two places where we use that function.
WDYT?

> +(defun completion-list-candidate-at-point ()
> +  "Return candidate string at point and bounds in completions buffer."

I suggest you use something like "(STRING BEG END)" to describe the format.


        Stefan






^ permalink raw reply	[flat|nested] 7+ messages in thread

* bug#74408: 30.0.92; FR: Add a function completion-list-candidate-at-point
  2024-11-18 23:25     ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-11-18 23:36       ` Daniel Mendler via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-11-19  2:59         ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 1 reply; 7+ messages in thread
From: Daniel Mendler via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-11-18 23:36 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: 74408

[-- Attachment #1: Type: text/plain, Size: 308 bytes --]

Stefan Monnier <monnier@iro.umontreal.ca> writes:

> AFAICT, it's easy to make `completion-list-candidate-at-point` accept an
> optional position argument (which would default to point), which would
> be helpful in the two places where we use that function.
> WDYT?

Indeed. Updated patch attached.

Daniel


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-New-function-completion-list-candidate-at-point.patch --]
[-- Type: text/x-diff, Size: 4290 bytes --]

From bd755ae662e6cc5815e795d3c54dd7bda3cdc4e2 Mon Sep 17 00:00:00 2001
From: Daniel Mendler <mail@daniel-mendler.de>
Date: Mon, 18 Nov 2024 00:58:48 +0100
Subject: [PATCH] New function `completion-list-candidate-at-point'

Replace `completions--start-of-candidate-at' with the new
function `completion-list-candidate-at-point' which returns the
candidate string and the candidate bounds as a list in the
format (STR BEG END).

* lisp/simple.el (completions--start-of-candidate-at): Remove.
(completion-list-candidate-at-point): New function.
(choose-completion): Use it.
* lisp/minibuffer.el (minibuffer-completion-help): Use it.
---
 lisp/minibuffer.el |  5 +++--
 lisp/simple.el     | 40 +++++++++++++++++++++-------------------
 2 files changed, 24 insertions(+), 21 deletions(-)

diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el
index 9b498615926..405ee21cdb2 100644
--- a/lisp/minibuffer.el
+++ b/lisp/minibuffer.el
@@ -2628,8 +2628,9 @@ minibuffer-completion-help
               (when-let* ((buffer (get-buffer "*Completions*"))
                           (window (get-buffer-window buffer 0)))
                 (with-current-buffer buffer
-                  (when-let* ((beg (completions--start-of-candidate-at (window-point window))))
-                    (cons (get-text-property beg 'completion--string) (- (point) beg))))))
+                  (when-let* ((cand (completion-list-candidate-at-point
+                                     (window-point window))))
+                    (cons (car cand) (- (point) (cadr cand)))))))
              ;; If the *Completions* buffer is shown in a new
              ;; window, mark it as softly-dedicated, so bury-buffer in
              ;; minibuffer-hide-completions will know whether to
diff --git a/lisp/simple.el b/lisp/simple.el
index 3a142ef14b3..443a848b0ab 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -10246,22 +10246,26 @@ choose-completion-deselect-if-after
 
 This makes `completions--deselect' effective.")
 
-(defun completions--start-of-candidate-at (position)
-  "Return the start position of the completion candidate at POSITION."
+(defun completion-list-candidate-at-point (&optional pt)
+  "Candidate string and bounds at PT in completions buffer.
+The return value has the format (STR BEG END).
+The optional argument PT defaults to (point)."
   (save-excursion
-    (goto-char position)
+    (when pt (goto-char pt))
     (let (beg)
-      (cond
-       ((and (not (eobp))
-             (get-text-property (point) 'completion--string))
-        (setq beg (1+ (point))))
-       ((and (not (bobp))
-             (get-text-property (1- (point)) 'completion--string))
-        (setq beg (point))))
-      (when beg
-        (or (previous-single-property-change
-             beg 'completion--string)
-            beg)))))
+      (when (cond
+             ((and (not (eobp))
+                   (get-text-property (point) 'completion--string))
+              (setq beg (1+ (point))))
+             ((and (not (bobp))
+                   (get-text-property (1- (point)) 'completion--string))
+              (setq beg (point))))
+        (setq beg (or (previous-single-property-change
+                       beg 'completion--string)
+                      beg))
+        (list (get-text-property beg 'completion--string) beg
+              (or (next-single-property-change beg 'completion--string)
+                  (point-max)))))))
 
 (defun choose-completion (&optional event no-exit no-quit)
   "Choose the completion at point.
@@ -10286,11 +10290,9 @@ choose-completion
                (or (get-text-property (posn-point (event-start event))
                                       'completion--string)
                    (error "No completion here"))
-             (if-let* ((candidate-start
-                        (completions--start-of-candidate-at
-                         (posn-point (event-start event)))))
-                 (get-text-property candidate-start 'completion--string)
-               (error "No completion here")))))
+             (or (car (completion-list-candidate-at-point
+                       (posn-point (event-start event))))
+                 (error "No completion here")))))
 
       (unless (buffer-live-p buffer)
         (error "Destination buffer is dead"))
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* bug#74408: 30.0.92; FR: Add a function completion-list-candidate-at-point
  2024-11-18 23:36       ` Daniel Mendler via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-11-19  2:59         ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-11-19 10:03           ` Daniel Mendler via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 1 reply; 7+ messages in thread
From: Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-11-19  2:59 UTC (permalink / raw)
  To: Daniel Mendler; +Cc: 74408

>> AFAICT, it's easy to make `completion-list-candidate-at-point` accept an
>> optional position argument (which would default to point), which would
>> be helpful in the two places where we use that function.
>> WDYT?
> Indeed. Updated patch attached.

LGTM, if there are no objections, I'll install it into `master` in
a few days.


        Stefan






^ permalink raw reply	[flat|nested] 7+ messages in thread

* bug#74408: 30.0.92; FR: Add a function completion-list-candidate-at-point
  2024-11-19  2:59         ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-11-19 10:03           ` Daniel Mendler via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 0 replies; 7+ messages in thread
From: Daniel Mendler via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-11-19 10:03 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: 74408

[-- Attachment #1: Type: text/plain, Size: 516 bytes --]

Stefan Monnier <monnier@iro.umontreal.ca> writes:

>>> AFAICT, it's easy to make `completion-list-candidate-at-point` accept an
>>> optional position argument (which would default to point), which would
>>> be helpful in the two places where we use that function.
>>> WDYT?
>> Indeed. Updated patch attached.
>
> LGTM, if there are no objections, I'll install it into `master` in
> a few days.

Thanks. I've attached the latest version of the patch, where the
function is simplified without save-excursion.

Daniel


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-New-function-completion-list-candidate-at-point.patch --]
[-- Type: text/x-diff, Size: 4152 bytes --]

From 8501d7cf9b81d03b2f00d738a6320d417917eca4 Mon Sep 17 00:00:00 2001
From: Daniel Mendler <mail@daniel-mendler.de>
Date: Mon, 18 Nov 2024 00:58:48 +0100
Subject: [PATCH] New function `completion-list-candidate-at-point'

Replace `completions--start-of-candidate-at' with the new
function `completion-list-candidate-at-point' which returns the
candidate string and the candidate bounds as a list in the
format (STR BEG END).

* lisp/simple.el (completions--start-of-candidate-at): Remove.
(completion-list-candidate-at-point): New function.
(choose-completion): Use it.
* lisp/minibuffer.el (minibuffer-completion-help): Use it.
---
 lisp/minibuffer.el |  5 +++--
 lisp/simple.el     | 39 ++++++++++++++++++---------------------
 2 files changed, 21 insertions(+), 23 deletions(-)

diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el
index 9b498615926..405ee21cdb2 100644
--- a/lisp/minibuffer.el
+++ b/lisp/minibuffer.el
@@ -2628,8 +2628,9 @@ minibuffer-completion-help
               (when-let* ((buffer (get-buffer "*Completions*"))
                           (window (get-buffer-window buffer 0)))
                 (with-current-buffer buffer
-                  (when-let* ((beg (completions--start-of-candidate-at (window-point window))))
-                    (cons (get-text-property beg 'completion--string) (- (point) beg))))))
+                  (when-let* ((cand (completion-list-candidate-at-point
+                                     (window-point window))))
+                    (cons (car cand) (- (point) (cadr cand)))))))
              ;; If the *Completions* buffer is shown in a new
              ;; window, mark it as softly-dedicated, so bury-buffer in
              ;; minibuffer-hide-completions will know whether to
diff --git a/lisp/simple.el b/lisp/simple.el
index 3a142ef14b3..32ac8af627c 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -10246,22 +10246,21 @@ choose-completion-deselect-if-after
 
 This makes `completions--deselect' effective.")
 
-(defun completions--start-of-candidate-at (position)
-  "Return the start position of the completion candidate at POSITION."
-  (save-excursion
-    (goto-char position)
-    (let (beg)
-      (cond
-       ((and (not (eobp))
-             (get-text-property (point) 'completion--string))
-        (setq beg (1+ (point))))
-       ((and (not (bobp))
-             (get-text-property (1- (point)) 'completion--string))
-        (setq beg (point))))
-      (when beg
-        (or (previous-single-property-change
-             beg 'completion--string)
-            beg)))))
+(defun completion-list-candidate-at-point (&optional pt)
+  "Candidate string and bounds at PT in completions buffer.
+The return value has the format (STR BEG END).
+The optional argument PT defaults to (point)."
+  (setq pt (or pt (point)))
+  (when (cond
+         ((and (/= pt (point-max))
+               (get-text-property pt 'completion--string))
+          (cl-incf pt))
+         ((and (/= pt (point-min))
+               (get-text-property (1- pt) 'completion--string))))
+    (setq pt (or (previous-single-property-change pt 'completion--string) pt))
+    (list (get-text-property pt 'completion--string) pt
+          (or (next-single-property-change pt 'completion--string)
+              (point-max)))))
 
 (defun choose-completion (&optional event no-exit no-quit)
   "Choose the completion at point.
@@ -10286,11 +10285,9 @@ choose-completion
                (or (get-text-property (posn-point (event-start event))
                                       'completion--string)
                    (error "No completion here"))
-             (if-let* ((candidate-start
-                        (completions--start-of-candidate-at
-                         (posn-point (event-start event)))))
-                 (get-text-property candidate-start 'completion--string)
-               (error "No completion here")))))
+             (or (car (completion-list-candidate-at-point
+                       (posn-point (event-start event))))
+                 (error "No completion here")))))
 
       (unless (buffer-live-p buffer)
         (error "Destination buffer is dead"))
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2024-11-19 10:03 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-11-17 21:10 bug#74408: 30.0.92; FR: Add a function completion-list-candidate-at-point Daniel Mendler via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-11-17 21:46 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-11-18  0:06   ` Daniel Mendler via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-11-18 23:25     ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-11-18 23:36       ` Daniel Mendler via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-11-19  2:59         ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-11-19 10:03           ` Daniel Mendler via Bug reports for GNU Emacs, the Swiss army knife of text editors

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.