I have two org subtrees that look like this:
* Subtree A [2016-03-31 Thu 07:11]
This is subtree A.
* Subtree B [2016-03-31 Thu 07:12]
This is subtree B.
If I run M-x org-cut-subtree
with my cursor at the beginning of Subtree A and then immediately run it again (at the beginning of Subtree B), what I end up with is a single kill-ring entry that looks like this:
* Subtree A [2016-03-31 Thu 07:11]
This is subtree A.
* Subtree B [2016-03-31 Thu 07:12]
This is subtree B.
I want only the subtree I'm cutting to end up in each kill ring; I don't want subsequent cuts to be appended.
I've spent a good amount of time trying to figure this out (I'm relatively new to Emacs) and I believe the reason for this appending behavior is the following:
two or more kill commands in a row combine their text into a single entry, so that a single C-y yanks all the text as a unit, just as it was before it was killed. https://www.gnu.org/software/emacs/manual/html_node/emacs/Appending-Kills.html
What I want is to only push the currently cut subtree onto the ring, not append.
I'm using org-cut-subtree
in a function that I run repeatedly while reviewing my refile.org
. I run the function to refile each subtree once I've reviewed it, however this appending to existing kill ring behavior is causing duplicate entries to be refiled whenever I run the command more than once (the second call ends up refiling a copy of both the previous and the current subtree).
How can I prevent this from happening? I noticed if I run M-SPC
to set a new mark before calling org-cut-subtree
again, the issue seems to get resolved, but I haven't been able to figure out how to do that from within my function.
For a little context, here's the function where I'm using org-cut-subtree
(to refile journal entries from refile.org
into my main journal file):
(defun my/org-refile-to-journal ()
"Refile an entry to journal file's date-tree"
(interactive)
(require 'org-datetree)
(let ((journal (expand-file-name "journal-2016.org" org-directory))
post-date)
(setq post-date (or (org-entry-get (point) "TIMESTAMP_IA")
(org-entry-get (point) "TIMESTAMP")))
(setq post-date (nthcdr 3 (parse-time-string post-date)))
(setq post-date (list (cadr post-date)
(car post-date)
(caddr post-date)))
(org-cut-subtree)
(with-current-buffer (or (find-buffer-visiting journal)
(find-file-noselect journal))
(save-excursion
(org-datetree-file-entry-under (current-kill 0) post-date)
(bookmark-set "org-refile-last-stored")))
(message "Refiled to %s" journal)))
Answer
As @lawlist explained in a comment to his answer below, adding (setq this-command 'my/org-refile-to-journal)
to the end of my function does exactly what I wanted.
A review of the source for kill-region
(which org-cut-subtree
uses to cut) reveals that kill-region
will only append to an existing ring if this-command
is set to a kill-related function (i.e., if the previous command was a kill-related function).
Since 'my/org-refile-to-journal
is not a kill-related function, setting this-command
to that function effectively temporarily disables the append-to-kill-ring behavior when running my function multiple times in a row.
For reference, here's my updated function that is working as expected:
(defun my/org-refile-to-journal ()
"Refile an entry to journal file's date-tree"
(interactive)
(require 'org-datetree)
(let ((journal (expand-file-name "journal-2016.org" org-directory))
post-date)
(setq post-date (or (org-entry-get (point) "TIMESTAMP_IA")
(org-entry-get (point) "TIMESTAMP")))
(setq post-date (nthcdr 3 (parse-time-string post-date)))
(setq post-date (list (cadr post-date)
(car post-date)
(caddr post-date)))
(org-cut-subtree)
(with-current-buffer (or (find-buffer-visiting journal)
(find-file-noselect journal))
(save-excursion
(org-datetree-file-entry-under (current-kill 0) post-date)
(bookmark-set "org-refile-last-stored")))
(message "Refiled to %s" journal))
(setq this-command 'my/org-refile-to-journal))