在Emacs org-mode中,如何将高亮文本归档到org标题下?

7
在Emacs org-mode中,是否有一种方法可以自动将突出显示的文本归档到org-heading下?即剪切突出显示的文本并自动粘贴到我选择的org-heading下。您可以称其为org-refile-region,类似于org-refile,但不是将整个子树重新分类,而是在当前文档中的任何标题下将突出显示的区域重新分类。更新:理想情况下,此功能应独立于org-refile使用的org-agenda文件,以避免显示不相关的标题作为可能的目标。

目前可以通过以下方式实现:
1. 选择文本
2. 剪切
3. 其他窗口
4. 导航到所需的目标标题
5. 粘贴文本
6. 其他窗口

建议的新函数将使此过程更加高效:
1. 选择文本
2. org-refile-region
3. 选择目标

最有用的形式将允许您从当前打开的任何文档中选择目标。我的用例涉及从一个缓冲区选择文本,并将其从另一个缓冲区中的org-heading重新分配,即从在一个窗口中显示的源文档移动文本,并将其重新分配到在另一个窗口中显示的目标文档的层次结构中的目标。如下图所示:

你是使用类似于 *word* 的方式来突出文本,还是使用其他方法?如果是其他方法,请说明与你问题相关的突出方式。 - lawlist
Shift-select,即S-<right>和S-<left>。 - incandescentman
1个回答

5
如果您使用的是 Emacs 24.1 或更高版本,可以尝试以下操作:
(setq org-refile-active-region-within-subtree t)

这个功能几乎可以满足您的需求,但会将您所选中的文本行(emacs术语为“活动区域”)转换为标题。

如果您想要将所选中的文本移动到另一个标题下,您需要扩展org-mode。幸运的是,org提供了必要的工具。以下是一个示例:

(defvar org-refile-region-format "\n%s\n")

(defvar org-refile-region-position 'top
  "Where to refile a region. Use 'bottom to refile at the
end of the subtree. ")

(defun org-refile-region (beg end copy)
  "Refile the active region.
If no region is active, refile the current paragraph.
With prefix arg C-u, copy region instad of killing it."
  (interactive "r\nP")
  ;; mark paragraph if no region is set
  (unless (use-region-p)
    (setq beg (save-excursion
                (backward-paragraph)
                (skip-chars-forward "\n\t ")
                (point))
          end (save-excursion
                (forward-paragraph)
                (skip-chars-backward "\n\t ")
                (point))))
  (let* ((target (save-excursion (org-refile-get-location)))
         (file (nth 1 target))
         (pos (nth 3 target))
         (text (buffer-substring-no-properties beg end)))
    (unless copy (kill-region beg end))
    (deactivate-mark)
    (with-current-buffer (find-file-noselect file)
      (save-excursion
        (goto-char pos)
        (if (eql org-refile-region-position 'bottom)
            (org-end-of-subtree)
          (org-end-of-meta-data-and-drawers))
        (insert (format org-refile-region-format text))))))

我们使用org-refile-get-location来应用org重定位机制并提取文件和位置。然后我们去到那个位置并插入复制的文本。为了方便添加了两个变量。 org-refile-targets可以让您控制要考虑哪些文件,例如:
nil  ;; only the current file
'((org-agenda-files :maxlevel . 2)) ;; all agenda files, 1st/2nd level
'((org-files-list :maxlevel . 4)) ;; all agenda and all open files
'((my-org-files-list :maxlevel . 4)) ;; all files returned by `my-org-files-list'

为了将重新归档限制在当前打开的org缓冲区中,请定义一个函数

(defun my-org-files-list ()
  (mapcar (lambda (buffer)
            (buffer-file-name buffer))
          (org-buffer-list 'files t)))

然后要么

(setq org-refile-targets '((my-org-files-list :maxlevel . 4)))

或使用。
M-x customize-option <ret> org-refile-targets

从“值菜单”中选择“功能”,并输入my-org-files-list

1
是的。可能的目标根据org-refile-targets进行选择。如果此变量为nil(默认情况下是这样),则仅考虑当前缓冲区。我修改了我的示例,因为您特别要求“在当前文档中的任何标题”。 - olaf b
2
我已经更新了我的回答。org-refile-region现在使用org-refile-targets,并且我添加了如何自定义后者的说明。 - olaf b
我收到了“错误的重新填充目标描述(:max-level . 4)”的信息。 - incandescentman
1
关键字应该叫做:maxlevel,而不是:max-level。对于笔误我感到抱歉。 - olaf b
2
那个完美地运作了!有没有办法指定函数使用ido界面(好)或helm界面(更好)来选择标题? - incandescentman
显示剩余7条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接