lang/org: major refactor

The motivation for this change was to rethink lang/org's flags. Many of
its former flags represented non-features. Therefore, its flags have
been reduced to five: +dragndrop, +ipython, +pandoc, +gnuplot and
+present. Everything else is included as org-load-hooks and treated as
reasonable defaults.

Other changes:
- Fixes #1502: don't autopair certain pairs when in a math region
- Fixes #1483: broken localleader in org-agenda
- Adds gnuplot support #1108
- Doom's org submodules have been moved into lang/org/contrib/, because
  I expect there will be *many* more to come, and I don't want to
  pollute the moudle's root.
This commit is contained in:
Henrik Lissner 2019-06-28 16:53:26 +02:00
parent 9752cc005c
commit 11bfb17894
No known key found for this signature in database
GPG key ID: 5F6C0EA160557395
17 changed files with 972 additions and 809 deletions

View file

@ -125,13 +125,10 @@
;;nix ; I hereby declare "nix geht mehr!" ;;nix ; I hereby declare "nix geht mehr!"
;;ocaml ; an objective camel ;;ocaml ; an objective camel
(org ; organize your plain life in plain text (org ; organize your plain life in plain text
+attach ; custom attachment system +dragndrop ; file drag & drop support
+babel ; running code in org +ipython ; ipython support for babel
+capture ; org-capture in and outside of Emacs +pandoc ; pandoc integration into org's exporter
+export ; Exporting org to whatever you want +present) ; using Emacs for presentations
+habit ; Keep track of your habits
+present ; Emacs for presentations
+protocol) ; Support for org-protocol:// links
;;perl ; write code no one else can comprehend ;;perl ; write code no one else can comprehend
;;php ; perl's insecure younger brother ;;php ; perl's insecure younger brother
;;plantuml ; diagrams for confusing people more ;;plantuml ; diagrams for confusing people more

View file

