如何在 org-mode emacs 中将一个子树移动到另一个子树

发布于 2024-12-05 20:56:23 字数 233 浏览 0 评论 0原文

我想执行一项简单的任务,但似乎没有明确的解决方案:

我有这样的子树结构:

* Tree A
** Subtree A1
** Subtree A2
* Tree B
** Subtree B1
** Subtree B2

我想设置一个快捷键将子树从树 A 移动到树 B。归档似乎很容易,但是您知道如何在一个文件中执行此操作吗?

任何帮助表示赞赏!谢谢!

I'd like to perform one simple task but there seems to be no clear solution for it:

I have a structure of subtrees like this:

* Tree A
** Subtree A1
** Subtree A2
* Tree B
** Subtree B1
** Subtree B2

I'd like to set up one key shortcut to move subtrees from Tree A to Tree B. Moving to the archive seems to be easy, but do you have any clue how to do it within one file?

Any help appreciated! Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

眼眸印温柔 2024-12-12 20:56:23

您可以尝试使用 Cc Cw 重新填充子树(它也可以将子树移动到另一个文件)。

另一种方法是折叠子树,然后用 Ck Ck 杀死它并将其粘贴到应该的位置。

我使用的第三个解决方案是使用 M-left 更改子树的级别,然后使用 M-upM-down< 移动它/kbd>,然后M-right再次将其放在正确的水平上。第三种方法的缺点是有时它会使树的其他部分移动。

You could try to refill the subtree with C-c C-w (it work also to move the subtree to another file).

Another way is to fold the subtree, then to kill it with C-k C-k and to paste it where it should be.

The third solution I use some time is to change the level of the subtree with M-left, then to move it with M-up and M-down, then M-right put it again on the correct level. This third way have the shortcoming that some time it make other part of the tree to move.

若水般的淡然安静女子 2024-12-12 20:56:23

您可以使用Cc Cw重新归档子树,具体取决于您重新归档的设置方式。根据目的地的深度,您可能无法将其用作有效目的地。

您可以使用终止/复制子树命令来终止或复制子树,而无需折叠结构:分别是Cc Cx CwCc Cx Mw,拉动子树可以是< kbd>Cc Cx Cy 或简单地 Cy

You can refile the subtree using C-c C-w, depending on how you have refile set up. Depending on the depth of your destination you may not be able to use it as a valid destination.

You can kill or copy a subtree without having to fold the structure using the kill/copy subtree commands: C-c C-x C-w and C-c C-x M-w respectively, yanking a subtree is either C-c C-x C-y or simply C-y

屋顶上的小猫咪 2024-12-12 20:56:23

我还想要一种让 org-refile 轻松重新文件到子树的方法,因此我编写了一些代码并将其概括,以便它可以在任何地方设置任意直接目标(而不仅仅是在同一个文件中)。

基本用法是移动到Tree B中的某处并输入Cc Cx Cm来标记要重新归档的目标,然后移动到Tree A中的条目并输入Cc Cw,这将立即重新归档到您在Tree B中设置的目标位置,而不会提示您,除非您调用org-refile-immediate-target 带有前缀 arg Cu Cc Cx Cm

请注意,如果您快速连续按Cc Cw重新提交多个条目,即使org-reverse-note-order设置为,它也会保留条目的顺序>t,但您可以将其关闭以遵循带有双前缀 arg Cu Cu Cc Cx Cmorg-reverse-note-order 设置。

(defvar org-refile-immediate nil
  "Refile immediately using `org-refile-immediate-target' instead of prompting.")
