Updating Doom Emacs.

This commit is contained in:
Derek Taylor
2020-06-19 22:43:40 -05:00
parent 0f664d532a
commit a5c86c514a
453 changed files with 13527 additions and 12455 deletions

View File

@@ -18,15 +18,16 @@
- [[#built-in-custom-link-types][Built-in custom link types]]
- [[#configuration][Configuration]]
- [[#changing-org-directory][Changing ~org-directory~]]
- [[#changing-org-noter-notes-search-path][Changing ~org-noter-notes-search-path~]]
* Description
This module adds org-mode support to Doom Emacs, along with a number of
adjustments, extensions and reasonable defaults to make it more performant and
intuitive out of the box:
+ A custom, centralized attachment and export system that stores files in one
place, rather than in the same directory as the input file(s) (only applies to
attachments/exporting from files in/under =org-directory=).
+ A custom, centralized attachment system that stores files in one place, rather
than in the same directory as the input file(s) (only applies to attachments
from files in/under =org-directory=).
+ Executable code blocks with support for a variety of languages and tools
(depending on what :lang modules are enabled).
+ Supports an external org-capture workflow through the =bin/org-capture= shell
@@ -35,8 +36,8 @@ intuitive out of the box:
org files to reveal.js slideshows.
+ Drag-and-drop support for images (with inline preview) and media files (drops
a file icon and a short link) (requires =+dragndrop= flag).
+ Integration with pandoc, ipython, reveal.js, beamer, and others (requires
flags).
+ Integration with pandoc, ipython, jupyter, reveal.js, beamer, and others
(requires flags).
+ Export-to-clipboard functionality, for copying text into formatted html,
markdown or rich text to the clipboard (see ~+org/export-to-clipboard~ and
~+org/export-to-clipboard-as-rich-text~).
@@ -52,27 +53,35 @@ https://www.mfoot.com/blog/2015/11/22/literate-emacs-configuration-with-org-mode
#+end_quote
** Module Flags
+ =+brain= Enables [[https://github.com/Kungsgeten/org-brain][org-brain]] integration.
+ =+dragndrop= Enables drag-and-drop support for images and files; inserts
inline previews for images and an icon+link for other media types.
+ =+gnuplot= Installs gnuplot & gnuplot-mode, which enables rendering images
from gnuplot src blocks or plotting tables with ~org-plot/gnuplot~ (bound to
=SPC m b p=, by default).
+ =+ipython= Enables ipython+babel integration.
+ =+hugo= Enables integration with [[https://gohugo.io][hugo]] to export from Emacs well-formed
([[https://github.com/russross/blackfriday][blackfriday]]) markdown.
+ =+ipython= (**DEPRECATED**) Enables ipython integration for babel.
+ =+journal= Enables [[https://github.com/bastibe/org-journal][org-journal]] integration.
+ =+jupyter= Enables Jupyter integration for babel.
+ =+noter= Enables org-noter integration. Keeps notes in sync with a document.
Requires [[https://github.com/politza/pdf-tools][pdf-tools]] (=:tools pdf=) or [[https://www.gnu.org/software/emacs/manual/html_node/emacs/Document-View.html][DocView]] or [[https://github.com/wasamasa/nov.el][nov.el]] to be enabled.
+ =+pandoc= Enables pandoc integration into the Org exporter.
+ =+pomodoro= Enables a pomodoro timer for clocking time on tasks.
+ =+present= Enables integration with reveal.js, beamer and org-tree-slide, so
Emacs can be used for presentations.
+ =+hugo= Enables integration with [[https://gohugo.io][hugo]] to export from Emacs well-formed
([[https://github.com/russross/blackfriday][blackfriday]]) markdown.
+ =+roam= Enables org-roam integration.
** Plugins
+ [[https://orgmode.org/][org-plus-contrib]]
+ [[https://github.com/sabof/org-bullets][org-bullets]]
+ [[https://github.com/TobiasZawada/org-yt][org-yt]]
+ [[https://github.com/snosov1/toc-org][toc-org]]
+ [[https://github.com/jkitchin/ox-clip][ox-clip]]
+ [[https://github.com/hniksic/emacs-htmlize][htmlize]]
+ [[https://github.com/astahlman/ob-async][ob-async]]
+ [[https://github.com/integral-dw/org-superstar-mode][org-superstar]]
+ [[https://github.com/rexim/org-cliplink][org-cliplink]]
+ [[https://github.com/magit/orgit][orgit]]
+ [[https://orgmode.org/][org-plus-contrib]]
+ [[https://github.com/TobiasZawada/org-yt][org-yt]]
+ [[https://github.com/jkitchin/ox-clip][ox-clip]]
+ [[https://github.com/snosov1/toc-org][toc-org]]
+ =:lang crystal=
+ [[https://github.com/brantou/ob-crystal][ob-crystal]]
+ =:lang go=
@@ -83,19 +92,27 @@ https://www.mfoot.com/blog/2015/11/22/literate-emacs-configuration-with-org-mode
+ [[https://github.com/DEADB17/ob-racket][ob-racket]]
+ =:lang rest=
+ [[https://github.com/alf/ob-restclient.el][ob-restclient]]
+ =:lang rst=
+ [[https://github.com/msnoigrs/ox-rst][ox-rst]]
+ =:lang rust=
+ [[https://github.com/micanzhang/ob-rust][ob-rust]]
+ =:lang scala=
+ [[https://github.com/zwild/ob-ammonite][ob-ammonite]]
+ =:editor evil=
+ [[https://github.com/Somelauw/evil-org-mode][evil-org]]
+ =:tools pdf=
+ [[https://github.com/markus1189/org-pdfview/tree/09ef4bf8ff8319c1ac78046c7e6b89f6a0beb82c][org-pdfview]]
+ [[https://github.com/fuxialexander/org-pdftools][org-pdftools]]
+ =+dragndrop=
+ [[https://github.com/abo-abo/org-download][org-download]]
+ =+gnuplot=
+ [[https://github.com/mkmcc/gnuplot-mode][gnuplot]]
+ [[https://github.com/bruceravel/gnuplot-mode][gnuplot-mode]]
+ =+hugo=
+ [[https://github.com/kaushalmodi/ox-hugo][ox-hugo]]
+ =+ipython=
+ [[https://github.com/gregsexton/ob-ipython][ob-ipython]]
+ =+jupyter=
+ [[https://github.com/dzop/emacs-jupyter][jupyter]]
+ =+pandoc=
+ [[https://github.com/kawabata/ox-pandoc][ox-pandoc]]
+ =+pomodoro=
@@ -104,8 +121,12 @@ https://www.mfoot.com/blog/2015/11/22/literate-emacs-configuration-with-org-mode
+ [[https://github.com/anler/centered-window-mode][centered-window]]
+ [[https://github.com/takaxp/org-tree-slide][org-tree-slide]]
+ [[https://gitlab.com/oer/org-re-reveal][org-re-reveal]]
+ =+hugo=
+ [[https://github.com/kaushalmodi/ox-hugo][ox-hugo]]
+ =+roam=
+ [[https://github.com/org-roam/org-roam][org-roam]]
+ [[https://github.com/org-roam/company-org-roam][company-org-roam]]
+ =+noter=
+ [[https://github.com/weirdNox/org-noter][org-noter]]
** Hacks
+ The window is recentered when following links.
@@ -197,6 +218,7 @@ They are (with examples):
+ ~google:search terms~
+ ~org:todo.org~ (={org-directory}/%s=)
+ ~wolfram:sin(x^3)~
+ ~wikipedia:Emacs~
+ ~youtube:P196hEuA_Xc~ (link only)
+ ~yt:P196hEuA_Xc~ (like =youtube=, but includes an inline preview of the video)
@@ -208,3 +230,10 @@ To modify ~org-directory~ it must be set /before/ =org= has loaded:
;; ~/.doom.d/config.el
(setq org-directory "~/new/org/location/")
#+END_SRC
** Changing ~org-noter-notes-search-path~
To modify ~org-noter-notes-search-path~ set:
#+BEGIN_SRC emacs-lisp
;; ~/.doom.d/config.el
(setq org-noter-notes-search-path '("~/notes/path/"))
#+END_SRC

View File

@@ -1,12 +0,0 @@
;;; lang/org/autoload/contrib-dragndrop.el -*- lexical-binding: t; -*-
;;;###if (featurep! +dragndrop)
;;;###autoload
(defun +org-dragndrop-download-dnd-fn (uri action)
"Handle file links and base64 data uris."
(if (eq major-mode 'org-mode)
(+org-attach/uri uri)
(let ((dnd-protocol-alist
(rassq-delete-all '+org-attach-download-dnd
(copy-alist dnd-protocol-alist))))
(dnd-handle-one-url nil action uri))))

View File

@@ -1,6 +1,9 @@
;;; lang/org/autoload/contrib-present.el -*- lexical-binding: t; -*-
;;;###if (featurep! +present)
(defvar +org-present--overlays nil)
;;
;;; Helpers
@@ -9,10 +12,13 @@
if (buffer-local-value 'org-tree-slide-mode buf)
return t)
(org-tree-slide-mode -1)
(remove-hook 'kill-buffer-hook #'+org-present--cleanup-org-tree-slides-mode)))
(remove-hook 'kill-buffer-hook #'+org-present--cleanup-org-tree-slides-mode
'local)))
(defun +org-present--make-invisible (beg end)
(let ((overlay (make-overlay beg end)))
(unless (assq '+org-present buffer-invisibility-spec)
(add-to-invisibility-spec '(+org-present)))
(let ((overlay (make-overlay beg (1+ end))))
(push overlay +org-present--overlays)
(overlay-put overlay 'invisible '+org-present)))
@@ -21,19 +27,21 @@
;;; Hooks
;;;###autoload
(defun +org-present-add-overlays-h ()
"TODO"
(add-to-invisibility-spec '(+org-present))
(defun +org-present-hide-blocks-h ()
"Hide org #+ constructs."
(save-excursion
;; hide org-mode options starting with #+
(goto-char (point-min))
(while (re-search-forward "^[[:space:]]*\\(#\\+\\)\\(\\(?:BEGIN\\|END\\|ATTR\\)[^[:space:]]+\\).*" nil t)
(+org-present--make-invisible
(match-beginning 1)
(match-end 0)))
;; hide stars in headings
(match-end 0)))))
;;;###autoload
(defun +org-present-hide-leading-stars-h ()
"Hide leading stars in headings."
(save-excursion
(goto-char (point-min))
(while (re-search-forward "^\\(\\*+\\s-\\)" nil t)
(while (re-search-forward "^\\(\\*+\\)" nil t)
(+org-present--make-invisible (match-beginning 1) (match-end 1)))))
;;;###autoload
@@ -55,43 +63,35 @@
(defvar cwm-left-fringe-ratio)
(defvar cwm-centered-window-width)
;;;###autoload
(defun +org-present-init-org-tree-window-h ()
(defun +org-present-prettify-slide-h ()
"TODO"
"Set up the org window for presentation."
(doom/window-maximize-buffer)
(let ((arg (if org-tree-slide-mode +1 -1)))
(when (fboundp 'centered-window-mode)
(let ((cwm-use-vertical-padding t)
(cwm-frame-internal-border 110)
(cwm-left-fringe-ratio -10)
(cwm-centered-window-width 240))
(centered-window-mode arg)))
(window-divider-mode (* arg -1))
(setq-local cwm-use-vertical-padding t)
(setq-local cwm-frame-internal-border 100)
(setq-local cwm-left-fringe-ratio -10)
(setq-local cwm-centered-window-width 300)
(centered-window-mode arg))
(hide-mode-line-mode arg)
(+org-pretty-mode arg)
(cond (org-tree-slide-mode
(org-indent-mode -1)
(set-window-fringes nil 0 0)
(when (bound-and-true-p solaire-mode)
(solaire-mode -1)
(fringe-mode 0))
(when (bound-and-true-p flyspell-mode)
(flyspell-mode -1))
(add-hook 'kill-buffer-hook #'+org-present--cleanup-org-tree-slides-mode
nil 'local)
(text-scale-set +org-present-text-scale)
(ignore-errors (org-latex-preview '(4)))
(set-face-attribute 'org-level-2 nil :height 1.4))
(ignore-errors (org-latex-preview '(4))))
(t
(org-indent-mode +1)
(text-scale-set 0)
(set-window-fringes nil fringe-mode fringe-mode)
(org-clear-latex-preview)
(set-face-attribute 'org-level-2 nil :height 1.0)
(+org-present-remove-overlays-h)
(org-remove-inline-images)))))
;;
;;; Commands
(defvar +org-present--overlays nil)
;;;###autoload
(defun +org-present/start ()
"TODO"
(interactive)
(unless (derived-mode-p 'org-mode)
(error "Not in an org buffer"))
(call-interactively #'org-tree-slide-mode)
(add-hook 'kill-buffer-hook #'+org-present--cleanup-org-tree-slides-mode))
(org-remove-inline-images)
(org-mode)))
(redraw-display)))

View File

@@ -1,30 +1,5 @@
;;; lang/org/autoload/org-attach.el -*- lexical-binding: t; -*-
;;
(defvar +org-attachments nil
"A list of all indexed attachments in `org-directory'.")
(defvar +org-attachments-files nil
"A list of all attachments in `org-attach-id-dir'.")
(defun +org-list-attachments (&optional beg end)
"Return a list of all attachment file names in the current buffer between BEG
and END (defaults to `point-min' and `point-max')."
(let ((case-fold-search t)
attachments)
(or end (setq end (point-max)))
(org-save-outline-visibility nil
(org-with-wide-buffer
(goto-char (or beg (point-min)))
(while (search-forward "[[attach:" end t)
(let* ((context (save-match-data (org-element-context)))
(link (expand-file-name (org-link-unescape (org-element-property :path context))
org-attach-id-dir)))
(when (and (equal "file" (org-element-property :type context))
(file-in-directory-p link org-attach-id-dir))
(push (file-name-nondirectory link) attachments))))))
(cl-delete-duplicates attachments :test #'string=)))
;;;###autoload
(defun +org-attach-icon-for (path)
(char-to-string
@@ -39,63 +14,46 @@ and END (defaults to `point-min' and `point-max')."
((or "zip" "gz" "tar" "7z" "rar") ?)
(_ ?))))
;;;###autoload
(defun +org/open-gallery-from-attachments ()
"TODO"
(interactive)
(require 'org-attach)
(if-let (dir (org-attach-dir))
(pop-to-buffer
;; Rather than opening dired *and* image-dired windows, suppress them
;; both and open only the image-dired window.
(save-window-excursion
(image-dired dir)
(current-buffer)))
(user-error "No attachments for this node")))
;;;###autoload
(defun +org-attach/sync (arg)
"Reindex all attachments in `org-directory' and delete orphaned attachments in
`org-attach-id-dir'. If ARG (universal arg), conduct a dry run."
(declare (interactive-only t))
(interactive "P")
(message "Reloading")
(setq +org-attachments-files (directory-files org-attach-id-dir nil "^[^.]" t))
(with-temp-buffer
(delay-mode-hooks (org-mode))
(dolist (org-file (directory-files-recursively org-directory "\\.org$"))
(insert-file-contents-literally org-file))
(setq +org-attachments (+org-list-attachments)))
;; clean up
(let ((deleted 0))
(dolist (file (cl-set-difference +org-attachments-files +org-attachments
:test #'string=))
(message "Deleting orphaned attachment: %s" file)
(cl-incf deleted)
(unless arg
(delete-file (expand-file-name file org-attach-id-dir))))
(message "Buffer's attachments synced (%d deleted)" deleted)))
;;;###autoload
(defun +org-attach/find-file ()
(defun +org/find-file-in-attachments ()
"Open a file from `org-attach-id-dir'."
(interactive)
(doom-project-browse org-attach-id-dir))
;;;###autoload
(defun +org-attach/file (path)
"Copies the file at PATH to `+org-attach-dir' and places an org link to it at
the cursor."
(interactive "fAttach file: ")
(+org-attach/uri path))
;;;###autoload
(defun +org-attach/uri (uri)
"Downloads the file at URL and place an org link to it at the cursor."
(defun +org/attach-file-and-insert-link (path)
"Downloads the file at PATH and insert an org link at point.
PATH (a string) can be an url, a local file path, or a base64 encoded datauri."
(interactive "sUri/file: ")
(unless (eq major-mode 'org-mode)
(user-error "Not in an org buffer"))
(require 'org-download)
(let ((raw-uri (url-unhex-string uri)))
(condition-case ex
(cond ((string-match-p "^data:image/png;base64," uri)
(org-download-dnd-base64 uri nil))
(condition-case-unless-debug e
(let ((raw-uri (url-unhex-string path)))
(cond ((string-match-p "^data:image/png;base64," path)
(org-download-dnd-base64 path nil))
((image-type-from-file-name raw-uri)
(org-download-image raw-uri))
(t
(let ((new-path (expand-file-name (org-download--fullname raw-uri))))
((let ((new-path (expand-file-name (org-download--fullname raw-uri))))
;; Download the file
(if (string-match-p (concat "^" (regexp-opt '("http" "https" "nfs" "ftp" "file")) ":/") uri)
(if (string-match-p (concat "^" (regexp-opt '("http" "https" "nfs" "ftp" "file")) ":/") path)
(url-copy-file raw-uri new-path)
(copy-file uri new-path))
(copy-file path new-path))
;; insert the link
(org-download-insert-link raw-uri new-path))))
(error
(user-error "Failed to attach file: %s" (error-message-string ex))))))
(org-download-insert-link raw-uri new-path)))))
(error
(user-error "Failed to attach file: %s" (error-message-string e)))))

View File

@@ -3,6 +3,7 @@
;;;###autoload
(defun +org-headline-avy ()
"TODO"
(require 'avy)
(save-excursion
(when-let* ((org-reverse-note-order t)
(pos (avy-with avy-goto-line (avy-jump (rx bol (1+ "*") (1+ blank))))))

View File

@@ -6,26 +6,33 @@
;;
;;; External frame
(defvar +org-capture-fn #'org-capture
"Command to use to initiate org-capture.")
;;;###autoload
(defvar +org-capture-frame-parameters
`((name . "org-capture")
`((name . "doom-capture")
(width . 70)
(height . 25)
(transient . t)
,(if IS-LINUX '(display . ":0")))
,(when (and IS-LINUX (not (getenv "DISPLAY")))
`(display . ":0"))
,(if IS-MAC '(menu-bar-lines . 1)))
"TODO")
;;;###autoload
(defun +org-capture-cleanup-frame-h ()
"Closes the org-capture frame once done adding an entry."
(when (+org-capture-frame-p)
(when (and (+org-capture-frame-p)
(not org-capture-is-refiling))
(delete-frame nil t)))
;;;###autoload
(defun +org-capture-frame-p (&rest _)
"Return t if the current frame is an org-capture frame opened by
`+org-capture/open-frame'."
(and (equal "org-capture" (frame-parameter nil 'name))
(and (equal (alist-get 'name +org-capture-frame-parameters)
(frame-parameter nil 'name))
(frame-parameter nil 'transient)))
;;;###autoload
@@ -45,23 +52,13 @@ you're done. This can be called from an external shell script."
(with-selected-frame frame
(require 'org-capture)
(condition-case ex
(cl-letf (((symbol-function #'pop-to-buffer)
(symbol-function #'switch-to-buffer)))
(letf! ((#'pop-to-buffer #'switch-to-buffer))
(switch-to-buffer (doom-fallback-buffer))
(let ((org-capture-initial initial-input)
org-capture-entry)
(when (and key (not (string-empty-p key)))
(setq org-capture-entry (org-capture-select-template key)))
(if (or org-capture-entry
(not (fboundp 'counsel-org-capture)))
(org-capture)
(unwind-protect
(counsel-org-capture)
(if-let (buf (cl-find-if (doom-partial #'buffer-local-value 'org-capture-mode)
(buffer-list)))
(with-current-buffer buf
(add-hook 'kill-buffer-hook #'+org-capture-cleanup-frame-h nil t))
(delete-frame frame))))))
(funcall +org-capture-fn)))
('error
(message "org-capture: %s" (error-message-string ex))
(delete-frame frame))))))
@@ -148,16 +145,16 @@ project."
(defun +org-capture-central-project-todo-file ()
"TODO"
(+org--capture-central-file
+org-capture-todo-file (projectile-project-name)))
+org-capture-projects-file (projectile-project-name)))
;;;###autoload
(defun +org-capture-central-project-notes-file ()
"TODO"
(+org--capture-central-file
+org-capture-notes-file (projectile-project-name)))
+org-capture-projects-file (projectile-project-name)))
;;;###autoload
(defun +org-capture-central-project-changelog-file ()
"TODO"
(+org--capture-central-file
+org-capture-changelog-file (projectile-project-name)))
+org-capture-projects-file (projectile-project-name)))

View File

@@ -1,27 +1,79 @@
;;; lang/org/autoload/org-link.el -*- lexical-binding: t; -*-
;;;###autoload
(defun +org-link-read-file (key dir)
(let ((file (read-file-name (format "%s: " (capitalize key)) dir)))
(format "%s:%s"
key
(file-relative-name file dir))))
(defun +org--relative-path (path root)
(if (and buffer-file-name (file-in-directory-p buffer-file-name root))
(file-relative-name path)
path))
(defun +org--read-link-path (key dir &optional fn)
(let ((file (funcall (or fn #'read-file-name) (format "%s: " (capitalize key)) dir)))
(format "%s:%s" key (file-relative-name file dir))))
;;;###autoload
(defun +org-link-read-directory (key dir)
(let ((file (read-directory-name (format "%s: " (capitalize key)) dir)))
(format "%s:%s"
key
(file-relative-name file dir))))
(defun +org-define-basic-link (key dir-var &rest plist)
"Define a link with some basic completion & fontification.
KEY is the name of the link type. DIR-VAR is the directory variable to resolve
links relative to. PLIST is passed to `org-link-set-parameters' verbatim.
Links defined with this will be rendered in the `error' face if the file doesn't
exist, and `org-link' otherwise."
(declare (indent 2))
(let ((requires (plist-get plist :requires))
(dir-fn (if (functionp dir-var)
dir-var
(lambda () (symbol-value dir-var)))))
(apply #'org-link-set-parameters
key
:complete (lambda ()
(if requires (mapc #'require (doom-enlist requires)))
(+org--relative-path (+org--read-link-path key (funcall dir-fn))
(funcall dir-fn)))
:follow (lambda (link)
(org-link-open-as-file (expand-file-name link (funcall dir-fn)) nil))
:face (lambda (link)
(let* ((path (expand-file-name link (funcall dir-fn)))
(option-index (string-match-p "::\\(.*\\)\\'" path))
(file-name (substring path 0 option-index)))
(if (file-exists-p file-name)
'org-link
'error)))
(doom-plist-delete plist :requires))))
;;
;;; Image data functions (for custom inline images)
;;;###autoload
(defun +org-inline-data-image (_protocol link _description)
(defun +org-image-file-data-fn (protocol link _description)
"Intepret LINK as an image file path and return its data."
(setq
link (expand-file-name
link (pcase protocol
("download"
(or (if (require 'org-download nil t) org-download-image-dir)
(if (require 'org-attach) org-attach-id-dir)
default-directory))
("attachment"
(require 'org-attach)
org-attach-id-dir)
(_ default-directory))))
(when (and (file-exists-p link)
(image-type-from-file-name link))
(with-temp-buffer
(set-buffer-multibyte nil)
(setq buffer-file-coding-system 'binary)
(insert-file-contents-literally link)
(buffer-substring-no-properties (point-min) (point-max)))))
;;;###autoload
(defun +org-inline-image-data-fn (_protocol link _description)
"Interpret LINK as base64-encoded image data."
(base64-decode-string link))
;;;###autoload
(defun +org-image-link (protocol link _description)
"Interpret LINK as base64-encoded image data."
(defun +org-http-image-data-fn (protocol link _description)
"Interpret LINK as an URL to an image file."
(when (image-type-from-file-name link)
(if-let* ((buf (url-retrieve-synchronously (concat protocol ":" link))))
(with-current-buffer buf

View File

@@ -3,15 +3,27 @@
;; REVIEW These are all proof-of-concept. Refactor me!
;;;###autoload
(defun +org/refile-to-current-file (arg)
(defun +org/refile-to-current-file (arg &optional file)
"TODO"
(interactive "P")
(let ((org-refile-targets `((nil :maxlevel . 10)))
(let ((org-refile-targets `((,file :maxlevel . 10)))
(org-refile-use-outline-path nil)
(org-refile-keep arg)
current-prefix-arg)
(call-interactively #'org-refile)))
;;;###autoload
(defun +org/refile-to-file (arg file)
"Refile current heading to a particular org file."
(interactive
(list current-prefix-arg
(read-file-name "Select file to refile to: "
default-directory
buffer-file-name
t nil
(lambda (f) (string-match-p "\\.org$" f)))))
(+org/refile-to-current-file arg file))
;;;###autoload
(defun +org/refile-to-other-window (arg)
"TODO"

View File

@@ -46,11 +46,10 @@ re-align the table if necessary. (Necessary because org-mode has a
;;;###autoload
(defun +org-realign-table-maybe-h ()
"Auto-align table under cursor and re-calculate formulas."
"Auto-align table under cursor."
(when (and (org-at-table-p) org-table-may-need-update)
(let ((pt (point))
(inhibit-message t))
(org-table-recalculate)
(if org-table-may-need-update (org-table-align))
(goto-char pt))))

View File

@@ -62,10 +62,7 @@
('above (save-excursion (org-shiftmetadown))
(+org/table-previous-row))))
((memq type '(headline inlinetask))
(let ((level (if (eq (org-element-type context) 'headline)
(org-element-property :level context)
1)))
((let ((level (or (org-current-level) 1)))
(pcase direction
(`below
(let (org-insert-heading-respect-content)
@@ -81,13 +78,12 @@
(org-todo (cond ((eq todo-type 'done)
(car (+org-get-todo-keywords-for todo-keyword)))
(todo-keyword)
('todo))))))
((user-error "Not a valid list, heading or table")))
('todo)))))))
(when (org-invisible-p)
(org-show-hidden-entry))
(when (bound-and-true-p evil-local-mode)
(when (and (bound-and-true-p evil-local-mode)
(not (evil-emacs-state-p)))
(evil-insert 1))))
(defun +org--get-property (name &optional bound)
@@ -145,7 +141,7 @@ current file). Only scans first 2048 bytes of the document."
;;; Commands
;;;###autoload
(defun +org/dwim-at-point ()
(defun +org/dwim-at-point (&optional arg)
"Do-what-I-mean at point.
If on a:
@@ -162,7 +158,7 @@ If on a:
- latex fragment: toggle it.
- link: follow it
- otherwise, refresh all inline images in current tree."
(interactive)
(interactive "P")
(let* ((context (org-element-context))
(type (org-element-type context)))
;; skip over unimportant contexts
@@ -171,7 +167,9 @@ If on a:
type (org-element-type context)))
(pcase type
(`headline
(cond ((and (fboundp 'toc-org-insert-toc)
(cond ((memq (bound-and-true-p org-goto-map) (current-active-maps))
(org-goto-ret))
((and (fboundp 'toc-org-insert-toc)
(member "TOC" (org-get-tags)))
(toc-org-insert-toc)
(message "Updating table of contents"))
@@ -210,7 +208,7 @@ If on a:
(`table-cell
(org-table-blank-field)
(org-table-recalculate)
(org-table-recalculate arg)
(when (and (string-empty-p (string-trim (org-table-get-field)))
(bound-and-true-p evil-local-mode))
(evil-change-state 'insert)))
@@ -219,13 +217,13 @@ If on a:
(org-babel-lob-execute-maybe))
(`statistics-cookie
(save-excursion (org-update-statistics-cookies nil)))
(save-excursion (org-update-statistics-cookies arg)))
((or `src-block `inline-src-block)
(org-babel-execute-src-block))
(org-babel-execute-src-block arg))
((or `latex-fragment `latex-environment)
(org-latex-preview))
(org-latex-preview arg))
(`link
(let* ((lineage (org-element-lineage context '(link) t))
@@ -233,13 +231,18 @@ If on a:
(if (or (equal (org-element-property :type lineage) "img")
(and path (image-type-from-file-name path)))
(+org--refresh-inline-images-in-subtree)
(org-open-at-point))))
(org-open-at-point arg))))
((guard (org-element-property :checkbox (org-element-lineage context '(item) t)))
(let ((match (and (org-at-item-checkbox-p) (match-string 1))))
(org-toggle-checkbox (if (equal match "[ ]") '(16)))))
(_ (+org--refresh-inline-images-in-subtree)))))
(_
(if (or (org-in-regexp org-ts-regexp-both nil t)
(org-in-regexp org-tsr-regexp-both nil t)
(org-in-regexp org-link-any-re nil t))
(call-interactively #'org-open-at-point)
(+org--refresh-inline-images-in-subtree))))))
;; I use this instead of `org-insert-item' or `org-insert-heading' which are too
@@ -305,6 +308,20 @@ the prefix ARG changes this command's behavior."
;;;###autoload
(defalias #'+org/close-fold #'outline-hide-subtree)
;;;###autoload
(defun +org/close-all-folds (&optional level)
"Close all folds in the buffer (or below LEVEL)."
(interactive "p")
(outline-hide-sublevels (or level 1)))
;;;###autoload
(defun +org/open-all-folds (&optional level)
"Open all folds in the buffer (or up to LEVEL)."
(interactive "P")
(if (integerp level)
(outline-hide-sublevels level)
(outline-show-all)))
(defun +org--get-foldlevel ()
(let ((max 1))
(save-restriction
@@ -320,22 +337,20 @@ the prefix ARG changes this command's behavior."
max)))
;;;###autoload
(defun +org/show-next-fold-level ()
(defun +org/show-next-fold-level (&optional count)
"Decrease the fold-level of the visible area of the buffer. This unfolds
another level of headings on each invocation."
(interactive)
(let* ((current-level (+org--get-foldlevel))
(new-level (1+ current-level)))
(interactive "p")
(let ((new-level (+ (+org--get-foldlevel) (or count 1))))
(outline-hide-sublevels new-level)
(message "Folded to level %s" new-level)))
;;;###autoload
(defun +org/hide-next-fold-level ()
(defun +org/hide-next-fold-level (&optional count)
"Increase the global fold-level of the visible area of the buffer. This folds
another level of headings on each invocation."
(interactive)
(let* ((current-level (+org--get-foldlevel))
(new-level (max 1 (1- current-level))))
(interactive "p")
(let ((new-level (max 1 (- (+org--get-foldlevel) (or count 1)))))
(outline-hide-sublevels new-level)
(message "Folded to level %s" new-level)))
@@ -365,6 +380,12 @@ Made for `org-tab-first-hook' in evil-mode."
((org-in-src-block-p t)
(org-babel-do-in-edit-buffer
(call-interactively #'indent-for-tab-command))
t)
((and (save-excursion
(skip-chars-backward " \t")
(bolp))
(org-in-subtree-not-table-p))
(call-interactively #'tab-to-tab-stop)
t)))
;;;###autoload
@@ -379,18 +400,25 @@ Made for `org-tab-first-hook' in evil-mode."
"Tries to expand a yasnippet snippet, if one is available. Made for
`org-tab-first-hook'."
(when (bound-and-true-p yas-minor-mode)
(cond ((and (or (not (bound-and-true-p evil-local-mode))
(evil-insert-state-p))
(yas--templates-for-key-at-point))
(call-interactively #'yas-expand)
t)
((use-region-p)
;; Triggering mode-specific indentation is expensive in src blocks
;; (if `org-src-tab-acts-natively' is non-nil), and can cause errors,
;; so we avoid smart indentation in this case.
(let ((yas-indent-line 'fixed))
(call-interactively #'yas-insert-snippet))
t))))
(and (let ((major-mode (if (org-in-src-block-p t)
(org-src-get-lang-mode (org-eldoc-get-src-lang))
major-mode))
(org-src-tab-acts-natively nil) ; causes breakages
;; Smart indentation doesn't work with yasnippet, and painfully slow
;; in the few cases where it does.
(yas-indent-line 'fixed))
(cond ((and (or (not (bound-and-true-p evil-local-mode))
(evil-insert-state-p))
(yas--templates-for-key-at-point))
(yas-expand)
t)
((use-region-p)
(yas-insert-snippet)
t)))
;; HACK Yasnippet breaks org-superstar-mode because yasnippets is
;; overzealous about cleaning up overlays.
(when (bound-and-true-p org-superstar-mode)
(org-superstar-restart)))))
;;;###autoload
(defun +org-cycle-only-current-subtree-h (&optional arg)
@@ -412,18 +440,22 @@ with `org-cycle')."
t)))))
;;;###autoload
(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."
(unless org-agenda-inhibit-startup
(when (eq org-startup-folded t)
(outline-hide-sublevels +org-initial-fold-level))
(when (outline-invisible-p)
(ignore-errors
(save-excursion
(outline-previous-visible-heading 1)
(org-show-subtree))))))
(defun +org-clear-babel-results-h ()
"Remove the results block for the org babel block at point."
(when (and (org-in-src-block-p t)
(org-babel-where-is-src-block-result))
(org-babel-remove-result)
t))
;;;###autoload
(defun +org-make-last-point-visible-h ()
"Unfold subtree around point if saveplace places it to a folded region."
(and (not org-agenda-inhibit-startup)
(outline-invisible-p)
(ignore-errors
(save-excursion
(outline-previous-visible-heading 1)
(org-show-subtree)))))
;;;###autoload
(defun +org-remove-occur-highlights-h ()

File diff suppressed because it is too large Load Diff

View File

@@ -2,59 +2,66 @@
;;;###if (featurep! +dragndrop)
(use-package! org-download
:commands org-download-dnd org-download-dnd-base64
:commands
org-download-dnd
org-download-yank
org-download-screenshot
org-download-dnd-base64
:init
;; HACK We add these manually so that org-download is truly lazy-loaded
(pushnew! dnd-protocol-alist
'("^\\(?:https?\\|ftp\\|file\\|nfs\\):" . +org-dragndrop-download-dnd-fn)
'("^\\(?:https?\\|ftp\\|file\\|nfs\\):" . org-download-dnd)
'("^data:" . org-download-dnd-base64))
(advice-add #'org-download-enable :override #'ignore)
(after! org
;; A shorter link to attachments
(+org-define-basic-link "download" (lambda () (or org-download-image-dir org-attach-id-dir "."))
:image-data-fun #'+org-image-file-data-fn
:requires 'org-download))
:config
(setq org-download-image-dir org-attach-directory
org-download-heading-lvl nil
(unless org-download-image-dir
(setq org-download-image-dir org-attach-id-dir))
(setq org-download-method 'attach
org-download-timestamp "_%Y%m%d_%H%M%S"
org-download-screenshot-method
(cond (IS-MAC "screencapture -i %s")
(IS-LINUX
(cond ((executable-find "maim") "maim -s %s")
((executable-find "scrot") "scrot -s %s")))))
((executable-find "scrot") "scrot -s %s")
((executable-find "gnome-screenshot") "gnome-screenshot -a -f %s"))))
;; 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.
(defadvice! +org--dragndrop-insert-link-a (_link filename)
"Produces and inserts a link to FILENAME into the document.
org-download-heading-lvl nil
org-download-link-format "[[download:%s]]\n"
org-download-annotate-function (lambda (_link) "")
org-download-link-format-function
(lambda (filename)
(if (eq org-download-method 'attach)
(format "[[attachment:%s]]\n"
(org-link-escape
(file-relative-name filename (org-attach-dir))))
;; Handle non-image files a little differently. Images should be
;; inserted as normal with previews. Other files, like pdfs or zips,
;; should be linked to, with an icon indicating the type of file.
(format (concat (unless (image-type-from-file-name filename)
(concat (+org-attach-icon-for filename)
" "))
org-download-link-format)
(org-link-escape
(funcall org-download-abbreviate-filename-function filename)))))
org-download-abbreviate-filename-function
(lambda (path)
(if (file-in-directory-p path org-download-image-dir)
(file-relative-name path org-download-image-dir)
path)))
If FILENAME is an image, produce an attach:%s path, otherwise use file:%s (with
an file icon produced by `+org-attach-icon-for')."
: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-for 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)
(defadvice! +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))))
(defadvice! +org--dragndrop-then-display-inline-images-a (_link filename)
:after #'org-download-insert-link
(when (image-type-from-file-name filename)
(save-excursion
(org-display-inline-images
t t
(progn (org-back-to-heading t) (point))
(progn (org-end-of-subtree t t)
(when (and (org-at-heading-p) (not (eobp))) (backward-char 1))
(point)))))))

View File

@@ -1,16 +1,62 @@
;;; lang/org/contrib/journal.el -*- lexical-binding: t; -*-
;;;###if (featurep! +journal)
(after! org-journal
(setq org-journal-dir (expand-file-name "journal/" org-directory)
org-journal-file-pattern
(expand-file-name "\\(?1:[0-9]\\{4\\}\\)\\(?2:[0-9][0-9]\\)\\(?3:[0-9][0-9]\\)\\'"
org-journal-dir))
(use-package! org-journal
:defer t
:init
;; HACK `org-journal' adds a `magic-mode-alist' entry for detecting journal
;; files, but this causes us lazy loaders a big problem: an unacceptable
;; delay on the first file the user opens, because calling the autoloaded
;; `org-journal-is-journal' pulls all of `org' with it. So, we replace it
;; with our own, extra layer of heuristics.
(setq magic-mode-alist (assq-delete-all 'org-journal-is-journal magic-mode-alist))
(add-to-list 'magic-mode-alist '(+org-journal-p . org-journal-mode))
(map! :localleader
(defun +org-journal-p ()
(when-let (buffer-file-name (buffer-file-name (buffer-base-buffer)))
(and (file-in-directory-p
buffer-file-name (expand-file-name org-journal-dir org-directory))
(delq! '+org-journal-p magic-mode-alist 'assq)
(require 'org-journal nil t)
(org-journal-is-journal))))
;; `org-journal-dir' defaults to "~/Documents/journal/", which is an odd
;; default, so we change it to {org-directory}/journal (we expand it after
;; org-journal is loaded).
(setq org-journal-dir "journal/"
org-journal-cache-file (concat doom-cache-dir "org-journal"))
:config
;; `org-journal' can't deal with symlinks, so resolve them here.
(setq org-journal-dir (expand-file-name org-journal-dir org-directory)
;; Doom opts for an "open in a popup or here" strategy as a default.
;; Open in "other window" is less predictable, and can replace a window
;; we wanted to keep visible.
org-journal-find-file #'find-file)
(set-popup-rule! "^\\*Org-journal search" :select t :quit t)
(map! (:map org-journal-mode-map
:n "]f" #'org-journal-open-next-entry
:n "[f" #'org-journal-open-previous-entry
:n "C-n" #'org-journal-open-next-entry
:n "C-p" #'org-journal-open-previous-entry)
(:map org-journal-search-mode-map
"n" #'org-journal-search-next
"p" #'org-journal-search-prev)
"C-n" #'org-journal-search-next
"C-p" #'org-journal-search-previous)
:localleader
(:map org-journal-mode-map
"n" #'org-journal-open-next-entry
"p" #'org-journal-open-previous-entry)))
"c" #'org-journal-new-entry
"d" #'org-journal-new-date-entry
"n" #'org-journal-open-next-entry
"p" #'org-journal-open-previous-entry
(:prefix "s"
"s" #'org-journal-search
"f" #'org-journal-search-forever
"F" #'org-journal-search-future
"w" #'org-journal-search-calendar-week
"m" #'org-journal-search-calendar-month
"y" #'org-journal-search-calendar-year))
(:map org-journal-search-mode-map
"n" #'org-journal-search-next
"p" #'org-journal-search-prev)))

View File

@@ -1,7 +1,7 @@
;;; lang/org/contrib/present.el -*- lexical-binding: t; -*-
;;;###if (featurep! +present)
(defvar +org-present-text-scale 7
(defvar +org-present-text-scale 6
"The `text-scale-amount' for `org-tree-slide-mode'.")
(after! ox
@@ -14,7 +14,7 @@
(use-package! org-re-reveal
:after ox
:init
(setq org-re-reveal-root "https://cdn.jsdelivr.net/npm/reveal.js@3/"))
(setq org-re-reveal-root "https://revealjs.com"))
(use-package! org-tree-slide
@@ -24,31 +24,36 @@
(setq org-tree-slide-skip-outline-level 2
org-tree-slide-activate-message " "
org-tree-slide-deactivate-message " "
org-tree-slide-modeline-display nil)
org-tree-slide-modeline-display nil
org-tree-slide-heading-emphasis t)
(map! :map org-tree-slide-mode-map
:n [right] #'org-tree-slide-move-next-tree
:n [left] #'org-tree-slide-move-previous-tree)
(add-hook 'org-tree-slide-mode-after-narrow-hook #'org-display-inline-images)
(add-hook! 'org-tree-slide-mode-hook
#'+org-present-hide-blocks-h
#'+org-present-prettify-slide-h)
(add-hook! 'org-tree-slide-mode-after-narrow-hook
#'+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-h)
(when (featurep! :editor evil)
(map! :map org-tree-slide-mode-map
:n [C-right] #'org-tree-slide-move-next-tree
:n [C-left] #'org-tree-slide-move-previous-tree)
(add-hook 'org-tree-slide-mode-hook #'evil-normalize-keymaps))
(defadvice! +org-present--narrow-to-subtree-a (orig-fn &rest args)
"Narrow to the target subtree when you start the presentation."
:around #'org-tree-slide--display-tree-with-narrow
(cl-letf (((symbol-function #'org-narrow-to-subtree)
(lambda () (save-excursion
(save-match-data
(org-with-limited-levels
(narrow-to-region
(progn (org-back-to-heading t)
(forward-line 1)
(point))
(progn (org-end-of-subtree t t)
(when (and (org-at-heading-p) (not (eobp))) (backward-char 1))
(point)))))))))
(letf! (defun org-narrow-to-subtree ()
(save-excursion
(save-match-data
(org-with-limited-levels
(narrow-to-region
(progn
(when (org-before-first-heading-p)
(org-next-visible-heading 1))
(ignore-errors (org-up-heading-all 99))
(forward-line 1)
(point))
(progn (org-end-of-subtree t t)
(when (and (org-at-heading-p) (not (eobp)))
(backward-char 1))
(point)))))))
(apply orig-fn args))))

View File

@@ -4,3 +4,7 @@
(when (featurep! +gnuplot)
(unless (executable-find "gnuplot")
(warn! "Couldn't find gnuplot. org-plot/gnuplot will not work")))
(when (featurep! +roam)
(unless (executable-find "dot")
(warn! "Couldn't find the dot executable (from graphviz). org-roam will not be able to generate graph visuallizations.")))

View File

@@ -13,69 +13,96 @@
;; call in the repo's root. Of course, this command won't work in a sparse
;; clone, and more than that, initiating these compilation step is a
;; hassle, so...
(setq straight-fix-org nil)
(add-hook! 'straight-use-package-pre-build-functions
(defun +org-fix-package-h (package &rest _)
(when (member package '("org" "org-plus-contrib"))
(with-temp-file (expand-file-name "org-version.el" (straight--repos-dir "org"))
(insert "(fset 'org-release (lambda () \"9.3\"))\n"
(when (equal package "org-mode")
(with-temp-file (expand-file-name "org-version.el" (straight--repos-dir "org-mode"))
(insert "(fset 'org-release (lambda () \"9.4\"))\n"
"(fset 'org-git-version #'ignore)\n"
"(provide 'org-version)\n")))))
(package! org-plus-contrib) ; install cutting-edge version of org-mode
;; Install cutting-edge version of org-mode, and from a mirror, because
;; code.orgmode.org runs on a potato.
(package! org-mode
:recipe (:host github
:repo "emacs-straight/org-mode"
:files ("*.el" "lisp/*.el" "contrib/lisp/*.el"))
:pin "c709187173ff2bb72c0f902c0299998c8c5a4260")
;; ...And prevent other packages from pulling org; org-plus-contrib satisfies
;; the dependency already: https://github.com/raxod502/straight.el/issues/352
(package! org :recipe (:local-repo nil))
(package! avy)
(package! htmlize)
(package! org-bullets :recipe (:host github :repo "Kaligule/org-bullets"))
(package! org-fancy-priorities)
(package! org-yt :recipe (:host github :repo "TobiasZawada/org-yt"))
(package! ox-clip)
(package! toc-org)
(package! org-cliplink)
(package! htmlize :pin "86f22f211e9230857197c42a9823d3f05381deed")
(package! org-superstar :pin "09ddc28383d363a4b353348a433e24535b4af0e3")
(package! org-yt
:recipe (:host github :repo "TobiasZawada/org-yt")
:pin "40cc1ac76d741055cbefa13860d9f070a7ade001")
(package! ox-clip :pin "bd36f9fb4e3b1b9e8686b993b02ccd780ff75a96")
(package! toc-org :pin "5deaec41ed0e5c51715737d7f74c5ae1b3c00387")
(package! org-cliplink :pin "82402cae7e118d67de7328417fd018a18f95fac2")
(when (featurep! :editor evil +everywhere)
(package! evil-org :recipe (:host github :repo "hlissner/evil-org-mode")))
(package! evil-org
:recipe (:host github :repo "hlissner/evil-org-mode")
:pin "2e9c4a295ee6aea7c97c5b1f3892b1c6e28a32d9"))
(when (featurep! :tools pdf)
(package! org-pdfview))
(package! org-pdftools :pin "8cc15bb8014ed1f047eecc0abd8bf447f86c0505"))
(when (featurep! :tools magit)
(package! orgit))
(package! orgit :pin "e147f055772cc934fe1f1d8619059badeb647c93"))
(when (featurep! +brain)
(package! org-brain :pin "6b2ec93ec92b4a244af9d600433e0d0a02eb5f1e"))
(when (featurep! +dragndrop)
(package! org-download))
(package! org-download :pin "40c8a1db186a4ec79d87805018237234c0aad878"))
(when (featurep! +gnuplot)
(package! gnuplot)
(package! gnuplot-mode))
(when (featurep! +ipython)
(package! ob-ipython))
(package! gnuplot :pin "f0001c30010b2899e36d7d89046322467e923088")
(package! gnuplot-mode :pin "601f6392986f0cba332c87678d31ae0d0a496ce7"))
(when (featurep! +ipython) ; DEPRECATED
(package! ob-ipython :pin "7147455230841744fb5b95dcbe03320313a77124"))
(when (featurep! +jupyter)
(package! jupyter :pin "785edbbff65abb0c929dc2fbd8b8305c77fd529e"))
(when (featurep! +journal)
(package! org-journal :pin "0d6d81234a20ac800d24373b89159ee33a69f6c3"))
(when (featurep! +noter)
(package! org-noter :pin "9ead81d42dd4dd5074782d239b2efddf9b8b7b3d"))
(when (featurep! +pomodoro)
(package! org-pomodoro))
(package! org-pomodoro :pin "aa07c11318f91219336197e62c47bc7a3d090479"))
(when (featurep! +present)
(package! centered-window
:recipe (:host github :repo "anler/centered-window-mode"))
(package! org-tree-slide)
(package! org-re-reveal))
(when (featurep! +journal)
(package! org-journal))
:recipe (:host github :repo "anler/centered-window-mode")
:pin "f50859941ab5c7cbeaee410f2d38716252b552ac")
(package! org-tree-slide :pin "7126a4365072a32898f169ead8fb59265dabc605")
(package! org-re-reveal :pin "a9e9d4ef88417b3af7741a8d8f444ece820e7a3b"))
(when (featurep! +roam)
(package! org-roam :pin "9cf26494e86b1cc18267fd70abf942d2fb75c774")
(when (featurep! :completion company)
(package! company-org-roam :pin "674c2bd493f571c5323d69279557a6c18ccbd14e")))
;;; Babel
(package! ob-async)
(package! ob-async :pin "80a30b96a007d419ece12c976a81804ede340311")
(when (featurep! :lang crystal)
(package! ob-crystal))
(package! ob-crystal :pin "d84c1adee4b269cdba06a97caedb8071561a09af"))
(when (featurep! :lang go)
(package! ob-go))
(package! ob-go :pin "2067ed55f4c1d33a43cb3f6948609d240a8915f5"))
(when (featurep! :lang hy)
(package! ob-hy :pin "a42ecaf440adc03e279afe43ee5ef6093ddd542a"))
(when (featurep! :lang nim)
(package! ob-nim))
(package! ob-nim :pin "bf1642cb93f0a898804dc13fd9408d2964403bd2"))
(when (featurep! :lang racket)
(package! ob-racket :recipe (:host github :repo "DEADB17/ob-racket")))
(package! ob-racket
:recipe (:host github :repo "DEADB17/ob-racket")
:pin "d8fd51bddb019b0eb68755255f88fc800cfe03cb"))
(when (featurep! :lang rest)
(package! ob-restclient))
(when (featurep! :lang rust)
(package! ob-rust))
(package! ob-restclient :pin "f7449b2068498fe9d8ab9589e0a638148861533f"))
(when (featurep! :lang scala)
(package! ob-ammonite :pin "39937dff395e70aff76a4224fa49cf2ec6c57cca"))
;;; Export
(when (featurep! +pandoc)
(package! ox-pandoc))
(package! ox-pandoc :pin "aa37dc7e94213d4ebedb85c384c1ba35007da18e"))
(when (featurep! +hugo)
(package! ox-hugo
:recipe (:host github :repo "kaushalmodi/ox-hugo" :nonrecursive t)))
:recipe (:host github :repo "kaushalmodi/ox-hugo" :nonrecursive t)
:pin "5de3da970f9ead05930781dd0b73b5011310b2ba"))
(when (featurep! :lang rst)
(package! ox-rst))
(package! ox-rst :pin "9158bfd18096c559e0a225ae62ab683f1c98a547"))