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.
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))))
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
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP