lang/org: fix org-capture workflow and org-shackle hacks
This commit is contained in:
parent
2f81ca11a5
commit
a446c58846
4 changed files with 90 additions and 81 deletions
|
@ -348,43 +348,66 @@ the command buffer."
|
||||||
|
|
||||||
|
|
||||||
(add-hook! org-load
|
(add-hook! org-load
|
||||||
;; Ensures org-src-edit yields control of its buffer to shackle.
|
(set! :popup
|
||||||
(defun doom*org-src-switch-to-buffer (buffer context) (pop-to-buffer buffer))
|
'("*Calendar*" :size 0.4 :noselect t)
|
||||||
(advice-add 'org-src-switch-to-buffer :override 'doom*org-src-switch-to-buffer)
|
'(" *Org todo*" :size 5 :noselect t)
|
||||||
|
'("*Org Note*" :size 10)
|
||||||
|
'("*Org Select*" :size 20 :noselect t)
|
||||||
|
'("*Org Links*" :size 5 :noselect t)
|
||||||
|
'(" *Agenda Commands*" :noselect t)
|
||||||
|
'("^\\*Org Agenda" :regexp t :size 0.4)
|
||||||
|
'("*Org Clock*" :noselect t)
|
||||||
|
'("*Edit Formulas*" :size 10)
|
||||||
|
'("\\*Org Src" :regexp t :size 15)
|
||||||
|
'("^\\*Org-Babel" :regexp t :size 0.4)
|
||||||
|
'("^CAPTURE.*\\.org$" :regexp t :size 20))
|
||||||
|
|
||||||
;; ...for org-todo, org-link and org-agenda popups
|
;; Org tries to do its own popup management, causing buffer/window config
|
||||||
(defun doom*org-pop-to-buffer-same-window (&optional buffer-or-name norecord label)
|
;; armageddon when paired with shackle. To fix this, first we suppress
|
||||||
"Pop to buffer specified by BUFFER-OR-NAME in the selected window."
|
;; delete-other-windows in org functions:
|
||||||
(display-buffer buffer-or-name))
|
(defun doom*suppress-delete-other-windows (orig-fn &rest args)
|
||||||
(advice-add 'org-pop-to-buffer-same-window :override 'doom*org-pop-to-buffer-same-window)
|
(cl-flet ((silence (&rest args) (ignore)))
|
||||||
|
(advice-add 'delete-other-windows :around #'silence)
|
||||||
|
(unwind-protect
|
||||||
|
(apply orig-fn args)
|
||||||
|
(advice-remove 'delete-other-windows #'silence))))
|
||||||
|
(advice-add 'org-capture-place-template :around #'doom*suppress-delete-other-windows)
|
||||||
|
(advice-add 'org-agenda :around #'doom*suppress-delete-other-windows)
|
||||||
|
(advice-add 'org-add-log-note :around #'doom*suppress-delete-other-windows)
|
||||||
|
|
||||||
|
;; Tell org-src-edit to open another window, which shackle can intercept.
|
||||||
|
(setq org-src-window-setup 'other-window)
|
||||||
|
|
||||||
|
;; Then, we tell org functions to use pop-to-buffer instead of
|
||||||
|
;; switch-to-buffer-*. Buffers get handed off to shackle properly this way.
|
||||||
(defun doom*org-switch-to-buffer-other-window (&rest args)
|
(defun doom*org-switch-to-buffer-other-window (&rest args)
|
||||||
(car-safe
|
(pop-to-buffer (car args)))
|
||||||
(mapc (lambda (b)
|
|
||||||
(let ((buf (if (stringp b) (get-buffer-create b) b)))
|
|
||||||
(pop-to-buffer buf t t)))
|
|
||||||
args)))
|
|
||||||
(advice-add 'org-switch-to-buffer-other-window :override 'doom*org-switch-to-buffer-other-window)
|
(advice-add 'org-switch-to-buffer-other-window :override 'doom*org-switch-to-buffer-other-window)
|
||||||
|
|
||||||
(defun doom/popup-org-agenda-quit ()
|
;; ...for org-todo, org-link and org-agenda popups
|
||||||
"Necessary to finagle org-agenda into shackle popups & behave on quit."
|
;; (defun doom*org-pop-to-buffer-same-window (&optional buffer-or-name norecord label)
|
||||||
(interactive)
|
;; "Pop to buffer specified by BUFFER-OR-NAME in the selected window."
|
||||||
(if org-agenda-columns-active
|
;; (switch-to-buffer buffer-or-name))
|
||||||
(org-columns-quit)
|
;; (advice-add 'org-pop-to-buffer-same-window :override 'doom*org-pop-to-buffer-same-window)
|
||||||
(let ((buf (current-buffer)))
|
|
||||||
(and (not (eq org-agenda-window-setup 'current-window))
|
;; (defun doom/popup-org-agenda-quit ()
|
||||||
(not (one-window-p))
|
;; "Necessary to finagle org-agenda into shackle popups & behave on quit."
|
||||||
(delete-window))
|
;; (interactive)
|
||||||
(kill-buffer buf)
|
;; (if org-agenda-columns-active
|
||||||
(setq org-agenda-archives-mode nil
|
;; (org-columns-quit)
|
||||||
org-agenda-buffer nil))))
|
;; (let ((buf (current-buffer)))
|
||||||
|
;; (and (not (eq org-agenda-window-setup 'current-window))
|
||||||
|
;; (not (one-window-p))
|
||||||
|
;; (delete-window))
|
||||||
|
;; (kill-buffer buf)
|
||||||
|
;; (setq org-agenda-archives-mode nil
|
||||||
|
;; org-agenda-buffer nil))))
|
||||||
|
|
||||||
(after! org-agenda
|
(after! org-agenda
|
||||||
(after! evil
|
(after! evil
|
||||||
(evil-define-key* 'motion org-agenda-mode-map
|
(map! :map* org-agenda-mode-map
|
||||||
[escape] 'doom/popup-org-agenda-quit
|
:m [escape] 'doom/popup-org-agenda-quit
|
||||||
(kbd "ESC") 'doom/popup-org-agenda-quit))
|
:m "ESC" 'doom/popup-org-agenda-quit))
|
||||||
|
|
||||||
(let ((map org-agenda-mode-map))
|
(let ((map org-agenda-mode-map))
|
||||||
(define-key map "q" 'doom/popup-org-agenda-quit)
|
(define-key map "q" 'doom/popup-org-agenda-quit)
|
||||||
(define-key map "Q" 'doom/popup-org-agenda-quit))))
|
(define-key map "Q" 'doom/popup-org-agenda-quit))))
|
||||||
|
|
|
@ -1,31 +1,26 @@
|
||||||
;;; lang/org/+capture.el --- -*- no-byte-compile: t; -*-
|
;;; lang/org/+capture.el --- -*- no-byte-compile: t; -*-
|
||||||
|
|
||||||
;; Sets up a sane `org-capture' workflow, wherein the org-capture buffer is
|
;; Sets up two `org-capture' workflows that I like:
|
||||||
;; opened in a popup frame, and can be invoked from outside Emacs as well.
|
|
||||||
;;
|
;;
|
||||||
;; See `+org/capture'
|
;; 1. The traditional way: invoking `org-capture' directly (or through a
|
||||||
|
;; command, like :org).
|
||||||
|
;;
|
||||||
|
;; 2. Through a org-capture popup frame that is invoked from outside Emacs (the
|
||||||
|
;; script is below). This lets me open an org-capture box anywhere I can call
|
||||||
|
;; org-capture.sh, like, say, from qutebrowser or vimperator.
|
||||||
|
;;
|
||||||
|
;; #!/usr/bin/env bash
|
||||||
|
;; emacsclient -c \
|
||||||
|
;; -F "((name . \"org-capture\") (height . 25) (width . 70))" \
|
||||||
|
;; --eval "(org-capture nil \"${1:-n}\")"
|
||||||
|
;;
|
||||||
|
;; Place this in, say, org-capture.sh somewhere in your $PATH.
|
||||||
|
|
||||||
(add-hook '+org-init-hook '+org|init-capture t)
|
(add-hook '+org-init-hook '+org|init-capture t)
|
||||||
|
|
||||||
(defun +org|init-capture ()
|
(defun +org|init-capture ()
|
||||||
"Set up a sane `org-capture' workflow."
|
"Set up a sane `org-capture' workflow."
|
||||||
(setq org-default-notes-file +org-quicknote-dir)
|
(setq org-default-notes-file (concat +org-dir "notes.org"))
|
||||||
|
|
||||||
(require 'org-capture)
|
|
||||||
(require 'org-protocol)
|
|
||||||
(set! :popup "*Org Select*" :size 0.4)
|
|
||||||
|
|
||||||
(defadvice org-capture (after make-full-window-frame activate)
|
|
||||||
"If org-capture creates a new frame, this initializes it properly, by
|
|
||||||
deleting other windows and blanking out the mode-line."
|
|
||||||
(when (equal "org-capture" (frame-parameter nil 'name))
|
|
||||||
(setq mode-line-format nil)
|
|
||||||
(delete-other-windows)))
|
|
||||||
|
|
||||||
(defadvice org-capture-finalize (after delete-capture-frame activate)
|
|
||||||
"Closes the frame once org-capture is done."
|
|
||||||
(when (equal "org-capture" (frame-parameter nil 'name))
|
|
||||||
(delete-frame)))
|
|
||||||
|
|
||||||
(setq org-capture-templates
|
(setq org-capture-templates
|
||||||
'(;; TODO: New Task (todo)
|
'(;; TODO: New Task (todo)
|
||||||
|
@ -44,11 +39,30 @@ deleting other windows and blanking out the mode-line."
|
||||||
;; "* %u %?\n%i" :prepend t)
|
;; "* %u %?\n%i" :prepend t)
|
||||||
|
|
||||||
("n" "Notes" entry
|
("n" "Notes" entry
|
||||||
(file+headline org-default-notes-file "Inbox")
|
(file+headline (concat +org-dir "notes.org") "Inbox")
|
||||||
"* %u %?\n%i" :prepend t)
|
"* %u %?\n%i" :prepend t)
|
||||||
|
|
||||||
;; ("v" "Vocab" entry
|
;; ("v" "Vocab" entry
|
||||||
;; (file+headline (concat org-directory "topics/vocab.org") "Unsorted")
|
;; (file+headline (concat org-directory "topics/vocab.org") "Unsorted")
|
||||||
;; "** %i%?\n")
|
;; "** %i%?\n")
|
||||||
)))
|
))
|
||||||
|
|
||||||
|
;; Allows the Emacs mini-frame (opened from an external shell script to run
|
||||||
|
;; and clean up properly) if the frame is named "org-capture".
|
||||||
|
(require 'org-capture)
|
||||||
|
(require 'org-protocol)
|
||||||
|
(defun +org*capture-init (&rest _)
|
||||||
|
"Makes sure the org-capture window is the only window in the frame."
|
||||||
|
(when (equal "org-capture" (frame-parameter nil 'name))
|
||||||
|
(setq mode-line-format nil)
|
||||||
|
(delete-other-windows)))
|
||||||
|
(advice-add 'org-capture :after '+org*capture-init)
|
||||||
|
|
||||||
|
(defun +org|capture-finalize ()
|
||||||
|
"Closes the frame once org-capture is done."
|
||||||
|
(when (equal "org-capture" (frame-parameter nil 'name))
|
||||||
|
(when (and (featurep 'persp-mode) persp-mode)
|
||||||
|
(+workspace/delete (+workspace-current-name)))
|
||||||
|
(delete-frame)))
|
||||||
|
(add-hook 'org-capture-after-finalize-hook '+org|capture-finalize))
|
||||||
|
|
||||||
|
|
|
@ -1,18 +1,3 @@
|
||||||
;;; lang/org/autoload/capture.el
|
;;; lang/org/autoload/capture.el
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun +org/capture (&optional template string)
|
|
||||||
"Run `org-capture' in a new, disposable popup frame."
|
|
||||||
(interactive)
|
|
||||||
(let ((org-capture-entry (org-capture-select-template template)))
|
|
||||||
(cond ((equal org-capture-entry "C")
|
|
||||||
(find-file (expand-file-name "module-org-notes.el" doom-modules-dir))
|
|
||||||
(re-search-forward "^\\s-+(setq org-capture-templates" (point-max) t)
|
|
||||||
(recenter))
|
|
||||||
((not (equal org-capture-entry "q"))
|
|
||||||
(let ((frame (make-frame '((name . "org-capture") (height . 15) (width . 80)))))
|
|
||||||
(with-selected-frame frame
|
|
||||||
(if string
|
|
||||||
(org-capture-string string)
|
|
||||||
(org-capture))))))))
|
|
||||||
|
|
||||||
|
|
|
@ -17,17 +17,13 @@
|
||||||
(add-hook 'org-mode-hook '+org|hook)
|
(add-hook 'org-mode-hook '+org|hook)
|
||||||
|
|
||||||
;; Custom variables
|
;; Custom variables
|
||||||
(defvar +org-dir "~/work/org/"
|
(defvar +org-dir (expand-file-name "~/work/org/")
|
||||||
"The directory where org files are kept.")
|
"The directory where org files are kept.")
|
||||||
|
|
||||||
(defvaralias 'org-directory '+org-dir)
|
(defvaralias 'org-directory '+org-dir)
|
||||||
|
|
||||||
(defvar +org-notes-dir (concat +org-dir "notes")
|
(defvar +org-notes-dir (concat +org-dir "notes")
|
||||||
"The directory where the notes are kept")
|
"The directory where the notes are kept")
|
||||||
|
|
||||||
(defvar +org-quicknote-dir (concat +org-dir "inbox")
|
|
||||||
"The directory to store quick notes produced by `doom:org-capture' (individual org files)")
|
|
||||||
|
|
||||||
(defvar +org-attachment-dir ".attach/"
|
(defvar +org-attachment-dir ".attach/"
|
||||||
"Where to store attachments (relative to current org file).")
|
"Where to store attachments (relative to current org file).")
|
||||||
|
|
||||||
|
@ -59,7 +55,7 @@
|
||||||
|
|
||||||
(defun +org|update-cookies ()
|
(defun +org|update-cookies ()
|
||||||
"Update counts on headlines (\"cookies\")."
|
"Update counts on headlines (\"cookies\")."
|
||||||
(when (file-exists-p buffer-file-name)
|
(when (and buffer-file-name (file-exists-p buffer-file-name))
|
||||||
(org-update-statistics-cookies t)))
|
(org-update-statistics-cookies t)))
|
||||||
|
|
||||||
(add-hook 'before-save-hook '+org|update-cookies nil t)
|
(add-hook 'before-save-hook '+org|update-cookies nil t)
|
||||||
|
@ -75,15 +71,6 @@
|
||||||
:keymap (make-sparse-keymap)
|
:keymap (make-sparse-keymap)
|
||||||
:group 'evil-org)
|
:group 'evil-org)
|
||||||
|
|
||||||
(set! :popup
|
|
||||||
'(" *Agenda Commands*" :size 30 :noselect t)
|
|
||||||
'(" *Org todo*" :size 5 :noselect t)
|
|
||||||
'("*Calendar*" :size 0.4 :noselect t)
|
|
||||||
'("*Org Links*" :size 5 :noselect t)
|
|
||||||
'("^\\*Org Agenda.+" :size 0.4 :regexp t)
|
|
||||||
'("^\\*Org Src .+\\*$" :size 0.4 :regexp t)
|
|
||||||
'("^\\*Org-Babel.*\\*$" :size 0.4 :regexp t))
|
|
||||||
|
|
||||||
(setq-default
|
(setq-default
|
||||||
org-export-coding-system 'utf-8
|
org-export-coding-system 'utf-8
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue