Speedrun guide to Org Mode
Table of Contents
Commentary
This started as a set of notes on Literate Devops with Emacs. I never thought this was to be published, but it was revised on , so that I can send it to a friend of mine.
Feel free to look at the source code of this file, since the whole post was written in Org Mode.
Introduction
Org Mode is a wonderful plain text markup format. It is like markdown on steroids, yet much more intuitive and readable.
* Header Headers start with *, this is a *bold* word, this is /italics/ You can have custom blocks with #+begin_src, language echo "I am no salesman, but well, you can also *execute* scripts inline with C-c C-c" #+end_src while inline code looks like this ~echo Hello World~ You can have references [[cref:...]], footnotes [[fn:1]] (C-c C-x f)... #+NAME: This is a table | column 1 | column 2 | |------------+-------------| | Elementary | Dear Watson | | | | #+CAPTION: Image caption #+attr_latex: :width 0.65\linewidth #+attr_html: :alt It usually works out best [[file:/the/path/to/a.img]] Links can be efficiently inserted with C-c C-l and look like this: [[http://chatziiola.github.io][Link]]
The thing is that OrgMode works best from within Emacs. Extensions exist for Nvim and other editors, but nothing even comes close.
Org mode features
This is found somewhere in the documentation of OrgMode (but it could
have been CDLatex for `
) - in any case it stands true:
When in doubt use C-c
- (it is the default prefix for OrgMode shortcuts)
Writing code
- You can write code easily within source blocks. You can write
#+begin_src <lang>
, followed by#+end_src
, but the simpler solution here is to useC-c C-,
. A menu then spawns showing you the different environments you can use: - You can edit the source block more efficiently, taking advantage of
your programming configuration by using
C-c '
while inside it. - After you have finished writing everything, execute it with
C-c C-c
- The RESULTS will be shown in buffer
brew search pyenv
#+RESULTS: | pyenv | | pyenv-ccache | | pyenv-pip-migrate | | pyenv-virtualenv | | pyenv-virtualenvwrapper | | pyenv-which-ext | | plenv | | pipenv |
Customizing the source blocks
By adding options to the first line of the source block one can modify its behavior. An example of that is the following, making sure that when exporting this file (see the exporting section for more), only the code block (not the results) will be exported:
#+begin_src python3 :exports code print("Nice ;)") #+end_src
You can also set the directory where the code block will be executed1, or set variables:
#+begin_src sh :dir ~ pwd #+end_src #+RESULTS: : /Users/sickvm
#+begin_src sh :var hellostring="Hello World" echo $hellostring #+end_src #+RESULTS: Hello World
Exporting
OrgMode files can instantly be exported to \LaTeX, HTML, ODT(?), even
Markdown2. Just run C-c C-e
to see more.
If you are interested in what an Org to HTML workflow looks like, this is an excellent article to have a look at… What a writer :P
Tangling
This is one of the best features of org mode, and in fact this is what
leads us to the next section of this article. One can use tangling so
that independent begin_src
blocks are then (through org-babel-tangle
)
combined to produce independent files. The next section, if tangled,
creates a minimal emacs configuration for writing in OrgMode.
#+begin_src sh :tangle <filename>
You can even set it for a whole file
#+TITLE: My file #+PROPERTY: :tangle ~/filename" * Header :PROPERTIES: :header-args:elisp: :tangle "~/filename" :END:
Sample-Configuration config
Package Management
Straight configuration
Using straight.el for package management
This snippet is necessary to load bootstrap.el
and get straight up and running.
(defvar bootstrap-version) (let ((bootstrap-file (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory)) (bootstrap-version 6)) (unless (file-exists-p bootstrap-file) (with-current-buffer (url-retrieve-synchronously "https://raw.githubusercontent.com/radian-software/straight.el/develop/install.el" 'silent 'inhibit-cookies) (goto-char (point-max)) (eval-print-last-sexp))) (load bootstrap-file nil 'nomessage))
This needs to be here to avoid mismatch org version
(straight-use-package 'org)
(setq straight-vc-git-default-clone-depth 1) (setq straight-recipes-gnu-elpa-use-mirror t)
Use use-package
forms when installing packages. This allows for the numerous
pieces of code to be self-dependent.
(straight-use-package 'use-package)
(setq straight-use-package-by-default t)
Auto Package Update
(use-package auto-package-update :custom (auto-package-update-interval 7) (auto-package-update-prompt-before-update t) (auto-package-update-hide-results t) :config (auto-package-update-maybe) (auto-package-update-at-time "09:00"))
Evil Mode and some useful packages
If you are a Vim user, then evil mode
is ideal, I can not help but
suggest it:
(use-package evil :demand :init (setq evil-want-keybinding nil) (setq evil-want-C-u-scroll t) (setq evil-want-integration t) (setq evil-want-keybinding nil) (setq evil-split-window-below t) (setq evil-vsplit-window-right t) (setq evil-want-C-u-scroll t) (setq evil-want-C-i-jump t) (setq evil-want-Y-yank-to-eol t) :config (evil-mode 1) ;; No really need to set leader keys like that (evil-set-leader 'normal (kbd "<SPC>")) (evil-set-leader 'insert (kbd "M-<SPC>")) ;; Use visual line motions even outside of visual-line-mode buffers (evil-global-set-key 'motion "j" 'evil-next-visual-line) (evil-global-set-key 'motion "k" 'evil-previous-visual-line) )
Evil Collection
Evil collection is a collection of multiple useful keybindings. Just like it is
shown in the following snippet, I have decided against using the default
evil-collection-mode-list
, mainly to avoid unwanted behavior in certain modes. I
have decided to keep evil collection only on certain modes (the ones described).
(use-package evil-collection :after evil :config (let ((evil-collection-mode-list '(org help man info helpful imenu imenu-list corfu popup (magit magit-repos magit-submodule magit-section magit-todos) org-roam git dired flycheck (pdf pdfview) doc-view eldoc python hackernews (term term mult-term) (which-key)))) (evil-collection-init)) )
This is for commenting out text as in vim
(use-package evil-commentary :ensure t :config (global-unset-key (kbd "C-x C-;")) ;; ;Do not use the default (evil-commentary-mode)) ;; Enables gc by default
Keyboard
The mode displays the key bindings following your currently entered incomplete command in a popup.
(use-package which-key :config (which-key-mode))
Clipboard
Allows system and Emacs clipboard to communicate smoothly (both ways)
(setq-default select-enable-clipboard t) ; Merge system's and Emacs' clipboard
Org Mode
Automatically tangle org-mode files with the option #+auto_tangle: t
; Tangle org file when it is saved (use-package org-auto-tangle :hook (org-mode . org-auto-tangle-mode))
This is mind-breaking, allowing you to quickly insert images, handling the file creation part. I use this with snippets, but it still is extremely powerful.
(use-package org-download :config (setq org-download-heading-lvl nil) ;; don't use headings when creating image names (setq org-download-timestamp "%Y%m%d_%H%M%S_") (setq org-download-screenshot-method "/user/local/bin/pngpaste %s") ;; Set the directory for storing images using :hook :hook (org-mode . (lambda () (setq-local org-download-image-dir "./images/"))))
And for references - bibliography management:
(use-package org-ref :config (setq org-ref-notes-directory "~/org") (setq org-ref-bibliography-notes (expand-file-name "notes.org" org-ref-notes-directory)) (setq org-ref-default-bibliography '("/path/to/your.bib")) (setq bibtex-completion-bibliography org-ref-default-bibliography) (setq bibtex-completion-notes-path org-ref-notes-directory) (setq bibtex-autokey-name-case-convert-function 'capitalize) (setq bibtex-autokey-name-year-separator "") (setq bibtex-autokey-titleword-length 5) (setq bibtex-autokey-titleword-separator "") (setq bibtex-autokey-titlewords 2) (setq bibtex-autokey-titlewords-stretch 1) (setq bibtex-autokey-year-length 4) (setq bibtex-autokey-year-title-separator "") (setq bibtex-completion-pdf-field "file") (setq org-ref-default-ref-type "cref") (setq bibtex-completion-pdf-open-function (lambda (fpath) (start-process "open-pdf" "*open-pdf*" "open" fpath))) (define-key bibtex-mode-map (kbd "H-b") 'org-ref-bibtex-hydra/body) (define-key org-mode-map (kbd "M-[") 'org-ref-insert-link-hydra/body))
Documents need to end with:
**** References <<bibliographystyle link>> bibliographystyle:ieeetr <<bibliography link>> bibliography:~/static/miref/master.bib
Further suggestions
- Snippets (
Yasnippets
): Cause we all want to write less and get more done Vertico
: Revolutionizes the way you move aroundMagit
: Git IntegrationCDLaTeX
: Efficiently writing LaTeX in OrgOrg-Roam
: An org-based obsidian-like solutionDeft
: If you are more into having lots of notes within one directory - like usingnvim
withripgrep
.- Colorschemes / Aesthetically configuring your emacs instance: Now
this is purely subjective, but I use
nano
, withnano-modeline
, but there is no shortage of configurations online. Find one that works for you.
I will try to publish my full emacs configuration some day in this blog. Have a look at tags/emacs: Maybe I finally got to it.