diff --git a/modules/lang/org/README.org b/modules/lang/org/README.org index ad82e82f9..b1c059e63 100644 --- a/modules/lang/org/README.org +++ b/modules/lang/org/README.org @@ -113,22 +113,22 @@ https://www.mfoot.com/blog/2015/11/22/literate-emacs-configuration-with-org-mode #+BEGIN_SRC emacs-lisp (after! org - (remove-hook 'org-tab-first-hook #'+org|cycle-only-current-subtree t)) + (remove-hook 'org-tab-first-hook #'+org-cycle-only-current-subtree-h t)) #+END_SRC + (Evil users) Nearby tables are formatted when exiting insert or replace mode - (see ~+org|enable-auto-reformat-tables~). + (see ~+org-enable-auto-reformat-tables-h~). + Statistics cookies are updated when saving the buffer of exiting insert mode - (see ~+org|enable-auto-update-cookies~). -+ Org-protocol has been lazy loaded (see ~+org|init-protocol-lazy-loader~); + (see ~+org-enable-auto-update-cookies-h~). ++ Org-protocol has been lazy loaded (see ~+org-init-protocol-lazy-loader-h~); loaded when the server recieves a request for an org-protocol:// url. + Babel and babel plugins are now lazy loaded (see - ~+org|init-babel-lazy-loader~); loaded when a src block is executed. No need + ~+org-init-babel-lazy-loader-h~); loaded when a src block is executed. No need to use ~org-babel-do-load-languages~ in your config, just install your babel packages to extend language support (and ensure its ~org-babel-execute:*~ function is autoloaded). + If a variable is used as a file path in ~org-capture-template~, it will be resolved relative to ~org-directory~, instead of ~default-directory~ (see - ~+org*capture-expand-variable-file~). + ~+org-capture-expand-variable-file-a~). * Prerequisites Org has a few soft dependencies that you will need to make use of Org's more @@ -176,7 +176,7 @@ emacsclient --eval '(+org-capture/open-frame INTIAL-INPUT KEY)' #+END_SRC ** Built-in custom link types -This module defines a number of custom link types in ~+org|init-custom-links~. +This module defines a number of custom link types in ~+org-init-custom-links-h~. They are (with examples): + ~doom-docs:news/2.1.0~ (=~/.emacs.d/docs/%s=) diff --git a/modules/lang/org/autoload/contrib-dragndrop.el b/modules/lang/org/autoload/contrib-dragndrop.el index 100786f94..7940be5d0 100644 --- a/modules/lang/org/autoload/contrib-dragndrop.el +++ b/modules/lang/org/autoload/contrib-dragndrop.el @@ -10,30 +10,3 @@ (rassq-delete-all '+org-attach-download-dnd (copy-alist dnd-protocol-alist)))) (dnd-handle-one-url nil action uri)))) - -;;;###autoload -(defun +org-dragndrop*insert-link (_link filename) - "Produces and inserts a link to FILENAME into the document. - -If FILENAME is an image, produce an attach:%s path, otherwise use file:%s (with -an file icon produced by `+org-attach--icon')." - (if (looking-back "^[ \t]+" (line-beginning-position)) - (delete-region (match-beginning 0) (match-end 0)) - (newline)) - (cond ((image-type-from-file-name filename) - (insert - (concat (if (= org-download-image-html-width 0) "" - (format "#+attr_html: :width %dpx\n" org-download-image-html-width)) - (if (= org-download-image-latex-width 0) "" - (format "#+attr_latex: :width %dcm\n" org-download-image-latex-width)) - (cond ((file-in-directory-p filename org-attach-directory) - (format "[[attach:%s]]" (file-relative-name filename org-attach-directory))) - ((file-in-directory-p filename org-directory) - (format org-download-link-format (file-relative-name filename org-directory))) - ((format org-download-link-format filename))))) - (org-display-inline-images)) - ((insert - (format "%s [[./%s][%s]] " - (+org-attach--icon filename) - (file-relative-name filename (file-name-directory buffer-file-name)) - (file-name-nondirectory (directory-file-name filename))))))) diff --git a/modules/lang/org/autoload/contrib-ipython.el b/modules/lang/org/autoload/contrib-ipython.el index 10296d2e4..4e8e82ef3 100644 --- a/modules/lang/org/autoload/contrib-ipython.el +++ b/modules/lang/org/autoload/contrib-ipython.el @@ -2,7 +2,7 @@ ;;;###if (featurep! +ipython) ;;;###autoload -(defun +org*ob-ipython-initiate-session (&optional session params) +(defun +org-ob-ipython-initiate-session-a (&optional session params) "Create a session named SESSION according to PARAMS." (if (string= session "none") (error @@ -54,7 +54,7 @@ Make sure your src block has a :session param.") (format "*%s*" proc)))) ;;;###autoload -(defun +org*ob-ipython--create-repl (name &optional params) +(defun +org-ob-ipython-create-repl-a (name &optional params) "Create repl based on NAME and PARAMS. If PARAMS specifies remote kernel, copy the kernel config from remote server and create a repl connecting to remote session." @@ -88,7 +88,7 @@ create a repl connecting to remote session." (format "*%s*" process-name)))))) ;;;###autoload -(defun +org*babel-execute:ipython (body params) +(defun +org-babel-execute:ipython-a (body params) "Execute a BODY of IPython code with PARAMS in org-babel. This function is called by `org-babel-execute-src-block'." (message default-directory) @@ -100,7 +100,7 @@ This function is called by `org-babel-execute-src-block'." ;; * org-src-edit ;;;###autoload -(defun +org*babel-edit-prep:ipython (info) +(defun +org-babel-edit-prep:ipython-a (info) (let* ((params (nth 2 info)) (session (cdr (assoc :session params)))) (org-babel-ipython-initiate-session session params)) @@ -144,7 +144,7 @@ The optional arg SCALE is scale factor, and defaults to 2." (substring filename pos)))) ;;;###autoload -(defun +org*ob-ipython--write-base64-string (oldfunc &rest args) +(defun +org-ob-ipython-write-base64-string-a (oldfunc &rest args) (let ((file (car args)) (b64-string (cdr args))) (let ((file2x (+org--ob-ipython-mac-2x-image-file-name file))) diff --git a/modules/lang/org/autoload/contrib-present.el b/modules/lang/org/autoload/contrib-present.el index 41434a817..cd50de4f5 100644 --- a/modules/lang/org/autoload/contrib-present.el +++ b/modules/lang/org/autoload/contrib-present.el @@ -16,7 +16,7 @@ ;;; Hooks ;;;###autoload -(defun +org-present|add-overlays () +(defun +org-present-add-overlays-h () (add-to-invisibility-spec '(+org-present)) (save-excursion ;; hide org-mode options starting with #+ @@ -36,14 +36,14 @@ (remove-from-invisibility-spec '(+org-present))) ;;;###autoload -(defun +org-present|detect-slide () +(defun +org-present-detect-slide-h () (outline-show-all) (if (member "title" (org-get-tags-at)) (text-scale-set 10) (text-scale-set +org-present-text-scale))) ;;;###autoload -(defun +org-present|init-org-tree-window () +(defun +org-present-init-org-tree-window-h () "Set up the org window for presentation." (doom/window-maximize-buffer) (let ((cwm-use-vertical-padding t) diff --git a/modules/lang/org/autoload/org-capture.el b/modules/lang/org/autoload/org-capture.el index 0fbd4516a..fa19ee6b7 100644 --- a/modules/lang/org/autoload/org-capture.el +++ b/modules/lang/org/autoload/org-capture.el @@ -15,7 +15,7 @@ "TODO") ;;;###autoload -(defun +org-capture|cleanup-frame () +(defun +org-capture-cleanup-frame-h () "Closes the org-capture frame once done adding an entry." (when (+org-capture-frame-p) (delete-frame nil t))) @@ -59,7 +59,7 @@ you're done. This can be called from an external shell script." if (buffer-local-value 'org-capture-mode buf) return buf))) (with-current-buffer buf - (add-hook 'kill-buffer-hook #'+org-capture|cleanup-frame nil t)) + (add-hook 'kill-buffer-hook #'+org-capture-cleanup-frame-h nil t)) (delete-frame frame)))))) ('error (message "org-capture: %s" (error-message-string ex)) diff --git a/modules/lang/org/autoload/org.el b/modules/lang/org/autoload/org.el index 0a569243a..590866344 100644 --- a/modules/lang/org/autoload/org.el +++ b/modules/lang/org/autoload/org.el @@ -298,7 +298,7 @@ wrong places)." (org-toggle-checkbox '(4))) ;;;###autoload -(defalias #'+org/toggle-fold #'+org|cycle-only-current-subtree) +(defalias #'+org/toggle-fold #'+org-cycle-only-current-subtree-h) ;;;###autoload (defun +org/open-fold () @@ -348,7 +348,7 @@ another level of headings on each invocation." ;;; Hooks ;;;###autoload -(defun +org|delete-backward-char-and-realign-table-maybe () +(defun +org-delete-backward-char-and-realign-table-maybe-h () "TODO" (when (eq major-mode 'org-mode) (org-check-before-invisible-edit 'delete-backward) @@ -371,7 +371,7 @@ another level of headings on each invocation." t)))) ;;;###autoload -(defun +org|indent-maybe () +(defun +org-indent-maybe-h () "Indent the current item (header or item), if possible. Made for `org-tab-first-hook' in evil-mode." (interactive) @@ -395,7 +395,7 @@ Made for `org-tab-first-hook' in evil-mode." t))) ;;;###autoload -(defun +org|realign-table-maybe () +(defun +org-realign-table-maybe-h () "Auto-align table under cursor and re-calculate formulas." (when (and (org-at-table-p) org-table-may-need-update) (let ((pt (point)) @@ -405,14 +405,14 @@ Made for `org-tab-first-hook' in evil-mode." (goto-char pt)))) ;;;###autoload -(defun +org|update-cookies () +(defun +org-update-cookies-h () "Update counts in headlines (aka \"cookies\")." (when (and buffer-file-name (file-exists-p buffer-file-name)) (let (org-hierarchical-todo-statistics) (org-update-parent-todo-statistics)))) ;;;###autoload -(defun +org|yas-expand-maybe () +(defun +org-yas-expand-maybe-h () "Tries to expand a yasnippet snippet, if one is available. Made for `org-tab-first-hook'." (when (bound-and-true-p yas-minor-mode) @@ -430,7 +430,7 @@ Made for `org-tab-first-hook' in evil-mode." t)))) ;;;###autoload -(defun +org|cycle-only-current-subtree (&optional arg) +(defun +org-cycle-only-current-subtree-h (&optional arg) "Toggle the local fold at the point (as opposed to cycling through all levels with `org-cycle')." (interactive "P") @@ -449,14 +449,14 @@ with `org-cycle')." t))))) ;;;###autoload -(defun +org|remove-occur-highlights () +(defun +org-remove-occur-highlights-h () "Remove org occur highlights on ESC in normal mode." (when org-occur-highlights (org-remove-occur-highlights) t)) ;;;###autoload -(defun +org|unfold-to-2nd-level-or-point () +(defun +org-unfold-to-2nd-level-or-point-h () "My version of the 'overview' #+STARTUP option: expand first-level headings. Expands the first level, but no further. If point was left somewhere deeper, unfold to point on startup." @@ -470,39 +470,39 @@ unfold to point on startup." (org-show-subtree)))))) ;;;###autoload -(defun +org|enable-auto-reformat-tables () +(defun +org-enable-auto-reformat-tables-h () "Realign tables & update formulas when exiting insert mode (`evil-mode')." (when (featurep 'evil) - (add-hook 'evil-insert-state-exit-hook #'+org|realign-table-maybe nil t) - (add-hook 'evil-replace-state-exit-hook #'+org|realign-table-maybe nil t) - (advice-add #'evil-replace :after #'+org*realign-table-maybe))) + (add-hook 'evil-insert-state-exit-hook #'+org-realign-table-maybe-h nil t) + (add-hook 'evil-replace-state-exit-hook #'+org-realign-table-maybe-h nil t) + (advice-add #'evil-replace :after #'+org-realign-table-maybe-a))) ;;;###autoload -(defun +org|enable-auto-update-cookies () +(defun +org-enable-auto-update-cookies-h () "Update statistics cookies when saving or exiting insert mode (`evil-mode')." (when (featurep 'evil) - (add-hook 'evil-insert-state-exit-hook #'+org|update-cookies nil t)) - (add-hook 'before-save-hook #'+org|update-cookies nil t)) + (add-hook 'evil-insert-state-exit-hook #'+org-update-cookies-h nil t)) + (add-hook 'before-save-hook #'+org-update-cookies-h nil t)) ;; ;;; Advice ;;;###autoload -(defun +org*fix-newline-and-indent-in-src-blocks () +(defun +org-fix-newline-and-indent-in-src-blocks-a () "Try to mimic `newline-and-indent' with correct indentation in src blocks." (when (org-in-src-block-p t) (org-babel-do-in-edit-buffer (call-interactively #'indent-for-tab-command)))) ;;;###autoload -(defun +org*realign-table-maybe (&rest _) +(defun +org-realign-table-maybe-a (&rest _) "Auto-align table under cursor and re-calculate formulas." (when (eq major-mode 'org-mode) - (+org|realign-table-maybe))) + (+org-realign-table-maybe-h))) ;;;###autoload -(defun +org*evil-org-open-below (orig-fn count) +(defun +org-evil-org-open-below-a (orig-fn count) "Fix o/O creating new list items in the middle of nested plain lists. Only has an effect when `evil-org-special-o/O' has `item' in it (not the default)." (cl-letf (((symbol-function 'end-of-visible-line) @@ -513,7 +513,7 @@ an effect when `evil-org-special-o/O' has `item' in it (not the default)." (funcall orig-fn count))) ;;;###autoload -(defun +org*display-link-in-eldoc (orig-fn &rest args) +(defun +org-display-link-in-eldoc-a (orig-fn &rest args) "Display the link at point in eldoc." (or (when-let (link (org-element-property :raw-link (org-element-context))) (format "Link: %s" link)) diff --git a/modules/lang/org/config.el b/modules/lang/org/config.el index 40371ba59..160f5bd7b 100644 --- a/modules/lang/org/config.el +++ b/modules/lang/org/config.el @@ -3,7 +3,7 @@ ;; ;;; `org-load' hooks -(defun +org|init-agenda () +(defun +org-init-agenda-h () (unless org-agenda-files (setq org-agenda-files (list org-directory))) (setq-default @@ -18,7 +18,7 @@ org-agenda-start-day "-3d")) -(defun +org|init-appearance () +(defun +org-init-appearance-h () "Configures the UI for `org-mode'." (setq-default org-adapt-indentation nil @@ -67,14 +67,14 @@ ;; Scale up LaTeX previews a bit (default is too small) org-format-latex-options (plist-put org-format-latex-options :scale 1.5)) - (advice-add #'org-eldoc-documentation-function :around #'+org*display-link-in-eldoc) + (advice-add #'org-eldoc-documentation-function :around #'+org-display-link-in-eldoc-a) ;; Don't do automatic indent detection in org files (add-to-list 'doom-detect-indentation-excluded-modes 'org-mode nil #'eq) ;; Previews are usually rendered with light backgrounds, so ensure their ;; background (and foreground) match the current theme. - (defun +org|update-latex-preview-background-color () + (defun +org-update-latex-preview-background-color-h () (setq-default org-format-latex-options (plist-put org-format-latex-options @@ -82,7 +82,7 @@ (face-attribute (or (cadr (assq 'default face-remapping-alist)) 'default) :background nil t)))) - (add-hook 'doom-load-theme-hook #'+org|update-latex-preview-background-color) + (add-hook 'doom-load-theme-hook #'+org-update-latex-preview-background-color-h) (set-pretty-symbols! 'org-mode :name "#+NAME:" @@ -90,7 +90,7 @@ :src_block_end "#+END_SRC")) -(defun +org|init-babel () +(defun +org-init-babel-h () (setq org-src-fontify-natively t ; make code pretty org-src-preserve-indentation t ; use native major-mode indentation org-src-tab-acts-natively t @@ -101,7 +101,7 @@ (define-key org-src-mode-map (kbd "C-c C-c") #'org-edit-src-exit) ;; Use major-mode native TAB indentation in SRC blocks - (advice-add #'org-return-indent :after #'+org*fix-newline-and-indent-in-src-blocks) + (advice-add #'org-return-indent :after #'+org-fix-newline-and-indent-in-src-blocks-a) ;; `org-babel-get-header' was removed from org in 9.0. Quite a few babel ;; plugins use it, so until those plugins update, this polyfill will do: @@ -115,7 +115,7 @@ (setq org-babel-js-function-wrapper "console.log(require('util').inspect(function(){\n%s\n}()));")) -(defun +org|init-babel-lazy-loader () +(defun +org-init-babel-lazy-loader-h () "Load babel libraries lazily when babel blocks are executed." (defvar +org-babel-mode-alist '((cpp . C) @@ -135,15 +135,16 @@ when executed.") take one argument (the language specified in the src block, as a string). Stops at the first function to return non-nil.") - (defun +org*src-lazy-load-library (lang) + (def-advice! +org--src-lazy-load-library-a (lang) "Lazy load a babel package to ensure syntax highlighting." + :before #'org-src--get-lang-mode (or (cdr (assoc lang org-src-lang-modes)) (fboundp (intern-soft (format "%s-mode" lang))) (require (intern-soft (format "ob-%s" lang)) nil t))) - (advice-add #'org-src--get-lang-mode :before #'+org*src-lazy-load-library) - (defun +org*babel-lazy-load-library (info) + (def-advice! +org--babel-lazy-load-library-a (info) "Load babel libraries lazily when babel blocks are executed." + :after-while #'org-babel-confirm-evaluate (let* ((lang (nth 0 info)) (lang (if (symbolp lang) lang (intern lang))) (lang (or (cdr (assq lang +org-babel-mode-alist)) @@ -156,11 +157,10 @@ at the first function to return non-nil.") ;; child process), so we only need to make sure it's loaded. (require 'ob-async nil t)) (add-to-list 'org-babel-load-languages (cons lang t))) - t)) - (advice-add #'org-babel-confirm-evaluate :after-while #'+org*babel-lazy-load-library)) + t))) -(defun +org|init-capture-defaults () +(defun +org-init-capture-defaults-h () "Sets up some reasonable defaults, as well as two `org-capture' workflows that I like: @@ -216,43 +216,43 @@ Is relative to `org-directory', unless it is absolute. Is used in Doom's default (file+headline +org-capture-project-notes-file "Unreleased") "* TODO %?\n%i\n%a" :prepend t :kill-buffer t))) - (defun +org*capture-expand-variable-file (file) + (def-advice! +org-capture-expand-variable-file-a (file) "If a variable is used for a file path in `org-capture-template', it is used as is, and expanded relative to `default-directory'. This changes it to be relative to `org-directory', unless it is an absolute path." + :filter-args #'org-capture-expand-file (if (and (symbolp file) (boundp file)) (expand-file-name (symbol-value file) org-directory) file)) - (advice-add #'org-capture-expand-file :filter-args #'+org*capture-expand-variable-file) - (defun +org*prevent-save-prompts-when-refiling (&rest _) + (def-advice! +org--prevent-save-prompts-when-refiling-a (&rest _) "Fix #462: when refiling from org-capture, Emacs prompts to kill the underlying, modified buffer. This fixes that." + :after 'org-refile (when (bound-and-true-p org-capture-is-refiling) (org-save-all-org-buffers))) - (advice-add 'org-refile :after #'+org*prevent-save-prompts-when-refiling) - (defun +org|show-target-in-capture-header () - (setq header-line-format - (format "%s%s%s" - (propertize (abbreviate-file-name (buffer-file-name (buffer-base-buffer))) - 'face 'font-lock-string-face) - org-eldoc-breadcrumb-separator - header-line-format))) - (add-hook 'org-capture-mode-hook #'+org|show-target-in-capture-header) + (add-hook 'org-capture-mode-hook + (defun +org-show-target-in-capture-header-h () + (setq header-line-format + (format "%s%s%s" + (propertize (abbreviate-file-name (buffer-file-name (buffer-base-buffer))) + 'face 'font-lock-string-face) + org-eldoc-breadcrumb-separator + header-line-format)))) (when (featurep! :editor evil) (add-hook 'org-capture-mode-hook #'evil-insert-state))) -(defun +org|init-capture-frame () - (add-hook 'org-capture-after-finalize-hook #'+org-capture|cleanup-frame) +(defun +org-init-capture-frame-h () + (add-hook 'org-capture-after-finalize-hook #'+org-capture-cleanup-frame-h) (when (featurep! :ui doom-dashboard) (add-hook '+doom-dashboard-inhibit-functions #'+org-capture-frame-p))) -(defun +org|init-centralized-attachments () +(defun +org-init-centralized-attachments-h () "I believe Org's native attachment system is over-complicated and litters files with metadata I don't want. So I wrote my own, which: @@ -294,7 +294,7 @@ Some commands of interest: (lambda (file) (file-in-directory-p file org-attach-directory))))) -(defun +org|init-centralized-exports () +(defun +org-init-centralized-exports-h () "TODO" (defvar +org-enable-centralized-exports t "If non-nil, files exported from files in `org-directory' will be stored in @@ -310,9 +310,10 @@ path too.") ;; place, and I want to be able to refer back to old exports if needed. (setq +org-export-directory (expand-file-name +org-export-directory org-directory)) - (defun +org*export-output-file-name (args) + (def-advice! +org--export-output-file-name-a (args) "Return a centralized export location unless one is provided or the current file isn't in `org-directory'." + :filter-args #'org-export-output-file-name (when (and +org-enable-centralized-exports (not (nth 2 args)) buffer-file-name @@ -322,11 +323,10 @@ file isn't in `org-directory'." (unless (file-directory-p dir) (make-directory dir t)) (setq args (list extension subtreep dir))))) - args) - (advice-add #'org-export-output-file-name :filter-args #'+org*export-output-file-name)) + args)) -(defun +org|init-custom-links () +(defun +org-init-custom-links-h () (defun +org--relpath (path root) (if (and buffer-file-name (file-in-directory-p buffer-file-name root)) (file-relative-name path) @@ -342,7 +342,6 @@ file isn't in `org-directory'." 'org-link 'error)))) - ;; Highlight broken file links (org-link-set-parameters "file" @@ -352,7 +351,6 @@ file isn't in `org-directory'." 'org-link 'error))) - ;; Add custom link types (setq org-link-abbrev-alist '(("github" . "https://github.com/%s") @@ -378,7 +376,7 @@ file isn't in `org-directory'." (def-package! org-yt)) -(defun +org|init-export () +(defun +org-init-export-h () (when (featurep! :lang markdown) (add-to-list 'org-export-backends 'md)) @@ -395,7 +393,7 @@ file isn't in `org-directory'." (variable . "revealjs-url=https://cdn.jsdelivr.net/npm/reveal.js@3/"))))) -(defun +org|init-habit () +(defun +org-init-habit-h () "TODO" (defvar +org-habit-graph-padding 2 "The padding added to the end of the consistency graph") @@ -406,41 +404,42 @@ file isn't in `org-directory'." (defvar +org-habit-graph-window-ratio 0.3 "The ratio of the consistency graphs relative to the window width") - (defun +org-habit|resize-graph() - "Right align and resize the consistency graphs based on + (add-hook 'org-agenda-mode-hook + (defun +org-habit-resize-graph-h () + "Right align and resize the consistency graphs based on `+org-habit-graph-window-ratio'" - (require 'org-habit) - (let* ((total-days (float (+ org-habit-preceding-days org-habit-following-days))) - (preceding-days-ratio (/ org-habit-preceding-days total-days)) - (graph-width (floor (* (window-width) +org-habit-graph-window-ratio))) - (preceding-days (floor (* graph-width preceding-days-ratio))) - (following-days (- graph-width preceding-days)) - (graph-column (- (window-width) (+ preceding-days following-days))) - (graph-column-adjusted (if (> graph-column +org-habit-min-width) - (- graph-column +org-habit-graph-padding) - nil))) - (setq-local org-habit-preceding-days preceding-days) - (setq-local org-habit-following-days following-days) - (setq-local org-habit-graph-column graph-column-adjusted))) - (add-hook 'org-agenda-mode-hook #'+org-habit|resize-graph)) + (require 'org-habit) + (let* ((total-days (float (+ org-habit-preceding-days org-habit-following-days))) + (preceding-days-ratio (/ org-habit-preceding-days total-days)) + (graph-width (floor (* (window-width) +org-habit-graph-window-ratio))) + (preceding-days (floor (* graph-width preceding-days-ratio))) + (following-days (- graph-width preceding-days)) + (graph-column (- (window-width) (+ preceding-days following-days))) + (graph-column-adjusted (if (> graph-column +org-habit-min-width) + (- graph-column +org-habit-graph-padding) + nil))) + (setq-local org-habit-preceding-days preceding-days) + (setq-local org-habit-following-days following-days) + (setq-local org-habit-graph-column graph-column-adjusted))))) -(defun +org|init-hacks () +(defun +org-init-hacks-h () "Getting org to behave." ;; Don't open separate windows (setf (alist-get 'file org-link-frame-setup) #'find-file) ;; Open directory links in Emacs (add-to-list 'org-file-apps '(directory . emacs)) - (defun +org|delayed-recenter () - "`recenter', but after a tiny delay. Necessary to prevent certain race + (add-hook 'org-follow-link-hook + (defun +org-delayed-recenter-h () + "`recenter', but after a tiny delay. Necessary to prevent certain race conditions where a window's buffer hasn't changed at the time this hook is run." - (run-at-time 0.1 nil #'recenter)) - (add-hook 'org-follow-link-hook #'+org|delayed-recenter) + (run-at-time 0.1 nil #'recenter))) - (defun +org*strip-properties-from-outline (orig-fn path &optional width prefix separator) + (def-advice! +org--strip-properties-from-outline-a (orig-fn path &optional width prefix separator) "Remove link syntax and fix variable height text (e.g. org headings) in the eldoc string." + :around #'org-format-outline-path (let ((result (funcall orig-fn path width prefix separator)) (separator (or separator "/"))) (string-join @@ -452,30 +451,28 @@ eldoc string." (org-add-props (replace-regexp-in-string org-any-link-re "\\4" part) nil 'face `(:foreground ,(face-foreground face nil t) :weight bold))) separator))) - (advice-add #'org-format-outline-path :around #'+org*strip-properties-from-outline) - (defun +org|exclude-agenda-buffers-from-workspace () - "Prevent from temporarily-opened agenda buffers from being associated with + (add-hook 'org-agenda-finalize-hook + (defun +org-exclude-agenda-buffers-from-workspace-h () + "Prevent from temporarily-opened agenda buffers from being associated with the current workspace." - (when (and org-agenda-new-buffers (bound-and-true-p persp-mode)) - (let (persp-autokill-buffer-on-remove) - (persp-remove-buffer org-agenda-new-buffers - (get-current-persp) - nil)))) - (add-hook 'org-agenda-finalize-hook #'+org|exclude-agenda-buffers-from-workspace) + (when (and org-agenda-new-buffers (bound-and-true-p persp-mode)) + (let (persp-autokill-buffer-on-remove) + (persp-remove-buffer org-agenda-new-buffers + (get-current-persp) + nil))))) - (defun +org*exclude-agenda-buffers-from-recentf (orig-fn file) + (def-advice! +org--exclude-agenda-buffers-from-recentf-a (orig-fn file) "Prevent temporarily opened agenda buffers from polluting recentf." + :around #'org-get-agenda-file-buffer (let ((recentf-exclude (list (lambda (_file) t)))) - (funcall orig-fn file))) - (advice-add #'org-get-agenda-file-buffer - :around #'+org*exclude-agenda-buffers-from-recentf)) + (funcall orig-fn file)))) -(defun +org|init-keybinds () +(defun +org-init-keybinds-h () "Sets up org-mode and evil keybindings. Tries to fix the idiosyncrasies between the two." - (add-hook 'doom-escape-hook #'+org|remove-occur-highlights) + (add-hook 'doom-escape-hook #'+org-remove-occur-highlights-h) ;; C-a & C-e act like `doom/backward-to-bol-or-indent' and ;; `doom/forward-to-last-non-comment-or-eol', but with more org awareness. @@ -485,8 +482,8 @@ between the two." ;; insert new headings after current subtree rather than inside it org-insert-heading-respect-content t) - (add-hook! 'org-tab-first-hook #'(+org|indent-maybe +org|yas-expand-maybe)) - (add-hook 'doom-delete-backward-functions #'+org|delete-backward-char-and-realign-table-maybe) + (add-hook! 'org-tab-first-hook #'(+org-indent-maybe-h +org-yas-expand-maybe-h)) + (add-hook 'doom-delete-backward-functions #'+org-delete-backward-char-and-realign-table-maybe-h) (map! :map org-mode-map ;; textmate-esque newline insertion @@ -589,7 +586,7 @@ between the two." "t" #'org-agenda-todo)) -(defun +org|init-keybinds-for-evil (&rest args) +(defun +org-init-keybinds-for-evil-h (&rest args) "TODO" (when (featurep! :editor evil +everywhere) (def-package! evil-org @@ -608,12 +605,12 @@ between the two." :config (evil-org-agenda-set-keys)) ;; Only fold the current tree, rather than recursively - (add-hook 'org-tab-first-hook #'+org|cycle-only-current-subtree t) + (add-hook 'org-tab-first-hook #'+org-cycle-only-current-subtree-h t) ;; Fix o/O creating new list items in the middle of nested plain lists. Only ;; has an effect when `evil-org-special-o/O' has `item' in it (not the ;; default). - (advice-add #'evil-org-open-below :around #'+org*evil-org-open-below) + (advice-add #'evil-org-open-below :around #'+org-evil-org-open-below-a) (map! :map outline-mode-map ;; Undo keybinds from `evil-collection-outline' @@ -698,7 +695,7 @@ between the two." "C-S-j" (λ! (org-eval-in-calendar '(calendar-forward-year 1)))))) -(defun +org|init-popup-rules () +(defun +org-init-popup-rules-h () (set-popup-rules! '(("^\\*Org Links" :slot -1 :vslot -1 :size 2 :ttl 0) ("^\\*\\(?:Agenda Com\\|Calendar\\|Org \\(?:Export Dispatcher\\|Select\\)\\)" @@ -708,13 +705,14 @@ between the two." ("^CAPTURE.*\\.org$" :size 0.2 :quit nil :select t :autosave t)))) -(defun +org|init-protocol-lazy-loader () +(defun +org-init-protocol-lazy-loader-h () "Brings lazy-loaded support for org-protocol, so external programs (like browsers) can invoke specialized behavior from Emacs. Normally you'd simply require `org-protocol' and use it, but the package loads all of org for no compelling reason, so..." - (defun +org*server-visit-files (args) + (def-advice! +org--server-visit-files-a (args) "Advise `server-visit-flist' to invoke `org-protocol' lazily." + :filter-args #'server-visit-files (cl-destructuring-bind (files proc &optional nowait) args (catch 'greedy (let ((flist (reverse files))) @@ -734,20 +732,19 @@ compelling reason, so..." (setcar var fname)) ((setq files (delq var files))))))))) (list files proc nowait))) - (advice-add #'server-visit-files :filter-args #'+org*server-visit-files) ;; Disable built-in, clumsy advice (after! org-protocol (ad-disable-advice 'server-visit-files 'before 'org-protocol-detect-protocol-server))) -(defun +org|init-protocol () +(defun +org-init-protocol-h () ;; TODO org-board or better link grabbing support ;; TODO org-capture + org-protocol instead of bin/org-capture ) -(defun +org|init-smartparens () +(defun +org-init-smartparens-h () "TODO" (after! smartparens (defun +org-sp-point-in-checkbox-p (_id action _context) @@ -807,29 +804,29 @@ compelling reason, so..." ;; Shows a lot of false positives, so... doom-disable-show-trailing-whitespace-h - +org|enable-auto-reformat-tables - +org|enable-auto-update-cookies - +org|unfold-to-2nd-level-or-point)) + +org-enable-auto-reformat-tables-h + +org-enable-auto-update-cookies-h + +org-unfold-to-2nd-level-or-point-h)) (add-hook! 'org-load-hook - #'(+org|init-appearance - +org|init-agenda - +org|init-babel - +org|init-babel-lazy-loader - +org|init-capture-defaults - +org|init-capture-frame - +org|init-centralized-attachments - +org|init-centralized-exports - +org|init-custom-links - +org|init-export - +org|init-habit - +org|init-hacks - +org|init-keybinds - +org|init-keybinds-for-evil ; will noop without :editor evil - +org|init-popup-rules - +org|init-protocol - +org|init-protocol-lazy-loader - +org|init-smartparens)) + #'(+org-init-appearance-h + +org-init-agenda-h + +org-init-babel-h + +org-init-babel-lazy-loader-h + +org-init-capture-defaults-h + +org-init-capture-frame-h + +org-init-centralized-attachments-h + +org-init-centralized-exports-h + +org-init-custom-links-h + +org-init-export-h + +org-init-habit-h + +org-init-hacks-h + +org-init-keybinds-h + +org-init-keybinds-for-evil-h ; will noop without :editor evil + +org-init-popup-rules-h + +org-init-protocol-h + +org-init-protocol-lazy-loader-h + +org-init-smartparens-h)) ;; In case the user has eagerly loaded org from their configs (when (featurep 'org) @@ -847,11 +844,11 @@ compelling reason, so..." ;;; Packages (after! toc-org (setq toc-org-hrefify-default "gh") - (defun +org*unfold-toc (&rest _) + (def-advice! +org-unfold-toc-a (&rest _) + :before #'toc-org-insert-toc (save-excursion (when (re-search-forward toc-org-toc-org-regexp (point-max) t) - (+org/open-fold)))) - (advice-add #'toc-org-insert-toc :before #'+org*unfold-toc)) + (+org/open-fold))))) (def-package! org-pdfview :when (featurep! :tools pdf) @@ -874,6 +871,14 @@ compelling reason, so..." (def-package! org-clock ; built-in :commands org-clock-save - :hook (org-mode . org-clock-load) - :init (setq org-clock-persist 'history) - :config (add-hook 'kill-emacs-hook #'org-clock-save))) + :init + (setq org-clock-persist t) + (def-advice! +org-clock-load-a (&rest _) + :before '(org-clock-in + org-clock-out + org-clock-in-last + org-clock-goto + org-clock-cancel) + (org-clock-load)) + :config + (add-hook 'kill-emacs-hook #'org-clock-save))) diff --git a/modules/lang/org/contrib/dragndrop.el b/modules/lang/org/contrib/dragndrop.el index a8f571489..2faf26c00 100644 --- a/modules/lang/org/contrib/dragndrop.el +++ b/modules/lang/org/contrib/dragndrop.el @@ -22,15 +22,39 @@ ;; Handle non-image files a little differently. Images should be inserted ;; as-is, as image previews. Other files, like pdfs or zips, should be linked ;; to, with an icon indicating the type of file. - (advice-add #'org-download-insert-link :override #'+org-dragndrop*insert-link) + (def-advice! +org-dragndrop-insert-link-a (_link filename) + "Produces and inserts a link to FILENAME into the document. - (defun +org-dragndrop*download-fullname (path) +If FILENAME is an image, produce an attach:%s path, otherwise use file:%s (with +an file icon produced by `+org-attach--icon')." + :override #'org-download-insert-link + (if (looking-back "^[ \t]+" (line-beginning-position)) + (delete-region (match-beginning 0) (match-end 0)) + (newline)) + (cond ((image-type-from-file-name filename) + (insert + (concat (if (= org-download-image-html-width 0) "" + (format "#+attr_html: :width %dpx\n" org-download-image-html-width)) + (if (= org-download-image-latex-width 0) "" + (format "#+attr_latex: :width %dcm\n" org-download-image-latex-width)) + (cond ((file-in-directory-p filename org-attach-directory) + (format "[[attach:%s]]" (file-relative-name filename org-attach-directory))) + ((file-in-directory-p filename org-directory) + (format org-download-link-format (file-relative-name filename org-directory))) + ((format org-download-link-format filename))))) + (org-display-inline-images)) + ((insert + (format "%s [[./%s][%s]] " + (+org-attach--icon filename) + (file-relative-name filename (file-name-directory buffer-file-name)) + (file-name-nondirectory (directory-file-name filename))))))) + + (advice-add #'org-download--dir-2 :override #'ignore) + (def-advice! +org-dragndrop-download-fullname-a (path) "Write PATH relative to current file." + :filter-return #'org-download--fullname (let ((dir (or (if buffer-file-name (file-name-directory buffer-file-name)) default-directory))) (if (file-in-directory-p dir org-directory) (file-relative-name path dir) - path))) - (advice-add #'org-download--dir-2 :override #'ignore) - (advice-add #'org-download--fullname - :filter-return #'+org-dragndrop*download-fullname)) + path)))) diff --git a/modules/lang/org/contrib/ipython.el b/modules/lang/org/contrib/ipython.el index ec0b9d47d..a6bbe0b2a 100644 --- a/modules/lang/org/contrib/ipython.el +++ b/modules/lang/org/contrib/ipython.el @@ -8,10 +8,10 @@ (setq ob-ipython-resources-dir ".ob-ipython-resrc") - (defun +org|babel-load-ipython (lang) - (and (string-prefix-p "jupyter-" (symbol-name lang)) - (require 'ob-ipython nil t))) - (add-hook '+org-babel-load-functions #'+org|babel-load-ipython) + (add-hook '+org-babel-load-functions + (defun +org-babel-load-ipython-h (lang) + (and (string-prefix-p "jupyter-" (symbol-name lang)) + (require 'ob-ipython nil t)))) (after! org-src (add-to-list 'org-src-lang-modes '("ipython" . python))) @@ -27,14 +27,14 @@ :select nil :quit nil :ttl nil))) ;; advices for remote kernel and org-src-edit - (advice-add #'ob-ipython--create-repl :override #'+org*ob-ipython--create-repl) - (advice-add #'org-babel-edit-prep:ipython :override #'+org*babel-edit-prep:ipython) - (advice-add #'org-babel-execute:ipython :before #'+org*babel-execute:ipython) - (advice-add #'org-babel-ipython-initiate-session :override #'+org*ob-ipython-initiate-session) + (advice-add #'ob-ipython--create-repl :override #'+org-ob-ipython-create-repl-a) + (advice-add #'org-babel-edit-prep:ipython :override #'+org-babel-edit-prep:ipython-a) + (advice-add #'org-babel-execute:ipython :before #'+org-babel-execute:ipython-a) + (advice-add #'org-babel-ipython-initiate-session :override #'+org-ob-ipython-initiate-session-a) ;; retina resolution image hack (when IS-MAC - (advice-add #'ob-ipython--write-base64-string :around #'+org*ob-ipython--write-base64-string)) + (advice-add #'ob-ipython--write-base64-string :around #'+org-ob-ipython-write-base64-string-a)) ;; ipython has its own async keyword, disable ipython in ob-async. (after! ob-async diff --git a/modules/lang/org/contrib/present.el b/modules/lang/org/contrib/present.el index 51996fd75..11dcfb97a 100644 --- a/modules/lang/org/contrib/present.el +++ b/modules/lang/org/contrib/present.el @@ -36,10 +36,10 @@ :n [left] #'org-tree-slide-move-previous-tree) (add-hook! 'org-tree-slide-mode-after-narrow-hook - #'(+org-present|detect-slide - +org-present|add-overlays + #'(+org-present-detect-slide-h + +org-present-add-overlays-h org-display-inline-images)) - (add-hook 'org-tree-slide-mode-hook #'+org-present|init-org-tree-window) + (add-hook 'org-tree-slide-mode-hook #'+org-present-init-org-tree-window-h) (advice-add #'org-tree-slide--display-tree-with-narrow :around #'+org-present*narrow-to-subtree))