diff options
author | Nicolas Goaziou <mail@nicolasgoaziou.fr> | 2020-02-08 08:51:02 +0100 |
---|---|---|
committer | Nicolas Goaziou <mail@nicolasgoaziou.fr> | 2020-02-08 08:51:02 +0100 |
commit | 82f9bff40c624fbc1a212ccb0b94125502586798 (patch) | |
tree | e654e5588bf0bb6ede5eae849d1839d35ebc4ece | |
parent | 4d92cc349763c389b84a0c8e8899f78ff515b2ab (diff) | |
parent | c8947f9b3394f7c3d80742e6c424d4cd98958b92 (diff) | |
download | org-mode-82f9bff40c624fbc1a212ccb0b94125502586798.tar.gz |
Merge branch 'master' of code.orgmode.org:bzg/org-mode
-rw-r--r-- | doc/org-manual.org | 4 | ||||
-rw-r--r-- | etc/ORG-NEWS | 6 | ||||
-rw-r--r-- | lisp/ol.el | 3 | ||||
-rw-r--r-- | lisp/org-agenda.el | 5 | ||||
-rw-r--r-- | lisp/org-attach.el | 16 | ||||
-rw-r--r-- | lisp/org-capture.el | 3 | ||||
-rw-r--r-- | lisp/org-element.el | 39 | ||||
-rw-r--r-- | lisp/org-faces.el | 4 | ||||
-rw-r--r-- | lisp/org-keys.el | 4 | ||||
-rw-r--r-- | lisp/org-mobile.el | 11 | ||||
-rw-r--r-- | lisp/org-refile.el | 879 | ||||
-rw-r--r-- | lisp/org-table.el | 80 | ||||
-rw-r--r-- | lisp/org.el | 1348 | ||||
-rw-r--r-- | lisp/ox-ascii.el | 3 | ||||
-rw-r--r-- | lisp/ox-html.el | 3 | ||||
-rw-r--r-- | lisp/ox-latex.el | 7 | ||||
-rw-r--r-- | lisp/ox-man.el | 4 | ||||
-rw-r--r-- | lisp/ox-md.el | 4 | ||||
-rw-r--r-- | lisp/ox-odt.el | 4 | ||||
-rw-r--r-- | lisp/ox-texinfo.el | 4 | ||||
-rw-r--r-- | testing/lisp/test-org-capture.el | 1 |
21 files changed, 1240 insertions, 1192 deletions
diff --git a/doc/org-manual.org b/doc/org-manual.org index de74c9c..05a2180 100644 --- a/doc/org-manual.org +++ b/doc/org-manual.org @@ -7126,10 +7126,10 @@ special command: by setting ~org-refile-use-cache~. To make the command see new possible targets, you have to clear the cache with this command. -- {{{kbd(C-c M-w)}}} (~org-copy~) :: +- {{{kbd(C-c M-w)}}} (~org-refile-copy~) :: #+kindex: C-c M-w - #+findex: org-copy + #+findex: org-refile-copy Copying works like refiling, except that the original note is not deleted. diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS index 899541b..bb6144d 100644 --- a/etc/ORG-NEWS +++ b/etc/ORG-NEWS @@ -165,6 +165,10 @@ From ~org-highest-priority~ to ~org-priority-highest~. From ~org-enable-priority-commands~ to ~org-priority-enable-commands~. From ~org-show-priority~ to ~org-priority-show~. +*** New =org-refile.el= file + +Org refile variables and functions have been moved to a new file. + * Version 9.3 ** Incompatible changes @@ -634,7 +638,7 @@ and ~org-list-radio-lists-templates~) are removed from the code base. Note that only radio /lists/ have been removed, not radio tables. If you want to manipulate lists like in Org in other modes, we suggest -to use orgalist.el, which you can install from GNU ELPA. +to use =orgalist.el=, which you can install from GNU ELPA. If you want to use Org folding outside of Org buffers, you can have a look at the outshine package in the MELPA repository. @@ -75,6 +75,7 @@ (declare-function org-src-source-type "org-src" ()) (declare-function org-time-stamp-format "org" (&optional long inactive)) (declare-function outline-next-heading "outline" ()) +(declare-function org-attach-link-expand "org-attach" (link &optional buffer-or-name)) ;;; Customization @@ -934,7 +935,7 @@ a \"file\" link." (cond ((member type '("file" "attachment")) (when (string= type "attachment") - (setq path (org-element-property :attachment-path link))) + (setq path (org-attach-link-expand link))) (if (string-match "[*?{]" (file-name-nondirectory path)) (dired path) ;; Look into `org-link-parameters' in order to find diff --git a/lisp/org-agenda.el b/lisp/org-agenda.el index 46eaa26..7131edd 100644 --- a/lisp/org-agenda.el +++ b/lisp/org-agenda.el @@ -49,6 +49,7 @@ (require 'ol) (require 'org) (require 'org-macs) +(require 'org-refile) (declare-function diary-add-to-list "diary-lib" (date string specifier &optional marker globcolor literal)) @@ -3930,7 +3931,7 @@ FILTER-ALIST is an alist of filters we need to apply when (defun org-agenda-mark-clocking-task () "Mark the current clock entry in the agenda if it is present." ;; We need to widen when `org-agenda-finalize' is called from - ;; `org-agenda-change-all-lines' (e.g. in `org-agenda-clock-in') + ;; `org-agenda-change-all-lines' (e.g. in `org-agenda-clock-in'). (when (bound-and-true-p org-clock-current-task) (save-restriction (widen) @@ -9589,7 +9590,7 @@ Called with a universal prefix arg, show the priority instead of setting it." (list 'display (org-add-props stamp nil 'face '(secondary-selection default)))) (beginning-of-line 1)) - (org-agenda-previous-line))))) + (beginning-of-line 0))))) (defun org-agenda-date-prompt (arg) "Change the date of this item. Date is prompted for, with default today. diff --git a/lisp/org-attach.el b/lisp/org-attach.el index c2aa5c3..0fac627 100644 --- a/lisp/org-attach.el +++ b/lisp/org-attach.el @@ -40,6 +40,7 @@ (require 'org-id) (declare-function dired-dwim-target-directory "dired-aux") +(declare-function org-element-property "org-element" (property element)) (defgroup org-attach nil "Options concerning attachments in Org mode." @@ -650,6 +651,21 @@ See `org-attach-open'." Basically, this adds the path to the attachment directory." (expand-file-name file (org-attach-dir))) +(defun org-attach-link-expand (link &optional buffer-or-name) + "Return the full path to the attachment in the LINK element. +Takes LINK which is a link element, as defined by +`org-element-link-parser'. If LINK `:type' is attachment the +full path to the attachment is expanded and returned. Otherwise, +return nil. If BUFFER-OR-NAME is specified, LINK is expanded in +that buffer, otherwise current buffer is assumed." + (let ((type (org-element-property :type link)) + (file (org-element-property :path link)) + (pos (org-element-property :begin link))) + (when (string= type "attachment") + (with-current-buffer (or buffer-or-name (current-buffer)) + (goto-char pos) + (org-attach-expand file))))) + (org-link-set-parameters "attachment" :complete #'org-attach-complete-link) diff --git a/lisp/org-capture.el b/lisp/org-capture.el index a8317dc..84b0e4f 100644 --- a/lisp/org-capture.el +++ b/lisp/org-capture.el @@ -49,6 +49,7 @@ (require 'cl-lib) (require 'org) +(require 'org-refile) (declare-function org-at-encrypted-entry-p "org-crypt" ()) (declare-function org-at-table-p "org-table" (&optional table-type)) @@ -1155,7 +1156,7 @@ may have been stored before." (org-capture-empty-lines-after) (unless (org-at-heading-p) (outline-next-heading)) (org-capture-mark-kill-region origin (point)) - (org-capture-narrow beg (1- (point))) + (org-capture-narrow beg (point)) (when (or (search-backward "%?" beg t) (search-forward "%?" nil t)) (replace-match "")))))) diff --git a/lisp/org-element.el b/lisp/org-element.el index 4fde27e..5c46f37 100644 --- a/lisp/org-element.el +++ b/lisp/org-element.el @@ -3116,11 +3116,7 @@ When at a link, return a list whose car is `link' and cdr a plist with `:type', `:path', `:format', `:raw-link', `:application', `:search-option', `:begin', `:end', `:contents-begin', `:contents-end' and `:post-blank' as keywords. Otherwise, return -nil. Additionally, in the context of attachment links one -further property, `:attachment-path' is set. That property -contains the attachment link expanded into a full filesystem -path. - +nil. Assume point is at the beginning of the link." (catch 'no-object @@ -3229,27 +3225,18 @@ Assume point is at the beginning of the link." (when trans (setq type (car trans)) (setq path (cdr trans)))) - (let ((link - (list 'link - (list :type type - :path path - :format format - :raw-link (or raw-link path) - :application application - :search-option search-option - :begin begin - :end end - :contents-begin contents-begin - :contents-end contents-end - :post-blank post-blank)))) - ;; Add additional type specific properties for link types that - ;; need it - (when (string= type "attachment") - (org-element-put-property - link :attachment-path - (file-relative-name - (org-attach-expand path)))) - link)))) + (list 'link + (list :type type + :path path + :format format + :raw-link (or raw-link path) + :application application + :search-option search-option + :begin begin + :end end + :contents-begin contents-begin + :contents-end contents-end + :post-blank post-blank))))) (defun org-element-link-interpreter (link contents) "Interpret LINK object as Org syntax. diff --git a/lisp/org-faces.el b/lisp/org-faces.el index d50f715..d78b606 100644 --- a/lisp/org-faces.el +++ b/lisp/org-faces.el @@ -364,7 +364,9 @@ changes." "Face used for tables." :group 'org-faces) -(defface org-table-header '((t :inherit org-table :background "LightGray")) +(defface org-table-header '((t :inherit org-table + :background "LightGray" + :foreground "Black")) "Face for table header." :group 'org-faces) diff --git a/lisp/org-keys.el b/lisp/org-keys.el index 4d4e124..7f86831 100644 --- a/lisp/org-keys.el +++ b/lisp/org-keys.el @@ -56,7 +56,7 @@ (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-comment-dwim "org" (arg)) -(declare-function org-copy "org" ()) +(declare-function org-refile-copy "org" ()) (declare-function org-copy-special "org" ()) (declare-function org-copy-visible "org" (beg end)) (declare-function org-ctrl-c-ctrl-c "org" (&optional arg)) @@ -580,7 +580,7 @@ COMMANDS is a list of alternating OLDDEF NEWDEF command names." (org-defkey org-mode-map (kbd "C-c C-d") #'org-deadline) (org-defkey org-mode-map (kbd "C-c ;") #'org-toggle-comment) (org-defkey org-mode-map (kbd "C-c C-w") #'org-refile) -(org-defkey org-mode-map (kbd "C-c M-w") #'org-copy) +(org-defkey org-mode-map (kbd "C-c M-w") #'org-refile-copy) (org-defkey org-mode-map (kbd "C-c /") #'org-sparse-tree) ;minor-mode reserved (org-defkey org-mode-map (kbd "C-c \\") #'org-match-sparse-tree) ;minor-mode r. (org-defkey org-mode-map (kbd "C-c RET") #'org-ctrl-c-ret) diff --git a/lisp/org-mobile.el b/lisp/org-mobile.el index 8749e49..6df567d 100644 --- a/lisp/org-mobile.el +++ b/lisp/org-mobile.el @@ -258,6 +258,17 @@ the old and new values for the entry.") (defvar org-mobile-files-alist nil) (defvar org-mobile-checksum-files nil) +;; Add org mobile commands to the main org menu +(easy-menu-add-item + org-org-menu + nil + '("MobileOrg" + ["Push Files and Views" org-mobile-push t] + ["Get Captured and Flagged" org-mobile-pull t] + ["Find FLAGGED Tasks" (org-agenda nil "?") :active t :keys "\\[org-agenda] ?"] + "--" + ["Setup" (customize-group 'org-mobile) t])) + (defun org-mobile-prepare-file-lists () (setq org-mobile-files-alist (org-mobile-files-alist)) (setq org-mobile-checksum-files nil)) diff --git a/lisp/org-refile.el b/lisp/org-refile.el new file mode 100644 index 0000000..e696945 --- /dev/null +++ b/lisp/org-refile.el @@ -0,0 +1,879 @@ +;;; org-refile.el --- Refile Org Subtrees -*- lexical-binding: t; -*- + +;; Copyright (C) 2010-2020 Free Software Foundation, Inc. + +;; Author: Carsten Dominik <carsten at orgmode dot org> +;; Keywords: outlines, hypermedia, calendar, wp +;; +;; This file is part of GNU Emacs. + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <https://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Org Refile allows you to refile subtrees to various locations. + +;;; Code: + +(declare-function org-inlinetask-remove-END-maybe "org-inlinetask" ()) + +(defgroup org-refile nil + "Options concerning refiling entries in Org mode." + :tag "Org Refile" + :group 'org) + +(defcustom org-directory "~/org" + "Directory with Org files. +This is just a default location to look for Org files. There is no need +at all to put your files into this directory. It is used in the +following situations: + +1. When a capture template specifies a target file that is not an + absolute path. The path will then be interpreted relative to + `org-directory' +2. When the value of variable `org-agenda-files' is a single file, any + relative paths in this file will be taken as relative to + `org-directory'." + :group 'org-refile + :group 'org-capture + :type 'directory) + +(defcustom org-default-notes-file (convert-standard-filename "~/.notes") + "Default target for storing notes. +Used as a fall back file for org-capture.el, for templates that +do not specify a target file." + :group 'org-refile + :group 'org-capture + :type 'file) + +(defcustom org-reverse-note-order nil + "Non-nil means store new notes at the beginning of a file or entry. +When nil, new notes will be filed to the end of a file or entry. +This can also be a list with cons cells of regular expressions that +are matched against file names, and values." + :group 'org-capture + :group 'org-refile + :type '(choice + (const :tag "Reverse always" t) + (const :tag "Reverse never" nil) + (repeat :tag "By file name regexp" + (cons regexp boolean)))) + +(defcustom org-log-refile nil + "Information to record when a task is refiled. + +Possible values are: + +nil Don't add anything +time Add a time stamp to the task +note Prompt for a note and add it with template `org-log-note-headings' + +This option can also be set with on a per-file-basis with + + #+STARTUP: nologrefile + #+STARTUP: logrefile + #+STARTUP: lognoterefile + +You can have local logging settings for a subtree by setting the LOGGING +property to one or more of these keywords. + +When bulk-refiling, e.g., from the agenda, the value `note' is +forbidden and will temporarily be changed to `time'." + :group 'org-refile + :group 'org-progress + :version "24.1" + :type '(choice + (const :tag "No logging" nil) + (const :tag "Record timestamp" time) + (const :tag "Record timestamp with note." note))) + +(defcustom org-refile-targets nil + "Targets for refiling entries with `\\[org-refile]'. +This is a list of cons cells. Each cell contains: +- a specification of the files to be considered, either a list of files, + or a symbol whose function or variable value will be used to retrieve + a file name or a list of file names. If you use `org-agenda-files' for + that, all agenda files will be scanned for targets. Nil means consider + headings in the current buffer. +- A specification of how to find candidate refile targets. This may be + any of: + - a cons cell (:tag . \"TAG\") to identify refile targets by a tag. + This tag has to be present in all target headlines, inheritance will + not be considered. + - a cons cell (:todo . \"KEYWORD\") to identify refile targets by + todo keyword. + - a cons cell (:regexp . \"REGEXP\") with a regular expression matching + headlines that are refiling targets. + - a cons cell (:level . N). Any headline of level N is considered a target. + Note that, when `org-odd-levels-only' is set, level corresponds to + order in hierarchy, not to the number of stars. + - a cons cell (:maxlevel . N). Any headline with level <= N is a target. + Note that, when `org-odd-levels-only' is set, level corresponds to + order in hierarchy, not to the number of stars. + +Each element of this list generates a set of possible targets. +The union of these sets is presented (with completion) to +the user by `org-refile'. + +You can set the variable `org-refile-target-verify-function' to a function +to verify each headline found by the simple criteria above. + +When this variable is nil, all top-level headlines in the current buffer +are used, equivalent to the value `((nil . (:level . 1))'." + :group 'org-refile + :type '(repeat + (cons + (choice :value org-agenda-files + (const :tag "All agenda files" org-agenda-files) + (const :tag "Current buffer" nil) + (function) (variable) (file)) + (choice :tag "Identify target headline by" + (cons :tag "Specific tag" (const :value :tag) (string)) + (cons :tag "TODO keyword" (const :value :todo) (string)) + (cons :tag "Regular expression" (const :value :regexp) (regexp)) + (cons :tag "Level number" (const :value :level) (integer)) + (cons :tag "Max Level number" (const :value :maxlevel) (integer)))))) + +(defcustom org-refile-target-verify-function nil + "Function to verify if the headline at point should be a refile target. +The function will be called without arguments, with point at the +beginning of the headline. It should return t and leave point +where it is if the headline is a valid target for refiling. + +If the target should not be selected, the function must return nil. +In addition to this, it may move point to a place from where the search +should be continued. For example, the function may decide that the entire +subtree of the current entry should be excluded and move point to the end +of the subtree." + :group 'org-refile + :type '(choice + (const nil) + (function))) + +(defcustom org-refile-use-cache nil + "Non-nil means cache refile targets to speed up the process. +\\<org-mode-map>\ +The cache for a particular file will be updated automatically when +the buffer has been killed, or when any of the marker used for flagging +refile targets no longer points at a live buffer. +If you have added new entries to a buffer that might themselves be targets, +you need to clear the cache manually by pressing `C-0 \\[org-refile]' or, +if you find that easier, \ +`\\[universal-argument] \\[universal-argument] \\[universal-argument] \ +\\[org-refile]'." + :group 'org-refile + :version "24.1" + :type 'boolean) + +(defcustom org-refile-use-outline-path nil + "Non-nil means provide refile targets as paths. +So a level 3 headline will be available as level1/level2/level3. + +When the value is `file', also include the file name (without directory) +into the path. In this case, you can also stop the completion after +the file name, to get entries inserted as top level in the file. + +When `full-file-path', include the full file path. + +When `buffer-name', use the buffer name." + :group 'org-refile + :type '(choice + (const :tag "Not" nil) + (const :tag "Yes" t) + (const :tag "Start with file name" file) + (const :tag "Start with full file path" full-file-path) + (const :tag "Start with buffer name" buffer-name))) + +(defcustom org-outline-path-complete-in-steps t + "Non-nil means complete the outline path in hierarchical steps. +When Org uses the refile interface to select an outline path (see +`org-refile-use-outline-path'), the completion of the path can be +done in a single go, or it can be done in steps down the headline +hierarchy. Going in steps is probably the best if you do not use +a special completion package like `ido' or `icicles'. However, +when using these packages, going in one step can be very fast, +while still showing the whole path to the entry." + :group 'org-refile + :type 'boolean) + +(defcustom org-refile-allow-creating-parent-nodes nil + "Non-nil means allow the creation of new nodes as refile targets. +New nodes are then created by adding \"/new node name\" to the completion +of an existing node. When the value of this variable is `confirm', +new node creation must be confirmed by the user (recommended). +When nil, the completion must match an existing entry. + +Note that, if the new heading is not seen by the criteria +listed in `org-refile-targets', multiple instances of the same +heading would be created by trying again to file under the new +heading." + :group 'org-refile + :type '(choice + (const :tag "Never" nil) + (const :tag "Always" t) + (const :tag "Prompt for confirmation" confirm))) + +(defcustom org-refile-active-region-within-subtree nil + "Non-nil means also refile active region within a subtree. + +By default `org-refile' doesn't allow refiling regions if they +don't contain a set of subtrees, but it might be convenient to +do so sometimes: in that case, the first line of the region is +converted to a headline before refiling." + :group 'org-refile + :version "24.1" + :type 'boolean) + +(defvar org-refile-target-table nil + "The list of refile targets, created by `org-refile'.") + +(defvar org-refile-cache nil + "Cache for refile targets.") + +(defvar org-refile-markers nil + "All the markers used for caching refile locations.") + +;; Add org refile commands to the main org menu +(mapc (lambda (i) (easy-menu-add-item + org-org-menu + '("Edit Structure") i)) + '(["Refile Subtree" org-refile (org-in-subtree-not-table-p)] + ["Refile and copy Subtree" org-copy (org-in-subtree-not-table-p)])) + +(defun org-refile-marker (pos) + "Get a new refile marker, but only if caching is in use." + (if (not org-refile-use-cache) + pos + (let ((m (make-marker))) + (move-marker m pos) + (push m org-refile-markers) + m))) + +(defun org-refile-cache-clear () + "Clear the refile cache and disable all the markers." + (dolist (m org-refile-markers) (move-marker m nil)) + (setq org-refile-markers nil) + (setq org-refile-cache nil) + (message "Refile cache has been cleared")) + +(defun org-refile-cache-check-set (set) + "Check if all the markers in the cache still have live buffers." + (let (marker) + (catch 'exit + (while (and set (setq marker (nth 3 (pop set)))) + ;; If `org-refile-use-outline-path' is 'file, marker may be nil + (when (and marker (null (marker-buffer marker))) + (message "Please regenerate the refile cache with `C-0 C-c C-w'") + (sit-for 3) + (throw 'exit nil))) + t))) + +(defun org-refile-cache-put (set &rest identifiers) + "Push the refile targets SET into the cache, under IDENTIFIERS." + (let* ((key (sha1 (prin1-to-string identifiers))) + (entry (assoc key org-refile-cache))) + (if entry + (setcdr entry set) + (push (cons key set) org-refile-cache)))) + +(defun org-refile-cache-get (&rest identifiers) + "Retrieve the cached value for refile targets given by IDENTIFIERS." + (cond + ((not org-refile-cache) nil) + ((not org-refile-use-cache) (org-refile-cache-clear) nil) + (t + (let ((set (cdr (assoc (sha1 (prin1-to-string identifiers)) + org-refile-cache)))) + (and set (org-refile-cache-check-set set) set))))) + +(defvar org-outline-path-cache nil + "Alist between buffer positions and outline paths. +It value is an alist (POSITION . PATH) where POSITION is the +buffer position at the beginning of an entry and PATH is a list +of strings describing the outline path for that entry, in reverse +order.") + +(defun org-refile-get-targets (&optional default-buffer) + "Produce a table with refile targets." + (let ((case-fold-search nil) + ;; otherwise org confuses "TODO" as a kw and "Todo" as a word + (entries (or org-refile-targets '((nil . (:level . 1))))) + targets tgs files desc descre) + (message "Getting targets...") + (with-current-buffer (or default-buffer (current-buffer)) + (dolist (entry entries) + (setq files (car entry) desc (cdr entry)) + (cond + ((null files) (setq files (list (current-buffer)))) + ((eq files 'org-agenda-files) + (setq files (org-agenda-files 'unrestricted))) + ((and (symbolp files) (fboundp files)) + (setq files (funcall files))) + ((and (symbolp files) (boundp files)) + (setq files (symbol-value files)))) + (when (stringp files) (setq files (list files))) + (cond + ((eq (car desc) :tag) + (setq descre (concat "^\\*+[ \t]+.*?:" (regexp-quote (cdr desc)) ":"))) + ((eq (car desc) :todo) + (setq descre (concat "^\\*+[ \t]+" (regexp-quote (cdr desc)) "[ \t]"))) + ((eq (car desc) :regexp) + (setq descre (cdr desc))) + ((eq (car desc) :level) + (setq descre (concat "^\\*\\{" (number-to-string + (if org-odd-levels-only + (1- (* 2 (cdr desc))) + (cdr desc))) + "\\}[ \t]"))) + ((eq (car desc) :maxlevel) + (setq descre (concat "^\\*\\{1," (number-to-string + (if org-odd-levels-only + (1- (* 2 (cdr desc))) + (cdr desc))) + "\\}[ \t]"))) + (t (error "Bad refiling target description %s" desc))) + (dolist (f files) + (with-current-buffer (if (bufferp f) f (org-get-agenda-file-buffer f)) + (or + (setq tgs (org-refile-cache-get (buffer-file-name) descre)) + (progn + (when (bufferp f) + (setq f (buffer-file-name (buffer-base-buffer f)))) + (setq f (and f (expand-file-name f))) + (when (eq org-refile-use-outline-path 'file) + (push (list (file-name-nondirectory f) f nil nil) tgs)) + (when (eq org-refile-use-outline-path 'buffer-name) + (push (list (buffer-name (buffer-base-buffer)) f nil nil) tgs)) + (when (eq org-refile-use-outline-path 'full-file-path) + (push (list (file-truename (buffer-file-name (buffer-base-buffer))) f nil nil) tgs)) + (org-with-wide-buffer + (goto-char (point-min)) + (setq org-outline-path-cache nil) + (while (re-search-forward descre nil t) + (beginning-of-line) + (let ((case-fold-search nil)) + (looking-at org-complex-heading-regexp)) + (let ((begin (point)) + (heading (match-string-no-properties 4))) + (unless (or (and + org-refile-target-verify-function + (not + (funcall org-refile-target-verify-function))) + (not heading)) + (let ((re (format org-complex-heading-regexp-format + (regexp-quote heading))) + (target + (if (not org-refile-use-outline-path) heading + (mapconcat + #'identity + (append + (pcase org-refile-use-outline-path + (`file (list (file-name-nondirectory + (buffer-file-name + (buffer-base-buffer))))) + (`full-file-path + (list (buffer-file-name + (buffer-base-buffer)))) + (`buffer-name + (list (buffer-name + (buffer-base-buffer)))) + (_ nil)) + (mapcar (lambda (s) (replace-regexp-in-string + "/" "\\/" s nil t)) + (org-get-outline-path t t))) + "/")))) + (push (list target f re (org-refile-marker (point))) + tgs))) + (when (= (point) begin) + ;; Verification function has not moved point. + (end-of-line))))))) + (when org-refile-use-cache + (org-refile-cache-put tgs (buffer-file-name) descre)) + (setq targets (append tgs targets)))))) + (message "Getting targets...done") + (delete-dups (nreverse targets)))) + +(defun org--get-outline-path-1 (&optional use-cache) + "Return outline path to current headline. + +Outline path is a list of strings, in reverse order. When +optional argument USE-CACHE is non-nil, make use of a cache. See +`org-get-outline-path' for details. + +Assume buffer is widened and point is on a headline." + (or (and use-cache (cdr (assq (point) org-outline-path-cache))) + (let ((p (point)) + (heading (let ((case-fold-search nil)) + (looking-at org-complex-heading-regexp) + (if (not (match-end 4)) "" + ;; Remove statistics cookies. + (org-trim + (org-link-display-format + (replace-regexp-in-string + "\\[[0-9]+%\\]\\|\\[[0-9]+/[0-9]+\\]" "" + (match-string-no-properties 4)))))))) + (if (org-up-heading-safe) + (let ((path (cons heading (org--get-outline-path-1 use-cache)))) + (when use-cache + (push (cons p path) org-outline-path-cache)) + path) + ;; This is a new root node. Since we assume we are moving + ;; forward, we can drop previous cache so as to limit number + ;; of associations there. + (let ((path (list heading))) + (when use-cache (setq org-outline-path-cache (list (cons p path)))) + path))))) + +(defun org-get-outline-path (&optional with-self use-cache) + "Return the outline path to the current entry. + +An outline path is a list of ancestors for current headline, as +a list of strings. Statistics cookies are removed and links are +replaced with their description, if any, or their path otherwise. + +When optional argument WITH-SELF is non-nil, the path also +includes the current headline. + +When optional argument USE-CACHE is non-nil, cache outline paths +between calls to this function so as to avoid backtracking. This +argument is useful when planning to find more than one outline +path in the same document. In that case, there are two +conditions to satisfy: + - `org-outline-path-cache' is set to nil before starting the + process; + - outline paths are computed by increasing buffer positions." + (org-with-wide-buffer + (and (or (and with-self (org-back-to-heading t)) + (org-up-heading-safe)) + (reverse (org--get-outline-path-1 use-cache))))) + +(defun org-format-outline-path (path &optional width prefix separator) + "Format the outline path PATH for display. +WIDTH is the maximum number of characters that is available. +PREFIX is a prefix to be included in the returned string, +such as the file name. +SEPARATOR is inserted between the different parts of the path, +the default is \"/\"." + (setq width (or width 79)) + (setq path (delq nil path)) + (unless (> width 0) + (user-error "Argument `width' must be positive")) + (setq separator (or separator "/")) + (let* ((org-odd-levels-only nil) + (fpath (concat + prefix (and prefix path separator) + (mapconcat + (lambda (s) (replace-regexp-in-string "[ \t]+\\'" "" s)) + (cl-loop for head in path + for n from 0 + collect (org-add-props + head nil 'face + (nth (% n org-n-level-faces) org-level-faces))) + separator)))) + (when (> (length fpath) width) + (if (< width 7) + ;; It's unlikely that `width' will be this small, but don't + ;; waste characters by adding ".." if it is. + (setq fpath (substring fpath 0 width)) + (setf (substring fpath (- width 2)) ".."))) + fpath)) + +(defun org-display-outline-path (&optional file current separator just-return-string) + "Display the current outline path in the echo area. + +If FILE is non-nil, prepend the output with the file name. +If CURRENT is non-nil, append the current heading to the output. +SEPARATOR is passed through to `org-format-outline-path'. It separates +the different parts of the path and defaults to \"/\". +If JUST-RETURN-STRING is non-nil, return a string, don't display a message." + (interactive "P") + (let* (case-fold-search + (bfn (buffer-file-name (buffer-base-buffer))) + (path (and (derived-mode-p 'org-mode) (org-get-outline-path))) + res) + (when current (setq path (append path + (save-excursion + (org-back-to-heading t) + (when (looking-at org-complex-heading-regexp) + (list (match-string 4))))))) + (setq res + (org-format-outline-path + path + (1- (frame-width)) + (and file bfn (concat (file-name-nondirectory bfn) separator)) + separator)) + (if just-return-string + (org-no-properties res) + (org-unlogged-message "%s" res)))) + +(defvar org-refile-history nil + "History for refiling operations.") + +(defvar org-after-refile-insert-hook nil + "Hook run after `org-refile' has inserted its stuff at the new location. +Note that this is still *before* the stuff will be removed from +the *old* location.") + +(defvar org-refile-keep nil + "Non-nil means `org-refile' will copy instead of refile.") + +;;;###autoload +(define-obsolete-function-alias 'org-copy 'org-refile-copy) +(defun org-refile-copy () + "Like `org-refile', but preserve the refiled subtree." + (interactive) + (let ((org-refile-keep t)) + (org-refile nil nil nil "Copy"))) + +(defvar org-capture-last-stored-marker) + +;;;###autoload +(defun org-refile (&optional arg default-buffer rfloc msg) + "Move the entry or entries at point to another heading. + +The list of target headings is compiled using the information in +`org-refile-targets', which see. + +At the target location, the entry is filed as a subitem of the +target heading. Depending on `org-reverse-note-order', the new +subitem will either be the first or the last subitem. + +If there is an active region, all entries in that region will be +refiled. However, the region must fulfill the requirement that +the first heading sets the top-level of the moved text. + +With a `\\[universal-argument]' ARG, the command will only visit the target \ +location +and not actually move anything. + +With a prefix `\\[universal-argument] \\[universal-argument]', go to the \ +location where the last +refiling operation has put the subtree. + +With a numeric prefix argument of `2', refile to the running clock. + +With a numeric prefix argument of `3', emulate `org-refile-keep' +being set to t and copy to the target location, don't move it. +Beware that keeping refiled entries may result in duplicated ID +properties. + +RFLOC can be a refile location obtained in a different way. + +MSG is a string to replace \"Refile\" in the default prompt with +another verb. E.g. `org-copy' sets this parameter to \"Copy\". + +See also `org-refile-use-outline-path'. + +If you are using target caching (see `org-refile-use-cache'), you +have to clear the target cache in order to find new targets. +This can be done with a `0' prefix (`C-0 C-c C-w') or a triple +prefix argument (`C-u C-u C-u C-c C-w')." + (interactive "P") + (if (member arg '(0 (64))) + (org-refile-cache-clear) + (let* ((actionmsg (cond (msg msg) + ((equal arg 3) "Refile (and keep)") + (t "Refile"))) + (regionp (org-region-active-p)) + (region-start (and regionp (region-beginning))) + (region-end (and regionp (region-end))) + (org-refile-keep (if (equal arg 3) t org-refile-keep)) + pos it nbuf file level reversed) + (setq last-command nil) + (when regionp + (goto-char region-start) + (beginning-of-line) + (setq region-start (point)) + (unless (or (org-kill-is-subtree-p + (buffer-substring region-start region-end)) + (prog1 org-refile-active-region-within-subtree + (let ((s (point-at-eol))) + (org-toggle-heading) + (setq region-end (+ (- (point-at-eol) s) region-end))))) + (user-error "The region is not a (sequence of) subtree(s)"))) + (if (equal arg '(16)) + (org-refile-goto-last-stored) + (when (or + (and (equal arg 2) + org-clock-hd-marker (marker-buffer org-clock-hd-marker) + (prog1 + (setq it (list (or org-clock-heading "running clock") + (buffer-file-name + (marker-buffer org-clock-hd-marker)) + "" + (marker-position org-clock-hd-marker))) + (setq arg nil))) + (setq it + (or rfloc + (let (heading-text) + (save-excursion + (unless (and arg (listp arg)) + (org-back-to-heading t) + (setq heading-text + (replace-regexp-in-string + org-link-bracket-re + "\\2" + (or (nth 4 (org-heading-components)) + "")))) + (org-refile-get-location + (cond ((and arg (listp arg)) "Goto") + (regionp (concat actionmsg " region to")) + (t (concat actionmsg " subtree \"" + heading-text "\" to"))) + default-buffer + (and (not (equal '(4) arg)) + org-refile-allow-creating-parent-nodes))))))) + (setq file (nth 1 it) + pos (nth 3 it)) + (when (and (not arg) + pos + (equal (buffer-file-name) file) + (if regionp + (and (>= pos region-start) + (<= pos region-end)) + (and (>= pos (point)) + (< pos (save-excursion + (org-end-of-subtree t t)))))) + (error "Cannot refile to position inside the tree or region")) + (setq nbuf (or (find-buffer-visiting file) + (find-file-noselect file))) + (if (and arg (not (equal arg 3))) + (progn + (pop-to-buffer-same-window nbuf) + (goto-char (cond (pos) + ((org-notes-order-reversed-p) (point-min)) + (t (point-max)))) + (org-show-context 'org-goto)) + (if regionp + (progn + (org-kill-new (buffer-substring region-start region-end)) + (org-save-markers-in-region region-start region-end)) + (org-copy-subtree 1 nil t)) + (with-current-buffer (setq nbuf (or (find-buffer-visiting file) + (find-file-noselect file))) + (setq reversed (org-notes-order-reversed-p)) + (org-with-wide-buffer + (if pos + (progn + (goto-char pos) + (setq level (org-get-valid-level (funcall outline-level) 1)) + (goto-char + (if reversed + (or (outline-next-heading) (point-max)) + (or (save-excursion (org-get-next-sibling)) + (org-end-of-subtree t t) + (point-max))))) + (setq level 1) + (if (not reversed) + (goto-char (point-max)) + (goto-char (point-min)) + (or (outline-next-heading) (goto-char (point-max))))) + (unless (bolp) (newline)) + (org-paste-subtree level nil nil t) + ;; Record information, according to `org-log-refile'. + ;; Do not prompt for a note when refiling multiple + ;; headlines, however. Simply add a time stamp. + (cond + ((not org-log-refile)) + (regionp + (org-map-region + (lambda () (org-add-log-setup 'refile nil nil 'time)) + (point) + (+ (point) (- region-end region-start)))) + (t + (org-add-log-setup 'refile nil nil org-log-refile))) + (and org-auto-align-tags + (let ((org-loop-over-headlines-in-active-region nil)) + (org-align-tags))) + (let ((bookmark-name (plist-get org-bookmark-names-plist + :last-refile))) + (when bookmark-name + (with-demoted-errors + (bookmark-set bookmark-name)))) + ;; If we are refiling for capture, make sure that the + ;; last-capture pointers point here + (when (bound-and-true-p org-capture-is-refiling) + (let ((bookmark-name (plist-get org-bookmark-names-plist + :last-capture-marker))) + (when bookmark-name + (with-demoted-errors + (bookmark-set bookmark-name)))) + (move-marker org-capture-last-stored-marker (point))) + (when (fboundp 'deactivate-mark) (deactivate-mark)) + (run-hooks 'org-after-refile-insert-hook))) + (unless org-refile-keep + (if regionp + (delete-region (point) (+ (point) (- region-end region-start))) + (org-preserve-local-variables + (delete-region + (and (org-back-to-heading t) (point)) + (min (1+ (buffer-size)) (org-end-of-subtree t t) (point)))))) + (when (featurep 'org-inlinetask) + (org-inlinetask-remove-END-maybe)) + (setq org-markers-to-move nil) + (message "%s to \"%s\" in file %s: done" actionmsg + (car it) file))))))) + +(defun org-refile-goto-last-stored () + "Go to the location where the last refile was stored." + (interactive) + (bookmark-jump (plist-get org-bookmark-names-plist :last-refile)) + (message "This is the location of the last refile")) + +(defun org-refile--get-location (refloc tbl) + "When user refile to REFLOC, find the associated target in TBL. +Also check `org-refile-target-table'." + (car (delq + nil + (mapcar + (lambda (r) (or (assoc r tbl) + (assoc r org-refile-target-table))) + (list (replace-regexp-in-string "/$" "" refloc) + (replace-regexp-in-string "\\([^/]\\)$" "\\1/" refloc)))))) + +(defun org-refile-get-location (&optional prompt default-buffer new-nodes) + "Prompt the user for a refile location, using PROMPT. +PROMPT should not be suffixed with a colon and a space, because +this function appends the default value from +`org-refile-history' automatically, if that is not empty." + (let ((org-refile-targets org-refile-targets) + (org-refile-use-outline-path org-refile-use-outline-path)) + (setq org-refile-target-table (org-refile-get-targets default-buffer))) + (unless org-refile-target-table + (user-error "No refile targets")) + (let* ((cbuf (current-buffer)) + (cfn (buffer-file-name (buffer-base-buffer cbuf))) + (cfunc (if (and org-refile-use-outline-path + org-outline-path-complete-in-steps) + #'org-olpath-completing-read + #'completing-read)) + (extra (if org-refile-use-outline-path "/" "")) + (cbnex (concat (buffer-name) extra)) + (filename (and cfn (expand-file-name cfn))) + (tbl (mapcar + (lambda (x) + (if (and (not (member org-refile-use-outline-path + '(file full-file-path))) + (not (equal filename (nth 1 x)))) + (cons (concat (car x) extra " (" + (file-name-nondirectory (nth 1 x)) ")") + (cdr x)) + (cons (concat (car x) extra) (cdr x)))) + org-refile-target-table)) + (completion-ignore-case t) + cdef + (prompt (concat prompt + (or (and (car org-refile-history) + (concat " (default " (car org-refile-history) ")")) + (and (assoc cbnex tbl) (setq cdef cbnex) + (concat " (default " cbnex ")"))) ": ")) + pa answ parent-target child parent old-hist) + (setq old-hist org-refile-history) + (setq answ (funcall cfunc prompt tbl nil (not new-nodes) + nil 'org-refile-history (or cdef (car org-refile-history)))) + (if (setq pa (org-refile--get-location answ tbl)) + (progn + (org-refile-check-position pa) + (when (or (not org-refile-history) + (not (eq old-hist org-refile-history)) + (not (equal (car pa) (car org-refile-history)))) + (setq org-refile-history + (cons (car pa) (if (assoc (car org-refile-history) tbl) + org-refile-history + (cdr org-refile-history)))) + (when (equal (car org-refile-history) (nth 1 org-refile-history)) + (pop org-refile-history))) + pa) + (if (string-match "\\`\\(.*\\)/\\([^/]+\\)\\'" answ) + (progn + (setq parent (match-string 1 answ) + child (match-string 2 answ)) + (setq parent-target (org-refile--get-location parent tbl)) + (when (and parent-target + (or (eq new-nodes t) + (and (eq new-nodes 'confirm) + (y-or-n-p (format "Create new node \"%s\"? " + child))))) + (org-refile-new-child parent-target child))) + (user-error "Invalid target location"))))) + +(defun org-refile-check-position (refile-pointer) + "Check if the refile pointer matches the headline to which it points." + (let* ((file (nth 1 refile-pointer)) + (re (nth 2 refile-pointer)) + (pos (nth 3 refile-pointer)) + buffer) + (if (and (not (markerp pos)) (not file)) + (user-error "Please indicate a target file in the refile path") + (when (org-string-nw-p re) + (setq buffer (if (markerp pos) + (marker-buffer pos) + (or (find-buffer-visiting file) + (find-file-noselect file)))) + (with-current-buffer buffer + (org-with-wide-buffer + (goto-char pos) + (beginning-of-line 1) + (unless (looking-at-p re) + (user-error "Invalid refile position, please clear the cache with `C-0 C-c C-w' before refiling")))))))) + +(defun org-refile-new-child (parent-target child) + "Use refile target PARENT-TARGET to add new CHILD below it." + (unless parent-target + (error "Cannot find parent for new node")) + (let ((file (nth 1 parent-target)) + (pos (nth 3 parent-target)) + level) + (with-current-buffer (or (find-buffer-visiting file) + (find-file-noselect file)) + (org-with-wide-buffer + (if pos + (goto-char pos) + (goto-char (point-max)) + (unless (bolp) (newline))) + (when (looking-at org-outline-regexp) + (setq level (funcall outline-level)) + (org-end-of-subtree t t)) + (org-back-over-empty-lines) + (insert "\n" (make-string + (if pos (org-get-valid-level level 1) 1) ?*) + " " child "\n") + (beginning-of-line 0) + (list (concat (car parent-target) "/" child) file "" (point)))))) + +(defun org-olpath-completing-read (prompt collection &rest args) + "Read an outline path like a file name." + (let ((thetable collection)) + (apply #'completing-read + prompt + (lambda (string predicate &optional flag) + (cond + ((eq flag nil) (try-completion string thetable)) + ((eq flag t) + (let ((l (length string))) + (mapcar (lambda (x) + (let ((r (substring x l)) + (f (if (string-match " ([^)]*)$" x) + (match-string 0 x) + ""))) + (if (string-match "/" r) + (concat string (substring r 0 (match-end 0)) f) + x))) + (all-completions string thetable predicate)))) + ;; Exact match? + ((eq flag 'lambda) (assoc string thetable)))) + args))) + +(provide 'org-refile) +;;; org-refile.el ends here diff --git a/lisp/org-table.el b/lisp/org-table.el index 3bbc20c..1cea9c6 100644 --- a/lisp/org-table.el +++ b/lisp/org-table.el @@ -450,13 +450,10 @@ prevents it from hanging Emacs." :package-version '(Org . "8.3")) -;;; Org table electric header minor mode -(defvar-local org-table-temp-header-line nil) -(defvar-local org-table-temp-header-remapping nil) - +;;; Org table header minor mode (defun org-table-row-get-visible-string (&optional pos) - "Get the visible string of a row. -This is useful when columns have been shrunk." + "Get the visible string of a table row. +This may be useful when columns have been shrunk." (save-excursion (when pos (goto-char pos)) (goto-char (line-beginning-position)) @@ -469,42 +466,32 @@ This is useful when columns have been shrunk." (goto-char (1- (overlay-end ov)))))) (format "|%s" (mapconcat #'identity (reverse str) ""))))) +(defvar-local org-table-header-overlay nil) (defun org-table-header-set-header () - "Set the header of table at point as the `header-line-format'. -Assume `org-table-temp-header-line' already stores the previously -existing value of `header-line-format' we might want to restore." - (ignore-errors (require 'face-remap)) - (face-remap-remove-relative org-table-temp-header-remapping) - (setq-local org-table-temp-header-remapping - (face-remap-add-relative 'header-line '(:inherit default))) - (if (not (org-at-table-p)) - (setq header-line-format org-table-temp-header-line) - (let* ((beg (org-table-begin)) - ;; Are we using `display-line-numbers-mode'? - (lin (and (boundp 'display-line-numbers-mode) - display-line-numbers-mode - (line-number-display-width))) - ;; Are we using `org-indent-mode'? - (pre (and (boundp 'org-indent-mode) org-indent-mode - (length (get-text-property (point) 'line-prefix)))) - (tbeg (save-excursion - (goto-char beg) - (while (or (org-at-table-hline-p) - (looking-at-p ".*|\\s-+<[rcl]?\\([0-9]+\\)?>")) - (move-beginning-of-line 2)) - (point)))) - (if (not (pos-visible-in-window-p tbeg)) - (setq header-line-format - (concat (when (eq scroll-bar-mode 'left) - (propertize " " 'display '(space :width scroll-bar))) - (propertize - " " 'display '(space :width (+ left-fringe left-margin))) - (when lin (propertize (make-string (+ lin 2) 32) - 'face 'line-number)) - (when pre (make-string pre 32)) - (propertize (org-table-row-get-visible-string tbeg) - 'face 'org-table-header))) - (setq header-line-format org-table-temp-header-line))))) + "Display the header of the table at point." + (when (overlayp org-table-header-overlay) + (delete-overlay org-table-header-overlay)) + (run-with-timer + 0.001 nil + (lambda () + (if (not (org-at-table-p)) + (when (overlayp org-table-header-overlay) + (delete-overlay org-table-header-overlay)) + (let* ((ws (window-start)) + (beg (save-excursion + (goto-char (org-table-begin)) + (while (or (org-at-table-hline-p) + (looking-at-p ".*|\\s-+<[rcl]?\\([0-9]+\\)?>")) + (move-beginning-of-line 2)) + (point))) + (end (save-excursion (goto-char beg) (point-at-eol)))) + (when (not (pos-visible-in-window-p beg)) + (setq org-table-header-overlay + (make-overlay ws (+ ws (- end beg)))) + (org-overlay-display + org-table-header-overlay + (org-table-row-get-visible-string beg) + 'org-table-header))))))) ;;;###autoload (defvar-local org-table-header-line-mode nil) @@ -512,13 +499,12 @@ existing value of `header-line-format' we might want to restore." "Display the first row of the table at point in the header line." nil " TblHeader" nil (unless (eq major-mode 'org-mode) - (user-error "Cannot turn org table electric mode outside org-mode buffers")) + (user-error "Cannot turn org table header mode outside org-mode buffers")) (if org-table-header-line-mode - (progn (setq-local org-table-temp-header-line header-line-format) - (add-hook 'post-command-hook 'org-table-header-set-header)) - (remove-hook 'post-command-hook 'org-table-header-set-header) - (face-remap-remove-relative org-table-temp-header-remapping) - (setq-local header-line-format org-table-temp-header-line))) + (add-hook 'post-command-hook #'org-table-header-set-header nil t) + (when (overlayp org-table-header-overlay) + (delete-overlay org-table-header-overlay)) + (remove-hook 'post-command-hook #'org-table-header-set-header t))) ;;; Regexps Constants diff --git a/lisp/org.el b/lisp/org.el index 3ce5973..ab8595d 100644 --- a/lisp/org.el +++ b/lisp/org.el @@ -1794,213 +1794,6 @@ Changing this requires a restart of Emacs to work correctly." :group 'org-link-follow :type 'integer) -(defgroup org-refile nil - "Options concerning refiling entries in Org mode." - :tag "Org Refile" - :group 'org) - -(defcustom org-directory "~/org" - "Directory with Org files. -This is just a default location to look for Org files. There is no need -at all to put your files into this directory. It is used in the -following situations: - -1. When a capture template specifies a target file that is not an - absolute path. The path will then be interpreted relative to - `org-directory' -2. When the value of variable `org-agenda-files' is a single file, any - relative paths in this file will be taken as relative to - `org-directory'." - :group 'org-refile - :group 'org-capture - :type 'directory) - -(defcustom org-default-notes-file (convert-standard-filename "~/.notes") - "Default target for storing notes. -Used as a fall back file for org-capture.el, for templates that -do not specify a target file." - :group 'org-refile - :group 'org-capture - :type 'file) - -(defcustom org-reverse-note-order nil - "Non-nil means store new notes at the beginning of a file or entry. -When nil, new notes will be filed to the end of a file or entry. -This can also be a list with cons cells of regular expressions that -are matched against file names, and values." - :group 'org-capture - :group 'org-refile - :type '(choice - (const :tag "Reverse always" t) - (const :tag "Reverse never" nil) - (repeat :tag "By file name regexp" - (cons regexp boolean)))) - -(defcustom org-log-refile nil - "Information to record when a task is refiled. - -Possible values are: - -nil Don't add anything -time Add a time stamp to the task -note Prompt for a note and add it with template `org-log-note-headings' - -This option can also be set with on a per-file-basis with - - #+STARTUP: nologrefile - #+STARTUP: logrefile - #+STARTUP: lognoterefile - -You can have local logging settings for a subtree by setting the LOGGING -property to one or more of these keywords. - -When bulk-refiling, e.g., from the agenda, the value `note' is -forbidden and will temporarily be changed to `time'." - :group 'org-refile - :group 'org-progress - :version "24.1" - :type '(choice - (const :tag "No logging" nil) - (const :tag "Record timestamp" time) - (const :tag "Record timestamp with note." note))) - -(defcustom org-refile-targets nil - "Targets for refiling entries with `\\[org-refile]'. -This is a list of cons cells. Each cell contains: -- a specification of the files to be considered, either a list of files, - or a symbol whose function or variable value will be used to retrieve - a file name or a list of file names. If you use `org-agenda-files' for - that, all agenda files will be scanned for targets. Nil means consider - headings in the current buffer. -- A specification of how to find candidate refile targets. This may be - any of: - - a cons cell (:tag . \"TAG\") to identify refile targets by a tag. - This tag has to be present in all target headlines, inheritance will - not be considered. - - a cons cell (:todo . \"KEYWORD\") to identify refile targets by - todo keyword. - - a cons cell (:regexp . \"REGEXP\") with a regular expression matching - headlines that are refiling targets. - - a cons cell (:level . N). Any headline of level N is considered a target. - Note that, when `org-odd-levels-only' is set, level corresponds to - order in hierarchy, not to the number of stars. - - a cons cell (:maxlevel . N). Any headline with level <= N is a target. - Note that, when `org-odd-levels-only' is set, level corresponds to - order in hierarchy, not to the number of stars. - -Each element of this list generates a set of possible targets. -The union of these sets is presented (with completion) to -the user by `org-refile'. - -You can set the variable `org-refile-target-verify-function' to a function -to verify each headline found by the simple criteria above. - -When this variable is nil, all top-level headlines in the current buffer -are used, equivalent to the value `((nil . (:level . 1))'." - :group 'org-refile - :type '(repeat - (cons - (choice :value org-agenda-files - (const :tag "All agenda files" org-agenda-files) - (const :tag "Current buffer" nil) - (function) (variable) (file)) - (choice :tag "Identify target headline by" - (cons :tag "Specific tag" (const :value :tag) (string)) - (cons :tag "TODO keyword" (const :value :todo) (string)) - (cons :tag "Regular expression" (const :value :regexp) (regexp)) - (cons :tag "Level number" (const :value :level) (integer)) - (cons :tag "Max Level number" (const :value :maxlevel) (integer)))))) - -(defcustom org-refile-target-verify-function nil - "Function to verify if the headline at point should be a refile target. -The function will be called without arguments, with point at the -beginning of the headline. It should return t and leave point -where it is if the headline is a valid target for refiling. - -If the target should not be selected, the function must return nil. -In addition to this, it may move point to a place from where the search -should be continued. For example, the function may decide that the entire -subtree of the current entry should be excluded and move point to the end -of the subtree." - :group 'org-refile - :type '(choice - (const nil) - (function))) - -(defcustom org-refile-use-cache nil - "Non-nil means cache refile targets to speed up the process. -\\<org-mode-map>\ -The cache for a particular file will be updated automatically when -the buffer has been killed, or when any of the marker used for flagging -refile targets no longer points at a live buffer. -If you have added new entries to a buffer that might themselves be targets, -you need to clear the cache manually by pressing `C-0 \\[org-refile]' or, -if you find that easier, \ -`\\[universal-argument] \\[universal-argument] \\[universal-argument] \ -\\[org-refile]'." - :group 'org-refile - :version "24.1" - :type 'boolean) - -(defcustom org-refile-use-outline-path nil - "Non-nil means provide refile targets as paths. -So a level 3 headline will be available as level1/level2/level3. - -When the value is `file', also include the file name (without directory) -into the path. In this case, you can also stop the completion after -the file name, to get entries inserted as top level in the file. - -When `full-file-path', include the full file path. - -When `buffer-name', use the buffer name." - :group 'org-refile - :type '(choice - (const :tag "Not" nil) - (const :tag "Yes" t) - (const :tag "Start with file name" file) - (const :tag "Start with full file path" full-file-path) - (const :tag "Start with buffer name" buffer-name))) - -(defcustom org-outline-path-complete-in-steps t - "Non-nil means complete the outline path in hierarchical steps. -When Org uses the refile interface to select an outline path (see -`org-refile-use-outline-path'), the completion of the path can be -done in a single go, or it can be done in steps down the headline -hierarchy. Going in steps is probably the best if you do not use -a special completion package like `ido' or `icicles'. However, -when using these packages, going in one step can be very fast, -while still showing the whole path to the entry." - :group 'org-refile - :type 'boolean) - -(defcustom org-refile-allow-creating-parent-nodes nil - "Non-nil means allow the creation of new nodes as refile targets. -New nodes are then created by adding \"/new node name\" to the completion -of an existing node. When the value of this variable is `confirm', -new node creation must be confirmed by the user (recommended). -When nil, the completion must match an existing entry. - -Note that, if the new heading is not seen by the criteria -listed in `org-refile-targets', multiple instances of the same -heading would be created by trying again to file under the new -heading." - :group 'org-refile - :type '(choice - (const :tag "Never" nil) - (const :tag "Always" t) - (const :tag "Prompt for confirmation" confirm))) - -(defcustom org-refile-active-region-within-subtree nil - "Non-nil means also refile active region within a subtree. - -By default `org-refile' doesn't allow refiling regions if they -don't contain a set of subtrees, but it might be convenient to -do so sometimes: in that case, the first line of the region is -converted to a headline before refiling." - :group 'org-refile - :version "24.1" - :type 'boolean) - (defgroup org-todo nil "Options concerning TODO items in Org mode." :tag "Org TODO" @@ -4852,9 +4645,7 @@ This is for getting out of special buffers like capture.") (autoload 'easy-menu-add "easymenu") (require 'overlay) -;; (require 'org-macs) moved higher up in the file before it is first used (require 'org-entities) -;; (require 'org-compat) moved higher up in the file before it is first used (require 'org-faces) (require 'org-list) (require 'org-pcomplete) @@ -5004,8 +4795,6 @@ The following commands are available: ;; Activate `org-table-header-line-mode' (when org-table-header-line-p (org-table-header-line-mode 1)) - ;; Set up Org menus - (org-menu-define) ;; Try to set `org-hide' face correctly. (let ((foreground (org-find-invisible-foreground))) (when foreground @@ -9007,639 +8796,10 @@ or to another Org file, automatically push the old position onto the ring." (when (string-match (car entry) buffer-file-name) (throw 'exit (cdr entry)))))))) -(defvar org-refile-target-table nil - "The list of refile targets, created by `org-refile'.") - (defvar org-agenda-new-buffers nil "Buffers created to visit agenda files.") -(defvar org-refile-cache nil - "Cache for refile targets.") - -(defvar org-refile-markers nil - "All the markers used for caching refile locations.") - -(defun org-refile-marker (pos) - "Get a new refile marker, but only if caching is in use." - (if (not org-refile-use-cache) - pos - (let ((m (make-marker))) - (move-marker m pos) - (push m org-refile-markers) - m))) - -(defun org-refile-cache-clear () - "Clear the refile cache and disable all the markers." - (dolist (m org-refile-markers) (move-marker m nil)) - (setq org-refile-markers nil) - (setq org-refile-cache nil) - (message "Refile cache has been cleared")) - -(defun org-refile-cache-check-set (set) - "Check if all the markers in the cache still have live buffers." - (let (marker) - (catch 'exit - (while (and set (setq marker (nth 3 (pop set)))) - ;; If `org-refile-use-outline-path' is 'file, marker may be nil - (when (and marker (null (marker-buffer marker))) - (message "Please regenerate the refile cache with `C-0 C-c C-w'") - (sit-for 3) - (throw 'exit nil))) - t))) - -(defun org-refile-cache-put (set &rest identifiers) - "Push the refile targets SET into the cache, under IDENTIFIERS." - (let* ((key (sha1 (prin1-to-string identifiers))) - (entry (assoc key org-refile-cache))) - (if entry - (setcdr entry set) - (push (cons key set) org-refile-cache)))) - -(defun org-refile-cache-get (&rest identifiers) - "Retrieve the cached value for refile targets given by IDENTIFIERS." - (cond - ((not org-refile-cache) nil) - ((not org-refile-use-cache) (org-refile-cache-clear) nil) - (t - (let ((set (cdr (assoc (sha1 (prin1-to-string identifiers)) - org-refile-cache)))) - (and set (org-refile-cache-check-set set) set))))) - -(defvar org-outline-path-cache nil - "Alist between buffer positions and outline paths. -It value is an alist (POSITION . PATH) where POSITION is the -buffer position at the beginning of an entry and PATH is a list -of strings describing the outline path for that entry, in reverse -order.") - -(defun org-refile-get-targets (&optional default-buffer) - "Produce a table with refile targets." - (let ((case-fold-search nil) - ;; otherwise org confuses "TODO" as a kw and "Todo" as a word - (entries (or org-refile-targets '((nil . (:level . 1))))) - targets tgs files desc descre) - (message "Getting targets...") - (with-current-buffer (or default-buffer (current-buffer)) - (dolist (entry entries) - (setq files (car entry) desc (cdr entry)) - (cond - ((null files) (setq files (list (current-buffer)))) - ((eq files 'org-agenda-files) - (setq files (org-agenda-files 'unrestricted))) - ((and (symbolp files) (fboundp files)) - (setq files (funcall files))) - ((and (symbolp files) (boundp files)) - (setq files (symbol-value files)))) - (when (stringp files) (setq files (list files))) - (cond - ((eq (car desc) :tag) - (setq descre (concat "^\\*+[ \t]+.*?:" (regexp-quote (cdr desc)) ":"))) - ((eq (car desc) :todo) - (setq descre (concat "^\\*+[ \t]+" (regexp-quote (cdr desc)) "[ \t]"))) - ((eq (car desc) :regexp) - (setq descre (cdr desc))) - ((eq (car desc) :level) - (setq descre (concat "^\\*\\{" (number-to-string - (if org-odd-levels-only - (1- (* 2 (cdr desc))) - (cdr desc))) - "\\}[ \t]"))) - ((eq (car desc) :maxlevel) - (setq descre (concat "^\\*\\{1," (number-to-string - (if org-odd-levels-only - (1- (* 2 (cdr desc))) - (cdr desc))) - "\\}[ \t]"))) - (t (error "Bad refiling target description %s" desc))) - (dolist (f files) - (with-current-buffer (if (bufferp f) f (org-get-agenda-file-buffer f)) - (or - (setq tgs (org-refile-cache-get (buffer-file-name) descre)) - (progn - (when (bufferp f) - (setq f (buffer-file-name (buffer-base-buffer f)))) - (setq f (and f (expand-file-name f))) - (when (eq org-refile-use-outline-path 'file) - (push (list (file-name-nondirectory f) f nil nil) tgs)) - (when (eq org-refile-use-outline-path 'buffer-name) - (push (list (buffer-name (buffer-base-buffer)) f nil nil) tgs)) - (when (eq org-refile-use-outline-path 'full-file-path) - (push (list (file-truename (buffer-file-name (buffer-base-buffer))) f nil nil) tgs)) - (org-with-wide-buffer - (goto-char (point-min)) - (setq org-outline-path-cache nil) - (while (re-search-forward descre nil t) - (beginning-of-line) - (let ((case-fold-search nil)) - (looking-at org-complex-heading-regexp)) - (let ((begin (point)) - (heading (match-string-no-properties 4))) - (unless (or (and - org-refile-target-verify-function - (not - (funcall org-refile-target-verify-function))) - (not heading)) - (let ((re (format org-complex-heading-regexp-format - (regexp-quote heading))) - (target - (if (not org-refile-use-outline-path) heading - (mapconcat - #'identity - (append - (pcase org-refile-use-outline-path - (`file (list (file-name-nondirectory - (buffer-file-name - (buffer-base-buffer))))) - (`full-file-path - (list (buffer-file-name - (buffer-base-buffer)))) - (`buffer-name - (list (buffer-name - (buffer-base-buffer)))) - (_ nil)) - (mapcar (lambda (s) (replace-regexp-in-string - "/" "\\/" s nil t)) - (org-get-outline-path t t))) - "/")))) - (push (list target f re (org-refile-marker (point))) - tgs))) - (when (= (point) begin) - ;; Verification function has not moved point. - (end-of-line))))))) - (when org-refile-use-cache - (org-refile-cache-put tgs (buffer-file-name) descre)) - (setq targets (append tgs targets)))))) - (message "Getting targets...done") - (delete-dups (nreverse targets)))) - -(defun org--get-outline-path-1 (&optional use-cache) - "Return outline path to current headline. - -Outline path is a list of strings, in reverse order. When -optional argument USE-CACHE is non-nil, make use of a cache. See -`org-get-outline-path' for details. - -Assume buffer is widened and point is on a headline." - (or (and use-cache (cdr (assq (point) org-outline-path-cache))) - (let ((p (point)) - (heading (let ((case-fold-search nil)) - (looking-at org-complex-heading-regexp) - (if (not (match-end 4)) "" - ;; Remove statistics cookies. - (org-trim - (org-link-display-format - (replace-regexp-in-string - "\\[[0-9]+%\\]\\|\\[[0-9]+/[0-9]+\\]" "" - (match-string-no-properties 4)))))))) - (if (org-up-heading-safe) - (let ((path (cons heading (org--get-outline-path-1 use-cache)))) - (when use-cache - (push (cons p path) org-outline-path-cache)) - path) - ;; This is a new root node. Since we assume we are moving - ;; forward, we can drop previous cache so as to limit number - ;; of associations there. - (let ((path (list heading))) - (when use-cache (setq org-outline-path-cache (list (cons p path)))) - path))))) - -(defun org-get-outline-path (&optional with-self use-cache) - "Return the outline path to the current entry. - -An outline path is a list of ancestors for current headline, as -a list of strings. Statistics cookies are removed and links are -replaced with their description, if any, or their path otherwise. - -When optional argument WITH-SELF is non-nil, the path also -includes the current headline. - -When optional argument USE-CACHE is non-nil, cache outline paths -between calls to this function so as to avoid backtracking. This -argument is useful when planning to find more than one outline -path in the same document. In that case, there are two -conditions to satisfy: - - `org-outline-path-cache' is set to nil before starting the - process; - - outline paths are computed by increasing buffer positions." - (org-with-wide-buffer - (and (or (and with-self (org-back-to-heading t)) - (org-up-heading-safe)) - (reverse (org--get-outline-path-1 use-cache))))) - -(defun org-format-outline-path (path &optional width prefix separator) - "Format the outline path PATH for display. -WIDTH is the maximum number of characters that is available. -PREFIX is a prefix to be included in the returned string, -such as the file name. -SEPARATOR is inserted between the different parts of the path, -the default is \"/\"." - (setq width (or width 79)) - (setq path (delq nil path)) - (unless (> width 0) - (user-error "Argument `width' must be positive")) - (setq separator (or separator "/")) - (let* ((org-odd-levels-only nil) - (fpath (concat - prefix (and prefix path separator) - (mapconcat - (lambda (s) (replace-regexp-in-string "[ \t]+\\'" "" s)) - (cl-loop for head in path - for n from 0 - collect (org-add-props - head nil 'face - (nth (% n org-n-level-faces) org-level-faces))) - separator)))) - (when (> (length fpath) width) - (if (< width 7) - ;; It's unlikely that `width' will be this small, but don't - ;; waste characters by adding ".." if it is. - (setq fpath (substring fpath 0 width)) - (setf (substring fpath (- width 2)) ".."))) - fpath)) - -(defun org-display-outline-path (&optional file current separator just-return-string) - "Display the current outline path in the echo area. - -If FILE is non-nil, prepend the output with the file name. -If CURRENT is non-nil, append the current heading to the output. -SEPARATOR is passed through to `org-format-outline-path'. It separates -the different parts of the path and defaults to \"/\". -If JUST-RETURN-STRING is non-nil, return a string, don't display a message." - (interactive "P") - (let* (case-fold-search - (bfn (buffer-file-name (buffer-base-buffer))) - (path (and (derived-mode-p 'org-mode) (org-get-outline-path))) - res) - (when current (setq path (append path - (save-excursion - (org-back-to-heading t) - (when (looking-at org-complex-heading-regexp) - (list (match-string 4))))))) - (setq res - (org-format-outline-path - path - (1- (frame-width)) - (and file bfn (concat (file-name-nondirectory bfn) separator)) - separator)) - (if just-return-string - (org-no-properties res) - (org-unlogged-message "%s" res)))) - -(defvar org-refile-history nil - "History for refiling operations.") - -(defvar org-after-refile-insert-hook nil - "Hook run after `org-refile' has inserted its stuff at the new location. -Note that this is still *before* the stuff will be removed from -the *old* location.") - -(defvar org-capture-last-stored-marker) -(defvar org-refile-keep nil - "Non-nil means `org-refile' will copy instead of refile.") - -(defun org-copy () - "Like `org-refile', but copy." - (interactive) - (let ((org-refile-keep t)) - (org-refile nil nil nil "Copy"))) - -(defun org-refile (&optional arg default-buffer rfloc msg) - "Move the entry or entries at point to another heading. - -The list of target headings is compiled using the information in -`org-refile-targets', which see. - -At the target location, the entry is filed as a subitem of the -target heading. Depending on `org-reverse-note-order', the new -subitem will either be the first or the last subitem. - -If there is an active region, all entries in that region will be -refiled. However, the region must fulfill the requirement that -the first heading sets the top-level of the moved text. - -With a `\\[universal-argument]' ARG, the command will only visit the target \ -location -and not actually move anything. - -With a prefix `\\[universal-argument] \\[universal-argument]', go to the \ -location where the last -refiling operation has put the subtree. - -With a numeric prefix argument of `2', refile to the running clock. - -With a numeric prefix argument of `3', emulate `org-refile-keep' -being set to t and copy to the target location, don't move it. -Beware that keeping refiled entries may result in duplicated ID -properties. - -RFLOC can be a refile location obtained in a different way. - -MSG is a string to replace \"Refile\" in the default prompt with -another verb. E.g. `org-copy' sets this parameter to \"Copy\". - -See also `org-refile-use-outline-path'. - -If you are using target caching (see `org-refile-use-cache'), you -have to clear the target cache in order to find new targets. -This can be done with a `0' prefix (`C-0 C-c C-w') or a triple -prefix argument (`C-u C-u C-u C-c C-w')." - (interactive "P") - (if (member arg '(0 (64))) - (org-refile-cache-clear) - (let* ((actionmsg (cond (msg msg) - ((equal arg 3) "Refile (and keep)") - (t "Refile"))) - (regionp (org-region-active-p)) - (region-start (and regionp (region-beginning))) - (region-end (and regionp (region-end))) - (org-refile-keep (if (equal arg 3) t org-refile-keep)) - pos it nbuf file level reversed) - (setq last-command nil) - (when regionp - (goto-char region-start) - (beginning-of-line) - (setq region-start (point)) - (unless (or (org-kill-is-subtree-p - (buffer-substring region-start region-end)) - (prog1 org-refile-active-region-within-subtree - (let ((s (point-at-eol))) - (org-toggle-heading) - (setq region-end (+ (- (point-at-eol) s) region-end))))) - (user-error "The region is not a (sequence of) subtree(s)"))) - (if (equal arg '(16)) - (org-refile-goto-last-stored) - (when (or - (and (equal arg 2) - org-clock-hd-marker (marker-buffer org-clock-hd-marker) - (prog1 - (setq it (list (or org-clock-heading "running clock") - (buffer-file-name - (marker-buffer org-clock-hd-marker)) - "" - (marker-position org-clock-hd-marker))) - (setq arg nil))) - (setq it - (or rfloc - (let (heading-text) - (save-excursion - (unless (and arg (listp arg)) - (org-back-to-heading t) - (setq heading-text - (replace-regexp-in-string - org-link-bracket-re - "\\2" - (or (nth 4 (org-heading-components)) - "")))) - (org-refile-get-location - (cond ((and arg (listp arg)) "Goto") - (regionp (concat actionmsg " region to")) - (t (concat actionmsg " subtree \"" - heading-text "\" to"))) - default-buffer - (and (not (equal '(4) arg)) - org-refile-allow-creating-parent-nodes))))))) - (setq file (nth 1 it) - pos (nth 3 it)) - (when (and (not arg) - pos - (equal (buffer-file-name) file) - (if regionp - (and (>= pos region-start) - (<= pos region-end)) - (and (>= pos (point)) - (< pos (save-excursion - (org-end-of-subtree t t)))))) - (error "Cannot refile to position inside the tree or region")) - (setq nbuf (or (find-buffer-visiting file) - (find-file-noselect file))) - (if (and arg (not (equal arg 3))) - (progn - (pop-to-buffer-same-window nbuf) - (goto-char (cond (pos) - ((org-notes-order-reversed-p) (point-min)) - (t (point-max)))) - (org-show-context 'org-goto)) - (if regionp - (progn - (org-kill-new (buffer-substring region-start region-end)) - (org-save-markers-in-region region-start region-end)) - (org-copy-subtree 1 nil t)) - (with-current-buffer (setq nbuf (or (find-buffer-visiting file) - (find-file-noselect file))) - (setq reversed (org-notes-order-reversed-p)) - (org-with-wide-buffer - (if pos - (progn - (goto-char pos) - (setq level (org-get-valid-level (funcall outline-level) 1)) - (goto-char - (if reversed - (or (outline-next-heading) (point-max)) - (or (save-excursion (org-get-next-sibling)) - (org-end-of-subtree t t) - (point-max))))) - (setq level 1) - (if (not reversed) - (goto-char (point-max)) - (goto-char (point-min)) - (or (outline-next-heading) (goto-char (point-max))))) - (unless (bolp) (newline)) - (org-paste-subtree level nil nil t) - ;; Record information, according to `org-log-refile'. - ;; Do not prompt for a note when refiling multiple - ;; headlines, however. Simply add a time stamp. - (cond - ((not org-log-refile)) - (regionp - (org-map-region - (lambda () (org-add-log-setup 'refile nil nil 'time)) - (point) - (+ (point) (- region-end region-start)))) - (t - (org-add-log-setup 'refile nil nil org-log-refile))) - (and org-auto-align-tags - (let ((org-loop-over-headlines-in-active-region nil)) - (org-align-tags))) - (let ((bookmark-name (plist-get org-bookmark-names-plist - :last-refile))) - (when bookmark-name - (with-demoted-errors - (bookmark-set bookmark-name)))) - ;; If we are refiling for capture, make sure that the - ;; last-capture pointers point here - (when (bound-and-true-p org-capture-is-refiling) - (let ((bookmark-name (plist-get org-bookmark-names-plist - :last-capture-marker))) - (when bookmark-name - (with-demoted-errors - (bookmark-set bookmark-name)))) - (move-marker org-capture-last-stored-marker (point))) - (when (fboundp 'deactivate-mark) (deactivate-mark)) - (run-hooks 'org-after-refile-insert-hook))) - (unless org-refile-keep - (if regionp - (delete-region (point) (+ (point) (- region-end region-start))) - (org-preserve-local-variables - (delete-region - (and (org-back-to-heading t) (point)) - (min (1+ (buffer-size)) (org-end-of-subtree t t) (point)))))) - (when (featurep 'org-inlinetask) - (org-inlinetask-remove-END-maybe)) - (setq org-markers-to-move nil) - (message "%s to \"%s\" in file %s: done" actionmsg - (car it) file))))))) - -(defun org-refile-goto-last-stored () - "Go to the location where the last refile was stored." - (interactive) - (bookmark-jump (plist-get org-bookmark-names-plist :last-refile)) - (message "This is the location of the last refile")) - -(defun org-refile--get-location (refloc tbl) - "When user refile to REFLOC, find the associated target in TBL. -Also check `org-refile-target-table'." - (car (delq - nil - (mapcar - (lambda (r) (or (assoc r tbl) - (assoc r org-refile-target-table))) - (list (replace-regexp-in-string "/$" "" refloc) - (replace-regexp-in-string "\\([^/]\\)$" "\\1/" refloc)))))) - -(defun org-refile-get-location (&optional prompt default-buffer new-nodes) - "Prompt the user for a refile location, using PROMPT. -PROMPT should not be suffixed with a colon and a space, because -this function appends the default value from -`org-refile-history' automatically, if that is not empty." - (let ((org-refile-targets org-refile-targets) - (org-refile-use-outline-path org-refile-use-outline-path)) - (setq org-refile-target-table (org-refile-get-targets default-buffer))) - (unless org-refile-target-table - (user-error "No refile targets")) - (let* ((cbuf (current-buffer)) - (cfn (buffer-file-name (buffer-base-buffer cbuf))) - (cfunc (if (and org-refile-use-outline-path - org-outline-path-complete-in-steps) - #'org-olpath-completing-read - #'completing-read)) - (extra (if org-refile-use-outline-path "/" "")) - (cbnex (concat (buffer-name) extra)) - (filename (and cfn (expand-file-name cfn))) - (tbl (mapcar - (lambda (x) - (if (and (not (member org-refile-use-outline-path - '(file full-file-path))) - (not (equal filename (nth 1 x)))) - (cons (concat (car x) extra " (" - (file-name-nondirectory (nth 1 x)) ")") - (cdr x)) - (cons (concat (car x) extra) (cdr x)))) - org-refile-target-table)) - (completion-ignore-case t) - cdef - (prompt (concat prompt - (or (and (car org-refile-history) - (concat " (default " (car org-refile-history) ")")) - (and (assoc cbnex tbl) (setq cdef cbnex) - (concat " (default " cbnex ")"))) ": ")) - pa answ parent-target child parent old-hist) - (setq old-hist org-refile-history) - (setq answ (funcall cfunc prompt tbl nil (not new-nodes) - nil 'org-refile-history (or cdef (car org-refile-history)))) - (if (setq pa (org-refile--get-location answ tbl)) - (progn - (org-refile-check-position pa) - (when (or (not org-refile-history) - (not (eq old-hist org-refile-history)) - (not (equal (car pa) (car org-refile-history)))) - (setq org-refile-history - (cons (car pa) (if (assoc (car org-refile-history) tbl) - org-refile-history - (cdr org-refile-history)))) - (when (equal (car org-refile-history) (nth 1 org-refile-history)) - (pop org-refile-history))) - pa) - (if (string-match "\\`\\(.*\\)/\\([^/]+\\)\\'" answ) - (progn - (setq parent (match-string 1 answ) - child (match-string 2 answ)) - (setq parent-target (org-refile--get-location parent tbl)) - (when (and parent-target - (or (eq new-nodes t) - (and (eq new-nodes 'confirm) - (y-or-n-p (format "Create new node \"%s\"? " - child))))) - (org-refile-new-child parent-target child))) - (user-error "Invalid target location"))))) - (declare-function org-string-nw-p "org-macs" (s)) -(defun org-refile-check-position (refile-pointer) - "Check if the refile pointer matches the headline to which it points." - (let* ((file (nth 1 refile-pointer)) - (re (nth 2 refile-pointer)) - (pos (nth 3 refile-pointer)) - buffer) - (if (and (not (markerp pos)) (not file)) - (user-error "Please indicate a target file in the refile path") - (when (org-string-nw-p re) - (setq buffer (if (markerp pos) - (marker-buffer pos) - (or (find-buffer-visiting file) - (find-file-noselect file)))) - (with-current-buffer buffer - (org-with-wide-buffer - (goto-char pos) - (beginning-of-line 1) - (unless (looking-at-p re) - (user-error "Invalid refile position, please clear the cache with `C-0 C-c C-w' before refiling")))))))) - -(defun org-refile-new-child (parent-target child) - "Use refile target PARENT-TARGET to add new CHILD below it." - (unless parent-target - (error "Cannot find parent for new node")) - (let ((file (nth 1 parent-target)) - (pos (nth 3 parent-target)) - level) - (with-current-buffer (or (find-buffer-visiting file) - (find-file-noselect file)) - (org-with-wide-buffer - (if pos - (goto-char pos) - (goto-char (point-max)) - (unless (bolp) (newline))) - (when (looking-at org-outline-regexp) - (setq level (funcall outline-level)) - (org-end-of-subtree t t)) - (org-back-over-empty-lines) - (insert "\n" (make-string - (if pos (org-get-valid-level level 1) 1) ?*) - " " child "\n") - (beginning-of-line 0) - (list (concat (car parent-target) "/" child) file "" (point)))))) - -(defun org-olpath-completing-read (prompt collection &rest args) - "Read an outline path like a file name." - (let ((thetable collection)) - (apply #'completing-read - prompt - (lambda (string predicate &optional flag) - (cond - ((eq flag nil) (try-completion string thetable)) - ((eq flag t) - (let ((l (length string))) - (mapcar (lambda (x) - (let ((r (substring x l)) - (f (if (string-match " ([^)]*)$" x) - (match-string 0 x) - ""))) - (if (string-match "/" r) - (concat string (substring r 0 (match-end 0)) f) - x))) - (all-completions string thetable predicate)))) - ;; Exact match? - ((eq flag 'lambda) (assoc string thetable)))) - args))) - ;;;; Dynamic blocks (defun org-find-dblock (name) @@ -18473,266 +17633,254 @@ an argument, unconditionally call `org-insert-heading'." (not (org-at-table-p)))) ;; Define the Org mode menus -(defun org-menu-define () - "Define Org mode menus" - (easy-menu-define org-org-menu org-mode-map "Org menu" - `("Org" - ("Show/Hide" - ["Cycle Visibility" org-cycle :active (or (bobp) (outline-on-heading-p))] - ["Cycle Global Visibility" org-shifttab :active (not (org-at-table-p))] - ["Sparse Tree..." org-sparse-tree t] - ["Reveal Context" org-reveal t] - ["Show All" org-show-all t] - "--" - ["Subtree to indirect buffer" org-tree-to-indirect-buffer t]) - "--" - ["New Heading" org-insert-heading t] - ("Navigate Headings" - ["Up" outline-up-heading t] - ["Next" outline-next-visible-heading t] - ["Previous" outline-previous-visible-heading t] - ["Next Same Level" outline-forward-same-level t] - ["Previous Same Level" outline-backward-same-level t] - "--" - ["Jump" org-goto t]) - ("Edit Structure" - ["Refile Subtree" org-refile (org-in-subtree-not-table-p)] - "--" - ["Move Subtree Up" org-metaup (org-at-heading-p)] - ["Move Subtree Down" org-metadown (org-at-heading-p)] - "--" - ["Copy Subtree" org-copy-special (org-in-subtree-not-table-p)] - ["Cut Subtree" org-cut-special (org-in-subtree-not-table-p)] - ["Paste Subtree" org-paste-special (not (org-at-table-p))] - "--" - ["Clone subtree, shift time" org-clone-subtree-with-time-shift t] - "--" - ["Copy visible text" org-copy-visible t] - "--" - ["Promote Heading" org-metaleft (org-in-subtree-not-table-p)] - ["Promote Subtree" org-shiftmetaleft (org-in-subtree-not-table-p)] - ["Demote Heading" org-metaright (org-in-subtree-not-table-p)] - ["Demote Subtree" org-shiftmetaright (org-in-subtree-not-table-p)] - "--" - ["Sort Region/Children" org-sort t] - "--" - ["Convert to odd levels" org-convert-to-odd-levels t] - ["Convert to odd/even levels" org-convert-to-oddeven-levels t]) - ("Editing" - ["Emphasis..." org-emphasize t] - ["Edit Source Example" org-edit-special t] - "--" - ["Footnote new/jump" org-footnote-action t] - ["Footnote extra" (org-footnote-action t) :active t :keys "C-u C-c C-x f"]) - ("Archive" - ["Archive (default method)" org-archive-subtree-default (org-in-subtree-not-table-p)] - "--" - ["Move Subtree to Archive file" org-archive-subtree (org-in-subtree-not-table-p)] - ["Toggle ARCHIVE tag" org-toggle-archive-tag (org-in-subtree-not-table-p)] - ["Move subtree to Archive sibling" org-archive-to-archive-sibling (org-in-subtree-not-table-p)] - ) - "--" - ("Hyperlinks" - ["Store Link (Global)" org-store-link t] - ["Find existing link to here" org-occur-link-in-agenda-files t] - ["Insert Link" org-insert-link t] - ["Follow Link" org-open-at-point t] - "--" - ["Next link" org-next-link t] - ["Previous link" org-previous-link t] - "--" - ["Descriptive Links" - org-toggle-link-display - :style radio - :selected org-descriptive-links - ] - ["Literal Links" - org-toggle-link-display - :style radio - :selected (not org-descriptive-links)]) - "--" - ("TODO Lists" - ["TODO/DONE/-" org-todo t] - ("Select keyword" - ["Next keyword" org-shiftright (org-at-heading-p)] - ["Previous keyword" org-shiftleft (org-at-heading-p)] - ["Complete Keyword" pcomplete (assq :todo-keyword (org-context))] - ["Next keyword set" org-shiftcontrolright (and (> (length org-todo-sets) 1) (org-at-heading-p))] - ["Previous keyword set" org-shiftcontrolright (and (> (length org-todo-sets) 1) (org-at-heading-p))]) - ["Show TODO Tree" org-show-todo-tree :active t :keys "C-c / t"] - ["Global TODO list" org-todo-list :active t :keys "\\[org-agenda] t"] - "--" - ["Enforce dependencies" (customize-variable 'org-enforce-todo-dependencies) - :selected org-enforce-todo-dependencies :style toggle :active t] - "Settings for tree at point" - ["Do Children sequentially" org-toggle-ordered-property :style radio - :selected (org-entry-get nil "ORDERED") - :active org-enforce-todo-dependencies :keys "C-c C-x o"] - ["Do Children parallel" org-toggle-ordered-property :style radio - :selected (not (org-entry-get nil "ORDERED")) - :active org-enforce-todo-dependencies :keys "C-c C-x o"] - "--" - ["Set Priority" org-priority t] - ["Priority Up" org-shiftup t] - ["Priority Down" org-shiftdown t] - "--" - ["Get news from all feeds" org-feed-update-all t] - ["Go to the inbox of a feed..." org-feed-goto-inbox t] - ["Customize feeds" (customize-variable 'org-feed-alist) t]) - ("TAGS and Properties" - ["Set Tags" org-set-tags-command (not (org-before-first-heading-p))] - ["Change tag in region" org-change-tag-in-region (org-region-active-p)] - "--" - ["Set property" org-set-property (not (org-before-first-heading-p))] - ["Column view of properties" org-columns t] - ["Insert Column View DBlock" org-columns-insert-dblock t]) - ("Dates and Scheduling" - ["Timestamp" org-time-stamp (not (org-before-first-heading-p))] - ["Timestamp (inactive)" org-time-stamp-inactive (not (org-before-first-heading-p))] - ("Change Date" - ["1 Day Later" org-shiftright (org-at-timestamp-p 'lax)] - ["1 Day Earlier" org-shiftleft (org-at-timestamp-p 'lax)] - ["1 ... Later" org-shiftup (org-at-timestamp-p 'lax)] - ["1 ... Earlier" org-shiftdown (org-at-timestamp-p 'lax)]) - ["Compute Time Range" org-evaluate-time-range t] - ["Schedule Item" org-schedule (not (org-before-first-heading-p))] - ["Deadline" org-deadline (not (org-before-first-heading-p))] - "--" - ["Custom time format" org-toggle-time-stamp-overlays - :style radio :selected org-display-custom-times] - "--" - ["Goto Calendar" org-goto-calendar t] - ["Date from Calendar" org-date-from-calendar t] - "--" - ["Start/Restart Timer" org-timer-start t] - ["Pause/Continue Timer" org-timer-pause-or-continue t] - ["Stop Timer" org-timer-pause-or-continue :active t :keys "C-u C-c C-x ,"] - ["Insert Timer String" org-timer t] - ["Insert Timer Item" org-timer-item t]) - ("Logging work" - ["Clock in" org-clock-in :active t :keys "C-c C-x C-i"] - ["Switch task" (lambda () (interactive) (org-clock-in '(4))) :active t :keys "C-u C-c C-x C-i"] - ["Clock out" org-clock-out t] - ["Clock cancel" org-clock-cancel t] - "--" - ["Mark as default task" org-clock-mark-default-task t] - ["Clock in, mark as default" (lambda () (interactive) (org-clock-in '(16))) :active t :keys "C-u C-u C-c C-x C-i"] - ["Goto running clock" org-clock-goto t] - "--" - ["Display times" org-clock-display t] - ["Create clock table" org-clock-report t] - "--" - ["Record DONE time" - (progn (setq org-log-done (not org-log-done)) - (message "Switching to %s will %s record a timestamp" - (car org-done-keywords) - (if org-log-done "automatically" "not"))) - :style toggle :selected org-log-done]) - "--" - ["Agenda Command..." org-agenda t] - ["Set Restriction Lock" org-agenda-set-restriction-lock t] - ("File List for Agenda") - ("Special views current file" - ["TODO Tree" org-show-todo-tree t] - ["Check Deadlines" org-check-deadlines t] - ["Tags/Property tree" org-match-sparse-tree t]) - "--" - ["Export/Publish..." org-export-dispatch t] - ("LaTeX" - ["Org CDLaTeX mode" org-cdlatex-mode :active (require 'cdlatex nil t) - :style toggle :selected org-cdlatex-mode] - ["Insert Environment" cdlatex-environment (fboundp 'cdlatex-environment)] - ["Insert math symbol" cdlatex-math-symbol (fboundp 'cdlatex-math-symbol)] - ["Modify math symbol" org-cdlatex-math-modify - (org-inside-LaTeX-fragment-p)] - ["Insert citation" org-reftex-citation t]) - "--" - ,@(when (featurep 'org-mobile) - '(("MobileOrg" - ["Push Files and Views" org-mobile-push t] - ["Get Captured and Flagged" org-mobile-pull t] - ["Find FLAGGED Tasks" (org-agenda nil "?") :active t :keys "\\[org-agenda] ?"] - "--" - ["Setup" (customize-group 'org-mobile) t]) - "--")) - ("Documentation" - ["Show Version" org-version t] - ["Info Documentation" org-info t] - ["Browse Org News" org-browse-news t]) - ("Customize" - ["Browse Org Group" org-customize t] - "--" - ["Expand This Menu" org-create-customize-menu - (fboundp 'customize-menu-create)]) - ["Send bug report" org-submit-bug-report t] - "--" - ("Refresh/Reload" - ["Refresh setup current buffer" org-mode-restart t] - ["Reload Org (after update)" org-reload t] - ["Reload Org uncompiled" (org-reload t) :active t :keys "C-u C-c C-x !"]))) - (easy-menu-define org-tbl-menu org-mode-map "Org Table menu" - '("Table" - ["Align" org-ctrl-c-ctrl-c :active (org-at-table-p)] - ["Next Field" org-cycle (org-at-table-p)] - ["Previous Field" org-shifttab (org-at-table-p)] - ["Next Row" org-return (org-at-table-p)] - "--" - ["Blank Field" org-table-blank-field (org-at-table-p)] - ["Edit Field" org-table-edit-field (org-at-table-p)] - ["Copy Field from Above" org-table-copy-down (org-at-table-p)] - "--" - ("Column" - ["Move Column Left" org-metaleft (org-at-table-p)] - ["Move Column Right" org-metaright (org-at-table-p)] - ["Delete Column" org-shiftmetaleft (org-at-table-p)] - ["Insert Column" org-shiftmetaright (org-at-table-p)] - ["Shrink Column" org-table-toggle-column-width (org-at-table-p)]) - ("Row" - ["Move Row Up" org-metaup (org-at-table-p)] - ["Move Row Down" org-metadown (org-at-table-p)] - ["Delete Row" org-shiftmetaup (org-at-table-p)] - ["Insert Row" org-shiftmetadown (org-at-table-p)] - ["Sort lines in region" org-table-sort-lines (org-at-table-p)] - "--" - ["Insert Hline" org-ctrl-c-minus (org-at-table-p)]) - ("Rectangle" - ["Copy Rectangle" org-copy-special (org-at-table-p)] - ["Cut Rectangle" org-cut-special (org-at-table-p)] - ["Paste Rectangle" org-paste-special (org-at-table-p)] - ["Fill Rectangle" org-table-wrap-region (org-at-table-p)]) - "--" - ("Calculate" - ["Set Column Formula" org-table-eval-formula (org-at-table-p)] - ["Set Field Formula" (org-table-eval-formula '(4)) :active (org-at-table-p) :keys "C-u C-c ="] - ["Edit Formulas" org-edit-special (org-at-table-p)] - "--" - ["Recalculate line" org-table-recalculate (org-at-table-p)] - ["Recalculate all" (lambda () (interactive) (org-table-recalculate '(4))) :active (org-at-table-p) :keys "C-u C-c *"] - ["Iterate all" (lambda () (interactive) (org-table-recalculate '(16))) :active (org-at-table-p) :keys "C-u C-u C-c *"] - "--" - ["Toggle Recalculate Mark" org-table-rotate-recalc-marks (org-at-table-p)] - "--" - ["Sum Column/Rectangle" org-table-sum - (or (org-at-table-p) (org-region-active-p))] - ["Which Column?" org-table-current-column (org-at-table-p)]) - ["Debug Formulas" - org-table-toggle-formula-debugger - :style toggle :selected (bound-and-true-p org-table-formula-debug)] - ["Show Col/Row Numbers" - org-table-toggle-coordinate-overlays - :style toggle - :selected (bound-and-true-p org-table-overlay-coordinates)] - "--" - ["Create" org-table-create (not (org-at-table-p))] - ["Convert Region" org-table-convert-region (not (org-at-table-p 'any))] - ["Import from File" org-table-import (not (org-at-table-p))] - ["Export to File" org-table-export (org-at-table-p)] - "--" - ["Create/Convert from/to table.el" org-table-create-with-table.el t] - "--" - ("Plot" - ["Ascii plot" orgtbl-ascii-plot :active (org-at-table-p) :keys "C-c \" a"] - ["Gnuplot" org-plot/gnuplot :active (org-at-table-p) :keys "C-c \" g"])))) +(easy-menu-define org-org-menu org-mode-map "Org menu" + `("Org" + ("Show/Hide" + ["Cycle Visibility" org-cycle :active (or (bobp) (outline-on-heading-p))] + ["Cycle Global Visibility" org-shifttab :active (not (org-at-table-p))] + ["Sparse Tree..." org-sparse-tree t] + ["Reveal Context" org-reveal t] + ["Show All" org-show-all t] + "--" + ["Subtree to indirect buffer" org-tree-to-indirect-buffer t]) + "--" + ["New Heading" org-insert-heading t] + ("Navigate Headings" + ["Up" outline-up-heading t] + ["Next" outline-next-visible-heading t] + ["Previous" outline-previous-visible-heading t] + ["Next Same Level" outline-forward-same-level t] + ["Previous Same Level" outline-backward-same-level t] + "--" + ["Jump" org-goto t]) + ("Edit Structure" + ["Move Subtree Up" org-metaup (org-at-heading-p)] + ["Move Subtree Down" org-metadown (org-at-heading-p)] + "--" + ["Copy Subtree" org-copy-special (org-in-subtree-not-table-p)] + ["Cut Subtree" org-cut-special (org-in-subtree-not-table-p)] + ["Paste Subtree" org-paste-special (not (org-at-table-p))] + "--" + ["Clone subtree, shift time" org-clone-subtree-with-time-shift t] + "--" + ["Copy visible text" org-copy-visible t] + "--" + ["Promote Heading" org-metaleft (org-in-subtree-not-table-p)] + ["Promote Subtree" org-shiftmetaleft (org-in-subtree-not-table-p)] + ["Demote Heading" org-metaright (org-in-subtree-not-table-p)] + ["Demote Subtree" org-shiftmetaright (org-in-subtree-not-table-p)] + "--" + ["Sort Region/Children" org-sort t] + "--" + ["Convert to odd levels" org-convert-to-odd-levels t] + ["Convert to odd/even levels" org-convert-to-oddeven-levels t]) + ("Editing" + ["Emphasis..." org-emphasize t] + ["Edit Source Example" org-edit-special t] + "--" + ["Footnote new/jump" org-footnote-action t] + ["Footnote extra" (org-footnote-action t) :active t :keys "C-u C-c C-x f"]) + ("Archive" + ["Archive (default method)" org-archive-subtree-default (org-in-subtree-not-table-p)] + "--" + ["Move Subtree to Archive file" org-archive-subtree (org-in-subtree-not-table-p)] + ["Toggle ARCHIVE tag" org-toggle-archive-tag (org-in-subtree-not-table-p)] + ["Move subtree to Archive sibling" org-archive-to-archive-sibling (org-in-subtree-not-table-p)]) + "--" + ("Hyperlinks" + ["Store Link (Global)" org-store-link t] + ["Find existing link to here" org-occur-link-in-agenda-files t] + ["Insert Link" org-insert-link t] + ["Follow Link" org-open-at-point t] + "--" + ["Next link" org-next-link t] + ["Previous link" org-previous-link t] + "--" + ["Descriptive Links" + org-toggle-link-display + :style radio + :selected org-descriptive-links + ] + ["Literal Links" + org-toggle-link-display + :style radio + :selected (not org-descriptive-links)]) + "--" + ("TODO Lists" + ["TODO/DONE/-" org-todo t] + ("Select keyword" + ["Next keyword" org-shiftright (org-at-heading-p)] + ["Previous keyword" org-shiftleft (org-at-heading-p)] + ["Complete Keyword" pcomplete (assq :todo-keyword (org-context))] + ["Next keyword set" org-shiftcontrolright (and (> (length org-todo-sets) 1) (org-at-heading-p))] + ["Previous keyword set" org-shiftcontrolright (and (> (length org-todo-sets) 1) (org-at-heading-p))]) + ["Show TODO Tree" org-show-todo-tree :active t :keys "C-c / t"] + ["Global TODO list" org-todo-list :active t :keys "\\[org-agenda] t"] + "--" + ["Enforce dependencies" (customize-variable 'org-enforce-todo-dependencies) + :selected org-enforce-todo-dependencies :style toggle :active t] + "Settings for tree at point" + ["Do Children sequentially" org-toggle-ordered-property :style radio + :selected (org-entry-get nil "ORDERED") + :active org-enforce-todo-dependencies :keys "C-c C-x o"] + ["Do Children parallel" org-toggle-ordered-property :style radio + :selected (not (org-entry-get nil "ORDERED")) + :active org-enforce-todo-dependencies :keys "C-c C-x o"] + "--" + ["Set Priority" org-priority t] + ["Priority Up" org-shiftup t] + ["Priority Down" org-shiftdown t] + "--" + ["Get news from all feeds" org-feed-update-all t] + ["Go to the inbox of a feed..." org-feed-goto-inbox t] + ["Customize feeds" (customize-variable 'org-feed-alist) t]) + ("TAGS and Properties" + ["Set Tags" org-set-tags-command (not (org-before-first-heading-p))] + ["Change tag in region" org-change-tag-in-region (org-region-active-p)] + "--" + ["Set property" org-set-property (not (org-before-first-heading-p))] + ["Column view of properties" org-columns t] + ["Insert Column View DBlock" org-columns-insert-dblock t]) + ("Dates and Scheduling" + ["Timestamp" org-time-stamp (not (org-before-first-heading-p))] + ["Timestamp (inactive)" org-time-stamp-inactive (not (org-before-first-heading-p))] + ("Change Date" + ["1 Day Later" org-shiftright (org-at-timestamp-p 'lax)] + ["1 Day Earlier" org-shiftleft (org-at-timestamp-p 'lax)] + ["1 ... Later" org-shiftup (org-at-timestamp-p 'lax)] + ["1 ... Earlier" org-shiftdown (org-at-timestamp-p 'lax)]) + ["Compute Time Range" org-evaluate-time-range t] + ["Schedule Item" org-schedule (not (org-before-first-heading-p))] + ["Deadline" org-deadline (not (org-before-first-heading-p))] + "--" + ["Custom time format" org-toggle-time-stamp-overlays + :style radio :selected org-display-custom-times] + "--" + ["Goto Calendar" org-goto-calendar t] + ["Date from Calendar" org-date-from-calendar t] + "--" + ["Start/Restart Timer" org-timer-start t] + ["Pause/Continue Timer" org-timer-pause-or-continue t] + ["Stop Timer" org-timer-pause-or-continue :active t :keys "C-u C-c C-x ,"] + ["Insert Timer String" org-timer t] + ["Insert Timer Item" org-timer-item t]) + ("Logging work" + ["Clock in" org-clock-in :active t :keys "C-c C-x C-i"] + ["Switch task" (lambda () (interactive) (org-clock-in '(4))) :active t :keys "C-u C-c C-x C-i"] + ["Clock out" org-clock-out t] + ["Clock cancel" org-clock-cancel t] + "--" + ["Mark as default task" org-clock-mark-default-task t] + ["Clock in, mark as default" (lambda () (interactive) (org-clock-in '(16))) :active t :keys "C-u C-u C-c C-x C-i"] + ["Goto running clock" org-clock-goto t] + "--" + ["Display times" org-clock-display t] + ["Create clock table" org-clock-report t] + "--" + ["Record DONE time" + (progn (setq org-log-done (not org-log-done)) + (message "Switching to %s will %s record a timestamp" + (car org-done-keywords) + (if org-log-done "automatically" "not"))) + :style toggle :selected org-log-done]) + "--" + ["Agenda Command..." org-agenda t] + ["Set Restriction Lock" org-agenda-set-restriction-lock t] + ("File List for Agenda") + ("Special views current file" + ["TODO Tree" org-show-todo-tree t] + ["Check Deadlines" org-check-deadlines t] + ["Tags/Property tree" org-match-sparse-tree t]) + "--" + ["Export/Publish..." org-export-dispatch t] + ("LaTeX" + ["Org CDLaTeX mode" org-cdlatex-mode :active (require 'cdlatex nil t) + :style toggle :selected org-cdlatex-mode] + ["Insert Environment" cdlatex-environment (fboundp 'cdlatex-environment)] + ["Insert math symbol" cdlatex-math-symbol (fboundp 'cdlatex-math-symbol)] + ["Modify math symbol" org-cdlatex-math-modify + (org-inside-LaTeX-fragment-p)] + ["Insert citation" org-reftex-citation t]) + "--" + ("Documentation" + ["Show Version" org-version t] + ["Info Documentation" org-info t] + ["Browse Org News" org-browse-news t]) + ("Customize" + ["Browse Org Group" org-customize t] + "--" + ["Expand This Menu" org-create-customize-menu + (fboundp 'customize-menu-create)]) + ["Send bug report" org-submit-bug-report t] + "--" + ("Refresh/Reload" + ["Refresh setup current buffer" org-mode-restart t] + ["Reload Org (after update)" org-reload t] + ["Reload Org uncompiled" (org-reload t) :active t :keys "C-u C-c C-x !"]))) + +(easy-menu-define org-tbl-menu org-mode-map "Org Table menu" + '("Table" + ["Align" org-ctrl-c-ctrl-c :active (org-at-table-p)] + ["Next Field" org-cycle (org-at-table-p)] + ["Previous Field" org-shifttab (org-at-table-p)] + ["Next Row" org-return (org-at-table-p)] + "--" + ["Blank Field" org-table-blank-field (org-at-table-p)] + ["Edit Field" org-table-edit-field (org-at-table-p)] + ["Copy Field from Above" org-table-copy-down (org-at-table-p)] + "--" + ("Column" + ["Move Column Left" org-metaleft (org-at-table-p)] + ["Move Column Right" org-metaright (org-at-table-p)] + ["Delete Column" org-shiftmetaleft (org-at-table-p)] + ["Insert Column" org-shiftmetaright (org-at-table-p)] + ["Shrink Column" org-table-toggle-column-width (org-at-table-p)]) + ("Row" + ["Move Row Up" org-metaup (org-at-table-p)] + ["Move Row Down" org-metadown (org-at-table-p)] + ["Delete Row" org-shiftmetaup (org-at-table-p)] + ["Insert Row" org-shiftmetadown (org-at-table-p)] + ["Sort lines in region" org-table-sort-lines (org-at-table-p)] + "--" + ["Insert Hline" org-ctrl-c-minus (org-at-table-p)]) + ("Rectangle" + ["Copy Rectangle" org-copy-special (org-at-table-p)] + ["Cut Rectangle" org-cut-special (org-at-table-p)] + ["Paste Rectangle" org-paste-special (org-at-table-p)] + ["Fill Rectangle" org-table-wrap-region (org-at-table-p)]) + "--" + ("Calculate" + ["Set Column Formula" org-table-eval-formula (org-at-table-p)] + ["Set Field Formula" (org-table-eval-formula '(4)) :active (org-at-table-p) :keys "C-u C-c ="] + ["Edit Formulas" org-edit-special (org-at-table-p)] + "--" + ["Recalculate line" org-table-recalculate (org-at-table-p)] + ["Recalculate all" (lambda () (interactive) (org-table-recalculate '(4))) :active (org-at-table-p) :keys "C-u C-c *"] + ["Iterate all" (lambda () (interactive) (org-table-recalculate '(16))) :active (org-at-table-p) :keys "C-u C-u C-c *"] + "--" + ["Toggle Recalculate Mark" org-table-rotate-recalc-marks (org-at-table-p)] + "--" + ["Sum Column/Rectangle" org-table-sum + (or (org-at-table-p) (org-region-active-p))] + ["Which Column?" org-table-current-column (org-at-table-p)]) + ["Debug Formulas" + org-table-toggle-formula-debugger + :style toggle :selected (bound-and-true-p org-table-formula-debug)] + ["Show Col/Row Numbers" + org-table-toggle-coordinate-overlays + :style toggle + :selected (bound-and-true-p org-table-overlay-coordinates)] + "--" + ["Create" org-table-create (not (org-at-table-p))] + ["Convert Region" org-table-convert-region (not (org-at-table-p 'any))] + ["Import from File" org-table-import (not (org-at-table-p))] + ["Export to File" org-table-export (org-at-table-p)] + "--" + ["Create/Convert from/to table.el" org-table-create-with-table.el t] + "--" + ("Plot" + ["Ascii plot" orgtbl-ascii-plot :active (org-at-table-p) :keys "C-c \" a"] + ["Gnuplot" org-plot/gnuplot :active (org-at-table-p) :keys "C-c \" g"]))) (defun org-info (&optional node) "Read documentation for Org in the info system. diff --git a/lisp/ox-ascii.el b/lisp/ox-ascii.el index 019c26c..4ffb44a 100644 --- a/lisp/ox-ascii.el +++ b/lisp/ox-ascii.el @@ -34,6 +34,7 @@ ;;; Function Declarations (declare-function aa2u "ext:ascii-art-to-unicode" ()) +(declare-function org-attach-link-expand "org-attach" (link &optional buffer-or-name)) ;;; Define Back-End ;; @@ -1573,7 +1574,7 @@ INFO is a plist holding contextual information." (raw-path (org-element-property :path link)) (path (cond ((string= type "attachment") - (setq raw-path (org-element-property :attachment-path link)) + (setq raw-path (org-attach-link-expand link)) (concat type ":" raw-path)) (t (concat type ":" raw-path))))) (cond diff --git a/lisp/ox-html.el b/lisp/ox-html.el index 39ccae3..fa30bde 100644 --- a/lisp/ox-html.el +++ b/lisp/ox-html.el @@ -42,6 +42,7 @@ (declare-function org-id-find-id-file "org-id" (id)) (declare-function htmlize-region "ext:htmlize" (beg end)) (declare-function mm-url-decode-entities "mm-url" ()) +(declare-function org-attach-link-expand "org-attach" (link &optional buffer-or-name)) (defvar htmlize-css-name-prefix) (defvar htmlize-output-type) @@ -3074,7 +3075,7 @@ INFO is a plist holding contextual information. See (url-encode-url (concat type ":" raw-path))) ((member type '("file" "attachment")) (when (string= type "attachment") - (setq raw-path (org-element-property :attachment-path link))) + (setq raw-path (org-attach-link-expand link))) ;; During publishing, turn absolute file names belonging ;; to base directory into relative file names. Otherwise, ;; append "file" protocol to absolute file name. diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el index b307ff4..40f1c5c 100644 --- a/lisp/ox-latex.el +++ b/lisp/ox-latex.el @@ -32,6 +32,8 @@ ;;; Function Declarations +(declare-function org-attach-link-expand "org-attach" (link &optional buffer-or-name)) + (defvar org-latex-default-packages-alist) (defvar org-latex-packages-alist) (defvar orgtbl-exp-regexp) @@ -1590,6 +1592,7 @@ INFO is a plist used as a communication channel." lang)))) `((?a . ,(org-export-data (plist-get info :author) info)) (?t . ,(org-export-data (plist-get info :title) info)) + (?s . ,(org-export-data (plist-get info :subtitle) info)) (?k . ,(org-export-data (org-latex--wrap-latex-math-block (plist-get info :keywords) info) info)) @@ -2360,7 +2363,7 @@ LINK is the link pointing to the inline image. INFO is a plist used as a communication channel." (let* ((parent (org-export-get-parent-element link)) (path (let ((raw-path (if (string= (org-element-property :type link) "attachment") - (org-element-property :attachment-path link) + (org-attach-link-expand link) (org-element-property :path link)))) (if (not (file-name-absolute-p raw-path)) raw-path (expand-file-name raw-path)))) @@ -2528,7 +2531,7 @@ INFO is a plist holding contextual information. See (concat type ":" raw-path)) ((member type '("file" "attachment")) (when (string= type "attachment") - (setq raw-path (org-element-property :attachment-path link))) + (setq raw-path (org-attach-link-expand link))) (org-export-file-uri raw-path)) (t raw-path))))) diff --git a/lisp/ox-man.el b/lisp/ox-man.el index 5de4c5e..b6925c6 100644 --- a/lisp/ox-man.el +++ b/lisp/ox-man.el @@ -42,6 +42,8 @@ ;;; Function Declarations +(declare-function org-attach-link-expand "org-attach" (link &optional buffer-or-name)) + (defvar org-export-man-default-packages-alist) (defvar org-export-man-packages-alist) (defvar orgtbl-exp-regexp) @@ -616,7 +618,7 @@ INFO is a plist holding contextual information. See (concat type ":" raw-path)) ((member type '("file" "attachment")) (when (string= type "attachment") - (setq raw-path (org-element-property :attachment-path link))) + (setq raw-path (org-attach-link-expand link))) (org-export-file-uri raw-path)) (t raw-path)))) (cond diff --git a/lisp/ox-md.el b/lisp/ox-md.el index 61b31f9..7515df3 100644 --- a/lisp/ox-md.el +++ b/lisp/ox-md.el @@ -35,6 +35,8 @@ ;;; Function Declarations +(declare-function org-attach-link-expand "org-attach" (link &optional buffer-or-name)) + ;;; User-Configurable Variables (defgroup org-export-md nil @@ -405,7 +407,7 @@ INFO is a plist holding contextual information. See (concat type ":" raw-path)) ((member type '("file" "attachment")) (when (string= type "attachment") - (setq raw-path (org-element-property :attachment-path link))) + (setq raw-path (org-attach-link-expand link))) (org-export-file-uri (funcall link-org-files-as-md raw-path))) (t raw-path)))) (cond diff --git a/lisp/ox-odt.el b/lisp/ox-odt.el index 140323c..49e37cc 100644 --- a/lisp/ox-odt.el +++ b/lisp/ox-odt.el @@ -34,6 +34,8 @@ ;;; Function Declarations +(declare-function org-attach-link-expand "org-attach" (link &optional buffer-or-name)) + ;;; Define Back-End (org-export-define-backend 'odt @@ -2706,7 +2708,7 @@ INFO is a plist holding contextual information. See (concat type ":" raw-path)) ((member type '("file" "attachment")) (when (string= type "attachment") - (setq raw-path (org-element-property :attachment-path link))) + (setq raw-path (org-attach-link-expand link))) (org-export-file-uri raw-path)) (t raw-path))) ;; Convert & to & for correct XML representation diff --git a/lisp/ox-texinfo.el b/lisp/ox-texinfo.el index 22ea86e..89c6746 100644 --- a/lisp/ox-texinfo.el +++ b/lisp/ox-texinfo.el @@ -30,6 +30,8 @@ ;;; Function Declarations +(declare-function org-attach-link-expand "org-attach" (link &optional buffer-or-name)) + (defvar orgtbl-exp-regexp) @@ -1058,7 +1060,7 @@ INFO is a plist holding contextual information. See (concat type ":" raw-path)) ((member type '("file" "attachment")) (when (string= type "attachment") - (setq raw-path (org-element-property :attachment-path link))) + (setq raw-path (org-attach-link-expand link))) (org-export-file-uri raw-path)) (t raw-path)))) (cond diff --git a/testing/lisp/test-org-capture.el b/testing/lisp/test-org-capture.el index 124ef43..10cfcbf 100644 --- a/testing/lisp/test-org-capture.el +++ b/testing/lisp/test-org-capture.el @@ -208,7 +208,6 @@ (org-capture-templates `(("t" "Todo" entry (file+headline ,file "A") "** H1 %?")))) (org-capture nil "t") - (goto-char (point-max)) (insert "Capture text") (org-capture-finalize)) (buffer-string)))) |