This moves the logic from the series of commits starting in the commit named:
Improve sorting of flex completion style with non-nil minibuffer-default
to lisp/icomplete.el, so far the only confirmed beneficiary of that
functionality.
* lisp/icomplete.el (icomplete--sorted-completions): Consider
minibuffer-default here.
* lisp/minibuffer.el (completion--flex-adjust-metadata): Simplify.
(cherry picked from commit 0d2a711dc9)
If minibuffer-default coincided with the first of completions, the
empty list would be returned.
* lisp/minibuffer.el (completion--flex-adjust-metadata): Make sure
to never return empty list.
This previous commit targetting this function introduced a bug whereby
the completion table's sorting function wouldn't be called. That is
fixed by this commit, which also simplifies the function further: it
now skips re-sorting the completions completely if there is no
minibuffer input at all (in other words, when flex isn't doing
anything useful).
* lisp/minibuffer.el (completion--flex-adjust-metadata): Simplify.
This affects the behaviour of flex completion when there is a default
completion and the user hasn't entered any input pattern to flex-match
against. It is most visible when icomplete-mode or fido-mode are
being used in conjunctio.
When using M-x man, for instance, the default completion is picked
from text around point. Say it is "emacs" (for Emacs's man page). It
will not match the intended completion, "emacs(1)", exactly. If the
user hasn't yet given any input to the completion prompt, that
completion should bubble to top so that
icomplete-force-complete-and-exit will select it, but it didn't.
This new approach uses 'string-prefix-p' instead of 'equal' to find
the default to bubble to the top. This strategy could eventually be
improved, most naturally by flex-matching the default string to all
the candidates and picking the highest scoring one.
Additionally, the new strategy only considers minibuffer-default if
there is no input in the minibuffer, which seems sensible and produces
a small but noticeable speedup.
* lisp/minibuffer.el (completion--flex-adjust-metadata):
Reformulate sorting strategy.
* doc/lispref/display.texi (Displaying Messages): Document
set-message-function and clear-message-function.
* lisp/minibuffer.el (minibuffer-message-clear-timeout): New defcustom.
(minibuffer-message-timer, minibuffer-message-overlay): New variables.
(set-minibuffer-message, clear-minibuffer-message): New functions.
(set-message-function, clear-message-function): Set variables to
set-minibuffer-message and clear-minibuffer-message respectively.
* src/keyboard.c (read_char): Call clear_message when
Vclear_message_function is a function.
* src/xdisp.c (set_message): Call Vset_message_function when it's a function.
(clear_message): Call Vclear_message_function when it's a function.
(syms_of_xdisp): New variables set-message-function and clear-message-function
(bug#38457).
* lisp/minibuffer.el (minibuffer-local-map): Move remap of
recenter/scroll keybindings to read-char-from-minibuffer-map.
* lisp/subr.el (read-char-from-minibuffer-map): Move remap of
recenter/scroll keybindings here from minibuffer-local-map.
(bug#38502)
`completion-pcm--hilit-commonality` so that these faces doesn't
override possible already existing faces in other UIs.
* lisp/minibuffer.el (completion-pcm--hilit-commonality): Use
`add-face-text-property` instead of `put-text-property`.
This fixes bug#38458 where a final `point` in the pattern prevented
the expected normal behavior of point moving after the completion
of the final implicit `any`.
(completion-pcm--find-all-completions)
(completion-substring--all-completions): Use it.
(completion-basic--pattern): Don't both removing "" any more.
(completion-basic-try-completion): Use it as well as
`completion-basic--pattern`.
* doc/lispref/display.texi (Displaying Messages): Explain the
behavior of using minibuffer-message if the minibuffer is active.
* src/editfns.c (Fmessage_in_echo_area): New function with body
copied from Fmessage.
(Fmessage): Call minibuffer-message in the active minibuffer,
otherwise call Fmessage_in_echo_area.
(message-in-echo-area): New variable.
* lisp/isearch.el (isearch--momentary-message, isearch-message):
* lisp/minibuffer.el (minibuffer-message, minibuffer-completion-help):
Use 'message-in-echo-area' instead of 'message' where necessary.
* lisp/autorevert.el (auto-revert-handler):
* lisp/man.el (Man-bgproc-sentinel):
* lisp/subr.el (do-after-load-evaluation):
Revert recent changes that replaced 'message' with 'minibuffer-message'.
This is not needed anymore since 'message' uses 'minibuffer-message'
in the active minibuffer.
matching spaces. This allows flex style working smoothly with other
styles like helm using spaces.
* lisp/minibuffer.el (completion-flex-nospace): New user var.
(completion-flex-try-completion): Use it.
(completion-flex-all-completions): Same.
* lisp/subr.el (do-after-load-evaluation): Use minibuffer-message
to not obscure a possibly active minibuffer.
* lisp/minibuffer.el (minibuffer-message):
Record message in the *Messages* buffer.
* lisp/minibuffer.el (with-minibuffer-selected-window): New macro.
(minibuffer-recenter-top-bottom, minibuffer-scroll-up-command)
(minibuffer-scroll-down-command, minibuffer-scroll-other-window):
(minibuffer-scroll-other-window-down): New commands.
(minibuffer-local-map): Remap recenter/scroll symbols to their
minibuffer wrappers: recenter-top-bottom to minibuffer-recenter-top-bottom.
* src/window.c (Fother_window_for_scrolling): Use 'lambda' value for
MINIBUF arg of Fnext_window, so minibuffer-scroll-other-window and
minibuffer-scroll-other-window-down doesn't try to scroll the
minibuffer window.
This is the way the basic completion styles work. This fixes
candidate highlighting in icomplete.
* lisp/minibuffer.el (completion-pcm--hilit-commonality): Apply
faces to 'face property, not font-lock-face.
(completion-metadata): Always return a fresh new cons cell.
(completion--nth-completion): Don't bother calling adjust-metadata
if the result won't be used.
(completion-pcm--hilit-commonality): Revert recent change which had
removed support for `completions-first-difference` in `substring` and
`partial-completion` styles.
(completion--flex-adjust-metadata): Treat the arg as immutable.
This is so minibuffer.el can make use of cl-generic
* lisp/minibuffer.el (minibuffer-local-completion-map):
Move switch-to-completions bindings here from...
* lisp/simple.el (minibuffer-local-completion-map): ... here.
The previous algorithm had two problems: it considered non-matches in
the beginning and end of the string as matching "holes" and failed to
penalize larger holes, making flex-score-match-tightness only
effective in some corner cases.
The new formula, which is described in code and in pseudo-code in the
comments, fixes these problems.
As a result, by default, C-h f flex now correctly bubbles up
"company-search-flex-regexp" to the top, in front of "file-exists-p".
With a flex-score-match-tightness smaller than 1.0, the situation is
reversed.
* lisp/minibuffer.el (flex-score-match-tightness): Adjust default
value. Improve docstring example.
(completion-pcm--hilit-commonality): Improve example. Remove unused
variable. Improve algorithm.
The previous commit titled "Rework face hints for partial-string
completion styles" contained a potentially controversial
backwards-incompatible change to this face's default value.
* lisp/minibuffer.el (completions-common-part): Restore empty
default value.
Don't use completions-first-difference for the 'substring', 'flex' and
'partial-completion' styles, since there can be really no reasonable
definition of a "first" difference there.
Make completions-common-part inherit from 'underline' so that it is
useful by default for all completion styles.
* lisp/minibuffer.el (completions-common-part): Adjust
description and change default value.
(completions-first-difference): Ajust docstring.
(completion-pcm--hilit-commonality): Don't use
completions-first-difference.
This commit re-does the now-reverted commit with the same title. That
version relied on generic functions, which cannot be used yet in files
such as lisp/minibuffer.el. This version uses a symbol property
completion--adjust-metadata instead.
The new facility allows completion styles to have a say in metadata
properties such as cycle-sort-function and display-sort-function.
This is especially useful for completion styles such as 'flex', which
generally produce many matches, including some potentially "obscure"
ones. The default sorting strategy would often bubble the latter to
the top of the list.
The sorting function for 'flex' considers pre-computed matching scores
and is thus much better than the default for this particular style.
Additionally, it overrides the completion table's cycle-sort-function
or display-sort-function properties if they exist, although it still
uses them to pre-sort the result, so that they are still relevant for
resolving ties.
* lisp/minibuffer.el (completion--nth-completion)
(completion--flex-adjust-metadata): New helper.
(flex): Put completion--adjust-metadata property.
The new facility, realized in the completion-adjust-metadata-for-style
generic, allows completion styles to have a say in metadata properties
such as cycle-sort-function and display-sort-function. This is
especially useful for completion styles such as 'flex', which
generally produce many matches, including some potentially "obscure"
ones. The default sorting strategy would often bubble the latter
to the top of the list.
The sorting function for 'flex' considers pre-computed matching scores
and is thus much better than the default for this particular style.
Additionally, it overrides the completion table's cycle-sort-function
or display-sort-function properties if they exist, although it still
uses them to pre-sort the result, so that they are still relevant for
resolving ties.
* lisp/minibuffer.el (completion--nth-completion): Call
completion-adjust-metadata-for-style.
(completion-adjust-metadata-for-style): New generic.
(completion-adjust-metadata-for-style 'flex): New method.
* doc/lispref/minibuf.texi (Completion Commands)
(Text from Minibuffer): Document it.
* lisp/minibuffer.el (minibuffer-beginning-of-buffer): New command
(bug#3447).
(map): Bind it.
(minibuffer-message): Use it to propertize message unless already
propertized by the caller.
* lisp/simple.el (minibuffer-error-function): Propertize the error.
* lisp/isearch.el (isearch-message-properties): New variable.
(isearch--momentary-message, isearch-message-prefix)
(isearch-message-suffix): Use it. (Bug#21112)
To hopefully resolve a long-running discussion
(https://lists.gnu.org/archive/html/emacs-devel/2019-05/msg00162.html).
* lisp/progmodes/project.el (project-read-file-name-function):
New variable.
(project--read-file-absolute, project--read-file-cpd-relative):
New functions, possible values for the above.
(project-find-file-in): Use the introduced variable.
(project--completing-read-strict): Retain just the logic that fits
the name.
The previous strategy had problems comparing scores of matches to
strings of different lengths. This one seems slightly more sensible,
and uses a new constant `flex-score-match-tightness' instead of the
more abstract `flex-score-falloff'.
It's not completely without problems, and I think it shouldn't count
"holes" at the front and at the back, but that needs a different
"pattern-to-regexp" conversion in completion-pcm--hilit-commonality.
(defun test ()
(mapcar (lambda (a)
(cons (substring-no-properties a)
(get-text-property 0 'completion-score a)))
(sort (completion-pcm--hilit-commonality
'(prefix "f" star "o" star "o" point)
'("foo"
"barfoobaz"
"foobarbaz"
"barbazfoo"
"fabrobazo"
"foot"
"foto"
"fotttttttttttttttttttttttto"))
(lambda (a b)
(> (get-text-property 0 'completion-score a)
(get-text-property 0 'completion-score b))))))
(let ((flex-score-match-tightness 100)) (test))
=> (("foo" . 1.0)
("foot" . 0.375)
("foto" . 0.375)
("foobarbaz" . 0.16260162601626016) ;; one hole
("barbazfoo" . 0.16260162601626016) ;; one hole
("barfoobaz" . 0.10964912280701755) ;; two holes
("fabrobazo" . 0.10964912280701755) ;; two holes
("fotttttttttttttttttttttttto" . 0.04982561036372696))
(let ((flex-score-match-tightness 0.1)) (test))
=> (("foo" . 1.0)
("foot" . 0.375)
("foto" . 0.375)
("barfoobaz" . 0.007751937984496124) ;; two holes
("fabrobazo" . 0.007751937984496124) ;; two holes
("foobarbaz" . 0.00641025641025641) ;; one hole
("barbazfoo" . 0.00641025641025641) ;; one hole
("fotttttttttttttttttttttttto" . 0.0004789272030651341))
* lisp/minibuffer.el (flex-score-falloff): Rename to
flex-score-match-tightness.
(completion-pcm--hilit-commonality): Update function.
The new completion style needs to score completion matches so that we
can use it later on when sorting the completions. This is because
"foo" can flex-match "foobar", "frodo" and "barfromsober" but we
probably want "foobar" to appear at the top of the completion list.
This change introduces a scoring formula and adds scoring hints in the
candidate string's `completion-score' property.
* lisp/minibuffer.el (completion-pcm--hilit-commonality): Propertize
completion with 'completion-score
(flex-score-falloff): New variable.