>From e3397a665261bb2c9f9396b16e0100132a3275d5 Mon Sep 17 00:00:00 2001 From: stardiviner Date: Sun, 23 Dec 2018 13:35:38 +0800 Subject: [PATCH] * lisp/org.el (org-dynamic-block-insert-dblock): New function. (org-dynamic-block-parameters, org-dynamic-block-functions, org-dynamic-block-types, org-dynamic-block-set-parameters, org-dynamic-block-get-parameter): New variables, New functions. * lisp/org-keys.el: (org-dynamic-block-insert-dblock) New functions. (org-clock-report, org-columns-insert-dblock) Remove functions. * doc/org-manual.org: Add manual for dispatch command ~org-dynamic-block-insert-dblock~. --- doc/org-manual.org | 13 +++++++++--- etc/ORG-NEWS | 14 +++++++++++++ lisp/org-clock.el | 5 +++++ lisp/org-colview.el | 6 +++++- lisp/org-keys.el | 6 ++---- lisp/org.el | 50 +++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 86 insertions(+), 8 deletions(-) diff --git a/doc/org-manual.org b/doc/org-manual.org index aad190b3b..817b0ac25 100644 --- a/doc/org-manual.org +++ b/doc/org-manual.org @@ -19926,9 +19926,16 @@ users mailing list, at mailto:address@hidden Org supports /dynamic blocks/ in Org documents. They are inserted with begin and end markers like any other code block, but the contents -are updated automatically by a user function. For example, {{{kbd(C-c -C-x C-r)}}} inserts a dynamic table that updates the work time (see -[[*Clocking Work Time]]). +are updated automatically by a user function. You can use dispatch +command ~org-dynamic-block-insert-dblock~, which is bound to +keybinding {{{kbd(C-c C-x i)}}} by default. + +#+kindex: C-c C-x i +#+findex: org-dynamic-block-insert-dblock +Select one type of dynamic block to insert. + +For example, {{{kbd(C-c C-x i c l o c k t a b l e RET)}}} inserts a +dynamic table that updates the work time (see [[*Clocking Work Time]]). Dynamic blocks can have names and function parameters. The syntax is similar to source code block specifications: diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS index f9bea4b56..16e8884f5 100644 --- a/etc/ORG-NEWS +++ b/etc/ORG-NEWS @@ -40,6 +40,14 @@ arguments no longer imply a "file" result is expected. See [[git:3367ac9457]] for details. ** New features +*** Add a dispatcher command to insert dynamic blocks + +You can add dynamic block into ~org-dynamic-block-parameters~ with +function ~org-dynamic-block-set-parameters~ just like +~org-link-set-parameters~. All dynamic blocks in +~org-dynamic-block-set-parameters~ can be used by +~org-dynamic-block-insert-dblock~ command. + *** Babel **** Add LaTeX output support in PlantUML *** New property =HTML_HEADLINE_CLASS= in HTML export @@ -79,6 +87,12 @@ system than the main Org document. For example: the corresponding direction by swapping with the adjacent cell. ** New functions +*** ~org-dynamic-block-insert-dblock~ + +Use default keybinding == to run command +~org-dynamic-block-insert-dblock~. It will prompt user to select +dynamic block in ~org-dynamic-block-parameters~. + *** ~org-table-cell-up~ *** ~org-table-cell-down~ *** ~org-table-cell-left~ diff --git a/lisp/org-clock.el b/lisp/org-clock.el index 1ebfa0201..531a76d63 100644 --- a/lisp/org-clock.el +++ b/lisp/org-clock.el @@ -36,6 +36,7 @@ (declare-function org-element-property "org-element" (property element)) (declare-function org-element-type "org-element" (element)) (declare-function org-table-goto-line "org-table" (n)) +(declare-function org-dynamic-block-set-parameters "org" (type &rest rest)) (defvar org-frame-title-format-backup frame-title-format) (defvar org-time-stamp-formats) @@ -2052,6 +2053,10 @@ in the buffer and update it." (start (goto-char start))) (org-update-dblock)) +(org-dynamic-block-set-parameters + "clocktable" + :function 'org-clock-report) + (defun org-day-of-week (day month year) "Returns the day of the week as an integer." (nth 6 diff --git a/lisp/org-colview.el b/lisp/org-colview.el index 507c58a6a..f898c9695 100644 --- a/lisp/org-colview.el +++ b/lisp/org-colview.el @@ -41,6 +41,7 @@ (declare-function org-element-property "org-element" (property element)) (declare-function org-element-restriction "org-element" (element)) (declare-function org-element-type "org-element" (element)) +(declare-function org-dynamic-block-set-parameters "org" (type &rest rest)) (defvar org-agenda-columns-add-appointments-to-effort-sum) (defvar org-agenda-columns-compute-summary-properties) @@ -1237,7 +1238,7 @@ When PRINTF is non-nil, use it to format the result." "Summarize CHECK-BOXES with a check-box cookie." (format "[%d/%d]" (cl-count-if (lambda (b) (or (equal b "[X]") - (string-match-p "\\[\\([1-9]\\)/\\1\\]" b))) + (string-match-p "\\[\\([1-9]\\)/\\1\\]" b))) check-boxes) (length check-boxes))) @@ -1537,6 +1538,9 @@ PARAMS is a property list of parameters: (id))))) (org-update-dblock)) +(org-dynamic-block-set-parameters + "columnview" + :function 'org-columns-insert-dblock) ;;; Column view in the agenda diff --git a/lisp/org-keys.el b/lisp/org-keys.el index bed2f2ad4..5d12ce274 100644 --- a/lisp/org-keys.el +++ b/lisp/org-keys.el @@ -49,10 +49,8 @@ (declare-function org-clock-in "org" (&optional select start-time)) (declare-function org-clock-in-last "org" (&optional arg)) (declare-function org-clock-out "org" (&optional switch-to-state fail-quietly at-time)) -(declare-function org-clock-report "org" (&optional arg)) (declare-function org-clone-subtree-with-time-shift "org" (n &optional shift)) (declare-function org-columns "org" (&optional global columns-fmt-string)) -(declare-function org-columns-insert-dblock "org" ()) (declare-function org-comment-dwim "org" (arg)) (declare-function org-copy "org" ()) (declare-function org-copy-special "org" ()) @@ -67,6 +65,7 @@ (declare-function org-cycle "org" (&optional arg)) (declare-function org-cycle-agenda-files "org" ()) (declare-function org-date-from-calendar "org" ()) +(declare-function org-dynamic-block-insert-dblock "org" (&optional arg)) (declare-function org-dblock-update "org" (&optional arg)) (declare-function org-deadline "org" (arg1 &optional time)) (declare-function org-decrease-number-at-point "org" (&optional inc)) @@ -638,7 +637,7 @@ COMMANDS is a list of alternating OLDDEF NEWDEF command names." (org-defkey org-mode-map (kbd "C-c C-x C-j") #'org-clock-goto) (org-defkey org-mode-map (kbd "C-c C-x C-q") #'org-clock-cancel) (org-defkey org-mode-map (kbd "C-c C-x C-d") #'org-clock-display) -(org-defkey org-mode-map (kbd "C-c C-x C-r") #'org-clock-report) +(org-defkey org-mode-map (kbd "C-c C-x i") #'org-dynamic-block-insert-dblock) (org-defkey org-mode-map (kbd "C-c C-x C-u") #'org-dblock-update) (org-defkey org-mode-map (kbd "C-c C-x C-l") #'org-toggle-latex-fragment) (org-defkey org-mode-map (kbd "C-c C-x C-v") #'org-toggle-inline-images) @@ -650,7 +649,6 @@ COMMANDS is a list of alternating OLDDEF NEWDEF command names." (org-defkey org-mode-map (kbd "C-c C-x e") #'org-set-effort) (org-defkey org-mode-map (kbd "C-c C-x E") #'org-inc-effort) (org-defkey org-mode-map (kbd "C-c C-x o") #'org-toggle-ordered-property) -(org-defkey org-mode-map (kbd "C-c C-x i") #'org-columns-insert-dblock) (org-defkey org-mode-map (kbd "C-c C-,") #'org-insert-structure-template) (org-defkey org-mode-map (kbd "C-c C-x .") #'org-timer) (org-defkey org-mode-map (kbd "C-c C-x -") #'org-timer-item) diff --git a/lisp/org.el b/lisp/org.el index 1ee341f43..f87b898d1 100644 --- a/lisp/org.el +++ b/lisp/org.el @@ -11521,6 +11521,56 @@ If COMMAND is not given, use `org-update-dblock'." (unless (re-search-forward org-dblock-end-re nil t) (error "Dynamic block not terminated")))))) +(defcustom org-dynamic-block-parameters nil + "An alist of properties that defines all the Org dynamic blocks. +The key of alist is a string of the dynamic block type name. +The value of alist is a property list. +The property list is constructured by key `:function' and a function name. " + :type '(alist :tag "dynamic block name" + :key-type string + :value-type plist) + :safe #'listp + :group 'org-block + :package-version '(Org . "9.3")) + +(defun org-dynamic-block-get-parameter (type key) + "Get TYPE dynamic block property for KEY. +TYPE is a string and KEY is a plist keyword." + (plist-get + (cdr (assoc type org-dynamic-block-parameters)) + key)) + +(defun org-dynamic-block-set-parameters (type &rest parameters) + "Set dynamic block TYPE properties to PARAMETERS. +PARAMETERS should be :key val pairs. +The key is usually is `:function', and the value is a function name symbol." + (let ((data (assoc type org-dynamic-block-parameters))) + (if data (setcdr data (org-combine-plists (cdr data) parameters)) + (push (cons type parameters) org-dynamic-block-parameters)))) + +(defun org-dynamic-block-types () + "Return a list of known dynamic block types." + (mapcar #'car org-dynamic-block-parameters)) + +(defun org-dynamic-block-functions () + "Return a list of functions that are called to insert dynamic block." + (cl-loop for dblock in org-dynamic-block-parameters + with insert-func + do (setq insert-func (org-dynamic-block-get-parameter (car dblock) :function)) + if insert-func + collect insert-func)) + +(defun org-dynamic-block-insert-dblock (dblock-type) + "Insert a dynamic block of type DBLOCK-TYPE. +When used interactively, select the dynamic block types among +defined types, per `org-dynamic-block-set-parameters'." + (interactive (list (completing-read "dynamic block: " + (mapcar #'car org-dynamic-block-parameters)))) + (let ((func (org-dynamic-block-get-parameter dblock-type :function))) + (if (functionp func) + (funcall func) + (message "No such dynamic block: %s" func)))) + (defun org-dblock-update (&optional arg) "User command for updating dynamic blocks. Update the dynamic block at point. With prefix ARG, update all dynamic -- 2.20.1