From: Tassilo Horn <tsdh@gnu.org>
To: Stefan Monnier <monnier@IRO.UMontreal.CA>
Cc: help-gnu-emacs@gnu.org
Subject: Re: Completion: display of candidates
Date: Tue, 19 Feb 2019 08:27:49 +0100 [thread overview]
Message-ID: <87lg2cgruy.fsf@gnu.org> (raw)
In-Reply-To: <jwv7edwesgm.fsf-monnier+emacs@gnu.org> (Stefan Monnier's message of "Mon, 18 Feb 2019 15:48:36 -0500")
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
next prev parent reply other threads:[~2019-02-19 7:27 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-02-18 7:54 Completion: display of candidates Tassilo Horn
2019-02-18 13:26 ` Stefan Monnier
2019-02-18 14:55 ` Tassilo Horn
2019-02-18 18:05 ` Stefan Monnier
2019-02-18 19:24 ` Tassilo Horn
2019-02-18 20:48 ` Stefan Monnier
2019-02-19 7:27 ` Tassilo Horn [this message]
2019-02-19 15:28 ` Stefan Monnier
[not found] ` <87imxe1pfs.fsf@gnu.org>
2019-02-20 16:54 ` Stefan Monnier
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=87lg2cgruy.fsf@gnu.org \
--to=tsdh@gnu.org \
--cc=help-gnu-emacs@gnu.org \
--cc=monnier@IRO.UMontreal.CA \
/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.
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).