Yank adjusted trees.
When yanking a cut/copied subtree or a series of trees, even the nomal yank key `C-y' does now adjust the level of the tree to make it fit into the current outline position, without loosing its identity, and without swallowing other subtrees. This uses the command `org-past-subtree'. An additional change in that command has been implemented: Normally, this command picks the right outline level from the surrounding *visible* headlines, and uses the smaller on. So it the cursor is between a level 4 and a level 3 headline, the tree will be pasted as level 3. Now, if the cursor is actually *at* the beginning of a headline, the level of that headline will be used. So lets say you have a tree like this: * Level one ** Level two (1) (2)* Level one again with (1) and (2) indicating possible cursor positions for the insertion. When at (1), the tree will be pasted as level 2. When at (2), it will be pasted as level 1. If you do not like `C-y' to behave like this, configure the variable `org-yank-adjusted-subtrees'. Thanks to Samuel Wales for this idea and a partial implementation.
This commit is contained in:
commit
07657f3e80
|
@ -45,6 +45,37 @@
|
||||||
|
|
||||||
Thanks to James JD Smith for a patch to this effect.
|
Thanks to James JD Smith for a patch to this effect.
|
||||||
|
|
||||||
|
*** Yanking subtree with =C-y= now adjusts the tree level
|
||||||
|
When yanking a cut/copied subtree or a series of trees, even
|
||||||
|
the nomal yank key =C-y= does now adjust the level of the tree
|
||||||
|
to make it fit into the current outline position, without
|
||||||
|
loosing its identity, and without swallowing other subtrees.
|
||||||
|
|
||||||
|
This uses the command =org-past-subtree=. An additional
|
||||||
|
change in that command has been implemented: Normally, this
|
||||||
|
command picks the right outline level from the surrounding
|
||||||
|
*visible* headlines, and uses the smaller on. So it the
|
||||||
|
cursor is between a level 4 and a level 3 headline, the tree
|
||||||
|
will be pasted as level 3. Now, if the cursor is actually
|
||||||
|
*at* the beginning of a headline, the level of that headline
|
||||||
|
will be used. So lets say you have a tree like this:
|
||||||
|
|
||||||
|
#+begin_src org
|
||||||
|
,* Level one
|
||||||
|
,** Level two
|
||||||
|
,(1)
|
||||||
|
,(2)* Level one again
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
with (1) and (2) indicating possible cursor positions for the
|
||||||
|
insertion. When at (1), the tree will be pasted as level 2.
|
||||||
|
When at (2), it will be pasted as level 1.
|
||||||
|
|
||||||
|
If you do not like =C-y= to behave like this, configure the
|
||||||
|
variable =org-yank-adjusted-subtrees=.
|
||||||
|
|
||||||
|
Thanks to Samuel Wales for this idea and a partial implementation.
|
||||||
|
|
||||||
* Version 6.10
|
* Version 6.10
|
||||||
|
|
||||||
** Overview
|
** Overview
|
||||||
|
|
|
@ -944,6 +944,12 @@ Yank subtree from kill ring. This does modify the level of the subtree to
|
||||||
make sure the tree fits in nicely at the yank position. The yank level can
|
make sure the tree fits in nicely at the yank position. The yank level can
|
||||||
also be specified with a numeric prefix argument, or by yanking after a
|
also be specified with a numeric prefix argument, or by yanking after a
|
||||||
headline marker like @samp{****}.
|
headline marker like @samp{****}.
|
||||||
|
@kindex C-y
|
||||||
|
@item C-y
|
||||||
|
Depending on the variables @code{org-yank-adjusted-subtrees} and
|
||||||
|
@code{org-yank-folded-subtrees}, Org's internal @code{yank} command will
|
||||||
|
paste subtrees folded and in a clever way, using the same command as @kbd{C-c
|
||||||
|
C-x C-y}.
|
||||||
@kindex C-c C-w
|
@kindex C-c C-w
|
||||||
@item C-c C-w
|
@item C-c C-w
|
||||||
Refile entry to a different location. @xref{Refiling notes}.
|
Refile entry to a different location. @xref{Refiling notes}.
|
||||||
|
|
|
@ -316,7 +316,7 @@ are preserved on all copies.
|
||||||
\key{refile subtree}{C-c C-w}
|
\key{refile subtree}{C-c C-w}
|
||||||
\key{kill subtree}{C-c C-x C-w}
|
\key{kill subtree}{C-c C-x C-w}
|
||||||
\key{copy subtree}{C-c C-x M-w}
|
\key{copy subtree}{C-c C-x M-w}
|
||||||
\key{yank subtree}{C-c C-x C-y}
|
\metax{yank subtree}{C-c C-x C-y or C-y}
|
||||||
\key{narrow buffer to current subtree}{C-x n s}
|
\key{narrow buffer to current subtree}{C-x n s}
|
||||||
\key{widen restriction to full buffer}{C-x n w}
|
\key{widen restriction to full buffer}{C-x n w}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,17 @@
|
||||||
|
|
||||||
2008-10-27 Carsten Dominik <dominik@science.uva.nl>
|
2008-10-27 Carsten Dominik <dominik@science.uva.nl>
|
||||||
|
|
||||||
* org.el ("saveplace"): If saveplace puts point into an invisible
|
* org.el ("saveplace"): If saveplace puts point into an invisible
|
||||||
location, make it visible.
|
location, make it visible.
|
||||||
(org-make-tags-matcher): Allow inactive time stamps in time
|
(org-make-tags-matcher): Allow inactive time stamps in time
|
||||||
comparisons.
|
comparisons.
|
||||||
|
(org-yank-adjusted-subtrees): New option.
|
||||||
|
(org-yank): Incorporate adjusting trees.
|
||||||
|
(org-paste-subtree): New argument FOR-YANK which will cause
|
||||||
|
insertion at point without backing up over white lines, and leave
|
||||||
|
point at the end of the inserted text. Also if the cursor is
|
||||||
|
at the beginning of a headline, use the same level or the inserted
|
||||||
|
tree.
|
||||||
|
|
||||||
* org-publish.el (org-publish-get-base-files-1): Deal correctly
|
* org-publish.el (org-publish-get-base-files-1): Deal correctly
|
||||||
with broken symlinks
|
with broken symlinks
|
||||||
|
|
74
lisp/org.el
74
lisp/org.el
|
@ -641,6 +641,13 @@ or siblings, then fold all the subtrees."
|
||||||
:group 'org-edit-structure
|
:group 'org-edit-structure
|
||||||
:type 'boolean)
|
:type 'boolean)
|
||||||
|
|
||||||
|
(defcustom org-yank-adjusted-subtrees t
|
||||||
|
"Non-nil means, when yanking subtrees, adjust the level.
|
||||||
|
With this setting, `org-paste-subtree' is used to insert the subtree, see
|
||||||
|
this function for details."
|
||||||
|
:group 'org-edit-structure
|
||||||
|
:type 'boolean)
|
||||||
|
|
||||||
(defcustom org-M-RET-may-split-line '((default . t))
|
(defcustom org-M-RET-may-split-line '((default . t))
|
||||||
"Non-nil means, M-RET will split the line at the cursor position.
|
"Non-nil means, M-RET will split the line at the cursor position.
|
||||||
When nil, it will go to the end of the line before making a
|
When nil, it will go to the end of the line before making a
|
||||||
|
@ -5047,10 +5054,15 @@ useful if the caller implements cut-and-paste as copy-then-paste-then-cut."
|
||||||
(if cut "Cut" "Copied")
|
(if cut "Cut" "Copied")
|
||||||
(length org-subtree-clip)))))
|
(length org-subtree-clip)))))
|
||||||
|
|
||||||
(defun org-paste-subtree (&optional level tree)
|
(defun org-paste-subtree (&optional level tree for-yank)
|
||||||
"Paste the clipboard as a subtree, with modification of headline level.
|
"Paste the clipboard as a subtree, with modification of headline level.
|
||||||
The entire subtree is promoted or demoted in order to match a new headline
|
The entire subtree is promoted or demoted in order to match a new headline
|
||||||
level. By default, the new level is derived from the visible headings
|
level.
|
||||||
|
|
||||||
|
If the cursor is at the beginning of a headline, the same level as
|
||||||
|
that headline is used to paste the tree
|
||||||
|
|
||||||
|
If not, the new level is derived from the *visible* headings
|
||||||
before and after the insertion point, and taken to be the inferior headline
|
before and after the insertion point, and taken to be the inferior headline
|
||||||
level of the two. So if the previous visible heading is level 3 and the
|
level of the two. So if the previous visible heading is level 3 and the
|
||||||
next is level 4 (or vice versa), level 4 will be used for insertion.
|
next is level 4 (or vice versa), level 4 will be used for insertion.
|
||||||
|
@ -5061,9 +5073,11 @@ You can also force a different level, either by using a numeric prefix
|
||||||
argument, or by inserting the heading marker by hand. For example, if the
|
argument, or by inserting the heading marker by hand. For example, if the
|
||||||
cursor is after \"*****\", then the tree will be shifted to level 5.
|
cursor is after \"*****\", then the tree will be shifted to level 5.
|
||||||
|
|
||||||
If you want to insert the tree as is, just use \\[yank].
|
If optional TREE is given, use this text instead of the kill ring.
|
||||||
|
|
||||||
If optional TREE is given, use this text instead of the kill ring."
|
When FOR-YANK is set, this is called by `org-yank'. In this case, do not
|
||||||
|
move back over whitespace before inserting, and move point to the end of
|
||||||
|
the inserted text when done."
|
||||||
(interactive "P")
|
(interactive "P")
|
||||||
(unless (org-kill-is-subtree-p tree)
|
(unless (org-kill-is-subtree-p tree)
|
||||||
(error "%s"
|
(error "%s"
|
||||||
|
@ -5079,9 +5093,14 @@ If optional TREE is given, use this text instead of the kill ring."
|
||||||
(- (match-end 0) (match-beginning 0) 1)
|
(- (match-end 0) (match-beginning 0) 1)
|
||||||
-1))
|
-1))
|
||||||
(force-level (cond (level (prefix-numeric-value level))
|
(force-level (cond (level (prefix-numeric-value level))
|
||||||
((string-match
|
((and (looking-at "[ \t]*$")
|
||||||
^re_ (buffer-substring (point-at-bol) (point)))
|
(string-match
|
||||||
|
^re_ (buffer-substring
|
||||||
|
(point-at-bol) (point))))
|
||||||
(- (match-end 1) (match-beginning 1)))
|
(- (match-end 1) (match-beginning 1)))
|
||||||
|
((and (bolp)
|
||||||
|
(looking-at org-outline-regexp))
|
||||||
|
(- (match-end 0) (point) 1))
|
||||||
(t nil)))
|
(t nil)))
|
||||||
(previous-level (save-excursion
|
(previous-level (save-excursion
|
||||||
(condition-case nil
|
(condition-case nil
|
||||||
|
@ -5109,16 +5128,17 @@ If optional TREE is given, use this text instead of the kill ring."
|
||||||
(delta (if (> shift 0) -1 1))
|
(delta (if (> shift 0) -1 1))
|
||||||
(func (if (> shift 0) 'org-demote 'org-promote))
|
(func (if (> shift 0) 'org-demote 'org-promote))
|
||||||
(org-odd-levels-only nil)
|
(org-odd-levels-only nil)
|
||||||
beg end)
|
beg end newend)
|
||||||
;; Remove the forced level indicator
|
;; Remove the forced level indicator
|
||||||
(if force-level
|
(if force-level
|
||||||
(delete-region (point-at-bol) (point)))
|
(delete-region (point-at-bol) (point)))
|
||||||
;; Paste
|
;; Paste
|
||||||
(beginning-of-line 1)
|
(beginning-of-line 1)
|
||||||
(org-back-over-empty-lines)
|
(unless for-yank (org-back-over-empty-lines))
|
||||||
(setq beg (point))
|
(setq beg (point))
|
||||||
(insert-before-markers txt)
|
(insert-before-markers txt)
|
||||||
(unless (string-match "\n\\'" txt) (insert "\n"))
|
(unless (string-match "\n\\'" txt) (insert "\n"))
|
||||||
|
(setq newend (point))
|
||||||
(org-reinstall-markers-in-region beg)
|
(org-reinstall-markers-in-region beg)
|
||||||
(setq end (point))
|
(setq end (point))
|
||||||
(goto-char beg)
|
(goto-char beg)
|
||||||
|
@ -5133,14 +5153,17 @@ If optional TREE is given, use this text instead of the kill ring."
|
||||||
(while (not (= shift 0))
|
(while (not (= shift 0))
|
||||||
(org-map-region func (point-min) (point-max))
|
(org-map-region func (point-min) (point-max))
|
||||||
(setq shift (+ delta shift)))
|
(setq shift (+ delta shift)))
|
||||||
(goto-char (point-min))))
|
(goto-char (point-min))
|
||||||
(when (interactive-p)
|
(setq newend (point-max))))
|
||||||
|
(when (or (interactive-p) for-yank)
|
||||||
(message "Clipboard pasted as level %d subtree" new-level))
|
(message "Clipboard pasted as level %d subtree" new-level))
|
||||||
(if (and kill-ring
|
(if (and (not for-yank) ; in this case, org-yank will decide about folding
|
||||||
|
kill-ring
|
||||||
(eq org-subtree-clip (current-kill 0))
|
(eq org-subtree-clip (current-kill 0))
|
||||||
org-subtree-clip-folded)
|
org-subtree-clip-folded)
|
||||||
;; The tree was folded before it was killed/copied
|
;; The tree was folded before it was killed/copied
|
||||||
(hide-subtree))))
|
(hide-subtree))
|
||||||
|
(and for-yank (goto-char newend))))
|
||||||
|
|
||||||
(defun org-kill-is-subtree-p (&optional txt)
|
(defun org-kill-is-subtree-p (&optional txt)
|
||||||
"Check if the current kill is an outline subtree, or a set of trees.
|
"Check if the current kill is an outline subtree, or a set of trees.
|
||||||
|
@ -13872,18 +13895,33 @@ beyond the end of the headline."
|
||||||
(org-set-tags nil t))
|
(org-set-tags nil t))
|
||||||
(t (kill-region (point) (point-at-eol)))))
|
(t (kill-region (point) (point-at-eol)))))
|
||||||
|
|
||||||
|
|
||||||
(define-key org-mode-map "\C-k" 'org-kill-line)
|
(define-key org-mode-map "\C-k" 'org-kill-line)
|
||||||
|
|
||||||
(defun org-yank ()
|
(defun org-yank ()
|
||||||
"Yank, and if the yanked text is a single subtree, fold it.
|
"Yank. If the kill is a subtree, treat it specially.
|
||||||
In fact, if the yanked text is a sequence of subtrees, fold all of them."
|
This command will look at the current kill and check it is a single
|
||||||
|
subtree, or a series of subtrees[1]. If it passes the test, it is
|
||||||
|
treated specially, depending on the value of the following variables, both
|
||||||
|
set by default.
|
||||||
|
|
||||||
|
org-yank-folded-subtrees
|
||||||
|
When set, the subree(s) wiil be folded after insertion.
|
||||||
|
|
||||||
|
org-yank-adjusted-subtrees
|
||||||
|
When set, the subtree will be promoted or demoted in order to
|
||||||
|
fit into the local outline tree structure.
|
||||||
|
|
||||||
|
|
||||||
|
\[1] Basically, the test checks if the first non-white line is a heading
|
||||||
|
and if there are no other headings with fewer stars."
|
||||||
(interactive)
|
(interactive)
|
||||||
(if org-yank-folded-subtrees
|
(if org-yank-folded-subtrees
|
||||||
(let ((beg (point))
|
(let ((beg (point))
|
||||||
(subtreep (org-kill-is-subtree-p))
|
(subtreep (org-kill-is-subtree-p))
|
||||||
end)
|
end)
|
||||||
(call-interactively 'yank)
|
(if (and subtreep org-yank-adjusted-subtrees)
|
||||||
|
(org-paste-subtree nil nil 'for-yank)
|
||||||
|
(call-interactively 'yank))
|
||||||
(setq end (point))
|
(setq end (point))
|
||||||
(goto-char beg)
|
(goto-char beg)
|
||||||
(when (and (bolp) subtreep)
|
(when (and (bolp) subtreep)
|
||||||
|
@ -13897,7 +13935,9 @@ In fact, if the yanked text is a sequence of subtrees, fold all of them."
|
||||||
(error (goto-char end)))))
|
(error (goto-char end)))))
|
||||||
(goto-char end)
|
(goto-char end)
|
||||||
(skip-chars-forward " \t\n\r"))
|
(skip-chars-forward " \t\n\r"))
|
||||||
(call-interactively 'yank)))
|
(if (and subtreep org-yank-adjusted-subtrees)
|
||||||
|
(org-paste-subtree nil nil 'for-yank)
|
||||||
|
(call-interactively 'yank))))
|
||||||
|
|
||||||
(define-key org-mode-map "\C-y" 'org-yank)
|
(define-key org-mode-map "\C-y" 'org-yank)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue