bug-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bug#44016: 28.0.50; Add new "gnus-search" search interface to Gnus


From: Stefan Monnier
Subject: bug#44016: 28.0.50; Add new "gnus-search" search interface to Gnus
Date: Sun, 01 Nov 2020 18:50:50 -0500
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux)

> The expandable search keys are kept in `gnus-search-expandable-keys'.
> The programmatic completion part looks like:
>
> --8<---------------cut here---------------start------------->8---
> +(defun gnus-search-query-expand-key (key)
> +  (cond ((test-completion key gnus-search-expandable-keys)
> +      ;; We're done!
> +      key)
> +     ;; There is more than one possible completion.
> +     ((consp (cdr (completion-all-completions
> +                   key gnus-search-expandable-keys #'stringp 0)))
> +      (signal 'gnus-search-parse-error
> +              (list (format "Ambiguous keyword: %s" key))))
> +     ;; Return KEY, either completed or untouched.
> +     ((car-safe (completion-try-completion
> +                 key gnus-search-expandable-keys
> +                    #'stringp 0)))))
> --8<---------------cut here---------------end--------------->8---

IIUC this function is used to expand unambiguous abbreviations, right
(rather than the more usual "completion" which is done as the user is
typing)?

It just happens to reuse the completion machinery to do the work.
If so, it looks OK (I guess you could try and reuse the output from
completion-all-completions in the last branch instead of calling
completion-try-completion, but it might be more trouble than it's worth).

> --8<---------------cut here---------------start------------->8---
> +(defvar gnus-search-minibuffer-map
> +  (let ((km (make-sparse-keymap)))
> +    (set-keymap-parent km minibuffer-local-map)
> +    (define-key km (kbd "SPC") #'self-insert-command)
> +    (define-key km (kbd "TAB") #'gnus-search-complete-key)
> +    km))
> +
> +(defun gnus-search-complete-key ()
> +  "Complete a search key at point.
> +Used when reading a search query from the minibuffer."
> +  (interactive)
> +  (when (completion-in-region
> +      (save-excursion
> +        (if (re-search-backward " " (minibuffer-prompt-end) t)
> +            (1+ (point))
> +          (minibuffer-prompt-end)))
> +      (point) gnus-search-expandable-keys)
> +    (insert ":")))
> +
> +(defun gnus-search-make-spec (arg)
> +  (list (cons 'query
> +           (read-from-minibuffer
> +            "Query: " nil gnus-search-minibuffer-map
> +            nil 'gnus-search-history))
> +     (cons 'raw arg)))
> --8<---------------cut here---------------end--------------->8---

Hmm... here I think instead of calling `completion-in-region` yourself,
you'd want to do something like:

    (defvar gnus-search-minibuffer-map
      (let ((km (make-sparse-keymap)))
        (set-keymap-parent km minibuffer-local-map)
        (define-key km (kbd "SPC") #'self-insert-command) ;; Isn't this 
redundant?
        (define-key km (kbd "TAB") #'completion-at-point)
        km))

    (defun gnus-search--complete-key-data ()
      "Return completion data for gnus-search keys."
      (list (save-excursion
              (if (re-search-backward " " (minibuffer-prompt-end) t)
                  (1+ (point))
                (minibuffer-prompt-end)))
            (point)
            gnus-search-expandable-keys))

    (minibuffer-with-setup-hook
        (lambda ()
          (add-hook 'completion-at-point-functions
                    #'gnus-search--complete-key-data nil t))
      (read-from-minibuffer ...))

See `read--expression` (used to provide completion on Elisp function
and var names when reading an ELisp expression in the minibuffer, such
as in `M-:`) for an example.

If you want to auto-insert a `:` you'd then do it via an `:exit-function`.


        Stefan






reply via email to

[Prev in Thread] Current Thread [Next in Thread]