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:
parent
9752cc005c
commit
11bfb17894
17 changed files with 972 additions and 809 deletions
|
@ -125,13 +125,10 @@
|
|||
;;nix ; I hereby declare "nix geht mehr!"
|
||||
;;ocaml ; an objective camel
|
||||
(org ; organize your plain life in plain text
|
||||
+attach ; custom attachment system
|
||||
+babel ; running code in org
|
||||
+capture ; org-capture in and outside of Emacs
|
||||
+export ; Exporting org to whatever you want
|
||||
+habit ; Keep track of your habits
|
||||
+present ; Emacs for presentations
|
||||
+protocol) ; Support for org-protocol:// links
|
||||
+dragndrop ; file drag & drop support
|
||||
+ipython ; ipython support for babel
|
||||
+pandoc ; pandoc integration into org's exporter
|
||||
+present) ; using Emacs for presentations
|
||||
;;perl ; write code no one else can comprehend
|
||||
;;php ; perl's insecure younger brother
|
||||
;;plantuml ; diagrams for confusing people more
|
||||
|
|
|
@ -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))
|
|
@ -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")))
|
|
@ -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))
|
|
@ -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)
|
|
@ -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)
|
|
@ -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
|
|
@ -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.
|
||||
|
||||
+ A custom attachment system that keeps files in a centralized location.
|
||||
+ Drag-and-drop support for images (with inline preview) and media files (drops
|
||||
a file icon and a short link).
|
||||
+ Executable code blocks with support for a variety of languages and tools,
|
||||
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]]
|
||||
* Table of Contents :TOC_3:noexport:
|
||||
- [[#description][Description]]
|
||||
- [[#module-flags][Module Flags]]
|
||||
- [[#plugins][Plugins]]
|
||||
- [[#hacks][Hacks]]
|
||||
- [[#prerequisites][Prerequisites]]
|
||||
- [[#macos][MacOS]]
|
||||
- [[#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]]
|
||||
- [[#usage][Usage]]
|
||||
- [[#appendix][Appendix]]
|
||||
- [[#changing-org-directory][Changing ~org-directory~]]
|
||||
|
||||
* Install
|
||||
Org has no hard dependencies, but there are some things you'll need to make use of Org's more esoteric features.
|
||||
* 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=).
|
||||
+ 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~.
|
||||
+ To run babel code blocks, you need whatever dependencies those languages
|
||||
need. It is recommended you enable the associated module in =lang/= and ensure
|
||||
its dependencies are met.
|
||||
+ The =+crm= module uses a sqlite database to manage your contacts, invoices,
|
||||
and projects; this needs sqlite installed.
|
||||
+ For rendering GNUPlot images (with =+gnuplot= flag) you need the ~gnuplot~
|
||||
program installed.
|
||||
+ To run babel code blocks, you need whatever dependencies those languages need.
|
||||
It is recommended you enable the associated =:lang= module and ensure its
|
||||
dependencies are met, e.g. install the =ruby= executable for ruby support.
|
||||
|
||||
** MacOS
|
||||
#+BEGIN_SRC sh
|
||||
brew cask install mactex
|
||||
brew install sqlite
|
||||
brew install gnuplot
|
||||
#+END_SRC
|
||||
|
||||
** Arch Linux
|
||||
#+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
|
||||
|
||||
** 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
|
||||
(Coming soon)
|
||||
** Changing ~org-directory~
|
||||
To modify ~org-directory~ it must be set /before/ =org= has loaded:
|
||||
|
||||
* Usage
|
||||
(Coming soon)
|
||||
|
||||
* Appendix
|
||||
(Coming soon)
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
;; ~/.doom.d/config.el
|
||||
(setq org-directory "~/new/org/location/")
|
||||
#+END_SRC
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
;;; lang/org/autoload/org-attach.el -*- lexical-binding: t; -*-
|
||||
;;;###if (featurep! +attach)
|
||||
|
||||
(defun +org-attach--icon (path)
|
||||
(char-to-string
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
;;; lang/org/autoload/org-capture.el -*- lexical-binding: t; -*-
|
||||
;;;###if (featurep! +capture)
|
||||
|
||||
(defvar org-capture-initial)
|
||||
|
||||
|
@ -29,12 +28,12 @@
|
|||
(frame-parameter nil 'transient)))
|
||||
|
||||
;;;###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
|
||||
you're done. This can be called from an external shell script."
|
||||
(interactive)
|
||||
(when (and string (string-empty-p string))
|
||||
(setq string nil))
|
||||
(when (and initial-input (string-empty-p initial-input))
|
||||
(setq initial-input nil))
|
||||
(when (and key (string-empty-p key))
|
||||
(setq key nil))
|
||||
(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)
|
||||
(symbol-function #'switch-to-buffer)))
|
||||
(switch-to-buffer (doom-fallback-buffer))
|
||||
(let ((org-capture-initial string)
|
||||
(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)))
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
;;; lang/org/autoload/org-export.el -*- lexical-binding: t; -*-
|
||||
;;;###if (featurep! +export)
|
||||
|
||||
(defun +org--yank-html-buffer (buffer)
|
||||
(with-current-buffer buffer
|
||||
|
|
|
@ -149,15 +149,13 @@ If on a:
|
|||
|
||||
(_ (+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.
|
||||
DIRECTION can be 'above or 'below.
|
||||
|
||||
I use this instead of `org-insert-item' or `org-insert-heading' which are too
|
||||
opinionated and perform this simple task incorrectly (e.g. whitespace in the
|
||||
wrong places)."
|
||||
(interactive)
|
||||
(let* ((context
|
||||
(save-excursion
|
||||
(when (bolp)
|
||||
|
@ -237,6 +235,18 @@ wrong places)."
|
|||
(when (bound-and-true-p evil-local-mode)
|
||||
(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
|
||||
(defun +org/dedent ()
|
||||
"TODO"
|
||||
|
|
File diff suppressed because it is too large
Load diff
39
modules/lang/org/contrib/dragndrop.el
Normal file
39
modules/lang/org/contrib/dragndrop.el
Normal 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))
|
38
modules/lang/org/contrib/ipython.el
Normal file
38
modules/lang/org/contrib/ipython.el
Normal 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")))
|
|
@ -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
|
||||
"The `text-scale-amount' for `org-tree-slide-mode'.")
|
||||
|
||||
(after! ox
|
||||
(add-to-list 'org-export-backends 'beamer))
|
||||
|
||||
|
||||
;;
|
||||
;; Packages
|
||||
;;; Packages
|
||||
|
||||
(def-package! ox-reveal
|
||||
:after ox
|
|
@ -1,60 +1,54 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; 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
|
||||
;; `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)
|
||||
load-path)))
|
||||
;; Ignore org on ELPA, if possible
|
||||
(package! org :ignore t)
|
||||
(package! org-plus-contrib) ; install cutting-edge version of org-mode
|
||||
(package! org :ignore t) ; ignore org on ELPA, if possible
|
||||
|
||||
(package! org-bullets :recipe (:fetcher github :repo "Kaligule/org-bullets"))
|
||||
(package! org-yt :recipe (:fetcher github :repo "TobiasZawada/org-yt"))
|
||||
(package! toc-org)
|
||||
|
||||
(when (featurep! :editor evil)
|
||||
(package! evil-org))
|
||||
|
||||
(when (featurep! :tools pdf)
|
||||
(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))
|
||||
|
||||
(when (featurep! +babel)
|
||||
(package! ob-async)
|
||||
(package! ob-mongo)
|
||||
(package! ob-sql-mode)
|
||||
(package! ob-translate)
|
||||
(when (featurep! +gnuplot)
|
||||
(package! gnuplot)
|
||||
(package! gnuplot-mode))
|
||||
|
||||
(when (featurep! +ipython)
|
||||
(package! ob-ipython))
|
||||
(when (featurep! +ipython)
|
||||
(package! ob-ipython))
|
||||
|
||||
(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)))
|
||||
|
||||
(when (featurep! +export)
|
||||
(package! ox-clip)
|
||||
(package! ox-pandoc)
|
||||
(package! htmlize))
|
||||
(when (featurep! +pandoc)
|
||||
(package! ox-pandoc))
|
||||
|
||||
(when (featurep! +present)
|
||||
(package! centered-window :recipe (:fetcher github :repo "anler/centered-window-mode"))
|
||||
(package! org-tree-slide)
|
||||
(package! ox-reveal))
|
||||
|
||||
;; (when (featurep! +publish))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue