From: Stefan Monnier <monnier@iro.umontreal.ca>
To: emacs-devel@gnu.org
Subject: Re: new-flex-completion-style
Date: Tue, 12 Feb 2019 09:08:03 -0500 [thread overview]
Message-ID: <jwvimxpqh2m.fsf-monnier+emacs@gnu.org> (raw)
In-Reply-To: 87lg2mynrg.fsf@gmail.com
>> W.r.t the UI sorting minibuffer.el has 2 different UIs with 2 different
>> sorting behaviors: there's the *Completions* buffer where results are
>> sorted alphabetically, and there's the force-complete cycling which
>> sorts by most-recently seen (using the minibuffer history variable) and
>> by length.
> Tangent: When using icomplete (who else here uses icomplete?), this is
> (the length) not good at all for switching buffers.
Not sure if it's related to icomplete. Maybe the length-heuristic is
just not good for buffer names. It was mostly motivated by experience
with M-x where I do believe that there is a correlation between command
name length and frequency of use of that command.
I think this length heuristic also works reasonably well in several
other circumstances (e.g. file names).
[ I'm clearly talking about the TAB-cycling use case, but I can't think
of a good reason why the icomplete-mode should be very different. ]
> I want it to behave like ido, where the natural order of buffer-list
> is preserved when the buffer can't be found in the
> minibuffer-history-variable.
How 'bout we change the buffer name completion table so it specifies its
own cycle-sort-function which uses buffer-list, then. It seems like it
would be a clear win (the buffer-list order is a much better heuristic
than the length).
> The only problem is that completion-style doesn't have a point to
> plug-in sorting yet.
That's right.
> So I thought good place to start is to place hints
> in the completion-candidates.
It's probably a good idea, yes.
>> Still, in a case such as lisp/ecomplete.el where the completion table
>> provides its own sorting based on recent-usage-frequency, how should
>> this sorting be combined with that of flex? I can see arguments in
>> favor of saying that the flex-weight should be ignored in favor of the
>> usage-frequency.
> ecomplete has its own UI in ecomplete-display-matches?
It also offers a completion-table (which I use via
a completion-at-point-function).
> My view of the matter is: completion table provides its sorting which
> _can_ be overriden by completion style's sorting which _can_ be
> overriden by completion UI's sorting. AFAIU this can be done by writing
> comparison functions that return nil if the current sorting should be
> agnostic to both elements.
Writing the function is of course the easy part.
The problem is where/how to insert this function.
>> I'd like to move towards a completion-style API that uses cl-generic.
>> E.g. introduce generic functions like `completion-style-try-completion`
>> which would be like `completion-try-completion` but takes an additional
>> `style` argument and dispatches based on it (replacing the dispatch
>> based on completion-style-alist).
>
> This is a good change, but it's not absolutely necessary to what I am
> proposing right now.
Definitely. I just wanted to explain that the design to the current
solution can be done with this other change in mind.
>>> * lisp/minibuffer.el (minibuffer-completion-help): Use
>>> completion-style-sort-order and compeltion-style-annotation
>> ^^^^^^^^^^
>> completion
>>> properties.
>>> (completion-pcm--hilit-commonality): Propertize completion with
>>> 'completion-pcm-commonality-score.
>>> (completion-flx-all-completions): Porpertize completion with
>> ^^^^^^^^^^
>> Propertize
> Thanks.
Duh! I meant to add some idiotic scolding about those typos but got
side tracked by the annotations issue. Sorry. I promise to be more
firm next time.
>>> completion-style-sort-order and completion-style-annotation.
>> Regarding annotations, I think being able to `concat` at the end is
>> too limited. If you take your example from sly, we'd like the "15%"
>> annotations to be right-aligned and I don't see an easy way to do that
>> with the facility you introduce.
> I don't see the problem fully,
Hmm... I guess in the completion-style case, you could indeed look at
all the returned completions to compute the max-length and do some
right-alignment based on that. For some reason, I feel like it'd be
better done elsewhere, tho (e.g. maybe company would rather right-align
based on the max-length of the *displayed* completions rather than
based on the max-length of all the completions).
> but probably I'd rather remove the annotation completely for now,
> until we have a better of how where we want to place it. As Dmitry
> suggested, the flex score annotation is mostly a gimmick, we shouldn't
> add it until we have a good idea of how it should work.
Indeed, this annotation issue is orthogonal, so it can be kept for later.
>> So I'd encourage you to come up with a more flexible annotation system
>> that allows prepending annotations as well as right-alignment (and
>> ideally combinations of those, with several columns, ...).
>
> I'd prefer small things that can be added
> incrementally.
So do I.
> What do you suggest?
Nothing so far.
> So to summarize, I propose to add (1) the fafa9ec commit introducing
> flex completion and (2) a new commit extracted from 2c7577558 which adds
> the flex scoring calculation to each match, but doesn't do anything with
> it yet. Deal?
Fine by me. I'd call the score property `completion-score` because
I don't see any reason why it should be specific to the completion-style
(you could even have `flex` combine its score with a `completion-score`
property previously set by the completion-table, and then have the
front end combine that with its own scoring).
I think you can also make minibuffer-completion-help sort according to
that `completion-score`.
Regarding the code, see comments below.
Stefan
> + (setq completions
> + (sort completions
> + (lambda (a b)
> + (let ((va (get-text-property 0 'completion-style-sort-order a))
> + (vb (get-text-property 0 'completion-style-sort-order b)))
> + (if (and va vb) (< va vb) va)))))
This will signal an error when one of the completions is the empty string :-(
> @@ -3056,22 +3067,41 @@ PATTERN is as returned by `completion-pcm--string->pattern'."
> (let* ((pos (if point-idx (match-beginning point-idx) (match-end 0)))
> (md (match-data))
> (start (pop md))
> - (end (pop md)))
> + (end (pop md))
> + (len (length str))
> + (score-numerator 0)
> + (score-denominator 0)
> + (aux 0)
> + (update-score
> + (lambda (a b)
> + "Update score variables given match range (A B)."
> + (setq
> + score-numerator (+ score-numerator (- b a))
> + score-denominator (+ score-denominator (expt (- a aux) 1.5))
> + aux b))))
I don't understand this scoring algorithm: please add a comment
explaining it (and give a meaningful name to `aux`).
> + (funcall update-score 0 start)
> (while md
> - (put-text-property start (pop md)
> + (funcall update-score start (car md))
> + (put-text-property start
> + (pop md)
The extra line-break after `start` seems spurious.
> + (put-text-property
> + 0 1 'completion-pcm-commonality-score
> + (/ score-numerator (* len (1+ score-denominator)) 1.0) str))
This will signal an error when `str` is the empty string :-(
BTW, maybe PCM could also use this scoring for sorting (i.e. we could
set `completion-score` directly here)
> + (let ((score (get-text-property 0 'completion-pcm-commonality-score comp)))
> + (put-text-property 0 1 'completion-style-sort-order (- score) comp)
This will signal an error when `comp` is the empty string :-(
next prev parent reply other threads:[~2019-02-12 14:08 UTC|newest]
Thread overview: 71+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20190202232827.27331.87300@vcs0.savannah.gnu.org>
[not found] ` <20190202232828.4AE452159A@vcs0.savannah.gnu.org>
2019-02-06 3:11 ` [Emacs-diffs] scratch/new-flex-completion-style 2c75775 2/2: Score, sort and annotate flex-style completions according to match tightness Dmitry Gutov
2019-02-06 10:09 ` João Távora
2019-02-06 18:54 ` Dmitry Gutov
2019-02-06 19:47 ` João Távora
2019-02-12 0:25 ` Dmitry Gutov
2019-02-12 13:19 ` Stefan Monnier
2019-02-12 22:55 ` Dmitry Gutov
2019-02-13 16:00 ` Stefan Monnier
2019-02-14 1:33 ` Dmitry Gutov
2019-02-19 16:10 ` Stefan Monnier
2019-02-24 0:03 ` Dmitry Gutov
2019-02-27 17:12 ` Stefan Monnier
2019-03-11 0:17 ` Dmitry Gutov
2019-03-11 1:15 ` Stefan Monnier
2019-03-11 22:54 ` Dmitry Gutov
2019-03-12 1:10 ` Drew Adams
2019-03-12 22:25 ` Dmitry Gutov
2019-03-12 23:12 ` Drew Adams
2019-03-11 8:47 ` João Távora
2019-03-11 22:57 ` Dmitry Gutov
2019-02-12 17:21 ` João Távora
2019-02-12 23:47 ` Dmitry Gutov
2019-02-11 21:10 ` new-flex-completion-style (was: [Emacs-diffs] scratch/ 2c75775 2/2: Score, sort and annotate flex-style completions according to match tightness) Stefan Monnier
2019-02-11 22:16 ` new-flex-completion-style João Távora
2019-02-11 23:02 ` new-flex-completion-style Dmitry Gutov
2019-02-11 23:11 ` new-flex-completion-style João Távora
2019-02-12 0:10 ` new-flex-completion-style Dmitry Gutov
2019-02-12 0:16 ` new-flex-completion-style Óscar Fuentes
2019-02-12 22:04 ` new-flex-completion-style João Távora
2019-02-13 0:28 ` new-flex-completion-style Óscar Fuentes
2019-02-13 11:20 ` new-flex-completion-style João Távora
2019-02-13 14:23 ` new-flex-completion-style Óscar Fuentes
2019-02-13 14:38 ` new-flex-completion-style Drew Adams
2019-02-13 15:24 ` new-flex-completion-style Stefan Monnier
2019-02-13 15:33 ` new-flex-completion-style Drew Adams
2019-02-13 15:40 ` new-flex-completion-style Óscar Fuentes
2019-02-13 17:34 ` new-flex-completion-style Daniel Pittman
2019-02-12 14:08 ` Stefan Monnier [this message]
2019-02-12 22:17 ` new-flex-completion-style João Távora
2019-02-13 17:29 ` new-flex-completion-style João Távora
2019-02-13 18:54 ` new-flex-completion-style Stefan Monnier
2019-02-13 19:13 ` new-flex-completion-style João Távora
2019-02-14 13:36 ` new-flex-completion-style Stefan Monnier
2019-02-14 13:55 ` new-flex-completion-style João Távora
2019-02-14 14:59 ` new-flex-completion-style João Távora
2019-02-14 15:28 ` new-flex-completion-style Óscar Fuentes
2019-02-14 15:44 ` new-flex-completion-style Drew Adams
2019-02-14 16:21 ` new-flex-completion-style João Távora
2019-02-14 15:35 ` new-flex-completion-style Daniel Pittman
2019-02-14 16:12 ` new-flex-completion-style João Távora
2019-02-14 16:16 ` new-flex-completion-style João Távora
2019-02-14 16:34 ` new-flex-completion-style Drew Adams
2019-02-14 17:03 ` new-flex-completion-style João Távora
2019-02-14 17:49 ` new-flex-completion-style Drew Adams
2019-02-14 18:30 ` new-flex-completion-style João Távora
2019-02-14 19:20 ` new-flex-completion-style Drew Adams
2019-02-14 20:54 ` new-flex-completion-style João Távora
2019-02-14 22:03 ` new-flex-completion-style Drew Adams
2019-02-14 22:06 ` new-flex-completion-style João Távora
2019-02-14 22:22 ` new-flex-completion-style Stefan Monnier
2019-02-15 0:54 ` new-flex-completion-style Drew Adams
2019-02-15 4:50 ` new-flex-completion-style Stefan Monnier
2019-02-15 5:52 ` new-flex-completion-style Dmitry Gutov
2019-02-15 6:32 ` new-flex-completion-style Drew Adams
2019-02-18 20:46 ` new-flex-completion-style João Távora
2019-02-18 23:35 ` new-flex-completion-style Stefan Monnier
2019-02-19 9:16 ` new-flex-completion-style João Távora
2019-02-19 12:54 ` new-flex-completion-style Stefan Monnier
2019-02-19 13:01 ` new-flex-completion-style João Távora
2019-02-19 13:32 ` new-flex-completion-style Stefan Monnier
2019-02-11 22:57 ` new-flex-completion-style (was: [Emacs-diffs] scratch/ 2c75775 2/2: Score, sort and annotate flex-style completions according to match tightness) Drew Adams
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=jwvimxpqh2m.fsf-monnier+emacs@gnu.org \
--to=monnier@iro.umontreal.ca \
--cc=emacs-devel@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).