2011-09-22 49 views
11

Tôi muốn thực hiện một nhiệm vụ đơn giản nhưng có vẻ là không có giải pháp rõ ràng cho nó:Làm thế nào để di chuyển một cây con khác cây con trong emacs org-mode

Tôi có một cấu trúc của subtrees như thế này:

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

Tôi muốn thiết lập một phím tắt để di chuyển các cây con từ Cây A sang Cây B. Chuyển đến tệp lưu trữ có vẻ dễ dàng, nhưng bạn có bất kỳ đầu mối nào để thực hiện nó trong một tệp không?

Bất kỳ trợ giúp nào được đánh giá cao! Cảm ơn!

+0

Để cho cây nhánh phụ hoạt động (C-c C-w) cần thụt lề của bạn bằng 2. ví dụ: *** SubtreeA1. Tôi đã thiết lập indents của tôi như của bạn và không thể làm cho nó hoạt động cho đến khi tôi nhận ra điều này. – 79E09796

+0

[Câu hỏi này] (http://stackoverflow.com/questions/22200312/refile-from-one-file-to-other) có thể hữu ích. Bạn có thể (tạm thời) thêm tệp hiện tại vào 'target-orgile-target' với ': maxlevel' of> = 2 set bất cứ khi nào bạn refile. Tuy nhiên, lisp-fu của tôi chưa đủ mạnh để giúp bạn với điều đó. – Alex

Trả lời

7

Bạn có thể thử nạp lại cây con với C-c C-w (nó cũng hoạt động để di chuyển cây con sang tệp khác).

Cách khác là gấp cây con, sau đó giết nó bằng C-k C-k và dán vào vị trí cần thiết.

Giải pháp thứ ba tôi sử dụng một thời gian là để thay đổi mức độ của cây con với M-left, sau đó di chuyển nó với M-upM xuống, sau đó M-right đặt nó một lần nữa ở cấp độ chính xác. Cách thứ ba này có thiếu sót rằng một thời gian nó làm cho một phần khác của cây di chuyển.

4

tôi sử dụng M-left, M-up/down và sau đó M-right nếu cấu trúc của tập tin là không quá phức tạp. Nhưng hãy nhớ rằng nếu bạn cố gắng để di chuyển Subtree A1 đến Tree B sử dụng phương pháp này, bạn sẽ mất con của nó Subsubtree A1.1, trừ khi bạn di chuyển nó với MS-trái/phải:

* 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

Bạn có thể sắp xếp lại cây con bằng cách sử dụng Cc Cw, tùy thuộc vào cách bạn đã thiết lập lại công thức. Tùy thuộc vào độ sâu của điểm đến của bạn, bạn có thể không sử dụng được như một điểm đến hợp lệ.

Bạn có thể giết chết hoặc sao chép một cây con mà không cần phải gấp cấu trúc bằng cách sử dụng các lệnh subtree kill/copy: Cc Cx CwCc Cx Mw tương ứng, giật một cây con là một trong hai Cc Cx Cy hay đơn giản Cy

6

tôi cũng muốn có một cách cho org-refile để gửi lại thông báo một cách dễ dàng với một cây con, vì vậy tôi đã viết một số mã và khái quát hóa nó để nó sẽ thiết lập một mục tiêu trước mắt tùy ý bất cứ nơi nào (không chỉ trong cùng một tập tin).

sử dụng cơ bản là để di chuyển đâu đó trong Tree B và gõ Cc Cx Cm để đánh dấu mục tiêu cho refiling, sau đó di chuyển đến mục trong Tree A mà bạn muốn gửi lại thông báo và gõ Cc Cw mà ngay lập tức sẽ gửi lại thông báo vào vị trí mục tiêu bạn đặt trong Tree B mà không nhắc bạn, trừ khi bạn gọi là org-refile-immediate-target với tiền tố arg Cu Cc Cx Cm.

Lưu ý rằng nếu bạn bấm Cc Cw liên tiếp nhanh chóng để gửi lại thông báo nhiều mục nó sẽ giữ gìn trật tự của các mục của bạn ngay cả khi org-reverse-note-order được thiết lập để t, nhưng bạn có thể tắt nó đi để tuân thủ cài đặt của org-reverse-note-order với một tiền tố kép arg Cu Cu Cc Cx Cm.

(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) 

Thật khó để tìm một chìa khóa đó là miễn phí trên Cc Cx tiền tố, vì vậy tôi sử dụng m với mnemonic i * mm * ediate

+0

Tôi đang làm việc để tự động hóa điều này cho nhiều việc cần làm và tôi đã có một bản nháp làm việc của 'danh sách luật-tự động-refile': http://superuser.com/questions/613968/how-to-automate-org-refile-for- multiple-todo Nó chắc chắn sẽ hữu ích nếu 'aculich' hoặc một số maven khác có thể vui lòng tạo một biến tương tự như' (setq org-archive-location "~/0.todo.org :: * Các tác vụ đã lưu trữ") 'để chúng ta có thể chỉ định tệp và tiêu đề, đã là một phần của chức năng 'org-archive-subtree'. Tôi đang thực hiện tìm kiếm và đánh dấu bởi vì tôi không có tiền tố để tạo một cái gì đó như 'org-archive-location' cho thiết lập này. – lawlist

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

chạy (org-archive-subtree) tại subtree mà bạn muốn di chuyển, nó sẽ được chuyển vào "* Các tác vụ đã lưu trữ", tiêu đề

2

Di chuyển một cây con trong cùng một bộ đệm có thể làm ne với org-refile. Trong khi di chuyển, bạn thậm chí có thể thay đổi thứ bậc của bản gốc (số sao). Tuy nhiên, nó có thể không hoạt động ra khỏi hộp chủ yếu vì bộ đệm bạn đang làm việc không nằm trong số org-refile-targets. Bạn có thể thêm tệp vào mục tiêu refile bằng cách sử dụng C-[, sau đó chạy org-refile với C-c C-w và cuối cùng xóa tệp khỏi mục tiêu khôi phục bằng C-]. Điều này có thể quá nhiều (và có thể thất bại nếu cài đặt maxlevel của bạn quá thấp - dù sao bạn cũng có thể thay đổi). Ngoài ra, để tự động hóa các quy trình này trong một lần mua sắm, trước tiên bạn sẽ phải xác định một chức năng như thế này:

(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))) 

Các nil trong đó có nghĩa là "đệm hiện tại". Chỉ let xác định lại các biến cục bộ của bạn. Sau đó, bạn sẽ phải thêm một phím tắt để chạy hàm. Dưới đây là một cách để liên kết với số điện thoại C-c m:

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

Cảm ơn bạn, đây là một cách tuyệt vời. – gsl

Các vấn đề liên quan