(make-local-variable 'org-refile-immediate)

(defvar org-refile-immediate-preserve-order t
  "If last command was also `org-refile' then preserve ordering.")
(make-local-variable 'org-refile-immediate-preserve-order)

(defvar org-refile-immediate-target nil)
"Value uses the same format as an item in `org-refile-targets'."
(make-local-variable 'org-refile-immediate-target)

(defadvice org-refile (around org-immediate activate)
  (if (not org-refile-immediate)
      ad-do-it
    ;; if last command was `org-refile' then preserve ordering
    (let ((org-reverse-note-order
           (if (and org-refile-immediate-preserve-order
                    (eq last-command 'org-refile)) nil org-reverse-note-order)))
      (ad-set-arg 2 (assoc org-refile-immediate-target (org-refile-get-targets)))
      (prog1 ad-do-it
        (setq this-command 'org-refile)))))

(defadvice org-refile-cache-clear (after org-refile-history-clear activate)
  (setq org-refile-targets (default-value 'org-refile-targets))
  (setq org-refile-immediate nil)
  (setq org-refile-immediate-target nil)
  (setq org-refile-history nil))

;;;###autoload
(defun org-refile-immediate-target (&optional arg)
  "Set current entry as `org-refile' target.
Non-nil turns off `org-refile-immediate', otherwise `org-refile'
will immediately refile without prompting for target using most
recent entry in `org-refile-targets' that matches
`org-refile-immediate-target' as the default."
  (interactive "P")
  (if (equal arg '(16))
      (progn
        (setq org-refile-immediate-preserve-order
              (not org-refile-immediate-preserve-order))
        (message "Order preserving is turned: %s"
                 (if org-refile-immediate-preserve-order
                     "on" "off")))

    (setq org-refile-immediate (unless arg t))
    (make-local-variable 'org-refile-targets)
    (let* ((components (org-heading-components))
           (level (first components))
           (heading (nth 4 components))
           (string (substring-no-properties heading)))
      (add-to-list 'org-refile-targets
                   (append (list (buffer-file-name))
                           (cons :regexp
                                 (format "^%s %s$"
                                         (make-string level ?*)
                                         string))))
      (setq org-refile-immediate-target heading))))

(define-key org-mode-map "\C-c\C-x\C-m" 'org-refile-immediate-target)

很难找到 Cc Cx 前缀上免费的密钥,因此我使用了 m 和助记符 i*mm*ediate

I also wanted a way for org-refile to refile easily to a subtree, so I wrote some code and generalized it so that it will set an arbitrary immediate target anywhere (not just in the same file).

Basic usage is to move somewhere in Tree B and type C-c C-x C-m to mark the target for refiling, then move to the entry in Tree A that you want to refile and type C-c C-w which will immediately refile into the target location you set in Tree B without prompting you, unless you called org-refile-immediate-target with a prefix arg C-u C-c C-x C-m.

Note that if you press C-c C-w in rapid succession to refile multiple entries it will preserve the order of your entries even if org-reverse-note-order is set to t, but you can turn it off to respect the setting of org-reverse-note-order with a double prefix arg C-u C-u C-c C-x C-m.

(defvar org-refile-immediate nil
  "Refile immediately using `org-refile-immediate-target' instead of prompting.")
(make-local-variable 'org-refile-immediate)

(defvar org-refile-immediate-preserve-order t
  "If last command was also `org-refile' then preserve ordering.")
(make-local-variable 'org-refile-immediate-preserve-order)

(defvar org-refile-immediate-target nil)
"Value uses the same format as an item in `org-refile-targets'."
(make-local-variable 'org-refile-immediate-target)

(defadvice org-refile (around org-immediate activate)
  (if (not org-refile-immediate)
      ad-do-it
    ;; if last command was `org-refile' then preserve ordering
    (let ((org-reverse-note-order
           (if (and org-refile-immediate-preserve-order
                    (eq last-command 'org-refile)) nil org-reverse-note-order)))
      (ad-set-arg 2 (assoc org-refile-immediate-target (org-refile-get-targets)))
      (prog1 ad-do-it
        (setq this-command 'org-refile)))))

(defadvice org-refile-cache-clear (after org-refile-history-clear activate)
  (setq org-refile-targets (default-value 'org-refile-targets))
  (setq org-refile-immediate nil)
  (setq org-refile-immediate-target nil)
  (setq org-refile-history nil))

;;;###autoload
(defun org-refile-immediate-target (&optional arg)
  "Set current entry as `org-refile' target.
Non-nil turns off `org-refile-immediate', otherwise `org-refile'
will immediately refile without prompting for target using most
recent entry in `org-refile-targets' that matches
`org-refile-immediate-target' as the default."
  (interactive "P")
  (if (equal arg '(16))
      (progn
        (setq org-refile-immediate-preserve-order
              (not org-refile-immediate-preserve-order))
        (message "Order preserving is turned: %s"
                 (if org-refile-immediate-preserve-order
                     "on" "off")))

    (setq org-refile-immediate (unless arg t))
    (make-local-variable 'org-refile-targets)
    (let* ((components (org-heading-components))
           (level (first components))
           (heading (nth 4 components))
           (string (substring-no-properties heading)))
      (add-to-list 'org-refile-targets
                   (append (list (buffer-file-name))
                           (cons :regexp
                                 (format "^%s %s$"
                                         (make-string level ?*)
                                         string))))
      (setq org-refile-immediate-target heading))))

(define-key org-mode-map "\C-c\C-x\C-m" 'org-refile-immediate-target)

It was hard to find a key that was free on the C-c C-x prefix, so I used m with the mnemonic i*mm*ediate

女中豪杰 2024-12-12 20:56:23

如果文件结构不太复杂,我会使用 M-leftM-up/down,然后使用 M-right。但请记住,如果您尝试使用此方法将子树 A1 移动到树 B,您将丢失其子子树 A1.1,除非您使用 MS-left/right 移动它:

* Tree A
** Subtree A1             <=== move this heading with M-S-left
*** Subsubtree A1.1       <=== or you will leave this heading behind
** Subtree A2

* Tree B
** Subtree B1
** Subtree B2

I use M-left, M-up/down and then M-right if the structure of the file is not too complex. But keep in mind that if you try to move Subtree A1 to Tree B using this method, you will lose its child Subsubtree A1.1, unless you move it with M-S-left/right:

* Tree A
** Subtree A1             <=== move this heading with M-S-left
*** Subsubtree A1.1       <=== or you will leave this heading behind
** Subtree A2

* Tree B
** Subtree B1
** Subtree B2
作妖 2024-12-12 20:56:23

可以使用 org-refile 来移动同一缓冲区内的子树。移动时,您甚至可以更改原始的层次结构(星星的数量)。但是,它可能无法开箱即用,主要是因为您正在使用的缓冲区不在 org-refile-targets 中。您可以使用 C-[ 将文件添加到重新文件目标中,然后使用 Cc Cw 运行 org-refile,最后从重归档目标为 C-]。这可能太多了(如果您的 maxlevel 设置太低,则可能会失败 - 您无论如何都可以更改)。或者,要一次性自动执行此过程,您首先必须定义一个如下所示的函数:

(defun refile-in-current ()
"refile current item in current buffer"
(interactive)
(let ((org-refile-use-outline-path t)
    (org-refile-targets '((nil . (:maxlevel . 5)))))
(org-refile)))

其中的 nil 表示“当前缓冲区”。 let 仅在本地重新定义变量。然后,您必须添加快捷方式来运行该功能。以下是将其绑定到 Cc m 的一种方法:

(add-hook 'org-mode-hook (lambda ()
        (local-set-key "\C-c m" 'refile-in-current)

Moving a subtree within the same buffer can be done with org-refile. While moving, you can even change hierarchy of the original (number of stars). However, it might not work out of the box primarily because the buffer you are working with is not in the org-refile-targets. You could add the file in the refile targets by using C-[, then run org-refile with C-c C-w and finally remove the file from the refile targets with C-]. This might be too much (and might fail if your maxlevel setting is too low - which you can change anyway). Alternatively, to automate this procedure in one swoop, you will first have to define a function like this:

(defun refile-in-current ()
"refile current item in current buffer"
(interactive)
(let ((org-refile-use-outline-path t)
    (org-refile-targets '((nil . (:maxlevel . 5)))))
(org-refile)))

The nil in there means "current buffer". The let redefines your variables locally only. You will then have to add a shortcut to run the function. Here is one way to bind it to C-c m:

(add-hook 'org-mode-hook (lambda ()
        (local-set-key "\C-c m" 'refile-in-current)
风月客 2024-12-12 20:56:23
(require 'org-archive)                                                                               
(setq org-archive-save-context-info nil)                                                             
(setq org-archive-location "::* Archived Tasks")

在要移动的子树上运行(org-archive-subtree),它将被移动到“* Archived Tasks”标题中

(require 'org-archive)                                                                               
(setq org-archive-save-context-info nil)                                                             
(setq org-archive-location "::* Archived Tasks")

run (org-archive-subtree) at subtree which you want to move, it will be moved into "* Archived Tasks" heading

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文