2

Ivy (+swiper +counsel) is very cool and I use it constantly for an ever growing number of tasks. But there are some cases in which the requirements of a certain completion task defeats Ivy's logic. One of those is Org tags search, more precisely, org-tags-view which is commonly bound to C-c a m. And this command conflicts with Ivy's logic both because it requires (typically) multiple candidates, and is supposed to output a single string out of them, connected by plus or minus signs. So a typical case would be "+tag1+tag2-tag3".

The default completion works better in this case, and while using Ivy, I'd like to tell it to use default completion in this particular function. Theoretically, there is already a defcustom meant for this task: ivy-completing-read-handlers-alist. But I cannot get it to work with org-tags-view.

I've tried:

(add-to-list 'ivy-completing-read-handlers-alist
             '(org-tags-view . completing-read-default))

But also, as org-tags-view calls org-make-tags-matcher internally:

(add-to-list 'ivy-completing-read-handlers-alist
             '(org-make-tags-matcher . completing-read-default))

Neither inhibited Ivy completion from kicking in. Does anyone know what I may be missing? Or how to get this to work?

2

Are you sure you executed the code? I just tried:

(push  '(org-tags-view . completing-read-default)
   ivy-completing-read-handlers-alist)

and it worked as expected.

Responding to the comment:

Indeed when calling it from org-agenda it does not work. As you supposed, this is because this-command is changed to org-agenda. As you probably don't want affect other commands called from agenda I would recommend to advice org-tags-view.

There are different ways you could achieve what you want, by let binding this-command or ivy-completing-read-handlers-alist. One that does not depend on ivy (so continues to work should you switch the completing framework some day) is:

(define-advice org-tags-view (:around (f &rest args) use-completing-read-default)
  (let ((completing-read-function #'completing-read-default)
        (completion-in-region-function #'completion--in-region))
    (apply f args)))
  • clemera, thank you very much for your comment. I think it made me understand the problem. First, yes, I was executing the code, and checked the variable. But I believe the issue is how I was accessing org-tags-view. Indeed, if I call the command directly, the setting works. But not so if I do it from the agenda dispatcher. Probably what is happening is that ivy-completing-read-handlers-alist is testing for this-command and, in this case, it is org-agenda rather than org-tags-view. Do you have any idea on how to deal with that? – gusbrs Jul 26 at 23:22
  • @gusbrs I updated the answer, explaining how to work around that. – clemera Jul 27 at 6:41
  • clemera, thanks again. Since I asked, I had tried, among a number of things, to advise org-tags-view let binding completing-read-function. In my attempts, and in your proposed advice too, Ivy doesn't kick in at first, but in the end does so, once you press TAB. I couldn't figure out, but there is probably some recursion in the process. The only way I could make it work was really with an advice around org-tags-view which disabled ivy-mode before running the function and then reenabled it afterwards. [...] – gusbrs Jul 27 at 11:07
  • [...] Though I think a technically correct solution to this would indeed involve not tampering with any other agenda commands besides org-tags-view (your thought was the same as mine in the matter), in practice, all other default commands in the agenda dispatcher do not require completion. In my case, none of my custom ones require it either. So I ended up adding org-agenda to ivy-completing-read-handlers-alist, which I think was the cleanest solution given my settings. So I'll accept your answer for having taken me to the right place. Thank you very much! – gusbrs Jul 27 at 11:12
  • 1
    @gusbrs completion-in-region-function is used for in buffer completion (usually code completion or as in your case completing input in minibuffer). completing-read-function is used for completing against a set of items (buffers, tags ...). You are welcome! – clemera Jul 27 at 12:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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