TransWikia.com

org-set-effort fast effort selection?

Emacs Asked by whoever on February 19, 2021

I wonder if there is any easy way to configure effort selection dialogue to allow selecting effort value from the list using single key.

Currently I have configured Effort_ALL in the following way:

(add-to-list 'org-global-properties
         '("Effort_ALL". "0:05 0:15 0:30 1:00 2:00"))

and am using org-set-effort to pop up the dialogue. However the dialogue that it shows is just a regular narrow-list-of-candidates dialogue which takes multiple keystrokes (either arrows or partial string followed by return) to select the option I need.

What I would rather have instead is a org-fast-tag-selection-single-key-style dialogue that allows to select an entry from the list by just pressing a single button (e.g. 1, 2, 3, etc).

I’ve tried to look at the code for the org-set-effort and google for the ivy-like list-narrowing modules, but so far wasn’t able to find much.

One Answer

I'm just getting into using effort properties myself and stumbled on your question. Here is a function modified from org-fast-todo-selection which maps the index of the effort value to that number key (e.q. 0 -> 0:05 and 1 -> 0:15 per your provided EFFORT_ALL property).

(defun org-fast-effort-selection ()
  "Modification of `org-fast-todo-selection' for use with org-set-effert. Select an effort value with single keys.
Returns the new effort value, or nil if no state change should occur.

Motivated by https://emacs.stackexchange.com/questions/59424/org-set-effort-fast-effort-selection"
  ;; Format effort values into an alist keyed by index
  (let* ((fulltable (seq-map-indexed (lambda (e i) (cons (car e) (string-to-char (int-to-string i))))
                                     (org-property-get-allowed-values nil org-effort-property t)))
         (maxlen (apply 'max (mapcar
                              (lambda (x)
                                (if (stringp (car x)) (string-width (car x)) 0))
                              fulltable)))
         (expert (equal org-use-fast-todo-selection 'expert))
         (prompt "")
         (fwidth (+ maxlen 3 1 3))
         (ncol (/ (- (window-width) 4) fwidth))
         tg cnt e c tbl subtable)
    (save-excursion
      (save-window-excursion
        (if expert
            (set-buffer (get-buffer-create " *Org effort"))
          (delete-other-windows)
          (set-window-buffer (split-window-vertically) (get-buffer-create " *Org effort*"))
          (org-switch-to-buffer-other-window " *Org effort*"))
        (erase-buffer)
        (setq tbl fulltable cnt 0)
        (while (setq e (pop tbl))
          (setq tg (car e)
                c (cdr e))
          (print (char-to-string c))
          (when (and (= cnt 0))
            (insert "  "))
          (setq prompt (concat prompt "[" (char-to-string c) "] " tg " "))
          (insert "[" c "] " tg (make-string
                                 (- fwidth 4 (length tg)) ? ))
          (when (and (= (setq cnt (1+ cnt)) ncol)
                     ;; Avoid lines with just a closing delimiter.
                     (not (equal (car tbl) '(:endgroup))))
            (insert "n")
            (setq cnt 0)))
        (insert "n")
        (goto-char (point-min))
        (unless expert (org-fit-window-to-buffer))
        (message (concat "[1-9..]:Set [SPC]:clear"
                         (if expert (concat "n" prompt) "")))
        (setq c (let ((inhibit-quit t)) (read-char-exclusive)))
        (setq subtable (nreverse subtable))
        (cond
         ((or (= c ?C-g)
              (and (= c ?q) (not (rassoc c fulltable))))
          (setq quit-flag t))
         ((= c ? ) nil)
         ((setq e (or (rassoc c subtable) (rassoc c fulltable))
                tg (car e))
          tg)
         (t (setq quit-flag t)))))))

Using with org-set-effort and binding to a key:

(define-key org-mode-map
  (kbd "C-M-e") (lambda () (interactive) (org-set-effort nil (org-fast-set-effort))))

Update 07/27/2020

A possibly less intrusive solution is to add a case to org-set-effort where, if org-use-fast-todo-selection is set to 'expert, use org-fast-effort-selection as defined above.

The advantages are that you won't have to bind it to a specific key, and it will also work with org-agenda-set-effort out of the box.

I made a commit in my fork of org-mode showing how this can be done. After I use it a bit to make sure there's no edge cases that are being missed, I may submit it to the org-mode maintainers.

Correct answer by tuh8888 on February 19, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP