Wie erhalte ich die automatische Vervollständigung mehrerer Einträge in einer Erfassungsvorlage im Organisationsmodus?

856
Fredrik Forséll

Ich verwende den Emacs-Org-Modus ausgiebig mit Capture-Vorlagen, aber eine Sache reizt mich immer noch: Ich kann keine Autovervollständigung für mehrere Einträge in Eingabeaufforderungen erhalten, außer für Tags. Betrachten Sie die folgende Capture-Vorlage:

("m" "meeting" entry (file+datetree "~/Dropbox/org/meetings.org") "* %^ %^G Time: %T %? ** Meeting info Place: %^ Participants: %^ " :clock-in t) 

Für die Tags (% ^ G) funktioniert Autocomplete für mehrere Einträge wie ein Zauber, aber für Teilnehmer funktioniert Autocomplete nur für einen einzelnen Eintrag, unabhängig davon, ob ich sie durch Folgendes trenne: oder

Ich möchte den Teilnehmer für jeden Eintrag, den ich getrennt habe, automatisch vervollständigen, oder:

Noch besser wäre es, wenn eine dynamische Autovervollständigungsliste für die Teilnehmer erstellt würde, wie zum Beispiel, damit ich nicht alle möglichen Teilnehmer in der Capture-Vorlage angeben muss.

0

1 Antwort auf die Frage

0
Aaron Harris

Die %Aufzeichnungsvorlagen des Org-Modus enthalten ein -escape zum Ausführen von beliebigem Elisp, mit dem wir praktisch alles machen können. So nutzen Sie es, um das zu bekommen, was Sie möchten:

Zunächst zwei Funktionen, die eine dynamische Fertigstellungstabelle erstellen. Der erste findet nur alle Übereinstimmungen für einen angegebenen regulären Ausdruck. Der zweite verwendet den ersten, um gezielt die Art von Elementen zu erhalten, nach denen Sie suchen.

(defun my/dynamic-completion-table-regexp (regexp &optional group buffer) "Return alist containing all matches for REGEXP in BUFFER.  The returned alist contains the matches as keys, and each key is associated with a nil value.  If the optional parameter GROUP (an integer) is supplied, only that part matching the corresponding parenthetical subexpression is taken as the key.  If BUFFER is omitted, it defaults to the current buffer. Note that the entire buffer is scanned, regardless of narrowing." (let ((buffer (or buffer (current-buffer))) (group (or group 0)) table match) (with-current-buffer buffer (save-excursion (save-restriction (widen) (goto-char (point-min)) (while (re-search-forward regexp nil :noerror) (setq match (substring-no-properties (match-string group))) (add-to-list 'table (list match)))))) table))  (defun my/dynamic-completion-table-by-field (field &optional delims buffer) "Return alist containing all entries for FIELD in BUFFER.  Look in BUFFER for all lines of the form \"FIELD: TEXT\", possibly with leading or trailing whitespace. If DELIMS is omitted, consider TEXT as a single item; otherwise, it should be a regexp matching the delimiters between the items inside TEXT. Empty items are discarded, and whitespace surrounding the delimiters is removed.  The returned alist contains one key for each item found; all keys are associated with the value nil.  If BUFFER is omitted, it defaults to the current buffer. Note that the entire buffer is scanned, regardless of narrowing." (require 'cl-lib) ; For `cl-mapcan' (let ((table (my/dynamic-completion-table-regexp (concat "^\\s-*" (regexp-quote field) ": \\(.+\\)\\s-*$") 1 buffer))) (cl-mapcan (lambda (x) (mapcar #'list (split-string (car x) delims :omit-nulls "\\s-+"))) table))) 

Jetzt brauchen wir eine Funktion, die aus dem Minibuffer liest, weiß, wie diese Funktionen zu verwenden sind, und die Tag-Vervollständigung des Org-Modus verwendet, um die Art der Vervollständigung von Elementen zu erhalten, nach der Sie suchen. Es muss auch über den Erfassungsvorgang informiert sein, damit der Zielpuffer anstelle des Erfassungspuffers durchsucht werden kann.

(defun my/org-capture-read-multiple (field completion &optional delims) "Read one or more items for FIELD in capture template.  The COMPLETION parameter can be any sort of completion table or function valid for the second parameter of `completing-read'. It may also be the keyword :dynamic, which indicates that `my/dynamic-completion-table-by-field' should be used to generate a completion table dynamically.  The optional parameter DELIMS is ignored except with the :dynamic option, in which case it is passed to `my/dynamic-completion-table-by-field' as the parameter of the same name.  If this function is invoked from within an Org-mode capture process, the current buffer will be the target buffer for the capture attempt, not the buffer used to fill the capture template." (let* ((buffer (if (equal (buffer-name) "*Capture*") (org-capture-get :buffer) (current-buffer))) (completion (if (eq completion :dynamic) (my/dynamic-completion-table-by-field field delims buffer) completion))) (with-current-buffer buffer (let ((org-last-tags-completion-table completion) org-completion-use-ido) (org-completing-read-no-i (format "%s: " field) #'org-tags-completion-function))))) 

Um diese verwenden zu können, müssen Sie Ihre Vorlage ändern. Sie können beispielsweise die Zeile "Teilnehmer" in Ihrer Vorlage oben durch ersetzen

Participants: %(my/org-capture-read-multiple \"Participants\" :dynamic \"[,:]\") 
Ich habe eine Weile gebraucht, um das zu testen, aber oh mein Gott, es ist unglaublich! Deshalb liebe ich Superuser, vielen Dank! Es ist keine Autovervollständigung erlaubt, wenn ich Teilnehmer mit einem Leerzeichen nach dem Trennzeichen eingebe, aber das macht nichts. Fredrik Forséll vor 8 Jahren 0