組織のToDoキーワードバッファが表示される場所を制御するにはどうすればよいですか?


9

Qorgtodoキーワードバッファーが表示される場所を制御するにはどうすればよいですか?

()でtodoキーワードを入力すると、キーワードオプションを含む新しいバッファーが開き、バッファーを1つ選択した後で再び閉じます。ここまでは順調ですね。ただし、それを行うには別のウィンドウが引き継がれます。これは、特にキーワードで1行または2行を表示するだけで十分なので、あまり効果がありません。C-c C-torg-todo

したがって、次のレイアウトでC-c C-tは、左側のウィンドウ(some-org-buffer)でを押す*Org todo*と右側のウィンドウで開きます。

+---------------------+---------------------+
|                     |                     |
|                     |                     |
|                     |                     |
|                     |                     |
|   some-org-buffer   |  some-other-buffer  |
|                     |                     |
|                     |                     |
|                     |                     |
|                     |                     |
+---------------------+---------------------+

代わりに、次のように小さなウィンドウを垂直分割としてポップアップさせたいと思います。

+---------------------+---------------------+
|                     |                     |
|                     |                     |
|   some-org-buffer   |  some-other-buffer  |
|                     |                     |
|                     |                     |
+---------------------+                     |
|                     |                     |
|     *Org todo*      |                     |
|                     |                     |
+---------------------+---------------------+

この答えから不満を抱き 、私はに入れる関数を書きましたdisplay-buffer-alist

(defun org-todo-position (buffer alist)
  (let ((win (car (cl-delete-if-not
                   (lambda (window)
                     (with-current-buffer (window-buffer window)
                       (memq major-mode
                             '(org-mode org-agenda-mode))))
                   (window-list)))))
    (when win
      (let ((new (split-window win -5 'below)))
        (set-window-buffer new buffer)
        new))))

(add-to-list 'display-buffer-alist
             (list " \\*Org todo\\*" #'dan-org-todo-position))

ただし、これは機能しません。はぁ。 私は何を間違っていdisplay-buffer-alistますか? さらにtodoキーワードバッファを希望の場所にポップアップ表示するにはどうすればよい ですか。


あなたの質問に対する答えではありませんが、あなたがしたいことをするように変更org-switch-to-buffer-other-windowを検討したいかもしれません-あなたはあなたがしたいことを何でもする条件を作成することができます。
弁護士、2015

@lawlist:おかげで、私は周りを掘り下げて、org-switch-to-buffer-other-window他の醜い内部についてたくさん見つけましたorg。悪名高い「解決策」の回答をご覧ください。
ダン

これらすべてを.emacsに組み込んでいる間、私はあなたの位置決め機能を詳しく調べましたwin。あなたのの定義に関して何か欠けているような気がします。(selected-window)ここで使用できない理由はありますか?
アーロンハリス

@AaronHarris:まだ試していません。このメカニズムを使用する別の投稿からの回答を(軽く)調整しました。試してみて、機能するかどうかを確認します。
ダン

@ダン:うん、それは動作します。ちょっとしたケースで爆発するのではないかと少し心配でした。そして、その機能に感謝します。それはまさに私がそれがしたいことを行います、そして私がそれがこの質問を見る前に私が欲しかったものであることを明確に述べることができなかったと思います。
アーロンハリス

回答:


4

はぁ。「解決策」を見つけましたが、既存のorg関数を上書きする必要がある醜いものです。私はorgソースコードを変更する必要がないものを好みますが、他の誰かが使用できるように、ここに私の考古学的発掘の結果を入れています。

他のorg機能で 以前気付いたorg-modeように、ウィンドウの処理方法についてはかなり意見が分かれています。

のソースコードの奥深くに埋め込まれているのorg-todoは、関数の呼び出しorg-fast-todo-selectionです。その関数は、次に、org-switch-to-buffer-other-windowdocstringを部分的に読み取るを呼び出します 。

現在のフレームの2番目のウィンドウでバッファに切り替えます。特に、ポップアップフレームを許可しないください

ええとああ。

さて、私は噛みます:を見てみましょう org-switch-to-buffer-other-windoworg-no-popups マクロを使用します。そのdocstringの一部は次のようになっています。

ポップアップウィンドウを抑制します。 BODYの周りでいくつかの変数をnilにバインドします ...

これdisplay-buffer-alistは、にletバインドされている変数の1つです nil

頭が爆発します。

最終的には、行を編集してプレーンオールドに置き換えることで、を無視しないようにする ことができます。display-buffer-alistorg-fast-todo-selectionorg-switch-to-buffer-other-windowswitch-to-buffer-other-window

(defun org-fast-todo-selection ()
  "Fast TODO keyword selection with single keys.
Returns the new TODO keyword, or nil if no state change should occur."
  (let* ((fulltable org-todo-key-alist)
     (done-keywords org-done-keywords) ;; needed for the faces.
     (maxlen (apply 'max (mapcar
                  (lambda (x)
                (if (stringp (car x)) (string-width (car x)) 0))
                  fulltable)))
     (expert nil)
     (fwidth (+ maxlen 3 1 3))
     (ncol (/ (- (window-width) 4) fwidth))
     tg cnt e c tbl
     groups ingroup)
    (save-excursion
      (save-window-excursion
    (if expert
        (set-buffer (get-buffer-create " *Org todo*"))
      ;; (org-switch-to-buffer-other-window (get-buffer-create " *Org todo*")))
      (switch-to-buffer-other-window (get-buffer-create " *Org todo*")))
    (erase-buffer)
    (org-set-local 'org-done-keywords done-keywords)
    (setq tbl fulltable cnt 0)
    (while (setq e (pop tbl))
      (cond
       ((equal e '(:startgroup))
        (push '() groups) (setq ingroup t)
        (when (not (= cnt 0))
          (setq cnt 0)
          (insert "\n"))
        (insert "{ "))
       ((equal e '(:endgroup))
        (setq ingroup nil cnt 0)
        (insert "}\n"))
       ((equal e '(:newline))
        (when (not (= cnt 0))
          (setq cnt 0)
          (insert "\n")
          (setq e (car tbl))
          (while (equal (car tbl) '(:newline))
        (insert "\n")
        (setq tbl (cdr tbl)))))
       (t
        (setq tg (car e) c (cdr e))
        (if ingroup (push tg (car groups)))
        (setq tg (org-add-props tg nil 'face
                    (org-get-todo-face tg)))
        (if (and (= cnt 0) (not ingroup)) (insert "  "))
        (insert "[" c "] " tg (make-string
                   (- fwidth 4 (length tg)) ?\ ))
        (when (= (setq cnt (1+ cnt)) ncol)
          (insert "\n")
          (if ingroup (insert "  "))
          (setq cnt 0)))))
    (insert "\n")
    (goto-char (point-min))
    (if (not expert) (org-fit-window-to-buffer))
    (message "[a-z..]:Set [SPC]:clear")
    (setq c (let ((inhibit-quit t)) (read-char-exclusive)))
    (cond
     ((or (= c ?\C-g)
          (and (= c ?q) (not (rassoc c fulltable))))
      (setq quit-flag t))
     ((= c ?\ ) nil)
     ((setq e (rassoc c fulltable) tg (car e))
      tg)
     (t (setq quit-flag t)))))))

fletここでclを使用して再バインドできますorg-switch-to-buffer-other-windowか?それをorg-fast-todo-selection上書きするのではなく、アドバイスしたりラップしたりできるかどうか疑問に思っています。
グルカ2015

@glucas:いい考えです。それを試してみましたが、動作しませんでした。
ダン

1
@ダン、私はorg-switch-to-buffer-other-windowちょうどに再定義することでこれを機能させることができました(switch-to-buffer-other-window args)&rest関数の引数からも削除しました。
sk8ingdom 2016

3

私は最近、Org-modeを新しいフレームでキャプチャする方法を見つけました。関数を使用するようにそのコードを変更するのは非常に簡単です。ここに私がそれをする方法があります:

(defun my/org-todo-window-advice (orig-fn)
  "Advice to fix window placement in `org-fast-todo-selection'."
  (let  ((override '("\\*Org todo\\*" dan-org-todo-position)))
    (add-to-list 'display-buffer-alist override)
    (my/with-advice
        ((#'org-switch-to-buffer-other-window :override #'pop-to-buffer))
      (unwind-protect (funcall orig-fn)
        (setq display-buffer-alist
              (delete override display-buffer-alist))))))

(advice-add #'org-fast-todo-selection :around #'my/org-todo-window-advice)

完全を期すためにmy/with-advice、他の回答からのマクロの定義を次に示します。

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

2

他の誰かのconfigを見ると、どこ*Org Src.**Org todo*バッファが現れるかを制御する方法が見つかりました。ここで、ヒットするC-c C-tか、C-c 'これらのバッファーが現在のウィンドウレイアウトの下部にある新しいウィンドウに表示され、TODO状態を選択するかC-c 'org-edit-src-exit)を押すと、ウィンドウ構成が元のレイアウトに戻ります。

このソリューションでは、シャックルといくつかのElisp を使用します。

ステップ1

shackleMELPAからダウンロードしてください。これuse-packageが私のinitファイルで設定する方法です:

(use-package shackle
    :ensure t
    :diminish shackle-mode  ; hide name in mode-line
    :config
    (setq shackle-rules
          '(("\\*Org Src.*" :regexp t :align below :select t)
            (" *Org todo*" :align below :select t)))
    (shackle-mode t))

ここでの重要な設定は次のとおりです。

(setq shackle-rules
              '(("\\*Org Src.*" :regexp t :align below :select t)
                (" *Org todo*" :align below :select t)))

ソース

特に、下の行"とその間のスペースに注意してください*Org。私は:align他の場所への設定をテストしていませんshackleが、かなり柔軟性があるようですので、ドキュメントを読んでそれを試す価値があります。

ステップ2

次に、initファイルでさらにElisp を使用してorg-modeリッスンしshackleます。*Org Src.*フォローするバッファを取得するにはshackle-rules

(setq org-src-window-setup 'other-window)

ソース

残念ながらorg-mode*Org todo*バッファの類似の設定は提供されていません。このハックはそれを補います(そしておそらく(setq org-src-window-setup 'other-window)余計なものになりますが、より知識のある誰かがそれに対処する必要があります):

;; Re-define org-switch-to-buffer-other-window to NOT use org-no-popups.
;; Primarily for compatibility with shackle.
(defun org-switch-to-buffer-other-window (args)
  "Switch to buffer in a second window on the current frame.
In particular, do not allow pop-up frames.
Returns the newly created buffer.
Redefined to allow pop-up windows."
  ;;  (org-no-popups
  ;;     (apply 'switch-to-buffer-other-window args)))
  (switch-to-buffer-other-window args))

ソース

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.