@ -1,92 +0,0 @@
;;; lang/org/+attach.el -*- lexical-binding: t; -*-
;; 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:
;;
;; + Places attachments in a centralized location (`+org-attach-dir' in
;; `org-directory'), using an attach:* link abbreviation.
;; + Use `+org-attach/sync' to index all attachments in `org-directory' that use
;; the attach:* abbreviation and delete orphaned ones that are no longer
;; referenced.
;; + Adds drag-and-drop support for images (with inline image preview)
;; + Adds drag-and-drop support for media files (pdfs, zips, etc) with a
;; filetype icon and short link.
;; Some commands of interest:
;; + `org-download-screenshot'
;; + `+org-attach/file'
;; + `+org-attach/url'
;; + `+org-attach/sync'
(defvar +org-attach-dir ".attach/"
"Where to store attachments relative to `org-directory'.")
;;
;;; Bootstrap
(setq org-attach-directory (expand-file-name +org-attach-dir org-directory)
org-download-image-dir org-attach-directory
org-download-heading-lvl nil
org-download-timestamp "_%Y%m%d_%H%M%S")
;; A shorter link to attachments
(add-to-list 'org-link-abbrev-alist (cons "attach" (abbreviate-file-name org-attach-directory)))
(org-link-set-parameters
"attach"
:follow (lambda (link) (find-file (expand-file-name link org-attach-directory)))
:complete (lambda (&optional _arg)
(+org--relpath (+org-link-read-file "attach" org-attach-directory)
org-attach-directory))
:face (lambda (link)
(if (file-exists-p (expand-file-name link org-attach-directory))
'org-link
'error)))
(after! projectile
(add-to-list 'projectile-globally-ignored-directories
(car (last (split-string +org-attach-dir "/" t)))))
(after! recentf
(add-to-list 'recentf-exclude (format "%s.+$" (regexp-quote org-attach-directory))))
;;
;;; Packages
(def-package! org-download
:commands (org-download-dnd org-download-dnd-base64)
:init
;; Add these manually so that org-download is lazy-loaded...
(add-to-list 'dnd-protocol-alist '("^\\(https?\\|ftp\\|file\\|nfs\\):" . +org-attach-download-dnd))
(add-to-list 'dnd-protocol-alist '("^data:" . org-download-dnd-base64))
(advice-add #'org-download-enable :override #'ignore)
:config
(setq 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")))))
;; 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-attach*insert-link)
(defun +org-attach*download-subdir ()
(when (file-in-directory-p buffer-file-name org-directory)
(file-relative-name buffer-file-name org-directory)))
(defun +org-attach*download-fullname (path)
"Write PATH relative to current file."
(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-attach*download-fullname))

View file

@ -1,103 +0,0 @@
;;; lang/org/+babel.el -*- lexical-binding: t; -*-
(defvar +org-babel-mode-alist
'((cpp . C)
(C++ . C)
(D . C)
(sh . shell)
(bash . shell)
(matlab . octave))
"An alist mapping languages to babel libraries. This is necessary for babel
libraries (ob-*.el) that don't match the name of the language.
For example, with (fish . shell) will cause #+BEGIN_SRC fish to load ob-shell.el
when executed.")
(defvar +org-babel-load-functions ()
"A list of functions executed to load the current executing src block. They
take one argument (the language specified in the src block, as a string). Stops
at the first function to return non-nil.")
;;
;;; Bootstrap
(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
org-src-window-setup 'current-window
org-confirm-babel-evaluate nil) ; you don't need my permission
;; Use major-mode native TAB indentation in SRC blocks
(advice-add #'org-return-indent :after #'+org*fix-newline-and-indent-in-src-blocks)
(defun +org*babel-lazy-load-library (info)
"Load babel libraries lazily when babel blocks are executed."
(let* ((lang (nth 0 info))
(lang (if (symbolp lang) lang (intern lang)))
(lang (or (cdr (assq lang +org-babel-mode-alist))
lang)))
(when (and (not (cdr (assq lang org-babel-load-languages)))
(or (run-hook-with-args-until-success '+org-babel-load-functions lang)
(require (intern (format "ob-%s" lang)) nil t)))
(when (assq :async (nth 2 info))
;; ob-async has its own agenda for lazy loading packages (in the
;; 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)
;; I prefer C-c C-c over C-c ' (more consistent)
(define-key org-src-mode-map (kbd "C-c C-c") #'org-edit-src-exit)
;; `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:
(defun org-babel-get-header (params key &optional others)
(cl-loop with fn = (if others #'not #'identity)
for p in params
if (funcall fn (eq (car p) key))
collect p))
;;
;;; Packages
(def-package! ob-ipython
:when (featurep! +ipython)
:defer t
:init
(defvar +ob-ipython-local-runtime-dir nil
"TODO")
(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)
:config
(set-popup-rules!
'(("\\*ob-ipython.*"
:slot 2 :side right :size 100 :height 0.2
:select nil :quit nil :transient nil)
("^\\*Python"
:slot 0 :side right :size 100
:select nil :quit nil :ttl nil)
("\\*Python:.*"
:slot 0 :side right :size 100
:select nil :quit nil :transient nil)))
;; advices for remote kernel and org-src-edit
(advice-add 'org-babel-edit-prep:ipython :override #'+org*org-babel-edit-prep:ipython)
(advice-add 'org-babel-ipython-initiate-session :override #'+org*org-babel-ipython-initiate-session)
(advice-add 'ob-ipython--create-repl :override #'+org*ob-ipython--create-repl)
(advice-add 'org-babel-execute:ipython :override #'+org*org-babel-execute:ipython)
;; retina resolution image hack
(when (eq window-system 'ns)
(advice-add 'ob-ipython--write-base64-string :around #'+org*ob-ipython--write-base64-string))
;; ipython has its own async keyword, disable ipython in ob-async.
(after! ob-async
(add-to-list 'ob-async-no-async-languages-alist "ipython")))

View file

@ -1,93 +0,0 @@
;;; lang/org/+capture.el -*- lexical-binding: t; -*-
;; Sets up some reasonable defaults, as well as two `org-capture' workflows that
;; I like:
;;
;; 1. The traditional way: invoking `org-capture' directly, via SPC X, or
;; through the :cap ex command.
;; 2. Through a org-capture popup frame that is invoked from outside Emacs (the
;; ~/.emacs.d/bin/org-capture script). This can be invoked from qutebrowser,
;; vimperator, dmenu or a global keybinding.
(defvar +org-capture-todo-file "todo.org"
"Default target for todo entries.
Is relative to `org-directory', unless it is absolute. Is used in Doom's default
`org-capture-templates'.")
(defvar +org-capture-changelog-file "changelog.org"
"Default target for changelog entries.
Is relative to `org-directory' unless it is absolute. Is used in Doom's default
`org-capture-templates'.")
(defvar +org-capture-notes-file "notes.org"
"Default target for storing notes.
Used as a fall back file for org-capture.el, for templates that do not specify a
target file.
Is relative to `org-directory', unless it is absolute. Is used in Doom's default
`org-capture-templates'.")
(setq org-default-notes-file (expand-file-name +org-capture-notes-file org-directory))
;;
;;; Bootstrap
(setq org-capture-templates
'(("t" "Personal todo" entry
(file+headline +org-capture-todo-file "Inbox")
"* TODO %?\n%i\n%a" :prepend t :kill-buffer t)
("n" "Personal notes" entry
(file+headline +org-capture-notes-file "Inbox")
"* %u %?\n%i\n%a" :prepend t :kill-buffer t)
;; Will use {project-root}/{todo,notes,changelog}.org, unless a
;; {todo,notes,changelog}.org file is found in a parent directory.
;; Uses the basename from `+org-capture-todo-file',
;; `+org-capture-changelog-file' and `+org-capture-notes-file'.
("p" "Templates for projects")
("pt" "Project todo" entry ; {project-root}/todo.org
(file+headline +org-capture-project-todo-file "Inbox")
"* TODO %?\n%i\n%a" :prepend t :kill-buffer t)
("pn" "Project notes" entry ; {project-root}/notes.org
(file+headline +org-capture-project-notes-file "Inbox")
"* TODO %?\n%i\n%a" :prepend t :kill-buffer t)
("pc" "Project changelog" entry ; {project-root}/changelog.org
(file+headline +org-capture-project-notes-file "Unreleased")
"* TODO %?\n%i\n%a" :prepend t :kill-buffer t)))
(add-hook 'org-capture-after-finalize-hook #'+org-capture|cleanup-frame)
(defun +org*capture-expand-variable-file (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."
(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 _)
"Fix #462: when refiling from org-capture, Emacs prompts to kill the
underlying, modified buffer. This fixes that."
(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)
(when (featurep! :editor evil)
(add-hook 'org-capture-mode-hook #'evil-insert-state))
(when (featurep! :ui doom-dashboard)
(add-hook '+doom-dashboard-inhibit-functions #'+org-capture-frame-p))

View file

@ -1,40 +0,0 @@
;;; lang/org/+export.el -*- lexical-binding: t; -*-
;; I don't have any beef with org's built-in export system, but I do wish it
;; would export to a central directory (by default), rather than
;; `default-directory'. This is because all my org files are usually in one
;; place, and I want to be able to refer back to old exports if needed.
(defvar +org-export-dir ".export/"
"Where to store exported files relative to `org-directory'. Can be an absolute
path too.")
(define-obsolete-variable-alias 'org-export-directory '+org-export-dir "2.1.0")
;;
(setq org-export-backends '(ascii html latex md)
org-publish-timestamp-directory (concat doom-cache-dir "org-timestamps/"))
(when (and (executable-find "pandoc")
(require 'ox-pandoc nil t))
(add-to-list 'org-export-backends 'pandoc nil #'eq)
(setq org-pandoc-options
'((standalone . t)
(mathjax . t)
(variable . "revealjs-url=https://cdn.jsdelivr.net/npm/reveal.js@3/"))))
;; Export to a central location by default or if target isn't in
;; `org-directory'.
(defun +org*export-output-file-name (args)
"Return a centralized export location unless one is provided or the current
file isn't in `org-directory'."
(when (and (not (nth 2 args))
buffer-file-name
(file-in-directory-p buffer-file-name org-directory))
(cl-destructuring-bind (extension &optional subtreep _pubdir) args
(let ((dir (expand-file-name +org-export-dir 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)

View file

@ -1,28 +0,0 @@
;;; lang/org/+habit.el -*- lexical-binding: t; -*-
(defvar +org-habit-graph-padding 2
"The padding added to the end of the consistency graph")
(defvar +org-habit-min-width 30
"Hides the consistency graph if the `org-habit-graph-column' is less than this value")
(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 `+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)

View file

@ -1,36 +0,0 @@
;;; lang/org/+protocol.el -*- lexical-binding: t; -*-
;; 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)
"Advise `server-visit-flist' to invoke `org-protocol' lazily."
(cl-destructuring-bind (files proc &optional nowait) args
(catch 'greedy
(let ((flist (reverse files)))
(dolist (var flist)
(when (string-match-p ":/+" (car var))
(require 'server)
(require 'org-protocol)
;; `\' to `/' on windows
(let ((fname (org-protocol-check-filename-for-protocol
(expand-file-name (car var))
(member var flist)
proc)))
(cond ((eq fname t) ; greedy? We need the t return value.
(setq files nil)
(throw 'greedy t))
((stringp fname) ; probably filename
(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))
;; TODO org-board or better link grabbing support
;; TODO org-capture + org-protocol instead of bin/org-capture

View file

@ -1,59 +1,194 @@
#+TITLE: :lang org #+TITLE: lang/org
#+DATE: February 19, 2017
#+SINCE: 2.0
#+STARTUP: inlineimages
This module provides support for org-mode. * Table of Contents :TOC_3:noexport:
- [[#description][Description]]
+ A custom attachment system that keeps files in a centralized location. - [[#module-flags][Module Flags]]
+ Drag-and-drop support for images (with inline preview) and media files (drops - [[#plugins][Plugins]]
a file icon and a short link). - [[#hacks][Hacks]]
+ Executable code blocks with support for a variety of languages and tools, - [[#prerequisites][Prerequisites]]
including REST requests, SQL, google translate, plantuml, and matlab.
+ An org-capture workflow that works from outside Emacs (through the
=bin/org-capture= shell script).
+ Exported documents are saved to a centralized location.
+ A configuration for using org-mode for slide-show presentations, or exporting
org files to reveal.js slideshows.
+ (TODO) A static site generator based in org-mode and Emacs.
#+begin_quote
org-mode is a beast, and Doom's most difficult module to maintain. And its most
important. This module is /highly/ opinionated and experimental; my foray into
learning org is a neverending quest.
#+end_quote
* Table of Contents :TOC:
- [[#install][Install]]
- [[#macos][MacOS]] - [[#macos][MacOS]]
- [[#arch-linux][Arch Linux]] - [[#arch-linux][Arch Linux]]
- [[#nixos][NixOS]]
- [[#windows][Windows]]
- [[#features][Features]]
- [[#invoking-the-org-capture-frame-from-outside-emacs][Invoking the org-capture frame from outside Emacs]]
- [[#built-in-custom-link-types][Built-in custom link types]]
- [[#configuration][Configuration]] - [[#configuration][Configuration]]
- [[#usage][Usage]] - [[#changing-org-directory][Changing ~org-directory~]]
- [[#appendix][Appendix]]
* Install * Description
Org has no hard dependencies, but there are some things you'll need to make use of Org's more esoteric features. 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=).
+ 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
script and ~+org-capture/open-frame~.
+ A configuration for using org-mode for slide-show presentations or exporting
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).
+ 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~).
#+begin_quote
Org is a system for writing plain text notes with syntax highlighting, code
execution, task scheduling, agenda management, and many more. The whole idea is
that you can write notes and mix them with references to things like articles,
images, and example code combined with the output of that code after it is
executed.
https://www.mfoot.com/blog/2015/11/22/literate-emacs-configuration-with-org-mode/
#+end_quote
** Module Flags
+ =+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.
+ =+pandoc= Enables pandoc integration into the Org exporter.
+ =+present= Enables integration with reveal.js, beamer and org-tree-slide, so
Emacs can be used for presentations.
** 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]]
+ =:lang crystal=
+ [[https://github.com/brantou/ob-crystal][ob-crystal]]
+ =:lang go=
+ [[https://github.com/pope/ob-go][ob-go]]
+ =:lang nim=
+ [[https://github.com/Lompik/ob-nim][ob-nim]]
+ =:lang racket=
+ [[https://github.com/DEADB17/ob-racket][ob-racket]]
+ =:lang rest=
+ [[https://github.com/alf/ob-restclient.el][ob-restclient]]
+ =:lang rust=
+ [[https://github.com/micanzhang/ob-rust][ob-rust]]
+ =:editor evil=
+ [[https://github.com/Somelauw/evil-org-mode][evil-org]]
+ =:tools pdf=
+ [[https://github.com/markus1189/org-pdfview/tree/09ef4bf8ff8319c1ac78046c7e6b89f6a0beb82c][org-pdfview]]
+ =+dragndrop=
+ [[https://github.com/abo-abo/org-download][org-download]]
+ =+ipython=
+ [[https://github.com/gregsexton/ob-ipython][ob-ipython]]
+ =+pandoc=
+ [[https://github.com/kawabata/ox-pandoc][ox-pandoc]]
+ =+present=
+ [[https://github.com/anler/centered-window-mode][centered-window]]
+ [[https://github.com/takaxp/org-tree-slide][org-tree-slide]]
+ [[https://github.com/yjwen/org-reveal][ox-reveal]]
** Hacks
+ The window is recentered when following links.
+ The breadcrumbs displayed in eldoc when hovering over an org headline has been
reworked to strip out link syntax and normalize font-size disparities.
+ If =:ui workspaces= is enabled, persp-mode won't register org agenda buffers that
are temporarily opened in the background.
+ Temporary org agenda files aren't added to recentf.
+ =file:= links are highlighted with the ~error~ face if they are broken.
+ TAB was changed to toggle only the visibility state of the current subtree,
rather than cycle through it recursively. This can be reversed with:
#+BEGIN_SRC emacs-lisp
(after! org
(remove-hook 'org-tab-first-hook #'+org|cycle-only-current-subtree t))
#+END_SRC
+ (Evil users) Nearby tables are formatted when exiting insert or replace mode
(see ~+org|enable-auto-reformat-tables~).
+ 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~);
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
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~).
* Prerequisites
Org has a few soft dependencies that you will need to make use of Org's more
esoteric features:
+ For inline LaTeX previews, you need ~latex~ and ~dvipng~. + For inline LaTeX previews, you need ~latex~ and ~dvipng~.
+ To run babel code blocks, you need whatever dependencies those languages + For rendering GNUPlot images (with =+gnuplot= flag) you need the ~gnuplot~
need. It is recommended you enable the associated module in =lang/= and ensure program installed.
its dependencies are met. + To run babel code blocks, you need whatever dependencies those languages need.
+ The =+crm= module uses a sqlite database to manage your contacts, invoices, It is recommended you enable the associated =:lang= module and ensure its
and projects; this needs sqlite installed. dependencies are met, e.g. install the =ruby= executable for ruby support.
** MacOS ** MacOS
#+BEGIN_SRC sh #+BEGIN_SRC sh
brew cask install mactex brew cask install mactex
brew install sqlite brew install gnuplot
#+END_SRC #+END_SRC
** Arch Linux ** Arch Linux
#+BEGIN_SRC sh #+BEGIN_SRC sh
sudo pacman --needed --noconfirm -S texlive-core texlive-bin texlive-science sqlite pacman -S texlive-core texlive-bin texlive-science
pacman -S gnuplot
#+END_SRC #+END_SRC
** TODO NixOS
** TODO Windows
* Features
** Invoking the org-capture frame from outside Emacs
The simplest way to use the org-capture frame is through the ~bin/org-capture~
script. I'd recommend binding a shortcut key to it. If Emacs isn't running, it
will spawn a temporary daemon for you.
Alternatively, you can call ~+org-capture/open-frame~ directly, e.g.
#+BEGIN_SRC sh
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~.
They are (with examples):
+ ~doom-docs:news/2.1.0~ (=~/.emacs.d/docs/%s=)
+ ~doom-modules:editor/evil/README.org~ (=~/.emacs.d/modules/%s=)
+ ~doom-repo:issues~ (=https://github.com/hlissner/doom-emacs/%s=)
+ ~doom:core/core.el~ (=~/.emacs.d/%s=)
+ ~duckduckgo:search terms~
+ ~gimages:search terms~ (Google Images)
+ ~github:hlissner/doom-emacs~
+ ~gmap:Toronto, Ontario~ (Google Maps)
+ ~google:search terms~
+ ~org:todo.org~ (={org-directory}/%s=)
+ ~wolfram:sin(x^3)~
+ ~youtube:P196hEuA_Xc~ (link only)
+ ~yt:P196hEuA_Xc~ (like =youtube=, but includes an inline preview of the video)
* Configuration * Configuration
(Coming soon) ** Changing ~org-directory~
To modify ~org-directory~ it must be set /before/ =org= has loaded:
* Usage #+BEGIN_SRC emacs-lisp
(Coming soon) ;; ~/.doom.d/config.el
(setq org-directory "~/new/org/location/")
* Appendix #+END_SRC
(Coming soon)

View file

@ -1,5 +1,4 @@
;;; lang/org/autoload/org-attach.el -*- lexical-binding: t; -*- ;;; lang/org/autoload/org-attach.el -*- lexical-binding: t; -*-
;;;###if (featurep! +attach)
(defun +org-attach--icon (path) (defun +org-attach--icon (path)
(char-to-string (char-to-string

View file

@ -1,5 +1,4 @@
;;; lang/org/autoload/org-capture.el -*- lexical-binding: t; -*- ;;; lang/org/autoload/org-capture.el -*- lexical-binding: t; -*-
;;;###if (featurep! +capture)
(defvar org-capture-initial) (defvar org-capture-initial)
@ -29,12 +28,12 @@
(frame-parameter nil 'transient))) (frame-parameter nil 'transient)))
;;;###autoload ;;;###autoload
(defun +org-capture/open-frame (&optional string key) (defun +org-capture/open-frame (&optional initial-input key)
"Opens the org-capture window in a floating frame that cleans itself up once "Opens the org-capture window in a floating frame that cleans itself up once
you're done. This can be called from an external shell script." you're done. This can be called from an external shell script."
(interactive) (interactive)
(when (and string (string-empty-p string)) (when (and initial-input (string-empty-p initial-input))
(setq string nil)) (setq initial-input nil))
(when (and key (string-empty-p key)) (when (and key (string-empty-p key))
(setq key nil)) (setq key nil))
(let* ((frame-title-format "") (let* ((frame-title-format "")
@ -47,7 +46,7 @@ you're done. This can be called from an external shell script."
(cl-letf (((symbol-function #'pop-to-buffer) (cl-letf (((symbol-function #'pop-to-buffer)
(symbol-function #'switch-to-buffer))) (symbol-function #'switch-to-buffer)))
(switch-to-buffer (doom-fallback-buffer)) (switch-to-buffer (doom-fallback-buffer))
(let ((org-capture-initial string) (let ((org-capture-initial initial-input)
org-capture-entry) org-capture-entry)
(when (and key (not (string-empty-p key))) (when (and key (not (string-empty-p key)))
(setq org-capture-entry (org-capture-select-template key))) (setq org-capture-entry (org-capture-select-template key)))

View file

@ -1,5 +1,4 @@
;;; lang/org/autoload/org-export.el -*- lexical-binding: t; -*- ;;; lang/org/autoload/org-export.el -*- lexical-binding: t; -*-
;;;###if (featurep! +export)
(defun +org--yank-html-buffer (buffer) (defun +org--yank-html-buffer (buffer)
(with-current-buffer buffer (with-current-buffer buffer

View file

@ -149,15 +149,13 @@ If on a:
(_ (+org/refresh-inline-images))))) (_ (+org/refresh-inline-images)))))
;;;###autoload (defun +org-insert-item (direction)
(defun +org/insert-item (direction)
"Inserts a new heading, table cell or item, depending on the context. "Inserts a new heading, table cell or item, depending on the context.
DIRECTION can be 'above or 'below. DIRECTION can be 'above or 'below.
I use this instead of `org-insert-item' or `org-insert-heading' which are too I use this instead of `org-insert-item' or `org-insert-heading' which are too
opinionated and perform this simple task incorrectly (e.g. whitespace in the opinionated and perform this simple task incorrectly (e.g. whitespace in the
wrong places)." wrong places)."
(interactive)
(let* ((context (let* ((context
(save-excursion (save-excursion
(when (bolp) (when (bolp)
@ -237,6 +235,18 @@ wrong places)."
(when (bound-and-true-p evil-local-mode) (when (bound-and-true-p evil-local-mode)
(evil-insert 1)))) (evil-insert 1))))
;;;###autoload
(defun +org/insert-item-below (count)
(interactive "p")
(dotimes (_ count)
(+org-insert-item 'below)))
;;;###autoload
(defun +org/insert-item-above (count)
(interactive "p")
(dotimes (_ count)
(+org-insert-item 'above)))
;;;###autoload ;;;###autoload
(defun +org/dedent () (defun +org/dedent ()
"TODO" "TODO"

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,39 @@
;;; lang/org/contrib/dragndrop.el -*- lexical-binding: t; -*-
(def-package! org-download
:commands (org-download-dnd org-download-dnd-base64)
:init
;; Add these manually so that org-download is lazy-loaded...
(add-to-list 'dnd-protocol-alist '("^\\(https?\\|ftp\\|file\\|nfs\\):" . +org-dragndrop-download-dnd))
(add-to-list 'dnd-protocol-alist '("^data:" . org-download-dnd-base64))
(advice-add #'org-download-enable :override #'ignore)
:config
(setq org-download-image-dir org-attach-directory
org-download-heading-lvl nil
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")))))
;; 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)
(defun +org-dragndrop*download-subdir ()
(when (file-in-directory-p buffer-file-name org-directory)
(file-relative-name buffer-file-name org-directory)))
(defun +org-dragndrop*download-fullname (path)
"Write PATH relative to current file."
(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))

View file

@ -0,0 +1,38 @@
;;; lang/org/contrib/babel.el -*- lexical-binding: t; -*-
(def-package! ob-ipython
:defer t
:init
(defvar +ob-ipython-local-runtime-dir nil)
(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)
:config
(set-popup-rules!
'(("\\*ob-ipython.*"
:slot 2 :side right :size 100 :height 0.2
:select nil :quit nil :transient nil)
("^\\*Python"
:slot 0 :side right :size 100
:select nil :quit nil :ttl nil)
("\\*Python:.*"
:slot 0 :side right :size 100
:select nil :quit nil :transient 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*org-babel-edit-prep:ipython)
(advice-add 'org-babel-execute:ipython :override #'+org*org-babel-execute:ipython)
(advice-add 'org-babel-ipython-initiate-session :override #'+org*org-babel-ipython-initiate-session)
;; retina resolution image hack
(when (eq window-system 'ns)
(advice-add 'ob-ipython--write-base64-string :around #'+org*ob-ipython--write-base64-string))
;; ipython has its own async keyword, disable ipython in ob-async.
(after! ob-async
(add-to-list 'ob-async-no-async-languages-alist "ipython")))

View file

@ -1,11 +1,14 @@
;;; lang/org/+present.el -*- lexical-binding: t; -*- ;;; lang/org/contrib/present.el -*- lexical-binding: t; -*-
(defvar +org-present-text-scale 7 (defvar +org-present-text-scale 7
"The `text-scale-amount' for `org-tree-slide-mode'.") "The `text-scale-amount' for `org-tree-slide-mode'.")
(after! ox
(add-to-list 'org-export-backends 'beamer))
;; ;;
;; Packages ;;; Packages
(def-package! ox-reveal (def-package! ox-reveal
:after ox :after ox

View file

@ -1,60 +1,54 @@
;; -*- no-byte-compile: t; -*- ;; -*- no-byte-compile: t; -*-
;;; lang/org/packages.el ;;; lang/org/packages.el
;; Installs a cutting-edge version of org-mode
(package! org-plus-contrib)
;; Prevent built-in Org from playing into the byte-compilation of ;; Prevent built-in Org from playing into the byte-compilation of
;; `org-plus-contrib'. ;; `org-plus-contrib'.
(when-let* ((orglib (locate-library "org" nil doom-site-load-path))) (when-let (orglib (locate-library "org" nil doom-site-load-path))
(setq load-path (delete (substring (file-name-directory orglib) 0 -1) (setq load-path (delete (substring (file-name-directory orglib) 0 -1)
load-path))) load-path)))
;; Ignore org on ELPA, if possible (package! org-plus-contrib) ; install cutting-edge version of org-mode
(package! org :ignore t) (package! org :ignore t) ; ignore org on ELPA, if possible
(package! org-bullets :recipe (:fetcher github :repo "Kaligule/org-bullets")) (package! org-bullets :recipe (:fetcher github :repo "Kaligule/org-bullets"))
(package! org-yt :recipe (:fetcher github :repo "TobiasZawada/org-yt"))
(package! toc-org) (package! toc-org)
(when (featurep! :editor evil) (when (featurep! :editor evil)
(package! evil-org)) (package! evil-org))
(when (featurep! :tools pdf) (when (featurep! :tools pdf)
(package! org-pdfview)) (package! org-pdfview))
(package! htmlize)
(package! ox-clip)
(package! org-yt :recipe (:fetcher github :repo "TobiasZawada/org-yt"))
(when (featurep! +attach) ;;; Babel
(package! ob-async)
(when (featurep! :lang crystal)
(package! ob-crystal))
(when (featurep! :lang go)
(package! ob-go))
(when (featurep! :lang nim)
(package! ob-nim))
(when (featurep! :lang racket)
(package! ob-racket :recipe (:fetcher github :repo "DEADB17/ob-racket")))
(when (featurep! :lang rest)
(package! ob-restclient))
(when (featurep! :lang rust)
(package! ob-rust))
;;; Modules
(when (featurep! +dragndrop)
(package! org-download)) (package! org-download))
(when (featurep! +babel) (when (featurep! +gnuplot)
(package! ob-async) (package! gnuplot)
(package! ob-mongo) (package! gnuplot-mode))
(package! ob-sql-mode)
(package! ob-translate)
(when (featurep! +ipython) (when (featurep! +ipython)
(package! ob-ipython)) (package! ob-ipython))
(when (featurep! :lang crystal) (when (featurep! +pandoc)
(package! ob-crystal)) (package! ox-pandoc))
(when (featurep! :lang go)
(package! ob-go))
(when (featurep! :lang nim)
(package! ob-nim))
(when (featurep! :lang racket)
(package! ob-racket :recipe (:fetcher github :repo "DEADB17/ob-racket")))
(when (featurep! :lang rest)
(package! ob-restclient))
(when (featurep! :lang rust)
(package! ob-rust)))
(when (featurep! +export)
(package! ox-clip)
(package! ox-pandoc)
(package! htmlize))
(when (featurep! +present) (when (featurep! +present)
(package! centered-window :recipe (:fetcher github :repo "anler/centered-window-mode")) (package! centered-window :recipe (:fetcher github :repo "anler/centered-window-mode"))
(package! org-tree-slide) (package! org-tree-slide)
(package! ox-reveal)) (package! ox-reveal))
;; (when (featurep! +publish))