Как переместить поддерево в другое поддерево в org-mode emacs
Я хотел бы выполнить одну простую задачу, но, похоже, для нее нет четкого решения:
У меня есть структура таких поддеревьев:
* Tree A
** Subtree A1
** Subtree A2
* Tree B
** Subtree B1
** Subtree B2
Я хотел бы создать один ключевой ярлык для перемещения поддеревьев из дерева A в дерево B. Перемещение в архив кажется простым, но знаете ли вы, как это сделать в одном файле?
Любая помощь ценится! Спасибо!
Ответы
Ответ 1
Вы можете попробовать пополнить поддерево с помощью C-c C-w (он также работает, чтобы переместить поддерево в другой файл).
Другой способ - свернуть поддерево, а затем убить его с помощью C-k C-k и вставить его там, где он должен быть.
Третье решение, которое я использую некоторое время, это изменить уровень поддерева с помощью M-left, затем переместить его с помощью M-up и M-down, затем M-right снова направить его на правильный уровень. Этот третий путь имеет недостаток, что некоторое время он заставляет другую часть дерева двигаться.
Ответ 2
Я также хотел, чтобы org-refile
легко поддавался поддерево, поэтому я написал некоторый код и обобщил его так, чтобы он установил произвольную ближайшую цель в любом месте (не только в том же файле).
Основное использование - это перемещение где-то в Tree B
и введите C-c C-x C-m, чтобы пометить цель для перепрофилирования, затем перейдите к записи в Tree A
, которую вы хотите перефилировать, и введите C-c C-w, который будет немедленно повторно вставлен в целевое местоположение, установленное в Tree B
, без запроса, если вы не вызвали org-refile-immediate-target
с префиксом arg C-u C-c C-x C-m.
Обратите внимание, что если вы нажмете C-c C-w в быстрой последовательности для повторного набора нескольких записей, он сохранит порядок ваших записей, даже если для параметра org-reverse-note-order
установлено значение t
, но вы можете отключить его, чтобы соблюдать настройку org-reverse-note-order
с двойным префиксом 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)
Трудно было найти ключ, свободный от префикса C-c C-x, поэтому я использовал m с мнемонической я * mm * ediate
Ответ 3
Я использую M-left, M-up/down, а затем M-right, если структура файла не слишком сложна. Но имейте в виду, что если вы попытаетесь переместить Subtree A1 в Tree B с помощью этого метода, вы потеряете его дочерний Subsubtree A1.1, если вы не переместите его с помощью 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
Ответ 4
Вы можете подделать поддерево, используя C-c C-w, в зависимости от того, как вы настроили рефикс. В зависимости от глубины вашего адресата вы не сможете использовать его в качестве действительного адресата.
Вы можете убить или скопировать поддерево, не сворачивая структуру, используя команды поддерева kill/copy: C-c C-x C-w и C-c C-x M-w соответственно, yanking поддерева либо C-c C-x C-y, либо просто C-y
Ответ 5
Перемещение поддерева в том же буфере можно сделать с помощью org-refile
. Во время перемещения вы можете даже изменить иерархию оригинала (количество звезд). Тем не менее, это может не работать из коробки, потому что буфер, с которым вы работаете, находится не в org-refile-targets
. Вы можете добавить файл в целевые объекты refile с помощью C-[
, затем запустите org-refile
с помощью C-c C-w
и, наконец, удалите файл из целевых файлов 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
переопределяет ваши переменные только локально. Затем вам нужно будет добавить ярлык для запуска функции. Вот один из способов привязать его к C-c m
:
(add-hook 'org-mode-hook (lambda ()
(local-set-key "\C-c m" 'refile-in-current)
Ответ 6
(require 'org-archive)
(setq org-archive-save-context-info nil)
(setq org-archive-location "::* Archived Tasks")
run (org-archive-subtree) в поддереве, который вы хотите переместить, он будет перемещен в заголовок "* Архивные задачи"