aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--etc/NEWS20
-rw-r--r--lisp/icomplete.el123
2 files changed, 140 insertions, 3 deletions
diff --git a/etc/NEWS b/etc/NEWS
index 33a2b3fd07a..efd03313f17 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1591,6 +1591,26 @@ width of the 'speedbar-window' when it is closed and then restored.
1591--- 1591---
1592*** 'speedbar-easymenu-definition-trailer' is now a function. 1592*** 'speedbar-easymenu-definition-trailer' is now a function.
1593 1593
1594** Icomplete
1595
1596*** New user options for 'icomplete-vertical-mode'.
1597New user options have been added to enhance 'icomplete-vertical-mode':
1598- 'icomplete-vertical-in-buffer-adjust-list' aligns in-buffer
1599 completion to the original cursor column.
1600- 'icomplete-vertical-render-prefix-indicator' adds a prefix indicator
1601 to completion candidates.
1602- 'icomplete-vertical-selected-prefix-indicator' specifies the prefix
1603 string for the selected candidate.
1604- 'icomplete-vertical-unselected-prefix-indicator' specifies the prefix
1605 string for unselected candidates.
1606
1607*** New faces for 'icomplete-vertical-mode'.
1608New faces have been added to 'icomplete-vertical-mode':
1609- 'icomplete-vertical-selected-prefix-indicator-face' controls the
1610 appearance of the selected candidate prefix.
1611- 'icomplete-vertical-unselected-prefix-indicator-face' controls the
1612 appearance of unselected candidate prefixes.
1613
1594** Miscellaneous 1614** Miscellaneous
1595 1615
1596--- 1616---
diff --git a/lisp/icomplete.el b/lisp/icomplete.el
index c58bffbb36b..d0cc5674ba7 100644
--- a/lisp/icomplete.el
+++ b/lisp/icomplete.el
@@ -115,6 +115,18 @@ Otherwise this should be a list of the completion tables (e.g.,
115 "Face used by `icomplete-vertical-mode' for the section title." 115 "Face used by `icomplete-vertical-mode' for the section title."
116 :version "28.1") 116 :version "28.1")
117 117
118(defface icomplete-vertical-selected-prefix-indicator-face
119 '((t :inherit font-lock-keyword-face :weight bold :foreground "slate blue"))
120 "Face used by `icomplete-vertical-selected-prefix-indicator'."
121 :group 'icomplete
122 :version "31.1")
123
124(defface icomplete-vertical-unselected-prefix-indicator-face
125 '((t :inherit font-lock-keyword-face :weight normal :foreground "gray"))
126 "Face used by `icomplete-vertical-unselected-prefix-indicator'."
127 :group 'icomplete
128 :version "31.1")
129
118;;;_* User Customization variables 130;;;_* User Customization variables
119(defcustom icomplete-prospects-height 2 131(defcustom icomplete-prospects-height 2
120 ;; We used to compute how many lines 100 characters would take in 132 ;; We used to compute how many lines 100 characters would take in
@@ -166,6 +178,50 @@ will constrain Emacs to a maximum minibuffer height of 3 lines when
166icompletion is occurring." 178icompletion is occurring."
167 :type 'hook) 179 :type 'hook)
168 180
181(defcustom icomplete-vertical-in-buffer-adjust-list nil
182 "Control whether in-buffer completion should align the cursor position.
183If this is t and `icomplete-in-buffer' is t, and `icomplete-vertical-mode'
184is activated, the in-buffer vertical completions are shown aligned to the
185cursor position when the completion started, not on the first column, as
186the default behavior."
187 :type 'boolean
188 :group 'icomplete
189 :version "31.1")
190
191(defcustom icomplete-vertical-render-prefix-indicator nil
192 "Control whether an indicator is added as a prefix to each candidate.
193If this is t and `icomplete-vertical-mode' is activated, an indicator,
194controlled by `icomplete-vertical-selected-prefix-indicator' is shown
195as a prefix to the current under selection candidate, while the
196remaining of the candidates will receive the indicator controlled
197by `icomplete-vertical-unselected-prefix-indicator'."
198 :type 'boolean
199 :group 'icomplete
200 :version "31.1")
201
202(defcustom icomplete-vertical-selected-prefix-indicator
203 (if (char-displayable-p ?») "» " "> ")
204 "Prefix string used to mark the selected completion candidate.
205If `icomplete-vertical-render-prefix-indicator' is t, this string
206is used as a prefix of the currently selected entry in the list.
207It can be further customized by the face
208`icomplete-vertical-selected-prefix-indicator-face'.
209
210By default, this is set to \"» \" if the character is displayable,
211otherwise, it falls back to \"> \"."
212 :type 'string
213 :group 'icomplete
214 :version "31.1")
215
216(defcustom icomplete-vertical-unselected-prefix-indicator " "
217 "Prefix string used on the unselected completion candidates.
218If `icomplete-vertical-render-prefix-indicator' is t, the string
219defined here is used as a prefix for all unselected entries in the list.
220list. It can be further customized by the face
221`icomplete-vertical-unselected-prefix-indicator-face'."
222 :type 'string
223 :group 'icomplete
224 :version "31.1")
169 225
170;;;_* Initialization 226;;;_* Initialization
171 227
@@ -828,6 +884,58 @@ by `group-function''s second \"transformation\" protocol."
828 else collect (list tr prefix suffix )) 884 else collect (list tr prefix suffix ))
829 annotated))) 885 annotated)))
830 886
887(defun icomplete-vertical--adjust-lines-for-column (lines buffer data)
888 "Adjust the LINES to align with the column in BUFFER based on DATA."
889 (if icomplete-vertical-in-buffer-adjust-list
890 (let* ((column (current-column))
891 (prefix-indicator-width
892 (if icomplete-vertical-render-prefix-indicator
893 (max (length icomplete-vertical-selected-prefix-indicator)
894 (length icomplete-vertical-unselected-prefix-indicator))
895 0))
896 (wrapped-line (with-current-buffer buffer
897 (save-excursion
898 (goto-char (car data))
899 (beginning-of-line)
900 (count-screen-lines (point) (car data)))))
901 (window-width (+ (window-hscroll) (window-body-width)))
902 (longest-line-width (apply #'max (mapcar #'length lines)))
903 (spaces-to-add
904 (if (> wrapped-line 1)
905 (- column (* (- wrapped-line 1) (- window-width 5)))
906 column))
907 (spaces-to-add-avoiding-scrolling
908 (if (>= (+ spaces-to-add longest-line-width prefix-indicator-width) window-width)
909 (- spaces-to-add longest-line-width)
910 spaces-to-add)))
911
912 (mapcar (lambda (line)
913 (concat (make-string spaces-to-add-avoiding-scrolling ?\s) line))
914 lines))
915 lines))
916
917(defun icomplete-vertical--ensure-visible-lines-inside-buffer ()
918 "Ensure the completion list is visible in regular buffers only.
919Scrolls the screen to be at least `icomplete-prospects-height' real lines
920away from the bottom. Counts wrapped lines as real lines."
921 (unless (minibufferp)
922 (let* ((window-height (window-body-height))
923 (current-line (count-screen-lines (window-start) (point)))
924 (lines-to-bottom (- window-height current-line)))
925 (when (< lines-to-bottom icomplete-prospects-height)
926 (scroll-up (- icomplete-prospects-height lines-to-bottom))))))
927
928(defun icomplete-vertical--add-indicator-to-selected (comp)
929 "Add indicators to the selected/unselected COMP completions."
930 (if (and icomplete-vertical-render-prefix-indicator
931 (get-text-property 0 'icomplete-selected comp))
932 (concat (propertize icomplete-vertical-selected-prefix-indicator
933 'face 'icomplete-vertical-selected-prefix-indicator-face)
934 comp)
935 (concat (propertize icomplete-vertical-unselected-prefix-indicator
936 'face 'icomplete-vertical-unselected-prefix-indicator-face)
937 comp)))
938
831(cl-defun icomplete--render-vertical 939(cl-defun icomplete--render-vertical
832 (comps md &aux scroll-above scroll-below 940 (comps md &aux scroll-above scroll-below
833 (total-space ; number of mini-window lines available 941 (total-space ; number of mini-window lines available
@@ -843,12 +951,17 @@ by `group-function''s second \"transformation\" protocol."
843 ;; - both nil, there is no manual scroll; 951 ;; - both nil, there is no manual scroll;
844 ;; - both non-nil, there is a healthy manual scroll that doesn't need 952 ;; - both non-nil, there is a healthy manual scroll that doesn't need
845 ;; to be readjusted (user just moved around the minibuffer, for 953 ;; to be readjusted (user just moved around the minibuffer, for
846 ;; example)l 954 ;; example);
847 ;; - non-nil and nil, respectively, a refiltering took place and we 955 ;; - non-nil and nil, respectively, a refiltering took place and we
848 ;; may need to readjust them to the new filtered `comps'. 956 ;; may need to readjust them to the new filtered `comps'.
849 (when (and icomplete-scroll 957 (when (and icomplete-scroll
958 (not icomplete--scrolled-completions)
959 (not icomplete--scrolled-past))
960 (icomplete-vertical--ensure-visible-lines-inside-buffer))
961 (when (and icomplete-scroll
850 icomplete--scrolled-completions 962 icomplete--scrolled-completions
851 (null icomplete--scrolled-past)) 963 (null icomplete--scrolled-past))
964 (icomplete-vertical--ensure-visible-lines-inside-buffer)
852 (cl-loop with preds 965 (cl-loop with preds
853 for (comp . rest) on comps 966 for (comp . rest) on comps
854 when (equal comp (car icomplete--scrolled-completions)) 967 when (equal comp (car icomplete--scrolled-completions))
@@ -900,6 +1013,7 @@ by `group-function''s second \"transformation\" protocol."
900 ;; of lines to render 1013 ;; of lines to render
901 (cl-loop 1014 (cl-loop
902 for (comp prefix suffix section) in tuples 1015 for (comp prefix suffix section) in tuples
1016 do (setq comp (icomplete-vertical--add-indicator-to-selected comp))
903 when section 1017 when section
904 collect (propertize section 'face 'icomplete-section) into lines-aux 1018 collect (propertize section 'face 'icomplete-section) into lines-aux
905 and count 1 into nsections-aux 1019 and count 1 into nsections-aux
@@ -907,9 +1021,9 @@ by `group-function''s second \"transformation\" protocol."
907 do (add-face-text-property 0 (length comp) 1021 do (add-face-text-property 0 (length comp)
908 'icomplete-selected-match 'append comp) 1022 'icomplete-selected-match 'append comp)
909 collect (concat prefix 1023 collect (concat prefix
910 (make-string (- max-prefix-len (length prefix)) ? ) 1024 (make-string (max 0 (- max-prefix-len (length prefix))) ? )
911 (completion-lazy-hilit comp) 1025 (completion-lazy-hilit comp)
912 (make-string (- max-comp-len (length comp)) ? ) 1026 (make-string (max 0 (- max-comp-len (length comp))) ? )
913 suffix) 1027 suffix)
914 into lines-aux 1028 into lines-aux
915 finally (setq lines lines-aux 1029 finally (setq lines lines-aux
@@ -924,6 +1038,9 @@ by `group-function''s second \"transformation\" protocol."
924 ((> (length scroll-above) (length scroll-below)) nsections) 1038 ((> (length scroll-above) (length scroll-below)) nsections)
925 (t (min (ceiling nsections 2) (length scroll-above)))) 1039 (t (min (ceiling nsections 2) (length scroll-above))))
926 lines)) 1040 lines))
1041 (when icomplete--in-region-buffer
1042 (setq lines (icomplete-vertical--adjust-lines-for-column
1043 lines icomplete--in-region-buffer completion-in-region--data)))
927 ;; At long last, render final string return value. This may still 1044 ;; At long last, render final string return value. This may still
928 ;; kick out lines at the end. 1045 ;; kick out lines at the end.
929 (concat " \n" 1046 (concat " \n"