From a58cc18ce253b76ee5ba4e75db08690b6f66c344 Mon Sep 17 00:00:00 2001 From: Clemens Radermacher Date: Wed, 9 Dec 2020 12:09:33 +0100 Subject: [PATCH 01/10] Improve completion in region --- selectrum.el | 131 ++++++++++++++++++++++++++------------------------- 1 file changed, 67 insertions(+), 64 deletions(-) diff --git a/selectrum.el b/selectrum.el index 9c66bbf1..338d4077 100644 --- a/selectrum.el +++ b/selectrum.el @@ -1704,10 +1704,12 @@ COLLECTION, and PREDICATE, see `completion-in-region'." (pcase category ('file (setq result - (selectrum--completing-read-file-name - "Completion: " collection predicate - nil input) - exit-status 'finished)) + (if (not (cdr cands)) + (try-completion input collection predicate) + (selectrum--completing-read-file-name + "Completion: " collection predicate + nil input)) + exit-status 'sole)) (_ (setq result (if (not (cdr cands)) @@ -1721,6 +1723,7 @@ COLLECTION, and PREDICATE, see `completion-in-region'." exit-status (cond ((not (member result cands)) 'sole) (t 'finished))))) (delete-region bound end) + (push-mark (point) t) (insert (substring-no-properties result)) (when exit-func (funcall exit-func result exit-status)))))) @@ -1823,15 +1826,19 @@ For PROMPT, COLLECTION, PREDICATE, REQUIRE-MATCH, INITIAL-INPUT, (quit))))) `((input . ,ematch) (candidates . ,cands)))))) - (selectrum-read - prompt coll - :default-candidate (or (car-safe def) def) - :initial-input (or (car-safe initial-input) initial-input) - :history hist - :require-match (eq require-match t) - :may-modify-candidates t - :minibuffer-completion-table collection - :minibuffer-completion-predicate predicate))) + (minibuffer-with-setup-hook + (lambda () + (set-syntax-table + selectrum--minibuffer-local-filename-syntax)) + (selectrum-read + prompt coll + :default-candidate (or (car-safe def) def) + :initial-input (or (car-safe initial-input) initial-input) + :history hist + :require-match (eq require-match t) + :may-modify-candidates t + :minibuffer-completion-table collection + :minibuffer-completion-predicate predicate)))) ;;;###autoload (defun selectrum-read-file-name @@ -1839,57 +1846,53 @@ For PROMPT, COLLECTION, PREDICATE, REQUIRE-MATCH, INITIAL-INPUT, "Read file name using Selectrum. Can be used as `read-file-name-function'. For PROMPT, DIR, DEFAULT-FILENAME, MUSTMATCH, INITIAL, and PREDICATE, see `read-file-name'." - (minibuffer-with-setup-hook - (lambda () - (set-syntax-table - selectrum--minibuffer-local-filename-syntax)) - (let* ((crf completing-read-function) - ;; See . - ;; When you invoke another `completing-read' command - ;; recursively then it inherits the - ;; `completing-read-function' binding, and unless it's - ;; another file reading command using - ;; `selectrum--completing-read-file-name' this will cause - ;; an error. To circumvent this we use the function to - ;; reset the variable when called. - (completing-read-function - (lambda (&rest args) - (setq completing-read-function crf) - (when (and default-filename - ;; ./ should be omitted. - (not (equal - (expand-file-name default-filename) - (expand-file-name default-directory)))) - (setf (nth 6 args) ; DEFAULT - ;; Sort for directories needs any final - ;; slash removed. - (directory-file-name - ;; The candidate should be sorted by it's - ;; relative name. - (file-relative-name default-filename - default-directory)))) - (apply #'selectrum--completing-read-file-name args)))) - (read-file-name-default - prompt dir - ;; We don't pass default-candidate here to avoid that - ;; submitting the selected prompt results in the default file - ;; name. This is the stock Emacs behavior where there is no - ;; concept of an active selection. Instead we pass the initial - ;; prompt as default so it gets returned when submitted. In - ;; addition to that we adjust the DEF argument passed to - ;; `selectrum--completing-read-file-name' above so the actual - ;; default gets sorted to the top. This should give the same - ;; convenience as in default completion (where you can press - ;; RET at the initial prompt to get the default). The downside - ;; is that this convenience is gone when sorting is disabled or - ;; the default-filename is outside the prompting directory but - ;; this should be rare case. - (concat - (expand-file-name - (or dir - default-directory)) - initial) - mustmatch initial predicate)))) + (let* ((crf completing-read-function) + ;; See . + ;; When you invoke another `completing-read' command + ;; recursively then it inherits the + ;; `completing-read-function' binding, and unless it's + ;; another file reading command using + ;; `selectrum--completing-read-file-name' this will cause + ;; an error. To circumvent this we use the function to + ;; reset the variable when called. + (completing-read-function + (lambda (&rest args) + (setq completing-read-function crf) + (when (and default-filename + ;; ./ should be omitted. + (not (equal + (expand-file-name default-filename) + (expand-file-name default-directory)))) + (setf (nth 6 args) ; DEFAULT + ;; Sort for directories needs any final + ;; slash removed. + (directory-file-name + ;; The candidate should be sorted by it's + ;; relative name. + (file-relative-name default-filename + default-directory)))) + (apply #'selectrum--completing-read-file-name args)))) + (read-file-name-default + prompt dir + ;; We don't pass default-candidate here to avoid that + ;; submitting the selected prompt results in the default file + ;; name. This is the stock Emacs behavior where there is no + ;; concept of an active selection. Instead we pass the initial + ;; prompt as default so it gets returned when submitted. In + ;; addition to that we adjust the DEF argument passed to + ;; `selectrum--completing-read-file-name' above so the actual + ;; default gets sorted to the top. This should give the same + ;; convenience as in default completion (where you can press + ;; RET at the initial prompt to get the default). The downside + ;; is that this convenience is gone when sorting is disabled or + ;; the default-filename is outside the prompting directory but + ;; this should be rare case. + (concat + (expand-file-name + (or dir + default-directory)) + initial) + mustmatch initial predicate))) (defvar selectrum--old-read-file-name-function nil "Previous value of `read-file-name-function'.") From d46e82b91b676e7b2e2ec3d68b5b3162354ceac0 Mon Sep 17 00:00:00 2001 From: Clemens Radermacher Date: Wed, 9 Dec 2020 14:02:53 +0100 Subject: [PATCH 02/10] Restart minibuffer completion for single exact case --- selectrum.el | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/selectrum.el b/selectrum.el index 338d4077..be5fb68d 100644 --- a/selectrum.el +++ b/selectrum.el @@ -394,6 +394,11 @@ setting." Nil (the default) means to only highlight the displayed text." :type 'boolean) +;;;###autoload +(defcustom selectrum-complete-in-buffer nil + "If non-nil, also use Selectrum when completing in non-mini buffers." + :type 'boolean) + ;;;; Utility functions (defun selectrum--clamp (x lower upper) @@ -1703,13 +1708,15 @@ COLLECTION, and PREDICATE, see `completion-in-region'." (prog1 t (pcase category ('file - (setq result - (if (not (cdr cands)) - (try-completion input collection predicate) - (selectrum--completing-read-file-name - "Completion: " collection predicate - nil input)) - exit-status 'sole)) + (let ((try (try-completion input collection predicate))) + (setq result + (if (and (not (cdr cands)) + (stringp try)) + try + (selectrum--completing-read-file-name + "Completion: " collection predicate + nil input)) + exit-status 'sole))) (_ (setq result (if (not (cdr cands)) From 586796f642534e7cf22934d88ef792e5c00cdb99 Mon Sep 17 00:00:00 2001 From: Clemens Radermacher Date: Wed, 9 Dec 2020 14:06:01 +0100 Subject: [PATCH 03/10] Handle option for completion in region --- selectrum.el | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/selectrum.el b/selectrum.el index be5fb68d..0f70a247 100644 --- a/selectrum.el +++ b/selectrum.el @@ -2082,8 +2082,9 @@ ARGS are standard as in all `:around' advice." #'selectrum-read-file-name) (setq selectrum--old-completion-in-region-function (default-value 'completion-in-region-function)) - (setq-default completion-in-region-function - #'selectrum-completion-in-region) + (when selectrum-complete-in-buffer + (setq-default completion-in-region-function + #'selectrum-completion-in-region)) (advice-add #'completing-read-multiple :override #'selectrum-completing-read-multiple) ;; No sharp quote because Dired may not be loaded yet. From 4764941d62a2a027e61340bbcadf37892c1c426e Mon Sep 17 00:00:00 2001 From: Clemens Radermacher Date: Wed, 9 Dec 2020 14:09:23 +0100 Subject: [PATCH 04/10] Completion in region should be used by default --- selectrum.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/selectrum.el b/selectrum.el index 0f70a247..24dafae2 100644 --- a/selectrum.el +++ b/selectrum.el @@ -395,7 +395,7 @@ Nil (the default) means to only highlight the displayed text." :type 'boolean) ;;;###autoload -(defcustom selectrum-complete-in-buffer nil +(defcustom selectrum-complete-in-buffer t "If non-nil, also use Selectrum when completing in non-mini buffers." :type 'boolean) From 5d997416fbd79c1218a7f980f5697235eb85b779 Mon Sep 17 00:00:00 2001 From: Clemens Radermacher Date: Wed, 9 Dec 2020 14:48:00 +0100 Subject: [PATCH 05/10] Expand doc --- selectrum.el | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/selectrum.el b/selectrum.el index 24dafae2..d777e296 100644 --- a/selectrum.el +++ b/selectrum.el @@ -396,7 +396,8 @@ Nil (the default) means to only highlight the displayed text." ;;;###autoload (defcustom selectrum-complete-in-buffer t - "If non-nil, also use Selectrum when completing in non-mini buffers." + "If non-nil, also use Selectrum when completing in non-mini buffers. +This option needs to be set before activating `selectrum-mode'." :type 'boolean) ;;;; Utility functions From c9c70407cf2979f89c15c7b7cedc9a3cf13c31e1 Mon Sep 17 00:00:00 2001 From: Clemens Radermacher Date: Wed, 9 Dec 2020 14:51:48 +0100 Subject: [PATCH 06/10] Refactor --- selectrum.el | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/selectrum.el b/selectrum.el index d777e296..dfceffab 100644 --- a/selectrum.el +++ b/selectrum.el @@ -1709,10 +1709,11 @@ COLLECTION, and PREDICATE, see `completion-in-region'." (prog1 t (pcase category ('file - (let ((try (try-completion input collection predicate))) + (let ((try nil)) (setq result (if (and (not (cdr cands)) - (stringp try)) + (stringp (setq try (try-completion + input collection predicate)))) try (selectrum--completing-read-file-name "Completion: " collection predicate From 42e49a1c618bd4884c1d7527ba2927707169d456 Mon Sep 17 00:00:00 2001 From: Clemens Radermacher Date: Wed, 9 Dec 2020 15:03:57 +0100 Subject: [PATCH 07/10] Add changelog --- CHANGELOG.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b28f7e8..6f800c1b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,9 @@ The format is based on [Keep a Changelog]. * The user option `selectrum-extend-current-candidate-highlight` determines whether to extend the highlighting of the current candidate until the margin (the default is nil). See [#208]. +* The user option `selectrum-complete-in-buffer` can be used to + control whether Selectrum should handle in buffer completion (the + default is t) ([#261]). ### Enhancements * The argument passed to `selectrum-select-current-candidate` and @@ -27,8 +30,17 @@ The format is based on [Keep a Changelog]. first and will also make such prompts behave like in default Emacs completion where you can immediately submit the initial input ([#253]). +* In buffer file completions act like normal completion now and insert + the candidate without prompting if there is only one. You can drop + into the minibuffer by triggering the completion again ([#261]). +* The mark is pushed at the beginning of the candidate inserted by in + buffer completion so you can easily jump there ([#261]). ### Bugs fixed +* For in buffer file completions s-expression commands for path level + navigation did not work which has been fixed ([#261]). +* Do not insert spaces after path completion in comint buffers + ([#261])]. * The return value of `selectrum-completion-in-region` has been fixed according to the documented API of `completion-in-region` ([#251]). * When strings of Selectrum display properties or completion table From 62ffaa2807299dcf06dfd5264c39daf5670a6b63 Mon Sep 17 00:00:00 2001 From: Clemens Radermacher Date: Wed, 9 Dec 2020 15:30:20 +0100 Subject: [PATCH 08/10] Describe new option --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 274def42..64fae13c 100644 --- a/README.md +++ b/README.md @@ -295,6 +295,10 @@ matching and case-insensitive matching. instead of indices, roman numerals, etc.) you can set the `selectrum-show-indices` to a function that takes in the relative index of a candidate and returns the string you want to display. +* By default, Selectrum does also handle in buffer completion via + `completion-in-region`. If you would like to disable that you can + unset `selectrum-complete-in-buffer` before activating + `selectrum-mode`. * The `selectrum-completion-in-region` function can display annotations if the `completion-in-region-function` backend offers them. Customize the face `selectrum-completion-annotation` to change From 0d9ce3afbe3b10e90ebd17c02f042655c37229a2 Mon Sep 17 00:00:00 2001 From: Clemens Radermacher Date: Wed, 9 Dec 2020 15:34:00 +0100 Subject: [PATCH 09/10] Rephrase doc --- selectrum.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/selectrum.el b/selectrum.el index dfceffab..e1be02ba 100644 --- a/selectrum.el +++ b/selectrum.el @@ -396,7 +396,7 @@ Nil (the default) means to only highlight the displayed text." ;;;###autoload (defcustom selectrum-complete-in-buffer t - "If non-nil, also use Selectrum when completing in non-mini buffers. + "If non-nil, use Selectrum for `completion-in-region'. This option needs to be set before activating `selectrum-mode'." :type 'boolean) From d8dcea966367572c48d2596698d1d164d395d549 Mon Sep 17 00:00:00 2001 From: Clemens Radermacher Date: Wed, 9 Dec 2020 15:36:28 +0100 Subject: [PATCH 10/10] Make arg clear --- selectrum.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/selectrum.el b/selectrum.el index e1be02ba..a203b5d5 100644 --- a/selectrum.el +++ b/selectrum.el @@ -1732,7 +1732,7 @@ COLLECTION, and PREDICATE, see `completion-in-region'." exit-status (cond ((not (member result cands)) 'sole) (t 'finished))))) (delete-region bound end) - (push-mark (point) t) + (push-mark (point) 'no-message) (insert (substring-no-properties result)) (when exit-func (funcall exit-func result exit-status))))))