org-mode: major rewrite + refactor
This commit is contained in:
parent
77b1a93231
commit
dbacc26e11
7 changed files with 387 additions and 516 deletions
|
@ -105,5 +105,43 @@
|
||||||
(goto-char (cdr location))
|
(goto-char (cdr location))
|
||||||
(message "Unable to find location in file"))))))
|
(message "Unable to find location in file"))))))
|
||||||
|
|
||||||
|
(add-hook! org-load
|
||||||
|
;; Ensures org-src-edit yields control of its buffer to shackle.
|
||||||
|
(defun org-src-switch-to-buffer (buffer context)
|
||||||
|
(pop-to-buffer buffer))
|
||||||
|
|
||||||
|
;; And these for org-todo, org-link and org-agenda
|
||||||
|
(defun org-pop-to-buffer-same-window (&optional buffer-or-name norecord label)
|
||||||
|
"Pop to buffer specified by BUFFER-OR-NAME in the selected window."
|
||||||
|
(display-buffer buffer-or-name))
|
||||||
|
|
||||||
|
(defun org-switch-to-buffer-other-window (&rest args)
|
||||||
|
(car-safe
|
||||||
|
(mapc (lambda (b)
|
||||||
|
(let ((buf (if (stringp b) (get-buffer-create b) b)))
|
||||||
|
(pop-to-buffer buf t t)))
|
||||||
|
args)))
|
||||||
|
|
||||||
|
(defun doom/org-agenda-quit ()
|
||||||
|
"Necessary to finagle org-agenda into shackle popups and behave properly on quit."
|
||||||
|
(interactive)
|
||||||
|
(if org-agenda-columns-active
|
||||||
|
(org-columns-quit)
|
||||||
|
(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
|
||||||
|
(map! :map org-agenda-mode-map
|
||||||
|
:e "<escape>" 'doom/org-agenda-quit
|
||||||
|
:e "ESC" 'doom/org-agenda-quit
|
||||||
|
:e [escape] 'doom/org-agenda-quit
|
||||||
|
"q" 'doom/org-agenda-quit
|
||||||
|
"Q" 'doom/org-agenda-quit)))
|
||||||
|
|
||||||
(provide 'core-popup)
|
(provide 'core-popup)
|
||||||
;;; core-popup.el ends here
|
;;; core-popup.el ends here
|
||||||
|
|
2
init.el
2
init.el
|
@ -79,8 +79,6 @@
|
||||||
|
|
||||||
;;; Org
|
;;; Org
|
||||||
module-org ; for organized fearless leader
|
module-org ; for organized fearless leader
|
||||||
module-org-notes ; org-mode as a (modern?) note-taking platform
|
|
||||||
module-org-crm ; org-mode for business management
|
|
||||||
|
|
||||||
;;; Custom/experimental modules
|
;;; Custom/experimental modules
|
||||||
custom-db ; emacs as a db browser/client
|
custom-db ; emacs as a db browser/client
|
||||||
|
|
|
@ -1,112 +0,0 @@
|
||||||
;;; defuns-org-notes.el
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/org ()
|
|
||||||
(interactive)
|
|
||||||
(find-file (f-expand "inbox.org" org-directory)))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/org-notebook-new ()
|
|
||||||
(interactive)
|
|
||||||
(projectile-invalidate-cache nil)
|
|
||||||
(let* ((default-directory org-directory)
|
|
||||||
(dir (projectile-complete-dir))
|
|
||||||
(doom-org-quicknote-dir dir))
|
|
||||||
(when dir
|
|
||||||
(doom/org-notebook-quick-note))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/org-notebook-quick-note ()
|
|
||||||
(interactive)
|
|
||||||
(let (text)
|
|
||||||
(when (evil-visual-state-p)
|
|
||||||
(setq text (buffer-substring-no-properties evil-visual-beginning evil-visual-end)))
|
|
||||||
(switch-to-buffer (generate-new-buffer "*quick-note*"))
|
|
||||||
(setq default-directory doom-org-quicknote-dir)
|
|
||||||
(erase-buffer)
|
|
||||||
(insert text)))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/org-download-dnd (uri action)
|
|
||||||
(if (eq major-mode 'org-mode)
|
|
||||||
(doom:org-attach uri)
|
|
||||||
(let ((dnd-protocol-alist
|
|
||||||
(rassq-delete-all 'doom/org-download-dnd (copy-alist dnd-protocol-alist))))
|
|
||||||
(dnd-handle-one-url nil action uri))))
|
|
||||||
|
|
||||||
;;;###autoload (autoload 'doom:org-attach "defuns-org-notes" nil t)
|
|
||||||
(evil-define-command doom: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")))))
|
|
||||||
|
|
||||||
(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 doom/org-cleanup-attachments ()
|
|
||||||
;; "Deletes any attachments that are no longer present in the org-mode buffer."
|
|
||||||
(let* ((attachments-local (doom-org-attachments))
|
|
||||||
(attachments (f-entries org-attach-directory))
|
|
||||||
(to-delete (-difference attachments-local attachments)))
|
|
||||||
;; TODO
|
|
||||||
to-delete))
|
|
||||||
|
|
||||||
(defun doom-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))))
|
|
||||||
|
|
||||||
|
|
||||||
(provide 'defuns-org-notes)
|
|
||||||
;;; defuns-org-notes.el ends here
|
|
|
@ -1,31 +1,5 @@
|
||||||
;;; defuns-org.el
|
;;; defuns-org.el
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/org-find-file-in-notes ()
|
|
||||||
(interactive)
|
|
||||||
(let ((default-directory (f-slash org-directory)))
|
|
||||||
(projectile-find-file)))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/org-find-file ()
|
|
||||||
(interactive)
|
|
||||||
(let ((default-directory (f-slash org-directory)))
|
|
||||||
(counsel-find-file)))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/org-find-exported-file ()
|
|
||||||
(interactive)
|
|
||||||
(let ((default-directory (f-slash doom-org-export-directory)))
|
|
||||||
(counsel-find-file)))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/org-get-property (name)
|
|
||||||
(interactive)
|
|
||||||
(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))))
|
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun doom/org-indent ()
|
(defun doom/org-indent ()
|
||||||
"Indent the current item (header or item). Otherwise, forward to
|
"Indent the current item (header or item). Otherwise, forward to
|
||||||
|
@ -63,7 +37,8 @@
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun doom/org-dedent-or-prev-field ()
|
(defun doom/org-dedent-or-prev-field ()
|
||||||
"Depending on the context either dedent the current item or go the previous table field."
|
"Depending on the context either dedent the current item or go the previous
|
||||||
|
table field."
|
||||||
(interactive)
|
(interactive)
|
||||||
(call-interactively (if (org-at-table-p) 'org-table-previous-field 'doom/org-dedent)))
|
(call-interactively (if (org-at-table-p) 'org-table-previous-field 'doom/org-dedent)))
|
||||||
|
|
||||||
|
@ -139,6 +114,9 @@ wrong places)."
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun doom/org-dwim-at-point ()
|
(defun doom/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)
|
(interactive)
|
||||||
(let* ((scroll-pt (window-start))
|
(let* ((scroll-pt (window-start))
|
||||||
(context (org-element-context))
|
(context (org-element-context))
|
||||||
|
@ -190,6 +168,7 @@ wrong places)."
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun doom/org-refresh-inline-images ()
|
(defun doom/org-refresh-inline-images ()
|
||||||
|
"Refresh image previews in the current heading/tree."
|
||||||
(interactive)
|
(interactive)
|
||||||
(if (> (length org-inline-image-overlays) 0)
|
(if (> (length org-inline-image-overlays) 0)
|
||||||
(org-remove-inline-images)
|
(org-remove-inline-images)
|
||||||
|
@ -202,9 +181,9 @@ wrong places)."
|
||||||
(line-end-position)
|
(line-end-position)
|
||||||
(save-excursion (org-end-of-subtree) (point))))))
|
(save-excursion (org-end-of-subtree) (point))))))
|
||||||
|
|
||||||
;; Formatting shortcuts
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun doom/org-surround (delim)
|
(defun doom/org-surround (delim)
|
||||||
|
"Surround the cursor (or selected region) with DELIM."
|
||||||
(if (region-active-p)
|
(if (region-active-p)
|
||||||
(save-excursion
|
(save-excursion
|
||||||
(goto-char (region-beginning))
|
(goto-char (region-beginning))
|
||||||
|
@ -214,89 +193,10 @@ wrong places)."
|
||||||
(insert delim)
|
(insert delim)
|
||||||
(save-excursion (insert delim))))
|
(save-excursion (insert delim))))
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/org-word-count (beg end &optional count-footnotes?)
|
|
||||||
"Report the number of words in the Org mode buffer or selected region.
|
|
||||||
Ignores:
|
|
||||||
- comments
|
|
||||||
- tables
|
|
||||||
- source code blocks (#+BEGIN_SRC ... #+END_SRC, and inline blocks)
|
|
||||||
- hyperlinks (but does count words in hyperlink descriptions)
|
|
||||||
- tags, priorities, and TODO keywords in headers
|
|
||||||
- sections tagged as 'not for export'.
|
|
||||||
|
|
||||||
The text of footnote definitions is ignored, unless the optional argument
|
;;
|
||||||
COUNT-FOOTNOTES? is non-nil."
|
;; tables
|
||||||
(interactive "r")
|
;;
|
||||||
(unless mark-active
|
|
||||||
(setf beg (point-min)
|
|
||||||
end (point-max)))
|
|
||||||
(let ((wc 0))
|
|
||||||
(save-excursion
|
|
||||||
(goto-char beg)
|
|
||||||
(while (< (point) end)
|
|
||||||
(cond
|
|
||||||
;; Ignore comments.
|
|
||||||
((or (org-at-comment-p) (org-at-table-p))
|
|
||||||
nil)
|
|
||||||
;; Ignore hyperlinks. But if link has a description, count
|
|
||||||
;; the words within the description.
|
|
||||||
((looking-at org-bracket-link-analytic-regexp)
|
|
||||||
(when (match-string-no-properties 5)
|
|
||||||
(let ((desc (match-string-no-properties 5)))
|
|
||||||
(save-match-data
|
|
||||||
(incf wc (length (remove "" (org-split-string
|
|
||||||
desc "\\W")))))))
|
|
||||||
(goto-char (match-end 0)))
|
|
||||||
((looking-at org-any-link-re)
|
|
||||||
(goto-char (match-end 0)))
|
|
||||||
;; Ignore source code blocks.
|
|
||||||
((org-between-regexps-p "^#\\+BEGIN_SRC\\W" "^#\\+END_SRC\\W")
|
|
||||||
nil)
|
|
||||||
;; Ignore inline source blocks, counting them as 1 word.
|
|
||||||
((save-excursion
|
|
||||||
(backward-char)
|
|
||||||
(looking-at org-babel-inline-src-block-regexp))
|
|
||||||
(goto-char (match-end 0))
|
|
||||||
(setf wc (+ 2 wc)))
|
|
||||||
;; Ignore footnotes.
|
|
||||||
((and (not count-footnotes?)
|
|
||||||
(or (org-footnote-at-definition-p)
|
|
||||||
(org-footnote-at-reference-p)))
|
|
||||||
nil)
|
|
||||||
(t
|
|
||||||
(let ((contexts (org-context)))
|
|
||||||
(cond
|
|
||||||
;; Ignore tags and TODO keywords, etc.
|
|
||||||
((or (assoc :todo-keyword contexts)
|
|
||||||
(assoc :priority contexts)
|
|
||||||
(assoc :keyword contexts)
|
|
||||||
(assoc :checkbox contexts))
|
|
||||||
nil)
|
|
||||||
;; Ignore sections marked with tags that are
|
|
||||||
;; excluded from export.
|
|
||||||
((assoc :tags contexts)
|
|
||||||
(if (intersection (org-get-tags-at) org-export-exclude-tags
|
|
||||||
:test 'equal)
|
|
||||||
(org-forward-same-level 1)
|
|
||||||
nil))
|
|
||||||
(t
|
|
||||||
(incf wc))))))
|
|
||||||
(re-search-forward "\\w+\\W*")))
|
|
||||||
(message (format "%d words in %s." wc
|
|
||||||
(if mark-active "region" "buffer")))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun doom/org-remove-link ()
|
|
||||||
"Replace an org link by its description or if empty its address"
|
|
||||||
(interactive)
|
|
||||||
(if (org-in-regexp org-bracket-link-regexp 1)
|
|
||||||
(let ((remove (list (match-beginning 0) (match-end 0)))
|
|
||||||
(description (if (match-end 3)
|
|
||||||
(org-match-string-no-properties 3)
|
|
||||||
(org-match-string-no-properties 1))))
|
|
||||||
(apply 'delete-region remove)
|
|
||||||
(insert description))))
|
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun doom/org-table-next-row ()
|
(defun doom/org-table-next-row ()
|
||||||
|
@ -305,8 +205,25 @@ COUNT-FOOTNOTES? is non-nil."
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun doom/org-table-previous-row ()
|
(defun doom/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)
|
(interactive)
|
||||||
(if (org-at-table-p) (doom--org-table-previous-row) (org-up-element)))
|
(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
|
;;;###autoload
|
||||||
(defun doom/org-table-next-field ()
|
(defun doom/org-table-next-field ()
|
||||||
|
@ -327,9 +244,7 @@ COUNT-FOOTNOTES? is non-nil."
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun doom/org-table-prepend-field-or-shift-left ()
|
(defun doom/org-table-prepend-field-or-shift-left ()
|
||||||
(interactive)
|
(interactive)
|
||||||
(if (org-at-table-p)
|
(if (org-at-table-p) (org-shiftmetaright) (org-shiftmetaleft)))
|
||||||
(org-shiftmetaright)
|
|
||||||
(org-shiftmetaleft)))
|
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun doom/org-table-append-row-or-shift-down ()
|
(defun doom/org-table-append-row-or-shift-down ()
|
||||||
|
@ -344,23 +259,10 @@ COUNT-FOOTNOTES? is non-nil."
|
||||||
(org-shiftmetadown)
|
(org-shiftmetadown)
|
||||||
(org-shiftmetaup)))
|
(org-shiftmetaup)))
|
||||||
|
|
||||||
(defun doom--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
|
;; Links
|
||||||
`org-table-next-row', but not `org-table-previous-row')"
|
;;
|
||||||
(interactive)
|
|
||||||
(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))))
|
|
||||||
|
|
||||||
;;;###autoload (autoload 'doom:org-link "defuns-org" nil t)
|
;;;###autoload (autoload 'doom:org-link "defuns-org" nil t)
|
||||||
(evil-define-command doom:org-link (link)
|
(evil-define-command doom:org-link (link)
|
||||||
|
@ -373,22 +275,134 @@ re-align the table if necessary. (Necessary because org-mode has a
|
||||||
(org-insert-link nil link (when (and beg end) (buffer-substring-no-properties beg end)))))
|
(org-insert-link nil link (when (and beg end) (buffer-substring-no-properties beg end)))))
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun doom/sp-org-skip-asterisk (ms mb me)
|
(defun doom/org-remove-link ()
|
||||||
(or (and (= (line-beginning-position) mb)
|
"Replace an org link by its description or if empty its address"
|
||||||
(eq 32 (char-after (1+ mb))))
|
(interactive)
|
||||||
(and (= (1+ (line-beginning-position)) me)
|
(if (org-in-regexp org-bracket-link-regexp 1)
|
||||||
(eq 32 (char-after me)))))
|
(let ((remove (list (match-beginning 0) (match-end 0)))
|
||||||
|
(description (if (match-end 3)
|
||||||
|
(org-match-string-no-properties 3)
|
||||||
|
(org-match-string-no-properties 1))))
|
||||||
|
(apply 'delete-region remove)
|
||||||
|
(insert description))))
|
||||||
|
|
||||||
|
|
||||||
|
;;
|
||||||
|
;; org-capture
|
||||||
|
;;
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun doom/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))))))))
|
||||||
|
|
||||||
;;;###autoload (autoload 'doom:org-capture "defuns-org" nil t)
|
;;;###autoload (autoload 'doom:org-capture "defuns-org" nil t)
|
||||||
(evil-define-operator doom:org-capture (&optional beg end bang)
|
(evil-define-operator doom:org-capture (&optional beg end bang)
|
||||||
"Send a selection to `org-capture'."
|
"Send a selection to `doom/org-capture'."
|
||||||
:move-point nil
|
:move-point nil
|
||||||
:type inclusive
|
:type inclusive
|
||||||
(interactive "<r><!>")
|
(interactive "<r><!>")
|
||||||
(org-capture-string
|
(doom/org-capture
|
||||||
(if (and (evil-visual-state-p) beg end)
|
(if (and (evil-visual-state-p) beg end)
|
||||||
(buffer-substring beg end)
|
(buffer-substring beg end)
|
||||||
"")))
|
"")))
|
||||||
|
|
||||||
|
|
||||||
|
;;
|
||||||
|
;; attachments
|
||||||
|
;;
|
||||||
|
|
||||||
|
;;;###autoload (autoload 'doom:org-attach "defuns-org-notes" nil t)
|
||||||
|
(evil-define-command doom: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")))))
|
||||||
|
|
||||||
|
(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 doom/org-cleanup-attachments ()
|
||||||
|
;; "Deletes any attachments that are no longer present in the org-mode buffer."
|
||||||
|
(let* ((attachments-local (doom-org-attachments))
|
||||||
|
(attachments (f-entries org-attach-directory))
|
||||||
|
(to-delete (-difference attachments-local attachments)))
|
||||||
|
;; TODO
|
||||||
|
to-delete))
|
||||||
|
|
||||||
|
(defun doom-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 doom/org-download-dnd (uri action)
|
||||||
|
(if (eq major-mode 'org-mode)
|
||||||
|
(doom:org-attach uri)
|
||||||
|
(let ((dnd-protocol-alist
|
||||||
|
(rassq-delete-all 'doom/org-download-dnd (copy-alist dnd-protocol-alist))))
|
||||||
|
(dnd-handle-one-url nil action uri))))
|
||||||
|
|
||||||
(provide 'defuns-org)
|
(provide 'defuns-org)
|
||||||
;;; defuns-org.el ends here
|
;;; defuns-org.el ends here
|
||||||
|
|
|
@ -1,28 +0,0 @@
|
||||||
;;; module-org-crm.el
|
|
||||||
|
|
||||||
(add-hook 'org-load-hook 'doom|org-crm-init)
|
|
||||||
|
|
||||||
(defvar org-directory-crm (expand-file-name "/crm/" doom-org-dir)
|
|
||||||
"")
|
|
||||||
|
|
||||||
(defun doom|org-crm-init ()
|
|
||||||
;; (define-org-section! work "Work")
|
|
||||||
;; (define-org-section! project "Projects")
|
|
||||||
;; (define-org-section! contact "Contacts")
|
|
||||||
)
|
|
||||||
|
|
||||||
;;
|
|
||||||
(defun doom/org-crm-new (type name)
|
|
||||||
)
|
|
||||||
|
|
||||||
(defun doom/org-crm-visit-project (&optional name)
|
|
||||||
)
|
|
||||||
|
|
||||||
(defun doom/org-crm-visit-contact (&optional name)
|
|
||||||
)
|
|
||||||
|
|
||||||
(defun doom/org-crm-visit-invoice (&optional name)
|
|
||||||
)
|
|
||||||
|
|
||||||
(provide 'module-org-crm)
|
|
||||||
;;; module-org-crm.el ends here
|
|
|
@ -1,139 +0,0 @@
|
||||||
;;; module-org-notes.el
|
|
||||||
|
|
||||||
;; This transforms Emacs+org-mode into a notebook application with:
|
|
||||||
;; + Custom links for class notes
|
|
||||||
;; + Shortcuts for searching org files
|
|
||||||
;; + Shortcuts for creating new notes (there's org-capture, but this is suited to my
|
|
||||||
;; workflow)
|
|
||||||
;; + A simpler attachment system (with auto-deleting support) and drag-and-drop
|
|
||||||
;; for images and documents into org files
|
|
||||||
;; + A pandoc-powered export system
|
|
||||||
|
|
||||||
(add-hook 'org-load-hook 'doom|org-notebook-init t)
|
|
||||||
(add-hook 'org-load-hook 'doom|org-attach-init t)
|
|
||||||
(add-hook 'org-load-hook 'doom|org-export-init t)
|
|
||||||
|
|
||||||
(defvar doom-org-notes-dir (f-expand "notes" doom-org-dir)
|
|
||||||
"The directory where the notes are kept")
|
|
||||||
|
|
||||||
(defvar doom-org-quicknote-dir (f-expand "inbox" doom-org-notes-dir)
|
|
||||||
"")
|
|
||||||
|
|
||||||
(defvar doom-org-attachment-dir ".attach/"
|
|
||||||
"Where to store attachments (relative to current org file).")
|
|
||||||
|
|
||||||
;; Keep track of attachments
|
|
||||||
(defvar-local doom-org-attachments-list '()
|
|
||||||
"A list of attachments for the current buffer")
|
|
||||||
|
|
||||||
;; Tell helm to ignore these directories
|
|
||||||
(after! helm
|
|
||||||
(mapc (lambda (r) (add-to-list 'helm-boring-file-regexp-list r))
|
|
||||||
(list "\\.attach$" "\\.export$")))
|
|
||||||
|
|
||||||
|
|
||||||
;;
|
|
||||||
(defun doom|org-notebook-init ()
|
|
||||||
(setq org-default-notes-file (f-expand "inbox.org" doom-org-notes-dir)
|
|
||||||
org-attach-directory doom-org-attachment-dir
|
|
||||||
org-export-directory (f-expand ".export" org-directory)
|
|
||||||
org-capture-templates
|
|
||||||
'(;; TODO: New Note (note)
|
|
||||||
;; TODO: New Task (todo)
|
|
||||||
;; TODO: New vocabulary word
|
|
||||||
|
|
||||||
("c" "Changelog" entry
|
|
||||||
(file+headline (f-expand "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")
|
|
||||||
)))
|
|
||||||
|
|
||||||
;; I don't like Org's attachment system. So I replaced it with my own, which 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'
|
|
||||||
(defun doom|org-attach-init ()
|
|
||||||
;; FIXME Use all-the-icons
|
|
||||||
;; (doom-fix-unicode '("FontAwesome" 13) ? ? ? ? ? ? ? ?)
|
|
||||||
;; Drag-and-drop support
|
|
||||||
(require 'org-download)
|
|
||||||
(setq-default org-download-image-dir doom-org-attachment-dir
|
|
||||||
org-download-heading-lvl nil
|
|
||||||
org-download-timestamp "_%Y%m%d_%H%M%S")
|
|
||||||
|
|
||||||
(when IS-MAC
|
|
||||||
(setq org-download-screenshot-method "screencapture -i %s"))
|
|
||||||
|
|
||||||
;; Write download paths relative to current file
|
|
||||||
(defun org-download--dir-2 () nil)
|
|
||||||
(defun doom*org-download--fullname (path)
|
|
||||||
(f-relative path (f-dirname (buffer-file-name))))
|
|
||||||
(advice-add 'org-download--fullname :filter-return 'doom*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)))
|
|
||||||
|
|
||||||
|
|
||||||
;;
|
|
||||||
(defun doom|org-export-init ()
|
|
||||||
"Set up my own exporting system."
|
|
||||||
(setq org-export-backends '(ascii html latex md)
|
|
||||||
org-export-with-toc t
|
|
||||||
org-export-with-author t)
|
|
||||||
|
|
||||||
;; (require 'ox-pandoc)
|
|
||||||
;; (setq org-pandoc-options '((standalone . t) (mathjax . t) (parse-raw . t)))
|
|
||||||
|
|
||||||
;; Export to a central directory (why isn't this easier?)
|
|
||||||
(unless (file-directory-p org-export-directory)
|
|
||||||
(mkdir org-export-directory))
|
|
||||||
(defun doom*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 'doom*org-export-output-file-name))
|
|
||||||
|
|
||||||
;; TODO
|
|
||||||
;; (defvar doom-org-tags '())
|
|
||||||
;; (defun doom|org-tag-init ()
|
|
||||||
;; (async-start
|
|
||||||
;; `(lambda ()
|
|
||||||
;; (let* ((default-directory (doom/project-root))
|
|
||||||
;; (data (s-trim (shell-command-to-string "ag --nocolor --nonumbers '^#\\+TAGS:'")))
|
|
||||||
;; (alist '()))
|
|
||||||
;; (unless (zerop (length data))
|
|
||||||
;; (mapc (lambda (l)
|
|
||||||
;; (let* ((parts (s-split ":" l))
|
|
||||||
;; (file (car parts))
|
|
||||||
;; (tags (s-trim (nth 2 parts))))
|
|
||||||
;; (mapc (lambda (tag)
|
|
||||||
;; (setq tag (substring tag 1))
|
|
||||||
;; (unless (assoc tag alist)
|
|
||||||
;; (push (cons tag (list)) alist))
|
|
||||||
;; (push file (cdr (assoc tag alist))))
|
|
||||||
;; (s-split " " tags))))
|
|
||||||
;; (s-lines data))
|
|
||||||
;; alist)))
|
|
||||||
;; (lambda (_)
|
|
||||||
;; )))
|
|
||||||
|
|
||||||
;;
|
|
||||||
(provide 'module-org-notes)
|
|
||||||
;;; module-org-notes.el ends here
|
|
|
@ -1,5 +1,15 @@
|
||||||
;;; module-org.el --- -*- no-byte-compile: t; -*-
|
;;; module-org.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!)
|
||||||
|
|
||||||
(define-minor-mode evil-org-mode
|
(define-minor-mode evil-org-mode
|
||||||
"Evil-mode bindings for org-mode."
|
"Evil-mode bindings for org-mode."
|
||||||
:init-value nil
|
:init-value nil
|
||||||
|
@ -8,14 +18,32 @@
|
||||||
:group 'evil-org)
|
:group 'evil-org)
|
||||||
|
|
||||||
(add-hook 'org-load-hook 'doom|org-init t)
|
(add-hook 'org-load-hook 'doom|org-init t)
|
||||||
(add-hook 'org-load-hook 'doom|org-keybinds t)
|
(add-hook 'org-load-hook 'doom|org-init-attach t)
|
||||||
|
(add-hook 'org-load-hook 'doom|org-init-export t)
|
||||||
|
(add-hook 'org-load-hook 'doom|org-init-capture t)
|
||||||
(add-hook 'org-load-hook 'doom|org-hacks t)
|
(add-hook 'org-load-hook 'doom|org-hacks t)
|
||||||
(add-hook 'org-mode-hook 'doom|org-hook)
|
(add-hook 'org-mode-hook 'doom|org-hook)
|
||||||
|
|
||||||
|
;; Custom variables
|
||||||
(defvaralias 'org-directory 'doom-org-dir)
|
(defvaralias 'org-directory 'doom-org-dir)
|
||||||
|
|
||||||
|
(defvar doom-org-notes-dir (f-expand "notes" doom-org-dir)
|
||||||
|
"The directory where the notes are kept")
|
||||||
|
|
||||||
|
(defvar doom-org-quicknote-dir (f-expand "inbox" doom-org-dir)
|
||||||
|
"The directory to store quick notes produced by `doom:org-capture' (individual org files)")
|
||||||
|
|
||||||
|
(defvar doom-org-attachment-dir ".attach/"
|
||||||
|
"Where to store attachments (relative to current org file).")
|
||||||
|
|
||||||
|
(defvar-local doom-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.")
|
||||||
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
(defun doom|org-hook ()
|
(defun doom|org-hook ()
|
||||||
|
"Run everytime `org-mode' is enabled."
|
||||||
(evil-org-mode +1)
|
(evil-org-mode +1)
|
||||||
(visual-line-mode +1)
|
(visual-line-mode +1)
|
||||||
(setq line-spacing 1)
|
(setq line-spacing 1)
|
||||||
|
@ -34,7 +62,9 @@
|
||||||
(add-hook 'before-save-hook 'doom|org-update nil t)
|
(add-hook 'before-save-hook 'doom|org-update nil t)
|
||||||
(add-hook 'evil-insert-state-exit-hook 'doom|org-update nil t))
|
(add-hook 'evil-insert-state-exit-hook 'doom|org-update nil t))
|
||||||
|
|
||||||
|
|
||||||
(defun doom|org-init ()
|
(defun doom|org-init ()
|
||||||
|
"Initializes org core."
|
||||||
(def-popup! " *Agenda Commands*" :align below :size 30)
|
(def-popup! " *Agenda Commands*" :align below :size 30)
|
||||||
(def-popup! " *Org todo*" :align below :size 5 :noselect t)
|
(def-popup! " *Org todo*" :align below :size 5 :noselect t)
|
||||||
(def-popup! "*Calendar*" :align below :size 0.4)
|
(def-popup! "*Calendar*" :align below :size 0.4)
|
||||||
|
@ -167,73 +197,9 @@
|
||||||
(sp-local-pair "{" nil))
|
(sp-local-pair "{" nil))
|
||||||
|
|
||||||
;; bullets
|
;; bullets
|
||||||
(use-package org-bullets :commands org-bullets-mode))
|
(use-package org-bullets :commands org-bullets-mode)
|
||||||
|
|
||||||
(defun doom|org-hacks ()
|
;; Keybinds
|
||||||
;; Don't open separate windows
|
|
||||||
(push '(file . find-file) org-link-frame-setup)
|
|
||||||
|
|
||||||
;; Reveal files in finder
|
|
||||||
(setq org-file-apps '(("\\.org$" . emacs) (t . "open -R \"%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))
|
|
||||||
(pushnew 'org-is-agenda-file recentf-exclude)
|
|
||||||
|
|
||||||
;; Don't track attachments
|
|
||||||
(push (format "/%s.+$" (regexp-quote doom-org-attachment-dir)) recentf-exclude)
|
|
||||||
(push ".attach" projectile-globally-ignored-file-suffixes)
|
|
||||||
|
|
||||||
;; Remove highlights on ESC
|
|
||||||
(defun doom*org-remove-occur-highlights (&rest args)
|
|
||||||
(when (eq major-mode 'org-mode) (org-remove-occur-highlights)))
|
|
||||||
(advice-add 'evil-force-normal-state :before 'doom*org-remove-occur-highlights)
|
|
||||||
|
|
||||||
;; Don't reset org-hide!
|
|
||||||
(advice-add 'org-find-invisible-foreground :override 'ignore)
|
|
||||||
|
|
||||||
;; Tame org-mode popups
|
|
||||||
;; Ensures org-src-edit yields control of its buffer to shackle.
|
|
||||||
(defun org-src-switch-to-buffer (buffer context)
|
|
||||||
(pop-to-buffer buffer))
|
|
||||||
|
|
||||||
;; And these for org-todo, org-link and org-agenda
|
|
||||||
(defun org-pop-to-buffer-same-window (&optional buffer-or-name norecord label)
|
|
||||||
"Pop to buffer specified by BUFFER-OR-NAME in the selected window."
|
|
||||||
(display-buffer buffer-or-name))
|
|
||||||
|
|
||||||
(defun org-switch-to-buffer-other-window (&rest args)
|
|
||||||
(car-safe
|
|
||||||
(mapc (lambda (b)
|
|
||||||
(let ((buf (if (stringp b) (get-buffer-create b) b)))
|
|
||||||
(pop-to-buffer buf t t)))
|
|
||||||
args)))
|
|
||||||
|
|
||||||
;; Taming Org-agenda!
|
|
||||||
(defun doom/org-agenda-quit ()
|
|
||||||
"Necessary to finagle org-agenda into shackle popups and behave properly on quit."
|
|
||||||
(interactive)
|
|
||||||
(if org-agenda-columns-active
|
|
||||||
(org-columns-quit)
|
|
||||||
(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
|
|
||||||
(map! :map org-agenda-mode-map
|
|
||||||
:e "<escape>" 'doom/org-agenda-quit
|
|
||||||
:e "ESC" 'doom/org-agenda-quit
|
|
||||||
:e [escape] 'doom/org-agenda-quit
|
|
||||||
"q" 'doom/org-agenda-quit
|
|
||||||
"Q" 'doom/org-agenda-quit)))
|
|
||||||
|
|
||||||
(defun doom|org-keybinds ()
|
|
||||||
(map! (:map org-mode-map
|
(map! (:map org-mode-map
|
||||||
"RET" nil
|
"RET" nil
|
||||||
"C-j" nil
|
"C-j" nil
|
||||||
|
@ -283,6 +249,7 @@
|
||||||
:ni "<M-return>" (λ! (doom/org-insert-item 'below))
|
:ni "<M-return>" (λ! (doom/org-insert-item 'below))
|
||||||
:ni "<S-M-return>" (λ! (doom/org-insert-item 'above))
|
:ni "<S-M-return>" (λ! (doom/org-insert-item 'above))
|
||||||
|
|
||||||
|
;; Formatting shortcuts
|
||||||
:i "M-b" (λ! (doom/org-surround "*")) ; bold
|
:i "M-b" (λ! (doom/org-surround "*")) ; bold
|
||||||
:i "M-u" (λ! (doom/org-surround "_")) ; underline
|
:i "M-u" (λ! (doom/org-surround "_")) ; underline
|
||||||
:i "M-i" (λ! (doom/org-surround "/")) ; italics
|
:i "M-i" (λ! (doom/org-surround "/")) ; italics
|
||||||
|
@ -293,47 +260,40 @@
|
||||||
:v "M-i" "S/"
|
:v "M-i" "S/"
|
||||||
:v "M-`" "S+"
|
:v "M-`" "S+"
|
||||||
|
|
||||||
(:leader
|
|
||||||
:n "oa" 'doom/org-attachment-reveal)
|
|
||||||
|
|
||||||
(:localleader
|
(:localleader
|
||||||
:n "/" 'org-sparse-tree
|
|
||||||
:n "?" 'org-tags-view
|
|
||||||
|
|
||||||
:n "n" (λ! (if (buffer-narrowed-p) (widen) (org-narrow-to-subtree)))
|
|
||||||
:n "e" 'org-edit-special
|
|
||||||
:n "=" 'org-align-all-tags
|
|
||||||
:nv "l" 'org-insert-link
|
|
||||||
:n "L" 'org-store-link
|
|
||||||
:n "x" 'doom/org-remove-link
|
|
||||||
;; :n "w" 'writing-mode
|
|
||||||
:n "v" 'variable-pitch-mode
|
|
||||||
:n "SPC" 'doom/org-toggle-checkbox
|
|
||||||
:n "RET" 'org-archive-subtree
|
:n "RET" 'org-archive-subtree
|
||||||
|
:n "SPC" 'doom/org-toggle-checkbox
|
||||||
:n "a" 'org-agenda
|
:n "/" 'org-sparse-tree
|
||||||
:n "A" 'doom:org-attachment-list
|
:n "=" 'org-align-all-tags
|
||||||
|
:n "?" 'org-tags-view
|
||||||
:n "d" 'org-time-stamp
|
|
||||||
:n "D" 'org-deadline
|
:n "D" 'org-deadline
|
||||||
:n "i" 'doom/org-toggle-inline-images-at-point
|
:n "L" 'org-store-link
|
||||||
: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 "T" 'org-todo
|
|
||||||
:n "s" 'org-schedule
|
|
||||||
:n "r" 'org-refile
|
|
||||||
:n "R" (λ! (org-metaleft) (org-archive-to-archive-sibling))) ; archive to parent sibling
|
: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
|
||||||
|
:nv "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
|
;; TODO Improve folding bindings
|
||||||
:n "za" 'org-cycle
|
:n "za" 'org-cycle
|
||||||
:n "zA" 'org-shifttab
|
:n "zA" 'org-shifttab
|
||||||
:n "zm" (λ! (outline-hide-sublevels 1))
|
|
||||||
:n "zr" 'outline-show-all
|
|
||||||
:n "zo" 'outline-show-subtree
|
|
||||||
:n "zO" 'outline-show-all
|
|
||||||
:n "zc" 'outline-hide-subtree
|
:n "zc" 'outline-hide-subtree
|
||||||
:n "zC" (λ! (outline-hide-sublevels 1))
|
:n "zC" (λ! (outline-hide-sublevels 1))
|
||||||
:n "zd" (lambda (&optional arg) (interactive "p") (outline-hide-sublevels (or arg 3)))
|
: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-forward-heading-same-level) (org-beginning-of-line))
|
||||||
:m "[[" (λ! (call-interactively 'org-backward-heading-same-level) (org-beginning-of-line))
|
:m "[[" (λ! (call-interactively 'org-backward-heading-same-level) (org-beginning-of-line))
|
||||||
|
@ -373,5 +333,145 @@
|
||||||
:e "C-n" 'org-agenda-next-item
|
:e "C-n" 'org-agenda-next-item
|
||||||
:e "C-p" 'org-agenda-previous-item))))
|
:e "C-p" 'org-agenda-previous-item))))
|
||||||
|
|
||||||
|
|
||||||
|
;; 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'
|
||||||
|
(defun doom|org-init-attach ()
|
||||||
|
(setq org-attach-directory doom-org-attachment-dir)
|
||||||
|
|
||||||
|
;; Don't track attachments in recentf or projectile
|
||||||
|
(push (format "/%s.+$" (regexp-quote doom-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 doom-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
|
||||||
|
(defun org-download--dir-2 () nil)
|
||||||
|
(defun doom*org-download--fullname (path)
|
||||||
|
(f-relative path (f-dirname (buffer-file-name))))
|
||||||
|
(advice-add 'org-download--fullname :filter-return 'doom*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 doom-org-attachment-dir))))
|
||||||
|
|
||||||
|
|
||||||
|
;; My own, centralized exporting system as well.
|
||||||
|
(defun doom|org-init-export ()
|
||||||
|
(setq org-export-directory (f-expand ".export" org-directory)
|
||||||
|
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)
|
||||||
|
(mkdir org-export-directory))
|
||||||
|
(defun doom*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 'doom*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))))
|
||||||
|
|
||||||
|
|
||||||
|
;; 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 `doom/org-capture'
|
||||||
|
(defun doom|org-init-capture ()
|
||||||
|
"Set up a sane `org-capture' workflow."
|
||||||
|
(setq org-default-notes-file (f-expand "notes.org" doom-org-dir))
|
||||||
|
|
||||||
|
(require 'org-capture)
|
||||||
|
(require 'org-protocol)
|
||||||
|
(def-popup! "*Org Select*" :align below :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 (f-expand "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")
|
||||||
|
)))
|
||||||
|
|
||||||
|
;; Getting org to behave
|
||||||
|
(defun doom|org-hacks ()
|
||||||
|
;; 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))
|
||||||
|
(pushnew 'org-is-agenda-file recentf-exclude)
|
||||||
|
|
||||||
|
;; Remove highlights on ESC
|
||||||
|
(defun doom*org-remove-occur-highlights (&rest args)
|
||||||
|
(when (eq major-mode 'org-mode) (org-remove-occur-highlights)))
|
||||||
|
(advice-add 'evil-force-normal-state :before 'doom*org-remove-occur-highlights)
|
||||||
|
|
||||||
|
;; Don't reset org-hide!
|
||||||
|
(advice-add 'org-find-invisible-foreground :override 'ignore))
|
||||||
|
|
||||||
(provide 'module-org)
|
(provide 'module-org)
|
||||||
;;; module-org.el ends here
|
;;; module-org.el ends here
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue