我如何强制org-mode的捕捉缓冲区在新窗口中打开?我尝试过
(setq special-display-regexps
'("^\\*Capture\\*$"))
但是它没有起作用 - 我看到一个新的窗口短暂地出现,然后org-mode进行了两个垂直分割(我使用3个垂直分割),并将捕获缓冲区放入右侧分割。当我通过C-c C-c
或C-c C-k
完成后,原始的分割设置会恢复。
我也喜欢使用许多并排的窗口(通常是4个——我跨越了多个监视器),所以org-capture
将4个普通窗口转换为2个非常宽的窗口的行为每次都会让我感到头痛,这往往会打断我的工作流程。
+---+---+---+---+ +-------+-------+
| 1 | 2 | 3 | 4 | --> | 1 |capture| = head explosion
+---+---+---+---+ +-------+-------+
org-capture
修改您的窗口布局。经过一番搜索,似乎没有一种容易的方式来定制这种行为(或者至少没有明显的方式)。在源代码中跟踪函数调用将我们带到org-capture-place-template
,它保存您的原始窗口配置,然后删除其他窗口,然后给您两个窗口分屏。当然,在最终捕获时您会恢复窗口配置,但是如果能摆脱“让我们更改您的窗口布局而不需要您同意”的步骤,那就太好了。(delete-other-windows)
的单行,然后重新评估org-capture-place-template
即可。(defun org-capture-place-template ()
"Insert the template at the target location, and display the buffer."
(org-capture-put :return-to-wconf (current-window-configuration))
;; (delete-other-windows) ; this is the culprit!
(org-switch-to-buffer-other-window
(org-capture-get-indirect-buffer (org-capture-get :buffer) "CAPTURE"))
(widen)
(show-all)
(goto-char (org-capture-get :pos))
(org-set-local 'org-capture-target-marker
(point-marker))
(org-set-local 'outline-level 'org-outline-level)
(let* ((template (org-capture-get :template))
(type (org-capture-get :type)))
(case type
((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)
(org-set-local 'org-capture-current-plist org-capture-plist))
啊!每次使用org-capture
都感觉像被它打了一拳,但现在它停止了。
(编辑:接下来是新版org-mode的内容)
(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)))
;(delete-other-windows)
(org-switch-to-buffer-other-window
(org-capture-get-indirect-buffer (org-capture-get :buffer) "CAPTURE"))
(widen)
(show-all)
(goto-char (org-capture-get :pos))
(org-set-local 'org-capture-target-marker
(point-marker))
(org-set-local 'outline-level 'org-outline-level)
(let* ((template (org-capture-get :template))
(type (org-capture-get :type)))
(case type
((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)
(org-set-local 'org-capture-current-plist org-capture-plist))
org-set-local
函数定义为空。 - Caleb Jaysetq-local
来修复它。 - Iainsetq-local
解决了第一个问题,但现在我遇到了错误 Wrong type argument: symbolp, (quote org-capture-target-marker)
。 - Caleb Jay这是我想出来的解决方案。这会导致整个捕获过程在一个单独的弹出窗口中发生。
首先,需要几个帮助函数。
(defun my/get-frame-by-name (fname)
"If there is a frame with named FNAME, return it, else nil."
(require 'dash) ; For `-some'
(-some (lambda (frame)
(when (equal fname (frame-parameter frame 'name))
frame))
(frame-list)))
(defun my/display-buffer-in-named-frame (buffer alist)
"Display BUFFER in frame with specific name.
The name to use is the value associated with the 'named-frame key
in ALIST. If a frame with that name already exists, use it.
Otherwise, call `display-buffer-in-pop-up-frame' to create it.
If ALIST does not contain the key 'named-frame, use the name of BUFFER."
(let* ((fname (or (cdr (assq 'named-frame alist))
(buffer-name buffer)))
(frame (my/get-frame-by-name fname)))
(if frame
(window--display-buffer buffer
(frame-selected-window frame)
'reuse)
(display-buffer-pop-up-frame
buffer
(add-to-list 'alist `(pop-up-frame-parameters
(name . ,fname)))))))
(defmacro my/with-advice (adlist &rest body)
"Execute BODY with temporary advice in ADLIST.
Each element of ADLIST should be a list of the form
(SYMBOL WHERE FUNCTION [PROPS])
suitable for passing to `advice-add'. The BODY is wrapped in an
`unwind-protect' form, so the advice will be removed even in the
event of an error or nonlocal exit."
(declare (debug ((&rest (&rest form)) body))
(indent 1))
`(progn
,@(mapcar (lambda (adform)
(cons 'advice-add adform))
adlist)
(unwind-protect (progn ,@body)
,@(mapcar (lambda (adform)
`(advice-remove ,(car adform) ,(nth 2 adform)))
adlist))))
(defun my/org-capture-in-popout-frame (&optional goto keys)
"As `org-capture', but do all work in a new frame.
This function by itself doesn't clean up the frame following
capture. To do that, add `my/org-capture-delete-capture-frame'
to `org-capture-after-finalize-hook'."
(interactive "P")
(if goto
(org-capture goto keys)
(let ((override '("\\*Org Select\\*\\|\\*Capture\\*\\|CAPTURE-.*"
my/display-buffer-in-named-frame
(named-frame . "Capture"))))
;; Force all relevant buffers to open in a specific capture frame.
(add-to-list 'display-buffer-alist override)
(my/with-advice
(;; Make Org-mode respect `display-buffer-alist'.
(#'org-switch-to-buffer-other-window :override #'pop-to-buffer)
;; And stop Org-mode from messing with our window configuration.
(#'delete-other-windows :override #'ignore))
(unwind-protect (condition-case err
(org-capture goto keys)
(error (my/org-capture-delete-capture-frame)
(signal (car err) (cdr err))))
(setq display-buffer-alist
(delete override display-buffer-alist)))))))
在截图完成后去除框架,请使用以下函数:
(defun my/org-capture-delete-capture-frame ()
"Delete a frame named \"Capture\".
For use in `org-capture-after-finalize-hook' to clean up after
`my/org-capture-in-popout-frame'."
(let ((frame (my/get-frame-by-name "Capture")))
(when frame (delete-frame frame))))
这已经被my/capture-in-popout-frame
调用,以便在早期中止时(例如,在模板选择缓冲区中键入q
或对捕获模板提示的响应中键入C-g
)进行操作。对于正常完成(包括重新归档)或晚期中止(从捕获模板中的C-c C-k
),您需要将其添加到org-capture-after-finalize-hook
。
(add-hook 'org-capture-after-finalize-hook
#'my/org-capture-delete-capture-frame)
org-capture
的工作方式(除非你的电脑上有一个名为“Capture”的额外框架),因此如果您想要特定捕获的默认行为,仍然可以获得它。
org-capture.el
,可以快速搜索以下条目以更好地了解发生了什么:(org-pop-to-buffer-same-window (org-capture-get :buffer))
;(org-pop-to-buffer-same-window (get-buffer-create "*Capture*"))
;(org-capture-put :return-to-wconf (current-window-configuration))
;(set-window-configuration (org-capture-get :return-to-wconf))
。org-pop-to-buffer-same-window
在org-compat.el
中定义。我选择删除所有这些内容并使用with-current-buffer
创建新函数,然后以自己的方式显示。 - lawlistorg-capture
修改我的窗口配置。a) 你解决了这个问题吗?如果没有,b) 你只是想让capture
缓冲区在不修改你的三列设置的情况下在另一个窗口中打开,还是你想问是否可以在新的框架中打开capture
缓冲区? - Dan