Add modules/lang/org (WIP)
This commit is contained in:
parent
c3159b5649
commit
941f3abc6f
10 changed files with 912 additions and 0 deletions
44
modules/lang/org/+attach.el
Normal file
44
modules/lang/org/+attach.el
Normal file
|
@ -0,0 +1,44 @@
|
|||
;;; emacs/org/+attach.el --- -*- no-byte-compile: t; -*-
|
||||
|
||||
;; FIXME
|
||||
;; Initializes my own org-mode attachment system. I didn't like Org's native
|
||||
;; one. Mine stores attachments in a global org .attach directory. It also
|
||||
;; implements drag-and-drop file support and attachment icons. It also treats
|
||||
;; images specially.
|
||||
;;
|
||||
;; To clean up unreferenced attachments, call `doom/org-cleanup-attachments'
|
||||
(add-hook '+org-init-hook '+org|init-attach t)
|
||||
|
||||
(defun +org|init-attach ()
|
||||
(setq org-attach-directory +org-attachment-dir)
|
||||
|
||||
;; Don't track attachments in recentf or projectile
|
||||
(push (format "/%s.+$" (regexp-quote +org-attachment-dir)) recentf-exclude)
|
||||
(push ".attach" projectile-globally-ignored-file-suffixes)
|
||||
|
||||
;; FIXME Use all-the-icons
|
||||
;; (doom-fix-unicode '("FontAwesome" 13) ? ? ? ? ? ? ? ?)
|
||||
;; Drag-and-drop support
|
||||
(require 'org-download)
|
||||
(setq-default org-download-image-dir +org-attachment-dir
|
||||
org-download-heading-lvl nil
|
||||
org-download-timestamp "_%Y%m%d_%H%M%S")
|
||||
|
||||
(setq org-download-screenshot-method
|
||||
(cond (IS-MAC "screencapture -i %s")
|
||||
(IS-LINUX "maim --opengl -s %s")))
|
||||
|
||||
;; Write download paths relative to current file
|
||||
(advice-add 'org-download--dir-2 :override 'ignore)
|
||||
(defun +org*download-fullname (path)
|
||||
(file-relative-name path (f-dirname (buffer-file-name))))
|
||||
(advice-add 'org-download--fullname :filter-return '+org*download-fullname)
|
||||
|
||||
;; Add another drag-and-drop handler that will handle anything but image files
|
||||
(setq dnd-protocol-alist `(("^\\(https?\\|ftp\\|file\\|nfs\\):\\(//\\)?" . doom/org-download-dnd)
|
||||
,@dnd-protocol-alist))
|
||||
|
||||
;; keybinds
|
||||
;; (@map :leader :n "oa" (@find-file-in +org-attachment-dir))
|
||||
)
|
||||
|
54
modules/lang/org/+capture.el
Normal file
54
modules/lang/org/+capture.el
Normal file
|
@ -0,0 +1,54 @@
|
|||
;;; emacs/org/+capture.el --- -*- no-byte-compile: t; -*-
|
||||
|
||||
;; Sets up a sane `org-capture' workflow, wherein the org-capture buffer is
|
||||
;; opened in a popup frame, and can be invoked from outside Emacs as well.
|
||||
;;
|
||||
;; See `+org/capture'
|
||||
|
||||
(add-hook '+org-init-hook '+org|init-capture t)
|
||||
|
||||
(defun +org|init-capture ()
|
||||
"Set up a sane `org-capture' workflow."
|
||||
(setq org-default-notes-file +org-quicknote-dir)
|
||||
|
||||
(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
|
||||
'(;; TODO: New Task (todo)
|
||||
;; TODO: New vocabulary word
|
||||
|
||||
("c" "Changelog" entry
|
||||
(file+headline (expand-file-name "CHANGELOG.org" (doom/project-root)) "Unreleased")
|
||||
"* %?")
|
||||
|
||||
;; ("p" "Project Notes" entry
|
||||
;; (file+headline org-default-notes-file "Inbox")
|
||||
;; "* %u %?\n%i" :prepend t)
|
||||
|
||||
;; ("m" "Major-mode Notes" entry
|
||||
;; (file+headline org-default-notes-file "Inbox")
|
||||
;; "* %u %?\n%i" :prepend t)
|
||||
|
||||
("n" "Notes" entry
|
||||
(file+headline org-default-notes-file "Inbox")
|
||||
"* %u %?\n%i" :prepend t)
|
||||
|
||||
;; ("v" "Vocab" entry
|
||||
;; (file+headline (concat org-directory "topics/vocab.org") "Unsorted")
|
||||
;; "** %i%?\n")
|
||||
)))
|
||||
|
28
modules/lang/org/+export.el
Normal file
28
modules/lang/org/+export.el
Normal file
|
@ -0,0 +1,28 @@
|
|||
;;; emacs/org/+export.el --- -*- no-byte-compile: t; -*-
|
||||
|
||||
;; My own, centralized exporting system as well.
|
||||
|
||||
(add-hook '+org-init-hook '+org|init-export t)
|
||||
|
||||
(defun +org|init-export ()
|
||||
(setq org-export-directory (expand-file-name ".export" +org-dir)
|
||||
org-export-backends '(ascii html latex md)
|
||||
org-export-with-toc t
|
||||
org-export-with-author t)
|
||||
|
||||
;; Export to a central directory (why isn't this easier?)
|
||||
(unless (file-directory-p org-export-directory)
|
||||
(make-directory org-export-directory t))
|
||||
(defun +org*export-output-file-name (args)
|
||||
(unless (nth 2 args)
|
||||
(setq args (append args (list org-export-directory))))
|
||||
args)
|
||||
(advice-add 'org-export-output-file-name :filter-args '+org*export-output-file-name)
|
||||
|
||||
;; (require 'ox-pandoc)
|
||||
;; (setq org-pandoc-options '((standalone . t) (mathjax . t) (parse-raw . t)))
|
||||
|
||||
;; keybinds
|
||||
;; (@map :leader :n "oe" (@find-file-in org-export-directory))
|
||||
)
|
||||
|
52
modules/lang/org/autoload/attach.el
Normal file
52
modules/lang/org/autoload/attach.el
Normal file
|
@ -0,0 +1,52 @@
|
|||
;;; emacs/org/autoload/attach.el
|
||||
|
||||
(defun doom--org-attach-icon (path)
|
||||
(char-to-string (pcase (downcase (f-ext path))
|
||||
("jpg" ?) ("jpeg" ?) ("png" ?) ("gif" ?)
|
||||
("pdf" ?)
|
||||
("ppt" ?) ("pptx" ?)
|
||||
("xls" ?) ("xlsx" ?)
|
||||
("doc" ?) ("docx" ?)
|
||||
("ogg" ?) ("mp3" ?) ("wav" ?)
|
||||
("mp4" ?) ("mov" ?) ("avi" ?)
|
||||
("zip" ?) ("gz" ?) ("tar" ?) ("7z" ?) ("rar" ?)
|
||||
(_ ?))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +org-cleanup-attachments ()
|
||||
;; "Deletes any attachments that are no longer present in the org-mode buffer."
|
||||
(let* ((attachments-local (+org-attachments))
|
||||
(attachments (f-entries org-attach-directory))
|
||||
(to-delete (-difference attachments-local attachments)))
|
||||
;; TODO
|
||||
to-delete))
|
||||
|
||||
(defun +org-attachments ()
|
||||
(unless (eq major-mode 'org-mode)
|
||||
(user-error "Not an org buffer"))
|
||||
(org-save-outline-visibility nil
|
||||
(let ((attachments '())
|
||||
element
|
||||
file)
|
||||
(when (and (f-dir? org-attach-directory)
|
||||
(> (length (f-glob (concat (f-slash org-attach-directory) "*"))) 0))
|
||||
(save-excursion
|
||||
(goto-char (point-min))
|
||||
(while (progn (org-next-link) (not org-link-search-failed))
|
||||
(setq element (org-element-lineage (org-element-context) '(link) t))
|
||||
(when element
|
||||
(setq file (expand-file-name (org-element-property :path element)))
|
||||
(when (and (string= (org-element-property :type element) "file")
|
||||
(string= (concat (f-base (f-dirname file)) "/") org-attach-directory)
|
||||
(file-exists-p file))
|
||||
(push file attachments))))))
|
||||
(-distinct attachments))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +org-download-dnd (uri action)
|
||||
(if (eq major-mode 'org-mode)
|
||||
(doom:org-attach uri) ;; FIXME
|
||||
(let ((dnd-protocol-alist
|
||||
(rassq-delete-all '+org-download-dnd (copy-alist dnd-protocol-alist))))
|
||||
(dnd-handle-one-url nil action uri))))
|
||||
|
18
modules/lang/org/autoload/capture.el
Normal file
18
modules/lang/org/autoload/capture.el
Normal file
|
@ -0,0 +1,18 @@
|
|||
;;; emacs/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))))))))
|
||||
|
42
modules/lang/org/autoload/evil.el
Normal file
42
modules/lang/org/autoload/evil.el
Normal file
|
@ -0,0 +1,42 @@
|
|||
;;; emacs/org/autoload/evil.el
|
||||
|
||||
;;;###autoload (autoload '+org:capture "emacs/org/autoload/evil" nil t)
|
||||
(evil-define-operator +org:capture (&optional beg end bang)
|
||||
"Send a selection to `doom/org-capture'."
|
||||
:move-point nil :type inclusive
|
||||
(interactive "<r><!>")
|
||||
(doom/org-capture
|
||||
(if (and (evil-visual-state-p) beg end)
|
||||
(buffer-substring beg end)
|
||||
"")))
|
||||
|
||||
;;;###autoload (autoload '+org:attach "emacs/org/autoload/evil" nil t)
|
||||
(evil-define-command +org:attach (&optional uri)
|
||||
(interactive "<a>")
|
||||
(unless (eq major-mode 'org-mode)
|
||||
(user-error "Not in an org-mode buffer"))
|
||||
(if uri
|
||||
(let* ((rel-path (org-download--fullname uri))
|
||||
(new-path (f-expand rel-path))
|
||||
(image-p (image-type-from-file-name uri)))
|
||||
(cond ((string-match-p (concat "^" (regexp-opt '("http" "https" "nfs" "ftp" "file")) ":/") uri)
|
||||
(url-copy-file uri new-path))
|
||||
(t (copy-file uri new-path)))
|
||||
(unless new-path
|
||||
(user-error "No file was provided"))
|
||||
(if (evil-visual-state-p)
|
||||
(org-insert-link nil (format "./%s" rel-path)
|
||||
(concat (buffer-substring-no-properties (region-beginning) (region-end))
|
||||
" " (doom--org-attach-icon rel-path)))
|
||||
|
||||
(insert (if image-p
|
||||
(format "[[./%s]] " rel-path)
|
||||
(format "%s [[./%s][%s]] "
|
||||
(doom--org-attach-icon rel-path)
|
||||
rel-path (f-filename rel-path)))))
|
||||
(when (string-match-p (regexp-opt '("jpg" "jpeg" "gif" "png")) (f-ext rel-path))
|
||||
(org-redisplay-inline-images)))
|
||||
(let ((default-directory ".attach/"))
|
||||
(if (file-exists-p default-directory)
|
||||
(call-interactively 'find-file)
|
||||
(user-error "No attachments")))))
|
268
modules/lang/org/autoload/org.el
Normal file
268
modules/lang/org/autoload/org.el
Normal file
|
@ -0,0 +1,268 @@
|
|||
;;; emacs/org/autoload/org.el
|
||||
|
||||
;;;###autoload
|
||||
(defun +org/indent ()
|
||||
"Indent the current item (header or item). Otherwise, forward to
|
||||
`self-insert-command'."
|
||||
(interactive)
|
||||
(cond ((org-at-item-p)
|
||||
(org-indent-item-tree))
|
||||
((org-at-heading-p)
|
||||
(ignore-errors (org-demote)))
|
||||
(t (call-interactively 'self-insert-command))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +org/indent-or-next-field ()
|
||||
"Depending on the context either indent the current item or go the next table field."
|
||||
(interactive)
|
||||
(call-interactively (if (org-at-table-p) 'org-table-next-field '+org/indent)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +org/dedent ()
|
||||
"Dedent the current item (header or item). Otherwise, forward to
|
||||
`self-insert-command'."
|
||||
(interactive)
|
||||
(cond ((org-at-item-p)
|
||||
(let ((struct (if (org-region-active-p)
|
||||
(save-excursion (goto-char (region-beginning))
|
||||
(org-list-struct))
|
||||
(org-list-struct))))
|
||||
(org-list-indent-item-generic -1 nil struct)))
|
||||
((org-at-heading-p)
|
||||
(ignore-errors (org-promote)))
|
||||
(t (call-interactively 'self-insert-command))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +org/dedent-or-prev-field ()
|
||||
"Depending on the context either dedent the current item or go the previous
|
||||
table field."
|
||||
(interactive)
|
||||
(call-interactively (if (org-at-table-p) 'org-table-previous-field '+org/dedent)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +org/insert-item (direction)
|
||||
"Inserts a new heading, table cell or item, depending on the context.
|
||||
DIRECTION can be 'above or 'below.
|
||||
|
||||
I use this instead of `org-insert-item' or `org-insert-heading' which are too
|
||||
opinionated and perform this simple task incorrectly (e.g. whitespace in the
|
||||
wrong places)."
|
||||
(interactive)
|
||||
(let* ((context (org-element-lineage
|
||||
(org-element-context)
|
||||
'(table table-row headline inlinetask item plain-list)
|
||||
t))
|
||||
(type (org-element-type context)))
|
||||
(cond ((eq type 'item)
|
||||
(let ((marker (org-element-property :bullet context)))
|
||||
(cl-case direction
|
||||
('below
|
||||
(goto-char (line-end-position))
|
||||
(insert (concat "\n" marker)))
|
||||
('above
|
||||
(goto-char (line-beginning-position))
|
||||
(insert marker)
|
||||
(save-excursion (insert "\n")))))
|
||||
(when (org-element-property :checkbox context)
|
||||
(insert "[ ] ")))
|
||||
((memq type '(table table-row))
|
||||
(cl-case direction
|
||||
('below (org-table-insert-row t))
|
||||
('above (+org/table-prepend-row-or-shift-up))))
|
||||
(t
|
||||
(let ((level (save-excursion
|
||||
(org-back-to-heading)
|
||||
(org-element-property
|
||||
:level (org-element-lineage (org-element-context)
|
||||
'(headline) t)))))
|
||||
(cl-case direction
|
||||
('below
|
||||
(let ((at-eol (= (point) (1- (line-end-position)))))
|
||||
(goto-char (line-end-position))
|
||||
(org-end-of-subtree)
|
||||
(insert (concat "\n"
|
||||
(when (= level 1)
|
||||
(if at-eol
|
||||
(ignore (cl-incf level))
|
||||
"\n"))
|
||||
(make-string level ?*)
|
||||
" "))))
|
||||
('above
|
||||
(org-back-to-heading)
|
||||
(org-insert-heading)
|
||||
(when (= level 1)
|
||||
(save-excursion (evil-open-above 1))
|
||||
(save-excursion (insert "\n")))))
|
||||
(when (org-element-property :todo-type context)
|
||||
(org-todo 'todo)))))
|
||||
(evil-append-line 1)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +org/toggle-checkbox ()
|
||||
(interactive)
|
||||
(let ((context (org-element-lineage (org-element-context) '(item) t)))
|
||||
(when context
|
||||
(org-end-of-line)
|
||||
(org-beginning-of-line)
|
||||
(if (org-element-property :checkbox context)
|
||||
(when (search-backward-regexp "\\[[ +-]\\]" (line-beginning-position) t)
|
||||
(delete-char 4))
|
||||
(insert "[ ] ")))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +org/toggle-fold ()
|
||||
"Toggle the local fold at the point (as opposed to cycling through all levels
|
||||
with `org-cycle')."
|
||||
(interactive)
|
||||
(cond ((org-at-heading-p)
|
||||
(outline-toggle-children))
|
||||
((org-at-item-p)
|
||||
(org-cycle))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +org/dwim-at-point ()
|
||||
"Do-what-I-mean at point. This includes following timestamp links, aligning
|
||||
tables, toggling checkboxes/todos, executing babel blocks, previewing latex
|
||||
fragments, opening links, or refreshing images."
|
||||
(interactive)
|
||||
(let* ((scroll-pt (window-start))
|
||||
(context (org-element-context))
|
||||
(type (org-element-type context))
|
||||
(value (org-element-property :value context)))
|
||||
(cond
|
||||
((memq type '(planning timestamp))
|
||||
(org-follow-timestamp-link))
|
||||
|
||||
((memq type '(table table-row))
|
||||
(if (org-element-property :tblfm (org-element-property :parent context))
|
||||
(org-table-recalculate t)
|
||||
(org-table-align)))
|
||||
|
||||
((and (memq type '(item))
|
||||
(org-element-property :checkbox context))
|
||||
(org-toggle-checkbox))
|
||||
|
||||
((and (memq type '(headline))
|
||||
(org-element-property :todo-type context))
|
||||
(org-todo
|
||||
(if (eq (org-element-property :todo-type context) 'done) 'todo 'done)))
|
||||
|
||||
((and (memq type '(headline))
|
||||
(string= "ARCHIVE" (car-safe (org-get-tags))))
|
||||
(org-force-cycle-archived))
|
||||
|
||||
((memq type '(headline))
|
||||
(org-remove-latex-fragment-image-overlays)
|
||||
(org-preview-latex-fragment '(4)))
|
||||
|
||||
((memq type '(babel-call))
|
||||
(org-babel-lob-execute-maybe))
|
||||
|
||||
((memq type '(src-block inline-src-block))
|
||||
(org-babel-execute-src-block))
|
||||
|
||||
((memq type '(latex-fragment latex-environment))
|
||||
(org-preview-latex-fragment))
|
||||
|
||||
((memq type '(link))
|
||||
(let ((path (org-element-property :path (org-element-lineage (org-element-context) '(link) t))))
|
||||
(if (and path (image-type-from-file-name path))
|
||||
(+org/refresh-inline-images)
|
||||
(org-open-at-point))))
|
||||
|
||||
(t (+org/refresh-inline-images)))
|
||||
(set-window-start nil scroll-pt)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +org/refresh-inline-images ()
|
||||
"Refresh image previews in the current heading/tree."
|
||||
(interactive)
|
||||
(if (> (length org-inline-image-overlays) 0)
|
||||
(org-remove-inline-images)
|
||||
(org-display-inline-images
|
||||
t t
|
||||
(if (org-before-first-heading-p)
|
||||
(line-beginning-position)
|
||||
(save-excursion (org-back-to-heading) (point)))
|
||||
(if (org-before-first-heading-p)
|
||||
(line-end-position)
|
||||
(save-excursion (org-end-of-subtree) (point))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +org-surround (delim)
|
||||
"Surround the cursor (or selected region) with DELIM."
|
||||
(if (region-active-p)
|
||||
(save-excursion
|
||||
(goto-char (region-beginning))
|
||||
(insert delim)
|
||||
(goto-char (region-end))
|
||||
(insert delim))
|
||||
(insert delim)
|
||||
(save-excursion (insert delim))))
|
||||
|
||||
|
||||
;;
|
||||
;; tables
|
||||
;;
|
||||
|
||||
;;;###autoload
|
||||
(defun +org/table-next-row ()
|
||||
(interactive)
|
||||
(if (org-at-table-p) (org-table-next-row) (org-down-element)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +org/table-previous-row ()
|
||||
"Go to the previous row (same column) in the current table. Before doing so,
|
||||
re-align the table if necessary. (Necessary because org-mode has a
|
||||
`org-table-next-row', but not `org-table-previous-row')"
|
||||
(interactive)
|
||||
(if (org-at-table-p)
|
||||
(progn
|
||||
(org-table-maybe-eval-formula)
|
||||
(org-table-maybe-recalculate-line)
|
||||
(if (and org-table-automatic-realign
|
||||
org-table-may-need-update)
|
||||
(org-table-align))
|
||||
(let ((col (org-table-current-column)))
|
||||
(beginning-of-line 0)
|
||||
(when (or (not (org-at-table-p)) (org-at-table-hline-p))
|
||||
(beginning-of-line))
|
||||
(org-table-goto-column col)
|
||||
(skip-chars-backward "^|\n\r")
|
||||
(when (org-looking-at-p " ") (forward-char))))
|
||||
(org-up-element)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +org/table-next-field ()
|
||||
(interactive)
|
||||
(if (org-at-table-p) (org-table-next-field) (org-end-of-line)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +org/table-previous-field ()
|
||||
(interactive)
|
||||
(if (org-at-table-p) (org-table-previous-field) (org-beginning-of-line)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +org/table-append-field-or-shift-right ()
|
||||
(interactive)
|
||||
(org-shiftmetaright)
|
||||
(when (org-at-table-p) (org-metaright)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +org/table-prepend-field-or-shift-left ()
|
||||
(interactive)
|
||||
(if (org-at-table-p) (org-shiftmetaright) (org-shiftmetaleft)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +org/table-append-row-or-shift-down ()
|
||||
(interactive)
|
||||
(org-shiftmetadown)
|
||||
(when (org-at-table-p) (org-metadown)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +org/table-prepend-row-or-shift-up ()
|
||||
(interactive)
|
||||
(if (org-at-table-p)
|
||||
(org-shiftmetadown)
|
||||
(org-shiftmetaup)))
|
||||
|
10
modules/lang/org/autoload/util.el
Normal file
10
modules/lang/org/autoload/util.el
Normal file
|
@ -0,0 +1,10 @@
|
|||
;;; emacs/org/autoload/util.el
|
||||
|
||||
;;;###autoload
|
||||
(defun +org-get-property (name &optional file)
|
||||
"Get a propery from an org file."
|
||||
(save-excursion
|
||||
(goto-char 1)
|
||||
(re-search-forward (format "^#\\+%s:[ \t]*\\([^\n]+\\)" (upcase name)) nil t)
|
||||
(buffer-substring-no-properties (match-beginning 1) (match-end 1))))
|
||||
|
386
modules/lang/org/config.el
Normal file
386
modules/lang/org/config.el
Normal file
|
@ -0,0 +1,386 @@
|
|||
;;; emacs/org/config.el --- -*- no-byte-compile: t; -*-
|
||||
|
||||
;; A few things you can expect
|
||||
;; + `org-capture' in a popup frame (can be invoked from outside emacs too)
|
||||
;; + A simpler attachment system (with auto-deleting support) and
|
||||
;; drag-and-drop for images and documents into org files
|
||||
;; + Exported files are put in a centralized location (see
|
||||
;; `org-export-directory')
|
||||
;; + TODO Custom links for class notes
|
||||
;; + TODO An org-mode based CRM (including invoicing and pdf exporting) (see custom-crm)
|
||||
;; + TODO A tag-based file browser reminiscient of Evernote and Quiver (there's neotree too!)
|
||||
|
||||
(defvar +org-init-hook nil
|
||||
"TODO")
|
||||
|
||||
(add-hook 'org-load-hook '+org|init)
|
||||
(add-hook 'org-mode-hook '+org|hook)
|
||||
|
||||
;; Custom variables
|
||||
(defvar +org-dir "~/work/org/"
|
||||
"The directory where org files are kept.")
|
||||
|
||||
(defvaralias 'org-directory '+org-dir)
|
||||
|
||||
(defvar +org-notes-dir (concat +org-dir "notes")
|
||||
"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/"
|
||||
"Where to store attachments (relative to current org file).")
|
||||
|
||||
;; (defvar-local +org-attachments-list '()
|
||||
;; "A list of attachments for the current buffer. This is so my custom attachment
|
||||
;; system can keep track of each buffer's attachments.")
|
||||
|
||||
(@load +attach)
|
||||
(@load +capture)
|
||||
(@load +export)
|
||||
|
||||
|
||||
;;
|
||||
;; Config
|
||||
;;
|
||||
|
||||
(defun +org|hook ()
|
||||
"Run everytime `org-mode' is enabled."
|
||||
(evil-org-mode +1)
|
||||
(visual-line-mode +1)
|
||||
(setq line-spacing 1)
|
||||
|
||||
;; If saveplace places the point in a folded position, unfold it on load
|
||||
(when (outline-invisible-p)
|
||||
(ignore-errors
|
||||
(save-excursion
|
||||
(outline-previous-visible-heading 1)
|
||||
(org-show-subtree))))
|
||||
|
||||
(defun +org|update ()
|
||||
"Update counts on headlines (\"cookies\")."
|
||||
(when (file-exists-p buffer-file-name)
|
||||
(org-update-statistics-cookies t)))
|
||||
|
||||
(add-hook 'before-save-hook '+org|update nil t)
|
||||
(add-hook 'evil-insert-state-exit-hook '+org|update nil t))
|
||||
|
||||
|
||||
(defun +org|init ()
|
||||
"Initializes org core."
|
||||
(define-minor-mode evil-org-mode
|
||||
"Evil-mode bindings for org-mode."
|
||||
:init-value nil
|
||||
:lighter " !"
|
||||
:keymap (make-sparse-keymap)
|
||||
: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
|
||||
org-export-coding-system 'utf-8
|
||||
|
||||
;; Appearance
|
||||
outline-blank-line t
|
||||
org-indent-mode-turns-on-hiding-stars t
|
||||
org-adapt-indentation nil
|
||||
org-blank-before-new-entry '((heading . nil) (plain-list-item . auto))
|
||||
org-cycle-separator-lines 1
|
||||
org-cycle-include-plain-lists t
|
||||
org-ellipsis 'doom-folded-face
|
||||
org-entities-user '(("flat" "\\flat" nil "" "" "266D" "♭")
|
||||
("sharp" "\\sharp" nil "" "" "266F" "♯"))
|
||||
org-fontify-done-headline t
|
||||
org-fontify-quote-and-verse-blocks t
|
||||
org-fontify-whole-heading-line t
|
||||
org-footnote-auto-label 'plain
|
||||
org-hide-emphasis-markers t
|
||||
org-hide-leading-stars t
|
||||
org-image-actual-width nil
|
||||
org-indent-indentation-per-level 2
|
||||
org-pretty-entities t
|
||||
org-pretty-entities-include-sub-superscripts t
|
||||
org-startup-folded t
|
||||
org-startup-indented t
|
||||
org-startup-with-inline-images nil
|
||||
org-tags-column 0
|
||||
org-use-sub-superscripts '{}
|
||||
|
||||
;; Behavior
|
||||
org-catch-invisible-edits 'show
|
||||
org-checkbox-hierarchical-statistics nil
|
||||
org-completion-use-ido nil ; Use ivy/counsel for refiling
|
||||
org-confirm-elisp-link-function nil
|
||||
org-default-priority ?C
|
||||
org-hidden-keywords '(title)
|
||||
org-hierarchical-todo-statistics t
|
||||
org-log-done t
|
||||
org-loop-over-headlines-in-active-region t
|
||||
org-outline-path-complete-in-steps nil
|
||||
org-refile-use-outline-path t
|
||||
org-special-ctrl-a/e t
|
||||
|
||||
;; Sorting/refiling
|
||||
org-archive-location (concat +org-dir "/archived/%s::")
|
||||
org-refile-targets '((nil . (:maxlevel . 2))) ; display full path in refile completion
|
||||
|
||||
;; Agenda
|
||||
org-agenda-restore-windows-after-quit nil
|
||||
org-agenda-skip-unavailable-files nil
|
||||
org-agenda-dim-blocked-tasks nil
|
||||
org-agenda-window-setup 'other-frame ; to get org-agenda to behave with shackle...
|
||||
org-agenda-inhibit-startup t
|
||||
org-agenda-files (directory-files +org-dir t "\\.org$" t)
|
||||
org-todo-keywords '((sequence "[ ](t)" "[-](p)" "[?](m)" "|" "[X](d)")
|
||||
(sequence "TODO(T)" "|" "DONE(D)")
|
||||
(sequence "IDEA(i)" "NEXT(n)" "ACTIVE(a)" "WAITING(w)" "LATER(l)" "|" "CANCELLED(c)"))
|
||||
|
||||
|
||||
;; Babel
|
||||
org-confirm-babel-evaluate nil ; you don't need my permission
|
||||
org-src-fontify-natively t ; make code pretty
|
||||
org-src-preserve-indentation t
|
||||
org-src-tab-acts-natively t
|
||||
org-src-window-setup 'current-window
|
||||
org-edit-src-content-indentation 0
|
||||
|
||||
;; Latex
|
||||
org-format-latex-options
|
||||
(plist-put org-format-latex-options :scale 1.5)
|
||||
org-format-latex-options
|
||||
(plist-put org-format-latex-options
|
||||
:background (face-attribute (or (cadr (assq 'default face-remapping-alist))
|
||||
'default)
|
||||
:background nil t))
|
||||
|
||||
org-highlight-latex-and-related '(latex)
|
||||
org-latex-create-formula-image-program 'dvipng
|
||||
org-latex-image-default-width ".9\\linewidth"
|
||||
org-latex-preview-ltxpng-directory (concat doom-cache-dir "/ltxpng/")
|
||||
org-latex-remove-logfiles nil
|
||||
org-startup-with-latex-preview nil
|
||||
;; org-latex-packages-alist
|
||||
;; '(("" "gauss" t)
|
||||
;; ("" "physics" t) TODO Install this)
|
||||
)
|
||||
|
||||
(org-babel-do-load-languages
|
||||
'org-babel-load-languages
|
||||
'((python . t) (ruby . t) (sh . t) (js . t) (css . t)
|
||||
(plantuml . t) (emacs-lisp . t) (matlab . t)
|
||||
(latex . t) (calc . t) (lisp . t) (lilypond . t)
|
||||
;; (go . t)
|
||||
;; (http . t)
|
||||
;; (rust . t)
|
||||
))
|
||||
|
||||
(let ((ext-regexp (regexp-opt '("GIF" "JPG" "JPEG" "SVG" "TIF" "TIFF" "BMP" "XPM"
|
||||
"gif" "jpg" "jpeg" "svg" "tif" "tiff" "bmp" "xpm"))))
|
||||
(setq iimage-mode-image-regex-alist
|
||||
`((,(concat "\\(`?file://\\|\\[\\[\\|<\\|`\\)?\\([-+./_0-9a-zA-Z]+\\."
|
||||
ext-regexp "\\)\\(\\]\\]\\|>\\|'\\)?") . 2)
|
||||
(,(concat "<\\(http://.+\\." ext-regexp "\\)>") . 1))))
|
||||
|
||||
;; Fontify checkboxes and dividers
|
||||
(defface org-list-bullet
|
||||
'((t (:inherit font-lock-keyword-face)))
|
||||
"Face for list bullets")
|
||||
|
||||
(font-lock-add-keywords
|
||||
'org-mode '(("^ *\\([-+]\\|[0-9]+[).]\\) "
|
||||
(1 'org-list-bullet))
|
||||
("^ *\\(-----+\\)$"
|
||||
(1 'org-meta-line))))
|
||||
|
||||
;; Enable gpg support
|
||||
(require 'epa-file)
|
||||
(epa-file-enable)
|
||||
(require 'org-crypt)
|
||||
(org-crypt-use-before-save-magic)
|
||||
(setq org-tags-exclude-from-inheritance '("crypt")
|
||||
org-crypt-key user-mail-address
|
||||
epa-file-encrypt-to user-mail-address)
|
||||
|
||||
;; smartparens config
|
||||
(sp-with-modes '(org-mode)
|
||||
(sp-local-pair "\\[" "\\]" :post-handlers '(("| " "SPC")))
|
||||
(sp-local-pair "\\(" "\\)" :post-handlers '(("| " "SPC")))
|
||||
(sp-local-pair "$$" "$$" :post-handlers '((:add " | ")) :unless '(sp-point-at-bol-p))
|
||||
(sp-local-pair "{" nil))
|
||||
|
||||
;; bullets
|
||||
(@def-package org-bullets :commands org-bullets-mode)
|
||||
|
||||
;; Keybinds
|
||||
(@map (:map org-mode-map
|
||||
"RET" nil
|
||||
"C-j" nil
|
||||
"C-k" nil
|
||||
:i [remap doom/inflate-space-maybe] 'org-self-insert-command
|
||||
:i "RET" 'org-return-indent)
|
||||
|
||||
(:map evil-org-mode-map
|
||||
:n "RET" '+org/dwim-at-point
|
||||
;;
|
||||
:ni "A-l" 'org-metaright
|
||||
:ni "A-h" 'org-metaleft
|
||||
:ni "A-k" 'org-metaup
|
||||
:ni "A-j" 'org-metadown
|
||||
:ni "A-L" 'org-shiftmetaright
|
||||
:ni "A-H" 'org-shiftmetaleft
|
||||
:ni "A-K" 'org-shiftmetaup
|
||||
:ni "A-J" 'org-shiftmetadown
|
||||
;; Expand tables (or shiftmeta move)
|
||||
:ni "C-S-l" '+org/table-append-field-or-shift-right
|
||||
:ni "C-S-h" '+org/table-prepend-field-or-shift-left
|
||||
:ni "C-S-k" '+org/table-prepend-row-or-shift-up
|
||||
:ni "C-S-j" '+org/table-append-row-or-shift-down
|
||||
;; Navigate table cells
|
||||
:i "C-L" '+org/table-next-field
|
||||
:i "C-H" '+org/table-previous-field
|
||||
:i "C-K" '+org/table-previous-row
|
||||
:i "C-J" '+org/table-next-row
|
||||
|
||||
:i "C-e" 'org-end-of-line
|
||||
:i "C-a" 'org-beginning-of-line
|
||||
|
||||
:i "<tab>" '+org/indent-or-next-field
|
||||
:i [S-iso-lefttab] '+org/dedent-or-prev-field ; for GNU Emacs
|
||||
:i [(shift tab)] '+org/dedent-or-prev-field
|
||||
:i [backtab] '+org/dedent-or-prev-field
|
||||
|
||||
:n "<tab>" '+org/toggle-fold
|
||||
|
||||
:nv "j" 'evil-next-visual-line
|
||||
:nv "k" 'evil-previous-visual-line
|
||||
:v "<S-tab>" '+snippets/expand-on-region
|
||||
|
||||
:i "M-a" (@λ (evil-visual-state) (org-mark-element))
|
||||
:n "M-a" 'org-mark-element
|
||||
:v "M-a" 'mark-whole-buffer
|
||||
|
||||
:ni "<M-return>" (@λ (doom/org-insert-item 'below))
|
||||
:ni "<S-M-return>" (@λ (doom/org-insert-item 'above))
|
||||
|
||||
;; Formatting shortcuts
|
||||
:i "M-b" (@λ (doom/org-surround "*")) ; bold
|
||||
:i "M-u" (@λ (doom/org-surround "_")) ; underline
|
||||
:i "M-i" (@λ (doom/org-surround "/")) ; italics
|
||||
:i "M-`" (@λ (doom/org-surround "+")) ; strikethrough
|
||||
|
||||
:v "M-b" "S*"
|
||||
:v "M-u" "S_"
|
||||
:v "M-i" "S/"
|
||||
:v "M-`" "S+"
|
||||
|
||||
(:localleader
|
||||
:n "RET" 'org-archive-subtree
|
||||
:n "SPC" 'doom/org-toggle-checkbox
|
||||
:n "/" 'org-sparse-tree
|
||||
:n "=" 'org-align-all-tags
|
||||
:n "?" 'org-tags-view
|
||||
:n "D" 'org-deadline
|
||||
:nv "L" 'org-store-link
|
||||
:n "R" (@λ (org-metaleft) (org-archive-to-archive-sibling)) ; archive to parent sibling
|
||||
:n "T" 'org-todo
|
||||
:n "a" 'org-agenda
|
||||
:n "d" 'org-time-stamp
|
||||
:n "e" 'org-edit-special
|
||||
:n "i" 'doom/org-toggle-inline-images-at-point
|
||||
:n "l" 'org-insert-link
|
||||
:n "n" (@λ (if (buffer-narrowed-p) (widen) (org-narrow-to-subtree)))
|
||||
:n "r" 'org-refile
|
||||
:n "s" 'org-schedule
|
||||
:n "t" (@λ (org-todo (if (org-entry-is-todo-p) 'none 'todo)))
|
||||
:v "t" (@λ (evil-ex-normal evil-visual-beginning evil-visual-end "\\t"))
|
||||
:n "v" 'variable-pitch-mode
|
||||
;; :n "w" 'writing-mode
|
||||
:n "x" 'doom/org-remove-link)
|
||||
|
||||
;; TODO Improve folding bindings
|
||||
:n "za" 'doom/org-toggle-fold
|
||||
:n "zA" 'org-shifttab
|
||||
:n "zc" 'outline-hide-subtree
|
||||
:n "zC" (@λ (outline-hide-sublevels 1))
|
||||
:n "zd" (lambda (&optional arg) (interactive "p") (outline-hide-sublevels (or arg 3)))
|
||||
:n "zm" (@λ (outline-hide-sublevels 1))
|
||||
:n "zo" 'outline-show-subtree
|
||||
:n "zO" 'outline-show-all
|
||||
:n "zr" 'outline-show-all
|
||||
|
||||
:m "]]" (@λ (call-interactively 'org-forward-heading-same-level) (org-beginning-of-line))
|
||||
:m "[[" (@λ (call-interactively 'org-backward-heading-same-level) (org-beginning-of-line))
|
||||
:m "]l" 'org-next-link
|
||||
:m "[l" 'org-previous-link
|
||||
|
||||
:m "gh" 'outline-up-heading
|
||||
:m "gj" 'org-forward-heading-same-level
|
||||
:m "gk" 'org-backward-heading-same-level
|
||||
:m "gl" (@λ (call-interactively 'outline-next-visible-heading) (show-children))
|
||||
|
||||
:n "go" 'org-open-at-point
|
||||
:n "gO" (@λ (let ((org-link-frame-setup (append '((file . find-file-other-window)) org-link-frame-setup))
|
||||
(org-file-apps '(("\\.org$" . emacs)
|
||||
(t . "open \"%s\""))))
|
||||
(call-interactively 'org-open-at-point)))
|
||||
|
||||
:n "gQ" 'org-fill-paragraph
|
||||
:m "$" 'org-end-of-line
|
||||
:m "^" 'org-beginning-of-line
|
||||
:n "<" 'org-metaleft
|
||||
:n ">" 'org-metaright
|
||||
:v "<" (@λ (org-metaleft) (evil-visual-restore))
|
||||
:v ">" (@λ (org-metaright) (evil-visual-restore))
|
||||
:n "-" 'org-cycle-list-bullet
|
||||
:m "<tab>" 'org-cycle)
|
||||
|
||||
(:map org-src-mode-map
|
||||
:n "<escape>" (@λ (message "Exited") (org-edit-src-exit)))
|
||||
|
||||
(:after org-agenda
|
||||
(:map org-agenda-mode-map
|
||||
:e "<escape>" 'org-agenda-Quit
|
||||
:e "m" 'org-agenda-month-view
|
||||
:e "C-j" 'org-agenda-next-item
|
||||
:e "C-k" 'org-agenda-previous-item
|
||||
:e "C-n" 'org-agenda-next-item
|
||||
:e "C-p" 'org-agenda-previous-item)))
|
||||
|
||||
;; Initialize everything else
|
||||
(run-hooks '+org-init-hook)
|
||||
(+org|hacks))
|
||||
|
||||
|
||||
(defun +org|hacks ()
|
||||
"Getting org to behave."
|
||||
;; Don't open separate windows
|
||||
(push '(file . find-file) org-link-frame-setup)
|
||||
|
||||
;; Let OS decide what to do with files when opened
|
||||
(setq org-file-apps
|
||||
`(("\\.org$" . emacs)
|
||||
(t . ,(cond (IS-MAC "open -R \"%s\"")
|
||||
(IS-LINUX "xdg-open \"%s\"")))))
|
||||
|
||||
;; Don't clobber recentf with agenda files
|
||||
(defun +org-is-agenda-file (filename)
|
||||
(find (file-truename filename) org-agenda-files :key 'file-truename
|
||||
:test 'equal))
|
||||
(add-to-list 'recentf-exclude '+org-is-agenda-file)
|
||||
|
||||
;; Remove highlights on ESC
|
||||
(defun +org*remove-occur-highlights (&rest args)
|
||||
(when (eq major-mode 'org-mode)
|
||||
(org-remove-occur-highlights)))
|
||||
(advice-add 'evil-force-normal-state :before '+org*remove-occur-highlights)
|
||||
|
||||
;; Don't reset org-hide!
|
||||
(advice-add 'org-find-invisible-foreground :override 'ignore))
|
||||
|
10
modules/lang/org/packages.el
Normal file
10
modules/lang/org/packages.el
Normal file
|
@ -0,0 +1,10 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; emacs/org/packages.el
|
||||
|
||||
(@package org-plus-contrib)
|
||||
(@package org-download)
|
||||
;; (@package ox-pandox)
|
||||
;; (@package org-bullets)
|
||||
;; (@package ob-go :recipe (:fetcher github :repo "pope/ob-go"))
|
||||
;; (@package ob-http)
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue