[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#13322: 24.3.50; `completion-all-sorted-completions': sorting and dup
From: |
Drew Adams |
Subject: |
bug#13322: 24.3.50; `completion-all-sorted-completions': sorting and duplicate deletion |
Date: |
Thu, 3 Jan 2013 09:39:45 -0800 |
> Since the completion-all-sorted-completions function just returns the
> value of the completion-all-sorted-completions cache when
> that cache is populated, it clearly can't take arguments since they'd
> not always be obeyed.
They would be obeyed whenever the function does not simply return the cached
value. That's the point.
Code can call `completion--flush-all-sorted-completions' when it wants
`completion-all-sorted-completions' to update the cache. That function
(`c--f-a-s-c') should not be "internal", BTW, IMHO.
(It might also be helpful for `completion-all-sorted-completions' itself to be
able to decide whether to reuse the cached value - other than testing its mere
presence. It could do so based on another optional argument or on a(nother)
global variable value.)
FWIW, as an example, in `icomplete+.el' I use this version, which is essentially
what I sent here before, but this also handles `completion-ignored-extensions'
and an alist COLLECTION arg of absolute file names (for Icicles). (See also bug
#12939, which has gotten no reply, about handling
`completion-ignored-extensions'.)
(defun icompletep-completion-all-sorted-completions
(&optional sort-function dont-remove-dups)
"Like `completion-all-sorted-completions', but with added optional args.
If SORT-FUNCTION is nil, sort per `completion-all-sorted-completions':
* per property `cycle-sort-function', if defined
* else by shorter length, then by recent use."
(or completion-all-sorted-completions
(let* ((start (field-beginning))
(end (field-end))
(string (buffer-substring start end))
(md (completion--field-metadata start))
(all (completion-all-completions
string minibuffer-completion-table
minibuffer-completion-predicate
(- (point) start) md))
(last (last all))
(base-size (or (cdr last) 0))
(all-md (completion--metadata
(buffer-substring-no-properties start (point))
base-size md minibuffer-completion-table
minibuffer-completion-predicate))
(sort-fun (or sort-function
(completion-metadata-get
all-md 'cycle-sort-function))))
(when last
(setcdr last ())
;; Exclude files for `completion-ignored-extensions'.
(when (or minibuffer-completing-file-name
(and (boundp 'icicle-abs-file-candidates)
icicle-abs-file-candidates))
(setq all (delete-if
(lambda (fl)
(string-match-p
(regexp-opt
completion-ignored-extensions)
fl))
all)))
(unless dont-remove-dups (setq all (delete-dups all)))
(setq last (last all)
all (if sort-fun
(funcall sort-fun all)
(sort all (lambda (c1 c2)
(< (length c1)
(length c2))))))
(when (and (minibufferp) (not sort-fun))
(let ((hist (symbol-value minibuffer-history-variable)))
(setq all (sort all (lambda (c1 c2)
(> (length (member c1 hist))
(length (member c2 hist))))))))
(completion--cache-all-sorted-completions
(nconc all base-size))))))
I call `completion--flush-all-sorted-completions' from Icicles when a user hits
`C-,' in the minibuffer, which cycles to the next Icicles candidate sort order.
This cache flushing makes Icomplete re-order the candidates, so the order in
Icomplete reflects the new current (Icicles) sort order.