Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to Set Multiple Tags in org-mode #2063

Closed
ianbarton opened this issue Jul 7, 2018 · 20 comments
Closed

Unable to Set Multiple Tags in org-mode #2063

ianbarton opened this issue Jul 7, 2018 · 20 comments

Comments

@ianbarton
Copy link

There are several older reports of this problem, which is supposed to be fixed. However, if I try and set multiple tags on an org-mode headline helm shows any existing tags, but won't auto-complete any new tags when pressing tab. I can type each tag in manually.

I Have tried to stop helm completing org-mode tags (see last line of my configuration below), but org-set-tags still tries to use helm.

I am using the latest helm from melpa and org-mode from git master. If I launch a minimal version of Emacs, with just org-mode enabled the tag completion in the mini buffer works as expected.

Helm configuration:

(use-package helm
:ensure t
:init (progn
(require 'helm-config)
(require 'helm-eshell)
(require 'helm-files)
(require 'helm-grep)
;;(require 'helm-org)
(helm-mode 1)
)
:bind (("C-c h" . helm-mini)
( "C-x C-f". helm-find-files)
("M-y" . helm-show-kill-ring)
("M-x" . helm-M-x)
))
(add-to-list 'helm-completing-read-handlers-alist '(org-set-tags))

@ianbarton
Copy link
Author

Forgot to mention, I have disabled org-fast-tag-completion.

@thierryvolpiatto
Copy link
Member

thierryvolpiatto commented Jul 7, 2018 via email

@thierryvolpiatto
Copy link
Member

FWIW here what I am doing when I want to enter multiples tag:

Here a org header, the cursor is "|":

  • An org header |

From there I hit C-c C-c which provide a "Tags" prompt:
I hit TAB and RET if I want to enter an existing tag or I write a new tag in prompt.
At this point you end up with an entry in your prompt, if you enter RET, the entry is added as tag in your org header:
Tags: foo

If you want to add more tag to your org header, add a coma after your tag and write a new tag or hit TAB to find another existing tag, and so on until you have all the tags you want e.g "foo,bar,baz" then press RET to finally add the tags to your org header:

Tags: foo,bar,baz

@thierryvolpiatto
Copy link
Member

I don't know if this is what you are asking for, but if it is, I agree it should be documented somewhere, I suggest adding an org entry to wiki explaining this and other stuff not obvious helm-org does e.g. refiling.

@alphapapa
Copy link
Member

If I may, I think this is a chance to improve the UI. For a long time now I've been using code that works like this:

  1. C-c C-q to open tag completion.
  2. Select or enter a new tag with Helm.
  3. Press RET.
  4. To enter more tags, goto 2, or press RET to finish.

It works very well, and I don't have to type any commas. Here's the code (several years old, but still works perfectly):

;; From Anders Johansson <https://groups.google.com/d/msg/emacs-helm/tA6cn6TUdRY/G1S3TIdzBwAJ>

;; This works pretty well.  It's not perfect, but it's a great
;; start.  He posted it on 3 Mar 2016, on a thread that was
;; started in Oct 2013.  He also posted this message on 2 Apr
;; 2014, maybe an earlier attempt at a solution:
;; <http://article.gmane.org/gmane.emacs.orgmode/84495>

(add-to-list 'helm-completing-read-handlers-alist '(org-set-tags . aj/org-completing-read-tags))
(add-to-list 'helm-completing-read-handlers-alist '(org-capture . aj/org-completing-read-tags))

(defun aj/org-completing-read-tags (prompt coll pred req initial hist def inh)
  (if (not (string= "Tags: " prompt))
      ;; Not a tags prompt.  Use normal completion by calling
      ;; `org-icompleting-read' again without this function in
      ;; `helm-completing-read-handlers-alist'
      (let ((helm-completing-read-handlers-alist (rassq-delete-all
                                                  'aj/org-completing-read-tags
                                                  helm-completing-read-handlers-alist)))
        (org-icompleting-read prompt coll pred req initial hist def inh))
    ;; Tags prompt
    (let* ((initial (and (stringp initial)
                         (not (string= initial ""))
                         initial))
           (curr (when initial
                   (org-split-string initial ":")))
           (table (org-uniquify
                   (mapcar 'car org-last-tags-completion-table)))
           (table (if curr
                      ;; Remove current tags from list
                      (cl-delete-if (lambda (x)
                                      (member x curr))
                                    table)
                    table))
           (prompt (if initial
                       (concat "Tags " initial)
                     prompt)))
      (concat initial (mapconcat 'identity
                                 (nreverse (aj/helm-completing-read-multiple
                                            prompt table pred nil nil hist def
                                            t "Org tags" "*Helm org tags*" ":"))
                                 ":")))))

(defun aj/helm-completing-read-multiple (prompt choices
                                                &optional predicate require-match initial-input hist def
                                                inherit-input-method name buffer sentinel)
  "Read multiple items with `helm-completing-read-default-1'. Reading stops
when the user enters SENTINEL. By default, SENTINEL is
\"*done*\". SENTINEL is disambiguated with clashing completions
by appending _ to SENTINEL until it becomes unique. So if there
are multiple values that look like SENTINEL, the one with the
most _ at the end is the actual sentinel value. See
documentation for `ido-completing-read' for details on the
other parameters."
  (let ((sentinel (or sentinel "*done*"))
        this-choice res done-reading)
    ;; Uniquify the SENTINEL value
    (while (cl-find sentinel choices)
      (setq sentinel (concat sentinel "_")))
    (setq choices (cons sentinel choices))
    ;; Read choices
    (while (not done-reading)
      (setq this-choice (helm-completing-read-default-1 prompt choices
                                                        predicate require-match initial-input hist def
                                                        inherit-input-method name buffer nil t))
      (if (equal this-choice sentinel)
          (setq done-reading t)
        (setq res (cons this-choice res))
        (setq prompt (concat prompt this-choice ":"))))
    res)))

If it were to be merged into Helm, it would probably need tidying or rewriting. But I think the UI works much better this way, as it's much faster, easier, and more intuitive to enter multiple tags this way.

@thierryvolpiatto
Copy link
Member

thierryvolpiatto commented Jul 8, 2018 via email

@alphapapa
Copy link
Member

IIRC this is more or less the code introduced in helm some years ago by you... Seems the UI have changed though. The actual code works very well, this is just it is undocumented, you can enter multiple tags by separating with commas, space or ":".

Yes, I recall discussing this code a while back. I wonder if I forgot to remove my own config's code in favor of what you merged. I'll have to see. :)

Not at this stage of helm development, I will suspend helm development at version 3 (see README), I will make only bugfix maintainance, this is the kind of code that will lead to other bug reports, the actual code is stable, needs just to document it in wiki or somewhere, lets keep it.

I'm sorry I missed that announcement back in March. As you can imagine, I don't look at the Helm readme very often. :) I am very thankful for all the hard work you have put into Helm over the years, and I have often wondered how you managed to do so much so quickly.

Personally, I can't imagine using Emacs without Helm. I know some people use Ivy/Counsel/Swiper instead, but those are not nearly as powerful or useful. I think it's as fundamentally important as Magit. I guess its audience isn't as large as Magit's, so I don't know if a kind of support campaign would be as fruitful as Magit's was, but it might be worth a try.

Did you announce this suspension of development on Reddit or anywhere else? If not, maybe it should be announced, because I'm sure I'm not the only one who finds Helm extremely valuable.

Thanks.

@thierryvolpiatto
Copy link
Member

thierryvolpiatto commented Jul 8, 2018 via email

@ianbarton
Copy link
Author

Expected behavior

When in an org-mode buffer if I type C-c C-q on a headline I am offered a buffer to enter a tag. Any existing tags on the headline are shown in the buffer. I expect to be able to press Tab to show a list of tags I have defined and be able to choose a tag to add to the heading.

Actual behavior (from emacs-helm.sh if possible, see note at the bottom)

If I don't have any tags set on any headlines in the buffer I see the full list of tags as defined in #+TAGS: at the top of the buffer. However, if I already have a gtag on that header the buffer only shows that tag. I cannot add an additional tag using tag completion, or by pressing Tab. However, I can type in a tag.

Steps to reproduce (recipe)

#+TAGS: time chemo chromebook dell computer cycling mobile

  • Test Header. :chemo:

** Test 2. :chromebook:dell:

  • Test 3. :cycling:

Using the org buffer above if I type C-c C-q the buffer only shows tags already defined for that heading. I can't enter additional tags by using tab completion.

Describe versions of Helm, Emacs, operating system, etc.

Emacs version GNU Emacs 26.1 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.22.30)
of 2018-07-05

Helm: latest version from Melpa.

Are you using emacs-helm.sh to reproduce this bug (yes/no):

No.

OK. I just tried using emacs-helm.sh and tab completion for tags works OK. There must be something else in my configuration file causing this. I'll try bisecting my config file to see if I can identify what's causing the problem.

FYI a similar problem was reported in syl20bnr/spacemacs#3738

@thierryvolpiatto
Copy link
Member

thierryvolpiatto commented Jul 8, 2018 via email

@Dapuva76
Copy link

What can I do to disable helm for tag completion completely?
I tried adding
(add-hook 'org-mode-hook (lambda () (add-to-list 'helm-completing-read-handlers-alist '(org-set-tags-command))))
like someone mentioned in a different bug report, but that changed nothing. I'd just like to select multiple tags and be done with it, at this point.

@thierryvolpiatto
Copy link
Member

thierryvolpiatto commented Apr 17, 2020 via email

@thierryvolpiatto
Copy link
Member

Otherwise to disable helm completion, use:

(add-to-list 'helm-completing-read-handlers-alist '(org-set-tags))

@Dapuva76
Copy link

Dapuva76 commented Apr 17, 2020

Most people try to disable this because they don't understand it is a completing-read-multiple and not a completing-read. To use it: 1) M-x org-set-tags 2) once you have the prompt "Tags: " hit TAB 3) You can now enter your tags one by one by separating them with a "," or a space and hitting again TAB for each tag or enter all your tags at once in the prompt by marking them.

I've tried this, but TAB selects nothing and when I hit enter (to select the tag), it exits with a single tag. Entering the name of each tag manually, and separating with a comma, works. But that defeats the purpose of showing a list you could theoretically choose from.

e: maybe it's an org setting that conflicts with using TAB as select, I don't know. Not sure where to start looking

e2: also thanks for your work, love helm, don't mean to sound too abrasive.

@Dapuva76
Copy link

Dapuva76 commented Apr 17, 2020

Did a bit more digging, found the following setting in my .emacs

(define-key helm-map (kbd "<tab>") 'helm-execute-persistent-action)

After disabling it, I now get a prompt

Actions
[f1] Sole action (Identity)

when hitting TAB on a tag. Can't select multiple, hitting ENTER completes and exits.

@dariuskramer
Copy link

Same problem here. The only solution that I found was to use the snippet of code from alphapapa.

@thierryvolpiatto
Copy link
Member

thierryvolpiatto commented Jun 20, 2020 via email

@dariuskramer
Copy link

helm-org was already installed but this snippet of configuration was missing. Now it works great. Thank you!

@pedrormjunior
Copy link

A solution for Org mode version 9.2+ is with helm-org package, as indicated before, together with information in emacs-helm/helm-org#3.

@bitozoid
Copy link

This snippet in my config seems to work for me:

  (with-eval-after-load 'helm-org
      ;; Enable helm-org: https://github.com/emacs-helm/helm-org#configuration
      ; (add-to-list 'helm-completing-read-handlers-alist '(org-capture . helm-org-completing-read-tags))
      ;; Fix: for tags https://github.com/emacs-helm/helm-org/issues/3
      (add-to-list 'helm-completing-read-handlers-alist '(org-set-tags-command . helm-org-completing-read-tags))
      )

RyanGreenup added a commit to RyanGreenup/DotFiles_archive that referenced this issue Jul 17, 2021
This was done for the benefit of multi select with M-M-m [1],
this could also be implemented with Help using =,= [2] but helm
breaks ESS [3] so that's not an option.

References:
[1]: abo-abo/swiper#1191
[2]: emacs-helm/helm#2063
[3]: emacs-ess/ESS#1074
RyanGreenup added a commit to RyanGreenup/DotFiles_archive that referenced this issue Jul 21, 2021
This was done for the benefit of multi select with M-M-m [1],
this could also be implemented with Help using =,= [2] but helm
breaks ESS [3] so that's not an option.

References:
[1]: abo-abo/swiper#1191
[2]: emacs-helm/helm#2063
[3]: emacs-ess/ESS#1074
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants