조직 수행 키워드 버퍼가 표시되는 위치를 제어하는 ​​방법은 무엇입니까?


9

Q : 할 org일 키워드 버퍼가 나타나는 위치를 어떻게 제어 할 수 있습니까?

( ) 로 todo키워드를 입력 하면 키워드 옵션이 포함 된 새 버퍼가 열리고 하나를 선택한 후 다시 닫습니다. 여태까지는 그런대로 잘됐다. 그러나 그렇게하려면 다른 창을 사용합니다. 특히 키워드로 한두 줄만 표시하면되므로 좋지 않습니다.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것을 수행 하도록 수정하는 것을 고려할 수도 있습니다. 원하는 모든 것을 수행하는 조건을 만들 수 있습니다.
lawlist

@lawlist : 고마워, 나는 파고 들었고, org-switch-to-buffer-other-window다른 추악한 org내장에 대해 알았습니다 . 무지한 "솔루션"에 대한 답변을 참조하십시오.
Dan

이 모든 것을 내 .emacs에 통합하는 동안 포지셔닝 기능을 면밀히 검토했으며에 대한 정의와 관련하여 뭔가 빠진 것 같습니다 win. (selected-window)여기서 사용할 수없는 이유가 있습니까?
Aaron Harris

@AaronHarris : 시도하지 않았습니다. 이 메커니즘을 사용한 다른 게시물의 답변을 (약간) 조정했습니다. 촬영하고 작동하는지 확인하십시오.
Dan

@ Dan : 네, 작동합니다. 나는 약간의 모퉁이 사건 상황으로 인해 폭발이 일어 날까 걱정했다. 그리고 그 기능에 감사드립니다, btw. 그것은 내가하고 싶은 일을 정확하게 수행하며, 나는이 질문을보기 전에 내가 원하는 것을 분명히 말할 수 있다고 생각하지 않습니다.
Aaron Harris

답변:


4

한숨. "솔루션"을 찾았지만 기존 org함수를 덮어 써야하는 추악한 솔루션 입니다. org소스 코드를 수정하지 않아도 되지만 다른 사람이 사용할 수 있도록 고고 학적 발굴 결과를 여기에 넣습니다.

과거에 다른 org기능 과 함께 알았 듯이 org-mode창을 처리하는 방법에 대해 다소 의견이 있습니다.

의 소스 코드에 깊이 묻혀 org-todo함수를 호출합니다 org-fast-todo-selection. 그 함수는 차례로 org-switch-to-buffer-other-windowdocstring을 읽는을 호출합니다 .

현재 프레임의 두 번째 창에서 버퍼로 전환하십시오. 특히 팝업 프레임을 허용하지 마십시오 .

어 오.

좋아, 물어볼께 :을 보자 org-switch-to-buffer-other-window. org-no-popups 매크로를 사용합니다 . docstring은 다음과 같이 읽습니다.

팝업 창을 표시하지 않습니다. BODY 주변에 일부 변수를 바인딩하지 마십시오.

display-buffer-alist변수는에 let바인딩 된 변수 중 하나입니다 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)))))))

cl을 사용 flet하여 리 바인드 할 수 org-switch-to-buffer-other-window있습니까? org-fast-todo-selection덮어 쓰지 않고 조언하거나 포장 할 수 있는지 궁금 합니다.
glucas

@ glucas : 좋은 생각입니다. 그러나 그것을 시험해 보았지만 작동시키지 못했습니다.
Dan

1
@ Dan, 나는 이것을 다시 정의 org-switch-to-buffer-other-window하여 작동시킬 수있었습니다 (switch-to-buffer-other-window args). 또한 &rest함수 인수에서 제거 했습니다.
sk8ingdom

3

최근 에 새 프레임에서 조직 모드 캡처를 수행하는 방법을 알아 냈습니다 . 함수를 사용하도록 해당 코드를 수정하는 것은 매우 간단합니다. 내가하는 방법은 다음과 같습니다.

(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

누군가 다른 사람에서 찾고 설정 , 내가 통제 할 수있는 방법을 발견 *Org Src.*하고 *Org todo*버퍼를 표시합니다. 지금은 명중 할 때 C-c C-t또는 C-c '이러한 버퍼 내 현재 창 레이아웃의 하단에 새 창에 표시하고, TODO 상태를 선택하거나 타격 C-c '( org-edit-src-exit원래 레이아웃으로 내 창 구성을 반환).

이 솔루션은 걸쇠 와 일부 Elisp를 사용합니다.

1 단계

shackleMELPA에서 다운로드 하십시오. 다음은 use-packageinit 파일에서 설정하는 방법입니다 .

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