Package: emacs;
Reported by: Rahul Martim Juliato <rahuljuliato <at> gmail.com>
Date: Fri, 24 Jan 2025 02:52:02 UTC
Severity: wishlist
Tags: patch
Done: Eli Zaretskii <eliz <at> gnu.org>
Bug is archived. No further changes may be made.
View this message in rfc822 format
From: Rahul Martim Juliato <rahuljuliato <at> gmail.com> To: jixiuf <jixiuf <at> qq.com> Cc: eliz <at> gnu.org, 75794 <at> debbugs.gnu.org Subject: bug#75794: [PATCH] feat(icomplete): markers and vertical alignment Date: Wed, 12 Mar 2025 21:09:18 -0300
[Message part 1 (text/plain, inline)]
jixiuf <jixiuf <at> qq.com> writes: > > I could reproduce with: > > (setq show-paren-when-point-inside-paren t) > Thanks for your feedback! Please find attached a new version of this patch. Could you try it and tell if this one fixes this bug? For me, it did fixed it! :) -- Rahul Martim Juliato
[0001-Enhance-icomplete-vertical-mode-2025-03-12.patch (text/x-diff, inline)]
From e6f4d614b79949ecf1799e4cc4dc312fd33a5bbd Mon Sep 17 00:00:00 2001 From: Rahul Martim Juliato <rahul.juliato <at> gmail.com> Date: Wed, 12 Mar 2025 21:00:27 -0300 Subject: [PATCH] Enhance 'icomplete-vertical-mode' New user options have been added to enhance 'icomplete-vertical-mode': + 'icomplete-vertical-in-buffer-adjust-list': Aligns in-buffer completion to the original cursor column. + 'icomplete-vertical-render-prefix-indicator': When enabled, adds a prefix indicator to completion candidates. + 'icomplete-vertical-selected-prefix-indicator': Specifies the prefix string for the selected candidate. + 'icomplete-vertical-unselected-prefix-indicator': Specifies the prefix string for unselected candidates. New faces introduced: + 'icomplete-vertical-selected-prefix-indicator-face': Controls the appearance of the selected candidate prefix. + 'icomplete-vertical-unselected-prefix-indicator-face': Controls the appearance of unselected candidate prefixes. * etc/NEWS: Document the new user options and faces. * lisp/icomplete.el(icomplete-vertical-mode): Implement the new options --- etc/NEWS | 19 ++++++++ lisp/icomplete.el | 119 ++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 135 insertions(+), 3 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index 258f0dcc4ba..bf4afb8dac0 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -269,6 +269,25 @@ return value windows whose buffers share their text with BUFFER-OR-NAME. With such an entry, 'display-buffer-reuse-window' may also choose a window whose buffer shares text with the buffer to display. ++++ +*** New user options for 'icomplete-vertical-mode'. +New user options have been added to enhance 'icomplete-vertical-mode': + + - 'icomplete-vertical-in-buffer-adjust-list': Aligns in-buffer + completion to the original cursor column. + - 'icomplete-vertical-render-prefix-indicator': When enabled, adds a + prefix indicator to completion candidates. + - 'icomplete-vertical-selected-prefix-indicator': Specifies the prefix + string for the selected candidate. + - 'icomplete-vertical-unselected-prefix-indicator': Specifies the prefix + string for unselected candidates. + +New faces: + + - 'icomplete-vertical-selected-prefix-indicator-face': Controls the + appearance of the selected candidate prefix. + - 'icomplete-vertical-unselected-prefix-indicator-face': Controls the + appearance of unselected candidate prefixes. ** Frames diff --git a/lisp/icomplete.el b/lisp/icomplete.el index c58bffbb36b..fca941a09db 100644 --- a/lisp/icomplete.el +++ b/lisp/icomplete.el @@ -115,6 +115,18 @@ icomplete-section "Face used by `icomplete-vertical-mode' for the section title." :version "28.1") +(defface icomplete-vertical-selected-prefix-indicator-face + '((t :inherit font-lock-keyword-face :weight bold :foreground "cyan")) + "Face used for the prefix set by `icomplete-vertical-selected-prefix-indicator'." + :group 'icomplete + :version "31.1") + +(defface icomplete-vertical-unselected-prefix-indicator-face + '((t :inherit font-lock-keyword-face :weight normal :foreground "gray")) + "Face used for the prefix set by `icomplete-vertical-unselected-prefix-indicator'." + :group 'icomplete + :version "31.1") + ;;;_* User Customization variables (defcustom icomplete-prospects-height 2 ;; We used to compute how many lines 100 characters would take in @@ -166,6 +178,46 @@ icomplete-minibuffer-setup-hook icompletion is occurring." :type 'hook) +(defcustom icomplete-vertical-in-buffer-adjust-list nil + "Control whether in-buffer completion should align the cursor position. +If this is t and `icomplete-in-buffer' is t, and `icomplete-vertical-mode' +is activated, the in-buffer vertical completions are shown aligned to the +cursor position when the completion started, not on the first column, as +the default behaviour." + :type 'boolean + :group 'icomplete + :version "31.1") + +(defcustom icomplete-vertical-render-prefix-indicator nil + "Control whether a indicator is added as a prefix to each candidate. +If this is t and `icomplete-vertical-mode' is activated, a indicator, +controlled by `icomplete-vertical-selected-prefix-indicator' is shown +as a prefix to the current under selection candidate, while the +remaining of the candidates will receive the indicator controlled +by `icomplete-vertical-unselected-prefix-indicator'." + :type 'boolean + :group 'icomplete + :version "31.1") + +(defcustom icomplete-vertical-selected-prefix-indicator "ยป " + "Prefix string used to mark the selected completion candidate. +If `icomplete-vertical-render-prefix-indicator' is t, the string +defined here is used as a prefix of the currently selected entry in the +list. It can be further customized by the face +`icomplete-vertical-selected-prefix-indicator-face'." + :type 'string + :group 'icomplete + :version "31.1") + +(defcustom icomplete-vertical-unselected-prefix-indicator " " + "Prefix string used on the unselected completion candidates. +If `icomplete-vertical-render-prefix-indicator' is t, the string +defined here is used as a prefix for all unselected entries in the list. +list. It can be further customized by the face +`icomplete-vertical-unselected-prefix-indicator-face'." + :type 'string + :group 'icomplete + :version "31.1") ;;;_* Initialization @@ -828,6 +880,58 @@ icomplete--augment else collect (list tr prefix suffix )) annotated))) +(defun icomplete-vertical--adjust-lines-for-column (lines buffer data) + "Adjust the LINES to align with the column in BUFFER based on DATA." + (if icomplete-vertical-in-buffer-adjust-list + (let* ((column (current-column)) + (prefix-indicator-width + (if icomplete-vertical-render-prefix-indicator + (max (length icomplete-vertical-selected-prefix-indicator) + (length icomplete-vertical-unselected-prefix-indicator)) + 0)) + (wrapped-line (with-current-buffer buffer + (save-excursion + (goto-char (car data)) + (beginning-of-line) + (count-screen-lines (point) (car data))))) + (window-width (+ (window-hscroll) (window-body-width))) + (longest-line-width (apply #'max (mapcar #'length lines))) + (spaces-to-add + (if (> wrapped-line 1) + (- column (* (- wrapped-line 1) (- window-width 5))) + column)) + (spaces-to-add-avoiding-scrolling + (if (>= (+ spaces-to-add longest-line-width prefix-indicator-width) window-width) + (- spaces-to-add longest-line-width) + spaces-to-add))) + + (mapcar (lambda (line) + (concat (make-string spaces-to-add-avoiding-scrolling ?\s) line)) + lines)) + lines)) + +(defun icomplete-vertical--ensure-visible-lines-inside-buffer () + "Ensure the completion list is visible in regular buffers only. +Scrolls the screen to be at least `icomplete-prospects-height' real lines +away from the bottom. Counts wrapped lines as real lines." + (unless (minibufferp) + (let* ((window-height (window-body-height)) + (current-line (count-screen-lines (window-start) (point))) + (lines-to-bottom (- window-height current-line))) + (when (< lines-to-bottom icomplete-prospects-height) + (scroll-up (- icomplete-prospects-height lines-to-bottom)))))) + +(defun icomplete-vertical--add-indicator-to-selected (comp) + "Add indicators to the selected/unselected COMP completions." + (if (and icomplete-vertical-render-prefix-indicator + (get-text-property 0 'icomplete-selected comp)) + (concat (propertize icomplete-vertical-selected-prefix-indicator + 'face 'icomplete-vertical-selected-prefix-indicator-face) + comp) + (concat (propertize icomplete-vertical-unselected-prefix-indicator + 'face 'icomplete-vertical-unselected-prefix-indicator-face) + comp))) + (cl-defun icomplete--render-vertical (comps md &aux scroll-above scroll-below (total-space ; number of mini-window lines available @@ -843,12 +947,17 @@ icomplete--render-vertical ;; - both nil, there is no manual scroll; ;; - both non-nil, there is a healthy manual scroll that doesn't need ;; to be readjusted (user just moved around the minibuffer, for - ;; example)l + ;; example); ;; - non-nil and nil, respectively, a refiltering took place and we ;; may need to readjust them to the new filtered `comps'. + (when (and icomplete-scroll + (not icomplete--scrolled-completions) + (not icomplete--scrolled-past)) + (icomplete-vertical--ensure-visible-lines-inside-buffer)) (when (and icomplete-scroll icomplete--scrolled-completions (null icomplete--scrolled-past)) + (icomplete-vertical--ensure-visible-lines-inside-buffer) (cl-loop with preds for (comp . rest) on comps when (equal comp (car icomplete--scrolled-completions)) @@ -903,13 +1012,14 @@ icomplete--render-vertical when section collect (propertize section 'face 'icomplete-section) into lines-aux and count 1 into nsections-aux + for comp = (icomplete-vertical--add-indicator-to-selected comp) when (get-text-property 0 'icomplete-selected comp) do (add-face-text-property 0 (length comp) 'icomplete-selected-match 'append comp) collect (concat prefix - (make-string (- max-prefix-len (length prefix)) ? ) + (make-string (max 0 (- max-prefix-len (length prefix))) ? ) (completion-lazy-hilit comp) - (make-string (- max-comp-len (length comp)) ? ) + (make-string (max 0 (- max-comp-len (length comp))) ? ) suffix) into lines-aux finally (setq lines lines-aux @@ -924,6 +1034,9 @@ icomplete--render-vertical ((> (length scroll-above) (length scroll-below)) nsections) (t (min (ceiling nsections 2) (length scroll-above)))) lines)) + (when icomplete--in-region-buffer + (setq lines (icomplete-vertical--adjust-lines-for-column + lines icomplete--in-region-buffer completion-in-region--data))) ;; At long last, render final string return value. This may still ;; kick out lines at the end. (concat " \n" -- 2.39.5
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.