From: Austin Clements <amdragon@MIT.EDU>
To: Daniel Schoepe <daniel.schoepe@googlemail.com>
Cc: notmuch@notmuchmail.org
Subject: Re: [PATCH] emacs: Tab completion for notmuch-search and notmuch-search-filter
Date: Sat, 4 Jun 2011 17:55:24 -0400 [thread overview]
Message-ID: <20110604215523.GF29861@mit.edu> (raw)
In-Reply-To: <87mxhxjrry.fsf@gilead.invalid>
Quoth Daniel Schoepe on Jun 04 at 9:55 pm:
> On Sat, 4 Jun 2011 11:32:15 -0400, Austin Clements <amdragon@mit.edu> wrote:
> > Dynamic scoping is obnoxious, but I think programmed completion is
> > steeped in the assumption that you'll use it. This code would be much
> > simpler if notmuch-query-completions took only `string' and used the
> > dynamically-bound all-compls (which should probably be renamed
> > notmuch-completions or something if you do this). Then this could be
> > just
> > (minibuffer-completion-table (completion-table-dynamic
> > #'notmuch-query-completions)))
> > and there'd be no need for quasiquoting, comments, and fake lexical scoping.
>
> Sounds reasonable, I guess I really should stop fighting all those ugly
> parts of elisp with unreadable constructs like that. I made it a global
> variable though to avoid compilation warnings about notmuch-completion
> being a free variable. Since it's contents are not dependent on
> how/where notmuch-read-query is called, this shouldn't cause any
> problems, except my personal discomfort arising from the use of side
> effects for something as simple as this. :)
Oh, sorry, I wasn't suggesting setq'ing a global. I agree that that's
really ugly. Rather, something like
(defun notmuch-query-completions (string)
... as you have it now ...)
(defun notmuch-read-query (prompt)
(let ((notmuch-completions (append (list "folder:" ...)))
(keymap ...)
(minibuffer-completion-table ...))
(read-from-minibuffer ...)))
Unfortunately, you still need the global defvar to avoid compilation
warnings, but this at least avoids the side-effects, and is probably
how programmed completion was intended to be used.
Alternatively, here's a completely different way to structure this
that avoids globals and dynamic scoping entirely. This is how some of
the standard completing read functions appear to work:
(defun notmuch-read-query (prompt)
"Read a notmuch-query from the minibuffer with completion.
PROMPT is the string to prompt with."
(lexical-let ((completions
(append (list "folder:" "thread:" "id:" "date:" "from:" "to:"
"subject:" "attachment:")
(mapcar (lambda (tag)
(concat "tag:" tag))
(process-lines "notmuch" "search-tags")))))
(let ((minibuffer-completion-table
(completion-table-dynamic
(lambda (string)
(cond
;; this ugly regexp is used to get the last word of the
;; input possibly preceded by a '('
((string-match "\\(^\\|.* (?\\)\\([^ ]*\\)$" string)
(mapcar (lambda (compl)
(concat (match-string-no-properties 1 string) compl))
(all-completions (match-string-no-properties 2 string)
completions)))
(t (list string))))))
(keymap (copy-keymap minibuffer-local-map)))
;; this was simpler than convincing completing-read to accept spaces:
(define-key keymap (kbd "<tab>") 'minibuffer-complete)
(read-from-minibuffer prompt nil keymap nil minibuffer-history nil nil))))
> > > + (define-key keymap (kbd "<tab>") 'minibuffer-complete)
> >
> > This probably deserves a comment about why you're doing so much work
> > to avoid completing-read (which I assume is because it also binds SPC,
> > even if require-match is nil, which is unfortunate).
>
> Yes, that was the reason.
>
> Another thing that bugs me, is that I did not find a better way of doing
> the completion: Ideally I'd like to just specify a list of completions
> for individual words and have emacs handle separating the input string
> into individual words, but I couldn't find any options to accomplish
> that.
Yeah, I futzed with it for a bit, swearing that there had to be a
better way, but didn't find one either.
next prev parent reply other threads:[~2011-06-04 21:55 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-06-04 12:19 [PATCH] emacs: Tab completion for notmuch-search and notmuch-search-filter Daniel Schoepe
2011-06-04 13:14 ` Daniel Schoepe
2011-06-04 15:32 ` Austin Clements
2011-06-04 19:55 ` Daniel Schoepe
2011-06-04 20:39 ` Daniel Schoepe
2011-06-04 21:55 ` Austin Clements [this message]
2011-06-04 22:54 ` Daniel Schoepe
2011-06-06 16:32 ` Daniel Schoepe
2011-08-05 15:17 ` Daniel Schoepe
2011-08-05 21:00 ` Jameson Graef Rollins
2011-08-05 21:03 ` Jameson Graef Rollins
2011-08-06 6:09 ` Jameson Graef Rollins
2011-08-09 17:31 ` Daniel Schoepe
2011-08-09 21:41 ` Jameson Graef Rollins
2011-08-09 17:32 ` Daniel Schoepe
2011-11-03 1:19 ` David Bremner
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://notmuchmail.org/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20110604215523.GF29861@mit.edu \
--to=amdragon@mit.edu \
--cc=daniel.schoepe@googlemail.com \
--cc=notmuch@notmuchmail.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://yhetil.org/notmuch.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).