dotemacs

My Emacs configuration
git clone git://git.entf.net/dotemacs
Log | Files | Refs | LICENSE

org-refile.el (29010B)


      1 ;;; org-refile.el --- Refile Org Subtrees             -*- lexical-binding: t; -*-
      2 
      3 ;; Copyright (C) 2010-2023 Free Software Foundation, Inc.
      4 
      5 ;; Author: Carsten Dominik <carsten.dominik@gmail.com>
      6 ;; Keywords: outlines, hypermedia, calendar, wp
      7 ;;
      8 ;; This file is part of GNU Emacs.
      9 
     10 ;; GNU Emacs is free software: you can redistribute it and/or modify
     11 ;; it under the terms of the GNU General Public License as published by
     12 ;; the Free Software Foundation, either version 3 of the License, or
     13 ;; (at your option) any later version.
     14 
     15 ;; GNU Emacs is distributed in the hope that it will be useful,
     16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
     17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     18 ;; GNU General Public License for more details.
     19 
     20 ;; You should have received a copy of the GNU General Public License
     21 ;; along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.
     22 
     23 ;;; Commentary:
     24 
     25 ;; Org Refile allows you to refile subtrees to various locations.
     26 
     27 ;;; Code:
     28 (require 'org-macs)
     29 (org-assert-version)
     30 
     31 (require 'org)
     32 
     33 (declare-function org-inlinetask-remove-END-maybe "org-inlinetask" ())
     34 
     35 (defgroup org-refile nil
     36   "Options concerning refiling entries in Org mode."
     37   :tag "Org Refile"
     38   :group 'org)
     39 
     40 (defcustom org-log-refile nil
     41   "Information to record when a task is refiled.
     42 
     43 Possible values are:
     44 
     45 nil     Don't add anything
     46 time    Add a time stamp to the task
     47 note    Prompt for a note and add it with template `org-log-note-headings'
     48 
     49 This option can also be set with on a per-file-basis with
     50 
     51    #+STARTUP: nologrefile
     52    #+STARTUP: logrefile
     53    #+STARTUP: lognoterefile
     54 
     55 You can have local logging settings for a subtree by setting the LOGGING
     56 property to one or more of these keywords.
     57 
     58 When bulk-refiling, e.g., from the agenda, the value `note' is
     59 forbidden and will temporarily be changed to `time'."
     60   :group 'org-refile
     61   :group 'org-progress
     62   :version "24.1"
     63   :type '(choice
     64 	  (const :tag "No logging" nil)
     65 	  (const :tag "Record timestamp" time)
     66 	  (const :tag "Record timestamp with note." note)))
     67 
     68 (defcustom org-refile-targets nil
     69   "Targets for refiling entries with `\\[org-refile]'.
     70 This is a list of cons cells.  Each cell contains:
     71 - a specification of the files to be considered, either a list of files,
     72   or a symbol whose function or variable value will be used to retrieve
     73   a file name or a list of file names.  If you use `org-agenda-files' for
     74   that, all agenda files will be scanned for targets.  Nil means consider
     75   headings in the current buffer.
     76 - A specification of how to find candidate refile targets.  This may be
     77   any of:
     78   - a cons cell (:tag . \"TAG\") to identify refile targets by a tag.
     79     This tag has to be present in all target headlines, inheritance will
     80     not be considered.
     81   - a cons cell (:todo . \"KEYWORD\") to identify refile targets by
     82     todo keyword.
     83   - a cons cell (:regexp . \"REGEXP\") with a regular expression matching
     84     headlines that are refiling targets.
     85   - a cons cell (:level . N).  Any headline of level N is considered a target.
     86     Note that, when `org-odd-levels-only' is set, level corresponds to
     87     order in hierarchy, not to the number of stars.
     88   - a cons cell (:maxlevel . N).  Any headline with level <= N is a target.
     89     Note that, when `org-odd-levels-only' is set, level corresponds to
     90     order in hierarchy, not to the number of stars.
     91 
     92 Each element of this list generates a set of possible targets.
     93 The union of these sets is presented (with completion) to
     94 the user by `org-refile'.
     95 
     96 You can set the variable `org-refile-target-verify-function' to a function
     97 to verify each headline found by the simple criteria above.
     98 
     99 When this variable is nil, all top-level headlines in the current buffer
    100 are used, equivalent to the value `((nil . (:level . 1)))'."
    101   :group 'org-refile
    102   :type '(repeat
    103 	  (cons
    104 	   (choice :value org-agenda-files
    105 		   (const :tag "All agenda files" org-agenda-files)
    106 		   (const :tag "Current buffer" nil)
    107 		   (function) (variable) (file))
    108 	   (choice :tag "Identify target headline by"
    109 		   (cons :tag "Specific tag" (const :value :tag) (string))
    110 		   (cons :tag "TODO keyword" (const :value :todo) (string))
    111 		   (cons :tag "Regular expression" (const :value :regexp) (regexp))
    112 		   (cons :tag "Level number" (const :value :level) (integer))
    113 		   (cons :tag "Max Level number" (const :value :maxlevel) (integer))))))
    114 
    115 (defcustom org-refile-target-verify-function nil
    116   "Function to verify if the headline at point should be a refile target.
    117 The function will be called without arguments, with point at the
    118 beginning of the headline.  It should return t and leave point
    119 where it is if the headline is a valid target for refiling.
    120 
    121 If the target should not be selected, the function must return nil.
    122 In addition to this, it may move point to a place from where the search
    123 should be continued.  For example, the function may decide that the entire
    124 subtree of the current entry should be excluded and move point to the end
    125 of the subtree."
    126   :group 'org-refile
    127   :type '(choice
    128 	  (const nil)
    129 	  (function)))
    130 
    131 (defcustom org-refile-use-cache nil
    132   "Non-nil means cache refile targets to speed up the process.
    133 \\<org-mode-map>\
    134 The cache for a particular file will be updated automatically when
    135 the buffer has been killed, or when any of the marker used for flagging
    136 refile targets no longer points at a live buffer.
    137 If you have added new entries to a buffer that might themselves be targets,
    138 you need to clear the cache manually by pressing `C-0 \\[org-refile]' or,
    139 if you find that easier, \
    140 `\\[universal-argument] \\[universal-argument] \\[universal-argument] \
    141 \\[org-refile]'."
    142   :group 'org-refile
    143   :version "24.1"
    144   :type 'boolean)
    145 
    146 (defcustom org-refile-use-outline-path nil
    147   "Non-nil means provide refile targets as paths.
    148 So a level 3 headline will be available as level1/level2/level3.
    149 
    150 When the value is `file', also include the file name (without directory)
    151 into the path.  In this case, you can also stop the completion after
    152 the file name, to get entries inserted as top level in the file.
    153 
    154 When `full-file-path', include the full file path.
    155 
    156 When `buffer-name', use the buffer name."
    157   :group 'org-refile
    158   :package-version '(Org . "9.6")
    159   :type '(choice
    160 	  (const :tag "Not" nil)
    161 	  (const :tag "Yes" t)
    162 	  (const :tag "Start with file name" file)
    163 	  (const :tag "Start with full file path" full-file-path)
    164 	  (const :tag "Start with buffer name" buffer-name)
    165 	  (const :tag "Start with document title" title)))
    166 
    167 (defcustom org-outline-path-complete-in-steps t
    168   "Non-nil means complete the outline path in hierarchical steps.
    169 When Org uses the refile interface to select an outline path (see
    170 `org-refile-use-outline-path'), the completion of the path can be
    171 done in a single go, or it can be done in steps down the headline
    172 hierarchy.  Going in steps is probably the best if you do not use
    173 a special completion package like `ido' or `icicles'.  However,
    174 when using these packages, going in one step can be very fast,
    175 while still showing the whole path to the entry."
    176   :group 'org-refile
    177   :type 'boolean)
    178 
    179 (defcustom org-refile-allow-creating-parent-nodes nil
    180   "Non-nil means allow the creation of new nodes as refile targets.
    181 New nodes are then created by adding \"/new node name\" to the completion
    182 of an existing node.  When the value of this variable is `confirm',
    183 new node creation must be confirmed by the user (recommended).
    184 When nil, the completion must match an existing entry.
    185 
    186 Note that, if the new heading is not seen by the criteria
    187 listed in `org-refile-targets', multiple instances of the same
    188 heading would be created by trying again to file under the new
    189 heading."
    190   :group 'org-refile
    191   :type '(choice
    192 	  (const :tag "Never" nil)
    193 	  (const :tag "Always" t)
    194 	  (const :tag "Prompt for confirmation" confirm)))
    195 
    196 (defcustom org-refile-active-region-within-subtree nil
    197   "Non-nil means also refile active region within a subtree.
    198 
    199 By default `org-refile' doesn't allow refiling regions if they
    200 don't contain a set of subtrees, but it might be convenient to
    201 do so sometimes: in that case, the first line of the region is
    202 converted to a headline before refiling."
    203   :group 'org-refile
    204   :version "24.1"
    205   :type 'boolean)
    206 
    207 (defvar org-refile-target-table nil
    208   "The list of refile targets, created by `org-refile'.")
    209 
    210 (defvar org-refile-cache nil
    211   "Cache for refile targets.")
    212 
    213 (defvar org-refile-markers nil
    214   "All the markers used for caching refile locations.")
    215 
    216 ;; Add org refile commands to the main org menu
    217 (mapc (lambda (i) (easy-menu-add-item
    218 		   org-org-menu
    219 		   '("Edit Structure") i))
    220       '(["Refile Subtree" org-refile (org-in-subtree-not-table-p)]
    221 	["Refile and copy Subtree" org-refile-copy (org-in-subtree-not-table-p)]))
    222 
    223 (defun org-refile-marker (pos)
    224   "Get a new refile marker, but only if caching is in use."
    225   (if (not org-refile-use-cache)
    226       pos
    227     (let ((m (make-marker)))
    228       (move-marker m pos)
    229       (push m org-refile-markers)
    230       m)))
    231 
    232 (defun org-refile-cache-clear ()
    233   "Clear the refile cache and disable all the markers."
    234   (dolist (m org-refile-markers) (move-marker m nil))
    235   (setq org-refile-markers nil)
    236   (setq org-refile-cache nil)
    237   (message "Refile cache has been cleared"))
    238 
    239 (defun org-refile-cache-check-set (set)
    240   "Check if all the markers in the cache still have live buffers."
    241   (let (marker)
    242     (catch 'exit
    243       (while (and set (setq marker (nth 3 (pop set))))
    244 	;; If `org-refile-use-outline-path' is 'file, marker may be nil
    245 	(when (and marker (null (marker-buffer marker)))
    246 	  (message "Please regenerate the refile cache with `C-0 C-c C-w'")
    247 	  (sit-for 3)
    248 	  (throw 'exit nil)))
    249       t)))
    250 
    251 (defun org-refile-cache-put (set &rest identifiers)
    252   "Push the refile targets SET into the cache, under IDENTIFIERS."
    253   (let* ((key (sha1 (prin1-to-string identifiers)))
    254 	 (entry (assoc key org-refile-cache)))
    255     (if entry
    256 	(setcdr entry set)
    257       (push (cons key set) org-refile-cache))))
    258 
    259 (defun org-refile-cache-get (&rest identifiers)
    260   "Retrieve the cached value for refile targets given by IDENTIFIERS."
    261   (cond
    262    ((not org-refile-cache) nil)
    263    ((not org-refile-use-cache) (org-refile-cache-clear) nil)
    264    (t
    265     (let ((set (cdr (assoc (sha1 (prin1-to-string identifiers))
    266 			   org-refile-cache))))
    267       (and set (org-refile-cache-check-set set) set)))))
    268 
    269 (defun org-refile-get-targets (&optional default-buffer)
    270   "Produce a table with refile targets."
    271   (let ((case-fold-search nil)
    272 	;; otherwise org confuses "TODO" as a kw and "Todo" as a word
    273 	(entries (or org-refile-targets '((nil . (:level . 1)))))
    274 	targets tgs files desc descre)
    275     (message "Getting targets...")
    276     (with-current-buffer (or default-buffer (current-buffer))
    277       (dolist (entry entries)
    278 	(setq files (car entry) desc (cdr entry))
    279 	(cond
    280 	 ((null files) (setq files (list (current-buffer))))
    281 	 ((eq files 'org-agenda-files)
    282 	  (setq files (org-agenda-files 'unrestricted)))
    283 	 ((and (symbolp files) (fboundp files))
    284 	  (setq files (funcall files)))
    285 	 ((and (symbolp files) (boundp files))
    286 	  (setq files (symbol-value files))))
    287 	(when (stringp files) (setq files (list files)))
    288 	(cond
    289 	 ((eq (car desc) :tag)
    290 	  (setq descre (concat "^\\*+[ \t]+.*?:" (regexp-quote (cdr desc)) ":")))
    291 	 ((eq (car desc) :todo)
    292 	  (setq descre (concat "^\\*+[ \t]+" (regexp-quote (cdr desc)) "[ \t]")))
    293 	 ((eq (car desc) :regexp)
    294 	  (setq descre (cdr desc)))
    295 	 ((eq (car desc) :level)
    296 	  (setq descre (concat "^\\*\\{" (number-to-string
    297 					  (if org-odd-levels-only
    298 					      (1- (* 2 (cdr desc)))
    299 					    (cdr desc)))
    300 			       "\\}[ \t]")))
    301 	 ((eq (car desc) :maxlevel)
    302 	  (setq descre (concat "^\\*\\{1," (number-to-string
    303 					    (if org-odd-levels-only
    304 						(1- (* 2 (cdr desc)))
    305 					      (cdr desc)))
    306 			       "\\}[ \t]")))
    307 	 (t (error "Bad refiling target description %s" desc)))
    308 	(dolist (f files)
    309 	  (with-current-buffer (if (bufferp f) f (org-get-agenda-file-buffer f))
    310 	    (or
    311 	     (setq tgs (org-refile-cache-get (buffer-file-name) descre))
    312 	     (progn
    313 	       (when (bufferp f)
    314 		 (setq f (buffer-file-name (buffer-base-buffer f))))
    315 	       (setq f (and f (expand-file-name f)))
    316 	       (when (eq org-refile-use-outline-path 'file)
    317 		 (push (list (and f (file-name-nondirectory f)) f nil nil) tgs))
    318 	       (when (eq org-refile-use-outline-path 'buffer-name)
    319 		 (push (list (buffer-name (buffer-base-buffer)) f nil nil) tgs))
    320 	       (when (eq org-refile-use-outline-path 'full-file-path)
    321 		 (push (list (and (buffer-file-name (buffer-base-buffer))
    322                                   (file-truename (buffer-file-name (buffer-base-buffer))))
    323                              f nil nil) tgs))
    324                (when (eq org-refile-use-outline-path 'title)
    325                  (push (list (or (org-get-title)
    326                                  (and f (file-name-nondirectory f)))
    327                              f nil nil)
    328                        tgs))
    329 	       (org-with-wide-buffer
    330 		(goto-char (point-min))
    331 		(setq org-outline-path-cache nil)
    332 		(while (re-search-forward descre nil t)
    333 		  (beginning-of-line)
    334 		  (let ((case-fold-search nil))
    335 		    (looking-at org-complex-heading-regexp))
    336 		  (let ((begin (point))
    337 			(heading (match-string-no-properties 4)))
    338 		    (unless (or (and
    339 				 org-refile-target-verify-function
    340 				 (not
    341 				  (funcall org-refile-target-verify-function)))
    342 				(not heading))
    343 		      (let ((re (format org-complex-heading-regexp-format
    344 					(regexp-quote heading)))
    345 			    (target
    346 			     (if (not org-refile-use-outline-path) heading
    347 			       (mapconcat
    348 				#'identity
    349 				(append
    350 				 (pcase org-refile-use-outline-path
    351 				   (`file (list
    352                                            (and (buffer-file-name (buffer-base-buffer))
    353                                                 (file-name-nondirectory
    354                                                  (buffer-file-name (buffer-base-buffer))))))
    355                                    (`title (list
    356                                             (or (org-get-title)
    357                                                 (and (buffer-file-name (buffer-base-buffer))
    358                                                      (file-name-nondirectory
    359                                                       (buffer-file-name (buffer-base-buffer)))))))
    360                                    (`full-file-path
    361 				    (list (buffer-file-name
    362 					   (buffer-base-buffer))))
    363 				   (`buffer-name
    364 				    (list (buffer-name
    365 					   (buffer-base-buffer))))
    366 				   (_ nil))
    367 				 (mapcar (lambda (s) (replace-regexp-in-string
    368 						      "/" "\\/" s nil t))
    369 					 (org-get-outline-path t t)))
    370 				"/"))))
    371 			(push (list target f re (org-refile-marker (point)))
    372 			      tgs)))
    373 		    (when (= (point) begin)
    374 		      ;; Verification function has not moved point.
    375 		      (end-of-line)))))))
    376 	    (when org-refile-use-cache
    377 	      (org-refile-cache-put tgs (buffer-file-name) descre))
    378 	    (setq targets (append tgs targets))))))
    379     (message "Getting targets...done")
    380     (delete-dups (nreverse targets))))
    381 
    382 (defvar org-refile-history nil
    383   "History for refiling operations.")
    384 
    385 (defvar org-after-refile-insert-hook nil
    386   "Hook run after `org-refile' has inserted its stuff at the new location.
    387 Note that this is still *before* the stuff will be removed from
    388 the *old* location.")
    389 
    390 (defvar org-refile-keep nil
    391   "Non-nil means `org-refile' will copy instead of refile.")
    392 
    393 ;;;###autoload
    394 (defun org-refile-copy ()
    395   "Like `org-refile', but preserve the refiled subtree."
    396   (interactive)
    397   (let ((org-refile-keep t))
    398     (org-refile nil nil nil "Copy")))
    399 
    400 ;;;###autoload
    401 (defun org-refile-reverse (&optional arg default-buffer rfloc msg)
    402   "Refile while temporarily toggling `org-reverse-note-order'.
    403 So if `org-refile' would append the entry as the last entry under
    404 the target heading, `org-refile-reverse' will prepend it as the
    405 first entry, and vice-versa."
    406   (interactive "P")
    407   (let ((org-reverse-note-order (not (org-notes-order-reversed-p))))
    408     (org-refile arg default-buffer rfloc msg)))
    409 
    410 (defvar org-capture-last-stored-marker)
    411 
    412 
    413 ;;;###autoload
    414 (defun org-refile (&optional arg default-buffer rfloc msg)
    415   "Move the entry or entries at point to another heading.
    416 
    417 The list of target headings is compiled using the information in
    418 `org-refile-targets', which see.
    419 
    420 At the target location, the entry is filed as a subitem of the
    421 target heading.  Depending on `org-reverse-note-order', the new
    422 subitem will either be the first or the last subitem.
    423 
    424 If there is an active region, all entries in that region will be
    425 refiled.  However, the region must fulfill the requirement that
    426 the first heading sets the top-level of the moved text.
    427 
    428 With a `\\[universal-argument]' ARG, the command will only visit the target \
    429 location
    430 and not actually move anything.
    431 
    432 With a prefix `\\[universal-argument] \\[universal-argument]', go to the \
    433 location where the last
    434 refiling operation has put the subtree.
    435 
    436 With a numeric prefix argument of `2', refile to the running clock.
    437 
    438 With a numeric prefix argument of `3', emulate `org-refile-keep'
    439 being set to t and copy to the target location, don't move it.
    440 Beware that keeping refiled entries may result in duplicated ID
    441 properties.
    442 
    443 RFLOC can be a refile location obtained in a different way.  It
    444 should be a list with the following 4 elements:
    445 
    446 1. Name - an identifier for the refile location, typically the
    447 headline text
    448 2. File - the file the refile location is in
    449 3. nil - used for generating refile location candidates, not
    450 needed when passing RFLOC
    451 4. Position - the position in the specified file of the
    452 headline to refile under
    453 
    454 MSG is a string to replace \"Refile\" in the default prompt with
    455 another verb.  E.g. `org-refile-copy' sets this parameter to \"Copy\".
    456 
    457 See also `org-refile-use-outline-path'.
    458 
    459 If you are using target caching (see `org-refile-use-cache'), you
    460 have to clear the target cache in order to find new targets.
    461 This can be done with a `0' prefix (`C-0 C-c C-w') or a triple
    462 prefix argument (`C-u C-u C-u C-c C-w')."
    463   (interactive "P")
    464   (if (member arg '(0 (64)))
    465       (org-refile-cache-clear)
    466     (let* ((actionmsg (cond (msg msg)
    467 			    ((equal arg 3) "Refile (and keep)")
    468 			    (t "Refile")))
    469 	   (regionp (org-region-active-p))
    470 	   (region-start (and regionp (region-beginning)))
    471 	   (region-end (and regionp (region-end)))
    472 	   (org-refile-keep (if (equal arg 3) t org-refile-keep))
    473 	   pos it nbuf file level reversed)
    474       (setq last-command nil)
    475       (when regionp
    476 	(goto-char region-start)
    477 	(beginning-of-line)
    478 	(setq region-start (point))
    479 	(unless (or (org-kill-is-subtree-p
    480 		     (buffer-substring region-start region-end))
    481 		    (prog1 org-refile-active-region-within-subtree
    482                       (let ((s (line-end-position)))
    483 			(org-toggle-heading)
    484                         (setq region-end (+ (- (line-end-position) s) region-end)))))
    485 	  (user-error "The region is not a (sequence of) subtree(s)")))
    486       (if (equal arg '(16))
    487 	  (org-refile-goto-last-stored)
    488 	(when (or
    489 	       (and (equal arg 2)
    490 		    org-clock-hd-marker (marker-buffer org-clock-hd-marker)
    491 		    (prog1
    492 			(setq it (list (or org-clock-heading "running clock")
    493 				       (buffer-file-name
    494 					(marker-buffer org-clock-hd-marker))
    495 				       ""
    496 				       (marker-position org-clock-hd-marker)))
    497 		      (setq arg nil)))
    498 	       (setq it
    499 		     (or rfloc
    500 			 (let (heading-text)
    501 			   (save-excursion
    502 			     (unless (and arg (listp arg))
    503 			       (org-back-to-heading t)
    504 			       (setq heading-text
    505 				     (replace-regexp-in-string
    506 				      org-link-bracket-re
    507 				      "\\2"
    508 				      (or (nth 4 (org-heading-components))
    509 					  ""))))
    510 			     (org-refile-get-location
    511 			      (cond ((and arg (listp arg)) "Goto")
    512 				    (regionp (concat actionmsg " region to"))
    513 				    (t (concat actionmsg " subtree \""
    514 					       heading-text "\" to")))
    515 			      default-buffer
    516 			      (and (not (equal '(4) arg))
    517 				   org-refile-allow-creating-parent-nodes)))))))
    518 	  (setq file (nth 1 it)
    519 		pos (nth 3 it))
    520 	  (when (and (not arg)
    521 		     pos
    522 		     (equal (buffer-file-name) file)
    523 		     (if regionp
    524 			 (and (>= pos region-start)
    525 			      (<= pos region-end))
    526 		       (and (>= pos (point))
    527 			    (< pos (save-excursion
    528 				     (org-end-of-subtree t t))))))
    529 	    (error "Cannot refile to position inside the tree or region"))
    530 	  (setq nbuf (or (find-buffer-visiting file)
    531 			 (find-file-noselect file)))
    532 	  (if (and arg (not (equal arg 3)))
    533 	      (progn
    534 		(pop-to-buffer-same-window nbuf)
    535 		(goto-char (cond (pos)
    536 				 ((org-notes-order-reversed-p) (point-min))
    537 				 (t (point-max))))
    538 		(org-fold-show-context 'org-goto))
    539 	    (if regionp
    540 		(progn
    541 		  (org-kill-new (buffer-substring region-start region-end))
    542 		  (org-save-markers-in-region region-start region-end))
    543 	      (org-copy-subtree 1 nil t))
    544 	    (with-current-buffer (setq nbuf (or (find-buffer-visiting file)
    545 						(find-file-noselect file)))
    546 	      (setq reversed (org-notes-order-reversed-p))
    547 	      (org-with-wide-buffer
    548 	       (if pos
    549 		   (progn
    550 		     (goto-char pos)
    551 		     (setq level (org-get-valid-level (funcall outline-level) 1))
    552 		     (goto-char
    553 		      (if reversed
    554 			  (or (outline-next-heading) (point-max))
    555 			(or (save-excursion (org-get-next-sibling))
    556 			    (org-end-of-subtree t t)
    557 			    (point-max)))))
    558 		 (setq level 1)
    559 		 (if (not reversed)
    560 		     (goto-char (point-max))
    561 		   (goto-char (point-min))
    562 		   (or (outline-next-heading) (goto-char (point-max)))))
    563 	       (unless (bolp) (newline))
    564 	       (org-paste-subtree level nil nil t)
    565 	       ;; Record information, according to `org-log-refile'.
    566 	       ;; Do not prompt for a note when refiling multiple
    567 	       ;; headlines, however.  Simply add a time stamp.
    568 	       (cond
    569 		((not org-log-refile))
    570 		(regionp
    571 		 (org-map-region
    572 		  (lambda () (org-add-log-setup 'refile nil nil 'time))
    573 		  (point)
    574 		  (+ (point) (- region-end region-start))))
    575 		(t
    576 		 (org-add-log-setup 'refile nil nil org-log-refile)))
    577 	       (and org-auto-align-tags
    578 		    (let ((org-loop-over-headlines-in-active-region nil))
    579 		      (org-align-tags)))
    580 	       (let ((bookmark-name (plist-get org-bookmark-names-plist
    581 					       :last-refile)))
    582 		 (when bookmark-name
    583 		   (with-demoted-errors "Bookmark set error: %S"
    584 		     (bookmark-set bookmark-name))))
    585 	       ;; If we are refiling for capture, make sure that the
    586 	       ;; last-capture pointers point here
    587 	       (when (bound-and-true-p org-capture-is-refiling)
    588 		 (let ((bookmark-name (plist-get org-bookmark-names-plist
    589 						 :last-capture-marker)))
    590 		   (when bookmark-name
    591 		     (with-demoted-errors "Bookmark set error: %S"
    592 		       (bookmark-set bookmark-name))))
    593 		 (move-marker org-capture-last-stored-marker (point)))
    594                (deactivate-mark)
    595 	       (run-hooks 'org-after-refile-insert-hook)))
    596 	    (unless org-refile-keep
    597 	      (if regionp
    598 		  (delete-region (point) (+ (point) (- region-end region-start)))
    599 		(org-preserve-local-variables
    600 		 (delete-region
    601 		  (and (org-back-to-heading t) (point))
    602 		  (min (1+ (buffer-size)) (org-end-of-subtree t t) (point))))))
    603 	    (when (featurep 'org-inlinetask)
    604 	      (org-inlinetask-remove-END-maybe))
    605 	    (setq org-markers-to-move nil)
    606 	    (message "%s to \"%s\" in file %s: done" actionmsg
    607 		     (car it) file)))))))
    608 
    609 (defun org-refile-goto-last-stored ()
    610   "Go to the location where the last refile was stored."
    611   (interactive)
    612   (bookmark-jump (plist-get org-bookmark-names-plist :last-refile))
    613   (message "This is the location of the last refile"))
    614 
    615 (defun org-refile--get-location (refloc tbl)
    616   "When user refile to REFLOC, find the associated target in TBL.
    617 Also check `org-refile-target-table'."
    618   (car (delq
    619 	nil
    620 	(mapcar
    621 	 (lambda (r) (or (assoc r tbl)
    622 			 (assoc r org-refile-target-table)))
    623 	 (list (replace-regexp-in-string "/$" "" refloc)
    624 	       (replace-regexp-in-string "\\([^/]\\)$" "\\1/" refloc))))))
    625 
    626 (defun org-refile-get-location (&optional prompt default-buffer new-nodes)
    627   "Prompt the user for a refile location, using PROMPT.
    628 PROMPT should not be suffixed with a colon and a space, because
    629 this function appends the default value from
    630 `org-refile-history' automatically, if that is not empty."
    631   (let ((org-refile-targets org-refile-targets)
    632 	(org-refile-use-outline-path org-refile-use-outline-path))
    633     (setq org-refile-target-table (org-refile-get-targets default-buffer)))
    634   (unless org-refile-target-table
    635     (user-error "No refile targets"))
    636   (let* ((cbuf (current-buffer))
    637 	 (cfn (buffer-file-name (buffer-base-buffer cbuf)))
    638 	 (cfunc (if (and org-refile-use-outline-path
    639 			 org-outline-path-complete-in-steps)
    640 		    #'org-olpath-completing-read
    641 		  #'completing-read))
    642 	 (extra (if org-refile-use-outline-path "/" ""))
    643 	 (cbnex (concat (buffer-name) extra))
    644 	 (filename (and cfn (expand-file-name cfn)))
    645 	 (tbl (mapcar
    646 	       (lambda (x)
    647 		 (if (and (not (member org-refile-use-outline-path
    648 				       '(file full-file-path title)))
    649 			  (not (equal filename (nth 1 x))))
    650 		     (cons (concat (car x) extra " ("
    651 				   (file-name-nondirectory (nth 1 x)) ")")
    652 			   (cdr x))
    653 		   (cons (concat (car x) extra) (cdr x))))
    654 	       org-refile-target-table))
    655 	 (completion-ignore-case t)
    656 	 cdef
    657          (prompt (let ((default (or (car org-refile-history)
    658                                     (and (assoc cbnex tbl) (setq cdef cbnex)
    659                                          cbnex))))
    660                    (org-format-prompt prompt default)))
    661 	 pa answ parent-target child parent old-hist)
    662     (setq old-hist org-refile-history)
    663     (setq answ (funcall cfunc prompt tbl nil (not new-nodes)
    664 			nil 'org-refile-history
    665 			(or cdef (car org-refile-history))))
    666     (if (setq pa (org-refile--get-location answ tbl))
    667 	(let ((last-refile-loc (car org-refile-history)))
    668 	  (org-refile-check-position pa)
    669 	  (when (or (not org-refile-history)
    670 		    (not (eq old-hist org-refile-history))
    671 		    (not (equal (car pa) last-refile-loc)))
    672 	    (setq org-refile-history
    673 		  (cons (car pa) (if (assoc last-refile-loc tbl)
    674 				     org-refile-history
    675 				   (cdr org-refile-history))))
    676 	    (when (equal last-refile-loc (nth 1 org-refile-history))
    677 	      (pop org-refile-history)))
    678 	  pa)
    679       (if (string-match "\\`\\(.*\\)/\\([^/]+\\)\\'" answ)
    680 	  (progn
    681 	    (setq parent (match-string 1 answ)
    682 		  child (match-string 2 answ))
    683 	    (setq parent-target (org-refile--get-location parent tbl))
    684 	    (when (and parent-target
    685 		       (or (eq new-nodes t)
    686 			   (and (eq new-nodes 'confirm)
    687 				(y-or-n-p (format "Create new node \"%s\"? "
    688 						  child)))))
    689 	      (org-refile-new-child parent-target child)))
    690 	(user-error "Invalid target location")))))
    691 
    692 (defun org-refile-check-position (refile-pointer)
    693   "Check if the refile pointer matches the headline to which it points."
    694   (let* ((file (nth 1 refile-pointer))
    695 	 (re (nth 2 refile-pointer))
    696 	 (pos (nth 3 refile-pointer))
    697 	 buffer)
    698     (if (and (not (markerp pos)) (not file))
    699 	(user-error "Please indicate a target file in the refile path")
    700       (when (org-string-nw-p re)
    701 	(setq buffer (if (markerp pos)
    702 			 (marker-buffer pos)
    703 		       (or (find-buffer-visiting file)
    704 			   (find-file-noselect file))))
    705 	(with-current-buffer buffer
    706 	  (org-with-wide-buffer
    707 	   (goto-char pos)
    708 	   (beginning-of-line 1)
    709 	   (unless (looking-at-p re)
    710 	     (user-error "Invalid refile position, please clear the cache with `C-0 C-c C-w' before refiling"))))))))
    711 
    712 (defun org-refile-new-child (parent-target child)
    713   "Use refile target PARENT-TARGET to add new CHILD below it."
    714   (unless parent-target
    715     (error "Cannot find parent for new node"))
    716   (let ((file (nth 1 parent-target))
    717 	(pos (nth 3 parent-target))
    718 	level)
    719     (with-current-buffer (or (find-buffer-visiting file)
    720 			     (find-file-noselect file))
    721       (org-with-wide-buffer
    722        (if pos
    723 	   (goto-char pos)
    724 	 (goto-char (point-max))
    725 	 (unless (bolp) (newline)))
    726        (when (looking-at org-outline-regexp)
    727 	 (setq level (funcall outline-level))
    728 	 (org-end-of-subtree t t))
    729        (org-back-over-empty-lines)
    730        (insert "\n" (make-string
    731 		     (if pos (org-get-valid-level level 1) 1) ?*)
    732 	       " " child "\n")
    733        (beginning-of-line 0)
    734        (list (concat (car parent-target) "/" child) file "" (point))))))
    735 
    736 (defun org-olpath-completing-read (prompt collection &rest args)
    737   "Read an outline path like a file name."
    738   (let ((thetable collection))
    739     (apply #'completing-read
    740 	   prompt
    741 	   (lambda (string predicate &optional flag)
    742 	     (cond
    743 	      ((eq flag nil) (try-completion string thetable))
    744 	      ((eq flag t)
    745 	       (let ((l (length string)))
    746 		 (mapcar (lambda (x)
    747 			   (let ((r (substring x l))
    748 				 (f (if (string-match " ([^)]*)$" x)
    749 					(match-string 0 x)
    750 				      "")))
    751 			     (if (string-match "/" r)
    752 				 (concat string (substring r 0 (match-end 0)) f)
    753 			       x)))
    754 			 (all-completions string thetable predicate))))
    755 	      ;; Exact match?
    756 	      ((eq flag 'lambda) (assoc string thetable))))
    757 	   args)))
    758 
    759 (provide 'org-refile)
    760 
    761 ;; Local variables:
    762 ;; generated-autoload-file: "org-loaddefs.el"
    763 ;; End:
    764 
    765 ;;; org-refile.el ends here