在特定窗口中打开Org Capture缓冲区?

3
我已经使用Emacs大约一年左右了。每次会话我都会按照相同的方式设置窗口(四个窗口)。
我设置了捕获模板并可以捕获所需内容,但是:我希望所选的捕获模板在新的(第五个)窗口中打开,保留我的现有布局,而不是暂时将我从窗口布局中抽离出来。通常我想要打开捕获模板一段时间,这很干扰。
这似乎是一个显而易见的选项,但我无法弄清楚。感谢所有Emacs用户提前的帮助。

1
这个答案是否满足你的需求?链接 - legoscia
1
@legoscia 不好意思,不行。那个“已批准”的答案不起作用,评论中的链接也不起作用。 - James
1
@James:我刚刚尝试了在org-capture-place-template中注释掉(delete-other-windows),就像@legoscia指出的答案一样,这样做很好用:捕获缓冲区会在现有窗口中打开,其他窗口保持不变,当捕获完成后,修改过的窗口会恢复到之前的状态。然而,你不应该直接从那个答案中复制函数:你应该编辑正在使用的org-capture.el文件,如果你是在运行编译代码,可能需要重新编译文件,然后执行M-x org-reload来激活更改。 - NickD
1
如我所说,这不是配置:您必须修改org-capture-place-template函数。但是您确实有某个名为org-capture.el的文件:请执行M-x locate-file org-capture.el来查找它。然后您可以编辑它,保存它,如果需要的话编译它,然后重新加载org-mode。但是我理解您可能会觉得有些压力:您可以尝试下面@legoscia的回答,它只需添加到您的.emacs中即可。 - NickD
1
@NickD 啊,现在我明白了。我找到了org-capture.el并按照你描述的方式注释掉了delete-other-windows,然后它起作用了。我之前不知道包的目录/文件结构,但现在我也学到了这个。非常感谢你的回复,非常感激。如果还有其他问题,我会再向你请教的。 - James
显示剩余2条评论
3个回答

8

我提出了一个更易于使用的版本,基于丹(Dan)的答案,用于解决相关问题:

(defun my-org-capture-place-template-dont-delete-windows (oldfun &rest args)
  (cl-letf (((symbol-function 'delete-other-windows) 'ignore))
    (apply oldfun args)))

(with-eval-after-load "org-capture"
  (advice-add 'org-capture-place-template :around 'my-org-capture-place-template-dont-delete-windows))

那就是说,这段代码在调用org-capture-place-template时,临时将delete-other-windows重新定义为ignore,而不是必须修改Org-mode代码并删除对delete-other-windows的调用。它没有完全实现你想要的功能:它会选择一个已有的窗口并将捕获缓冲区放置在那里。至少它比默认行为更好,后者会删除除一个以外的所有先前窗口。也许通过自定义变量display-buffer-alist可以实现你想要的效果,但我无法想出具体方案...

谢谢,你最初提供的链接的文章很有用,一旦@NickD解释了修改org-capture.el的细节。如果你最初的评论是一个答案,我会将其标记为最佳答案。 - James
1
我认为你应该接受这个答案:它包含了指向另一个答案的指针,并且还提供了一种在不修改org源代码的情况下实现与那个答案道义等价的方法。你应该尝试将上面答案中的代码添加到你的.emacs文件中,而不要org-capture.el进行修改。这样做可以避免在升级org-mode版本时需要重复进行相同的修改。 - NickD
@NickD 同意。完成。 - James
你还可以在加载后使用el-patch来修补org-capture,像这样:(el-patch-feature org-capture) (with-eval-after-load 'org-capture (el-patch-defun org-capture-place-template (&optional inhibit-wconf-store) "在目标位置插入模板,并显示缓冲区。 当`inhibit-wconf-store'时,不要存储窗口配置,因为它可能已经被存储过。" (unless inhibit-wconf-store (org-capture-put :return-to-wconf (current-window-configuration))) (el-patch-remove (delete-other-windows)) ) - mathiasp
我尝试了这个,但是出现了一个错误,提示org-set-local的函数定义为空。 - Caleb Jay
这段代码有bug:你需要在args前面加上&rest,即(defun my-org-capture-place-template-dont-delete-windows (oldfun &rest args) ...)。如果没有这个修改,它将无法与org 9.5.2和其他版本一起正常工作。不过除此之外,它的功能非常好。 - Jun Inoue

1
你也可以在加载后使用https://github.com/raxod502/el-patch并修补org-capture(查找(el-patch-remove (delete-other-windows))):
  (el-patch-feature org-capture) 
  (with-eval-after-load 'org-capture
    (el-patch-defun org-capture-place-template  (&optional inhibit-wconf-store)
      "Insert the template at the target location, and display the buffer.
When `inhibit-wconf-store', don't store the window configuration, as it
may have been stored before."
      (unless inhibit-wconf-store
    (org-capture-put :return-to-wconf (current-window-configuration)))
      (el-patch-remove (delete-other-windows))
      (org-switch-to-buffer-other-window
       (org-capture-get-indirect-buffer (org-capture-get :buffer) "CAPTURE"))
      (widen)
      (org-show-all)
      (goto-char (org-capture-get :pos))
      (setq-local outline-level 'org-outline-level)
      (pcase (org-capture-get :type)
    ((or `nil `entry) (org-capture-place-entry))
    (`table-line (org-capture-place-table-line))
    (`plain (org-capture-place-plain-text))
    (`item (org-capture-place-item))
    (`checkitem (org-capture-place-item)))
      (org-capture-mode 1)
      (setq-local org-capture-current-plist org-capture-plist)) ) 

0

由于某些原因,@legoscia的方法在emacs 28中对我无效。

因此,这里是之前建议的el-patch代码片段:

(el-patch-feature org-capture)
(with-eval-after-load 'org-capture
  (el-patch-define-and-eval-template
    (defun org-capture-place-template)
    (el-patch-remove (delete-other-windows))))

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