2

I'd like to use something like ido-completing-read in the minibuffer, but on a per-word basis. Here is an example. If I provide a list ("tag:important " "tag:work" "subject" "from"), I'd like to be able to type any word, but each time a word match (fuzzyly) some elements of the list, I can select it using the TAB key, and continue typing until I'm happy and I type enter.


Demo: (the proposed words are in {}, the typed text is on the left part, each line is a key-strock after the last one):

Beginning, empty line

{tag:important |tag:work |subject|from}

Type "tag", the useless proposition are removed:

tag{tag:important |tag:work}

Type "liatelle", nothing match this word so nothing is proposed...

tagliatelle{}

... until I press space an start a new word:

tagliatelle {tag:important |tag:work |subject|from}

continue to type "AND tag":

tagliatelle AND tag{tag:important |tag:work}

now I press TAB to validate the first proposition (or cycle with C-s)

tagliatelle AND tag[TAB]{tag:important |tag:work}

the first proposition is took:

tagliatelle AND tag:important {tag:important |tag:work |subject|from}

Finally, type "ENTER" to validate: the output is tagliatelle AND tag:important

Thank you!

1 Answer 1

1

It's not exactly what I wanted before, but it's not too far away. The idea is to use recursive minibuffer and to run ido-completing-read with the good parameters each time the user type TAB. So you won't use exactly the keystrokes above, but it won't be too far since you will hit "tab" when you want to see what IDO can give you, and then you hit "Enter" when you are happy with the IDO proposition. If someone has another solution, please let me know! Note that by default I chosed to autocomplete if only one solution is available and if this solution does not need to "fuzzy-match".

Demo:

enter image description here

Code:

(setq xyz-keywords
      '( "touch"
     "touch_start"
     "touch_end"
     "for"
     "foreach"
     "forall"
     "chocolate"
     "banana"
     ))

(defun in-buffer-ido-replace (choices &optional even-if-one-solution)
  "Choices must be a list of string that can be chosen.
Set 'even-if-one-solution' to 't' if you want to run ido even when only one solution is available."
  (interactive)
  (let*
      ((choices_ (cons "" choices))
       (enable-recursive-minibuffers t)
       (bds (or (bounds-of-thing-at-point 'symbol) (cons (point) (point))))
       (start (car bds))
       (end (point))
       (beginword (buffer-substring start end))
       (textbefore (buffer-substring 1 start))
       (classic-completions (all-completions beginword choices_)))
    ;; Complete directly if one solution
    (if (and (not even-if-one-solution) (eq (length classic-completions) 1))
    (insert (car classic-completions))
      (insert (ido-completing-read
           (concat textbefore "")
           choices_ nil nil beginword)))
    (delete-region start end)
  ))

(setq my-mode-map (copy-keymap minibuffer-local-map))
(define-key my-mode-map (kbd "TAB") (lambda () (interactive) (in-buffer-ido-replace xyz-keywords)))
(let ((minibuffer-setup-hook (lambda () (add-hook 'completion-at-point-functions 'xyz-completion-at-point nil 'local))))
  (read-from-minibuffer "Prompt: " nil my-mode-map))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.