[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Completion: display of candidates
From: |
Tassilo Horn |
Subject: |
Re: Completion: display of candidates |
Date: |
Tue, 19 Feb 2019 08:27:49 +0100 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) |
Stefan Monnier <monnier@IRO.UMontreal.CA> writes:
>> Right, and here comes the next problem: concretely I get my
>> completions from `locate --basename <pattern>`. So the user (me)
>> might enter a wildcard pattern like "foo*bar.*". But the
>> completions/matches obviously have no * in it, so no completion
>> matches the candidates.
>
> That completely depends on the completion style.
>
> For example `partial-completion` (which is included in the default
> `completion-styles`) does accept * so you can do `M-x r*v*uf TAB` to
> find revert-buffer.
Hm, that there can be dependencies between (1) finding completion
candidates and (2) completion styles doesn't spark joy in my heart. I
thought of (1) as a kind of generic backend and (2) as a frontend which
users select based on personal preference. But since both have to work
with the user's input string, I don't see how to make it better...
>> How to handle that? Use the PREDICATE argument in completing-read so
>
> The PREDICATE argument can only rule out matches, not add new ones.
Yeah, in the end I've waived my hands and went without text properties
and just selected a unicode character which is unlikely to be used in
file names as separator. The results are quite satisfying.
--8<---------------cut here---------------start------------->8---
(defconst th/recentf-locate-excluded-paths
(let ((home (getenv "HOME")))
(list
#'backup-file-name-p
(expand-file-name ".cargo/" home)
(expand-file-name ".cache/" home)
(expand-file-name ".m2/" home)
(expand-file-name ".IntelliJIdea[^/]+/" home))))
(defun th/recentf-locate-completions (str)
(with-current-buffer (get-buffer-create " *th/locate-matches*")
(erase-buffer)
(mapc (lambda (rf) (insert rf "\n")) recentf-list)
(let ((home-dir (getenv "HOME"))
lst line-move-visual)
(when (> (length str) 2)
(call-process "locate" nil t nil
"--basename"
"--existing"
"--ignore-case"
"--limit" "500"
str))
(goto-char (point-min))
(while (not (eobp))
(let* ((path (buffer-substring (point) (line-end-position)))
(basename (file-name-nondirectory path))
(dir (file-name-directory path)))
(unless (seq-find (lambda (pred)
(cond
((stringp pred)
(string-match-p pred path))
((functionp pred) (funcall pred path))
(t (error "Don't know how to handle %S" pred))))
th/recentf-locate-excluded-paths)
(push (format "%s ‼ %s" basename dir) lst)))
(next-line))
(sort lst (lambda (a b)
(or
;; a is in HOME but b is not, so sort a before b
(and (string-match-p (concat " ‼ " home-dir) a)
(not (string-match-p (concat " ‼ " home-dir) b)))
;; otherwise sort by base name.
(string-lessp a b)))))))
(defun th/recentf-locate-file (locate-candidate)
(interactive
(list (completing-read
"Locate File: "
(completion-table-dynamic #'th/recentf-locate-completions)
nil t)))
(let ((path (progn
(string-match "^\\(.*\\) ‼ \\(.*\\)$" locate-candidate)
(expand-file-name (match-string 1 locate-candidate)
(match-string 2 locate-candidate)))))
(find-file path)))
(global-set-key (kbd "<f5>") #'th/recentf-locate-file)
--8<---------------cut here---------------end--------------->8---
Bye,
Tassilo
- Completion: display of candidates, Tassilo Horn, 2019/02/18
- Re: Completion: display of candidates, Stefan Monnier, 2019/02/18
- Re: Completion: display of candidates, Tassilo Horn, 2019/02/18
- Re: Completion: display of candidates, Stefan Monnier, 2019/02/18
- Re: Completion: display of candidates, Tassilo Horn, 2019/02/18
- Re: Completion: display of candidates, Stefan Monnier, 2019/02/18
- Re: Completion: display of candidates,
Tassilo Horn <=
- Re: Completion: display of candidates, Stefan Monnier, 2019/02/19
- Message not available
- Re: Completion: display of candidates, Stefan Monnier, 2019/02/20