如何在emacs org-mode中将函数限制为子树?

9
我正在广泛使用org-mode和org-attach,这意味着可以有许多附件目录与一个org文件相关联。
在worg上,我找到了Matt Lundi的一个函数,它允许查看属于整个文件的所有附件,并使用ido浏览它们。
我想将此功能限制为子树,这将使它对我的用例更加有用。
由于我不是Emacs新手,但几乎完全不懂elisp,所以我在这里提问。
以下是该函数:
(defun my-ido-find-org-attach ()
  "Find files in org-attachment directory"
  (interactive)
  (let* ((enable-recursive-minibuffers t)
         (files (find-lisp-find-files org-attach-directory "."))
         (file-assoc-list
          (mapcar (lambda (x)
                    (cons (file-name-nondirectory x)
                          x))
                  files))
         (filename-list
          (remove-duplicates (mapcar #'car file-assoc-list)
                             :test #'string=))
         (filename (ido-completing-read "Org attachments: " filename-list nil t))
         (longname (cdr (assoc filename file-assoc-list))))
    (ido-set-current-directory
     (if (file-directory-p longname)
         longname
       (file-name-directory longname)))
    (setq ido-exit 'refresh
          ido-text-init ido-text
          ido-rotate-temp t)
    (exit-minibuffer)))

你是否要求包含文件子树或org子树的附件? - Diego Sevilla
1
我希望该函数仅考虑组织子树。 - Otto Pichlhoefer
2个回答

3
也许我漏掉了什么,但是首先调用 org-narrow-to-subtree 应该会完成您想要的操作(然后再调用扩大以恢复原状)。

my-ido-find-org-attach 的写法中,org-narrow-to-subtree 没有任何效果,因为它盲目地使用了 org-attach-directory 的值。 - aculich

1

我认为这对我自己非常有用,所以受到你的问题的启发,我编写了一个版本,可以实现你想要的功能,还有一些其他的小功能。要调用它,您需要键入C-c o。注意:这不是通常的org-attach键前缀,因为该函数没有键映射,所以很难将功能添加到键前缀上。

(autoload 'org-attach-dir "org-attach")
(autoload 'find-lisp-find-files "find-lisp")
(defcustom ido-locate-org-attach-all-files nil
  "Non-nil means `ido-locate-org-attach' returns all files.
Otherwise the default behavior only returns files attached to the
current entry."
  :group 'ido
  :type 'boolean)

(defun ido-locate-org-attach (&optional find-all)
  "Find files in org-attachment directory for current entry.
When called with a prefix argument, include all files in
`org-attach-directory'. With a double `C-u' prefix arg the value
of `ido-locate-org-attach-all-files' will be toggled for the
session. If you want to save it permanently for future session
then customize the variable `ido-locate-org-attach-all-files'."
  (interactive "P")
  (when (org-attach-dir nil)
    (when (equal find-all '(16))
      (setq ido-locate-org-attach-all-files
        (not ido-locate-org-attach-all-files)))
    (let* ((enable-recursive-minibuffers t)
       (dir (if (org-xor ido-locate-org-attach-all-files
                 (equal find-all '(4)))
            org-attach-directory
          (org-attach-dir nil)))
       (files (find-lisp-find-files dir "."))
       (file-assoc-list
        (mapcar (lambda (x)
              (cons (file-name-nondirectory x)
                x))
            files))
       (filename-list
        (remove-duplicates (mapcar #'car file-assoc-list)
                   :test #'string=))
       (filename (ido-completing-read "Org attachments: " filename-list nil t))
       (longname (cdr (assoc filename file-assoc-list))))
      (ido-set-current-directory
       (if (file-directory-p longname)
       longname
     (file-name-directory longname)))
      (setq ido-exit 'refresh
        ido-text-init ido-text
        ido-rotate-temp t)
      (exit-minibuffer))))

;; Run ido-locate-org-attach when using org-open-at-point (C-c C-o) in
;; the current entry (except if you're on the header line itself it
;; will use the default behavior to open/close the entry.
(add-hook 'org-open-at-point-functions 'ido-locate-org-attach)

;; C-c o           will locate files for the current entry
;; C-u C-c o       will locate files for the whole file
;; C-u C-u C-c o   will toggle the default current entry / whole file
(define-key org-mode-map "\C-co" 'ido-locate-org-attach)

我会研究将此提交为org-attach.el的官方部分。

另外,'(4)'(16)是魔法数字,意味着在交互式调用命令之前,按一次C-u和按两次C-u C-u的前缀参数。


谢谢你的回复,很抱歉我回复晚了。但不幸的是,我无法让你的工作。当我在一个带有附件目录的标题上时,它与org-attach和o(打开当前任务的附件)相同。当在父标题上调用时,什么也不会发生,而我本来期望找到所有子标题的附件。我必须说我在Windows上,但我认为这与事情无关,因为org-attach运行得非常顺畅。 - Otto Pichlhoefer
尝试使用M-x ido-locate-org-attach调用它,以确保函数可用。您是否使用C-c o调用它,而不是使用org-attach的键组合C-c C-a o?我没有覆盖org-attach-open-in-emacs的默认键,只是在org-attach前缀之外添加了不同的键绑定。 - aculich
我已经完成了这个任务。C-C oM-x ido-locate-org-attach 都会得到相同的结果。顺便提一下,我使用的是 Emacs 24.2.1 和 org 版本 7.9.2(来自 ELPA)。 - Otto Pichlhoefer
你能否创建一个gist,包含你的*.org文件内容和一个示例附件目录,以便我可以尝试重现你所看到的问题?我也使用Org-mode版本7.9.2(来自ELPA),但使用GNU Emacs 24.1.1。 - aculich

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