16

An Annotated Spacemacs - For an org-mode workflow ·

 4 years ago
source link: https://out-of-cheese-error.netlify.com/spacemacs-config
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

An Annotated Spacemacs

For an org-mode workflow

I started using org-mode on SpacemacsI use this Emacs Mac-port version of Emacs since the normal one had issues like screen flickering and crashing on quitting a frame. EDIT Jan 30 2020: Using the latest and greatest homebrew-emacs-head now - finally doom-wilmersdorf works out the box something like two years ago to track projects for my PhD. Still using it now but it felt like a good time to standardize some stuff and remove redundant or unnecessary cruft, based on what I’ve actually used till now. First off, I’m not really an emacs user, and I don’t know a lot of lisp (except for our tiny scheme experiments from way back). I’ve gotten pretty used to vim keyboard shortcuts for text editing and even use the IdeaVim plugin in PyCharm. But vim doesn’t have something like org-mode (vim-wiki was nice and all but this is an entirely different beast) and a knowledge-base + project tracker comes in extremely handy for a PhD. So Spacemacs, with the motto

The best editor is neither Emacs nor Vim, it’s Emacs and Vim!”

fit the bill perfectly. Org-mode is seriously vast though, and can be almost infinitely extended with additional packages. Even cursory searches lead to all kinds of guides and configs of people who seem to be fiercely productive and really get things done. But I like building up from scratch, so I have time to get used to actually using bits and pieces of functionality before adding more, so my settings are going to start out a bit more minimal.

Since org-mode is amazing, it has this thing called org-babel which lets you write source code in any language in between text. You can run these code blocks, store, and manipulate the outputs too - kind of like a multi-lingual Jupyter notebook. That’s not all though, with org-babel-tangle you can extract all the source code into a separate file (since an org-mode file is seen to weave together text and code, the code can then be (un?)-tangled out).

This means that this post, written in org-mode, is actually my entire .spacemacs configuration file with plenty of annotations, descriptions, and examples of how I use each functionality. Every time I want to add something new or get rid of something I don’t use, I can make the change here in this post, with some notes on why and how, and then extract the code out into my new .spacemacs.

Added this to the beginning of the file and then called org-babel-tangle (ALT-x org-babel-tangle).

#+PROPERTY: header-args :tangle ".spacemacs"

Also, pelican doesn’t seem to like #BEGIN_EXAMPLE blocks - used #BEGIN_SRC blocks (with “:tangle no”) and ‘,’s inside them instead (like so).

So here it is, a living, breathing, changing Spacemacs configuration. It has everything I’ve been using for the past two years and I’ll keep it up to date with my future work flow as I figure it out. Also, before diving into the code, here’s what my typical Spacemacs window looks like:

org_mode.png

Figure 1: While editing this post

Edits

dotspacemacs / layers

To make things easier on the user, Spacemacs works with the concept of layers. Here’s a full list of them. Some emacs and org packages haven’t been neatly encapsulated into a layer yet but as long as it’s a MELPA package you can use them with pretty much the same amount of ease. The .spacemacs file starts out with defun dotspacemacs/layers which is where both these kinds of things go. I haven’t yet come across a must-have functionality that doesn’t fall into one of these two categories, maybe later.

;; -*- mode: emacs-lisp -*-
;; This file is loaded by Spacemacs at startup.
;; It must be stored in your home directory.
(defun dotspacemacs/layers ()
  "Configuration Layers declaration.
You should not put any user code in this function besides modifying the variable
values."
  (setq-default
   ;; Base distribution to use. This is a layer contained in the directory
   ;; `+distribution'. For now available distributions are `spacemacs-base'
   ;; or `spacemacs'. (default 'spacemacs)
   dotspacemacs-distribution 'spacemacs
   ;; Lazy installation of layers (i.e. layers  are installed only when a file
   ;; with a supported type is opened). Possible values are `all', `unused'
   ;; and `nil'. `unused' will lazy install only unused layers (i.e. layers
   ;; not listed in variable `dotspacemacs-configuration-layers'), `all' will
   ;; lazy install any layer that s  (set-face-attribute 'variable-pitch nil :family "ETBembo" :size 15) upport lazy installation even the layers
   ;; listed in `dotspacemacs-configuration-layers'. `nil' disable the lazy
   ;; installation feature and you have to explicitly list a layer in the
   ;; variable `dotspacemacs-configuration-layers' to install it.
   ;; (default 'unused)
   dotspacemacs-enable-lazy-installation 'unused
   ;; If non-nil then Spacemacs will ask for confirmation before installing
   ;; a layer lazily. (default t)
   dotspacemacs-ask-for-lazy-installation t
   ;; If non-nil layers with lazy install support are lazy installed.
   ;; List of additional paths where to look for configuration layers.
   ;; Paths must have a trailing slash (i.e. `~/.mycontribs/')
   dotspacemacs-configuration-layer-path '()
   ;; List of configuration layers to load.
   dotspacemacs-configuration-layers
   '(
     ;; ----------------------------------------------------------------
     ;; Example of useful layers you may want to use right away.
     ;; Uncomment some layer names and press <SPC f e R> (Vim style) or
     ;; <M-m f e R> (Emacs style) to install them.
     ;; ----------------------------------------------------------------
     ;;
     ;; org-mode
     org
     ;; Typing-related
     auto-completion
     (spell-checking :variables spell-checking-enable-by-default nil)
     syntax-checking
     ;; Search-related
     ivy
     deft
     ;; Language support
     python
     html
     rust
     emacs-lisp
     latex
     markdown
     yaml
     ;; For papers and PDFs
     bibtex
     pdf-tools
     ;; Other
     osx
     git
     )
 ;; List of additional packages that will be installed without being
 ;; wrapped in a layer. If you need some configuration for these
 ;; packages, then consider creating a layer. You can also put the
 ;; configuration in `dotspacemacs/user-config'.
   dotspacemacs-additional-packages
   '( 
     ;; Aesthetics
     doom-themes
     org-bullets
     olivetti
     ;; For org-drill
     org-plus-contrib
     ;; For defining nice org-capture templates
     org-starter
     dash
     dash-functional
     org-reverse-datetree
     ;; For annotating PDFs
     org-noter
     ;; For making a kanban from TODO entries
     org-kanban
     )
 ;; A list of packages that cannot be updated.
 dotspacemacs-frozen-packages '()
 ;; A list of packages that will not be installed and loaded.
 dotspacemacs-excluded-packages '(vi-tilde-fringe org-projectile doom-wilmersdorf-theme)
 ;; Defines the behaviour of Spacemacs when installing packages.
 ;; Possible values are `used-only', `used-but-keep-unused' and `all'.
 ;; `used-only' installs only explicitly used packages and uninstall any
 ;; unused packages as well as their unused dependencies.
 ;; `used-but-keep-unused' installs only the used packages but won't uninstall
 ;; them if they become unused. `all' installs *all* packages supported by
 ;; Spacemacs and never uninstall them. (default is `used-only')
 dotspacemacs-install-packages 'used-only))

The Org Layer

This is the layer that gives you org-mode functionality. There’ll be a lot more on this in other parts of the config. The Spacemacs org layer page has a crazy amount of keyboard shortcuts but here are the ones that I actually use. (For commands not starting with ALT, SHIFT, or CTRL, you have to press ESC first)

Tasks, scheduling, and agenda

  • Current week agenda - SPC m a * a

    The buffer window that you run this in shows everything you have scheduled for the week (top right in the picture above). The asterisk makes it a “sticky” agenda view, meaning you can call a different agenda command (such as the one below) in another window and still see this one.

  • List of tasks - SPC m a t

    The buffer window you run this in shows a list of tasks identified by keywords like “TODO” (bottom right in the picture above). I’ve added a couple of my own keywords to this list.

  • Refresh agenda - r

    You can run this inside an agenda buffer to make it reflect any changes you’ve made to your file(s).

  • Make a heading into a task - t

    Running this on a heading gives you a choice of TODO keywords that you can assign to it.

  • Tick a checkbox - CTRL-c CTRL-c
  • Schedule something - SPC m s
  • Give something a deadline - SPC m d

Adding text and moving it around

  • Add a heading - SPC m h i
  • Add a sub-heading - SPC m h s
  • Add a link - CTRL-c CTRL-l
  • Add a new list item - RET
  • Add tags to a heading - SPC m :
  • Re-organize headings / items - ALT--UP, ALT-DOWN
  • Demote a heading - ALT-SHIFT-RIGHT
  • Fold a heading’s subtree - TAB
  • Archive a subtree when you’re done with it - SPC m A

    This saves the heading and everything under it into “<filename>.orgarchive“.

  • Cut a subtree - CTRL-c CTRL-x CTRL-w
  • Paste a cut subtree - CTRL-c CTRL-x CTRL-y

Other [4/5]

  • DONE Showing entries related to a tag CTRL-c / m <tag name>
  • DONE Displaying statistics - CTRL-c #

    You can run this on a heading with [/] (or [%]) next to it to see how many (or what percentage of) that heading’s checkboxes you’ve ticked or TODOs you’ve DONE’d. This line’s parent heading demonstrates this.

  • DONE Edit source code (in a dedicated buffer) - CTRL-c '
  • DONE org-capture - SPC m c

    A lot more on this one here.

  • TODO Export - CTRL-c CTRL-e

Layers for typing

I use the auto-completion, spell-checking, and syntax-checking layers to make typing text and code more efficient. I’ve set spell-checking off by default though since I only need it for typing long-form articles like this one and you can enable it easily on a file by calling ALT-x-flyspell-mode.

Search-related

Ivy is supposed to be faster than Helm for searching within files, I haven’t really noticed or compared though. Deft is a neat package that lets you define a folder and gives you fast search within the files in that folder. You call it using SPC a n to get a window with a list of files that you can search through. You can just type in the search bar to make a new file. I’ve also used it for renaming ( SPC m r ) and deleting files ( SPC m d ). Refresh with CTRL-c CTRL-g.

Aesthetics

I occasionally try out different doom themes (with SPC T s) - I’m partial to the doom-wilmersdorf and doom-spacegrey themes. org-bullets is to make the heading bullet points look better than asterisks, and Olivetti mode (ALT-x olivetti mode) centers the part of the buffer with the text, which looks nicer when you have a lot of text on the screen.

Org-plus-contrib

This has a lot of packages but I just have it so I can use org-drill for learning Turkish. More on that in the next post.

Org-reverse-datetree

I use this one in some of my org-capture templates which need stored in reverse date order. The Dailies page of this blog is an example, you get the latest notes first.

Org-kanban

Having a giant list of TODOs was pretty daunting and I found myself procrastinating a lot. A kanban board is meant to alleviate this by giving you a visual idea of how much you’ve taken on your plate and how much you can actually work on at a given moment. The org-kanban package accomplishes this in org-mode by pulling in active TODOs from a file into a table, divided into the different TODO states. I have this linked to the Task capture template.

The keyboard shortcuts related to this are quite simple:

  • Initialize the kanban - ALT-x org-kanban/initialize-at-beginning
  • Refresh after adding a new TODO - CTRL-c CTRL-c on the kanban block
  • Shift from TODO -> RUNNING, RUNNING -> DONE - ALT-x org-kanban/shift a
  • Shift from DONE -> RUNNING, RUNNING -> TODO - ALT-x org-kanban/shift d

Handling papers and PDFs

The bibtex layer lets you cite papers from a bibliography, and the org-noter + pdf-tools combo lets you view and annotate (even huge) PDFs in emacs buffers. I think this topic deserves its own post so I’ll keep it short here and add a link later.

dotspacemacs / init

Spacemacs is crazy customizable. I didn’t really change many of the defaults, except making the default font Jetbrains Mono and make ripgrep the default search tool. You can probably skip this section.

By the by, since this section was so long and mostly pointless to readers I dug around to find ways to make it fold and expand with a click, as it is now. Used this reddit answer to do it. Here’s how:

#+BEGIN_EXPORT html
  <details>
  <summary>Click to expand</summary>
#+BEGIN_SRC emacs-lisp
  ;; your code goes here
#+END_SRC
#+BEGIN_EXPORT html
  </details>
#+END_EXPORT

Click to expand

dotspacemacs / user-init

Nothing to see here, move along.

Click to expand

dotspacemacs / user-config

This is where the meat of the customizations reside so I’ll go through it bit by bit. The remaining code blocks all belong to the same functionI used org-babel-demarcate-block (CTRL-c CTRL-v d) to quickly split up the source code block of this function into smaller blocks. .

(defun dotspacemacs/user-config ()
  "Configuration function for user code.
    This function is called at the very end of Spacemacs initialization after
    layers configuration.
    This is the place where most of your configurations should be done. Unless it is
    explicitly specified that a variable should be set before a package is loaded,
    you should place your code here."
    (require 'org-drill)
    (setq org-drill-scope (quote directory))
    (setq org-link-frame-setup (quote (file . find-file)))
    (setq org-link-frame-setup
     (quote
      ((file . find-file)
       (vm . vm-visit-folder-other-frame)
       (vm-imap . vm-visit-imap-folder-other-frame)
       (gnus . org-gnus-no-new-news)
       (wl . wl-other-frame))))
  • The first two lines are for my org-drill setup, I’ll post about it next.
  • The org-link-frame-setup lines (I only changed the file, the rest are the default) make it so that if I click on a file link it opens the file in the current buffer window, instead of another one - this ensures that nothing messes with my agenda views.

Org Agenda and Todo

(setq org-agenda-window-setup (quote current-window))
;; To add all org files in a repository to the agenda
(setq org-agenda-files (directory-files-recursively "~/Dropbox/organizer/" "\.org$"))
;; Set task-related keywords
(setq org-todo-keywords
      '((sequence "IDEA(i)" "TODO(t)" "RUNNING(r)" "|" "DONE(d)" "CANCELLED(c)" "DEFERRED(f)")
	(sequence "MEETING(m)" "|" "MET(M)")))
;; Ignore scheduled tasks and tasks with a deadline in task list view (SPC m a t)
(setq org-agenda-todo-ignore-with-date t)
;; Skip finished items
(setq org-agenda-skip-deadline-if-done t)
(setq org-agenda-skip-scheduled-if-done t)
(setq org-agenda-skip-timestamp-if-done t)
;; Skip deleted files
(setq org-agenda-skip-unavailable-files t)
  • The org-agenda-files line makes agenda check recursively in my Dropbox organizer folder for org files. This comes in handy since I tend to group files into folders when it makes sense - e.g. a folder for conferences with one file of notes per conference etc. The window-setup makes it so that when I call an agenda command in a buffer then it opens in that buffer instead of any old one it finds lying around (I feel like this should be the default somehow).
  • org-todo-keywords defines extra TODO-like keywords. The | between the two sets of words is the difference between TODO and DONE. So MET is the closed state of MEETING. Each keyword has a letter in brackets next to it that I can use to quickly add it to a heading / change an existing one (by calling t on the heading). Other people seem to have a lot more keywords here but I mostly find myself using these.
  • Then I make it so that the org-agenda-todo view (SPC m a t) doesn’t show TODO items which have a scheduled date attached to them. This fits my typical setup (in the Figure at the top) with two vertically stacked windows, one with the week agenda and one that lists unscheduled TODOs, since this way the same item isn’t repeated in both views. I mostly use unscheduled TODOs for ideas (with the IDEA keyword) and more generic/vague statements that don’t really have a deadline (like “Think about projects related to X” or “Look into topic X”). I also use it for meetings/appointments which I still have to set up (with the MEETING keyword).
  • The org-agenda-skip lines make the agenda stop showing DONE’d TODO items.
;; Deft-related
(setq deft-directory "~/Dropbox/organizer")
(setq deft-extensions '("org"))
(setq deft-recursive t)

These should be self-explanatory - sets the folder for Deft to index and makes it look recursively for org files.

Org-capture templates

This is my favorite part - capture templates!

;; Org-Capture templates
(setq org-capture-templates
	  (quote (

These are basically endlessly code-able templates that let you add specific content of any kind anywhere with a couple of keypresses. I shall demonstrate.

Blog-related

  • Making a draft blog post
    ("b" "Blog-related templates")
      ("bn" "Blog Entry" plain
       (file
        (lambda nil
          (interactive)
          (let ((name (read-string "Filename: ")))
    	(expand-file-name (format "%s.org" name)
    			  "~/Dropbox/organizer/pelican_blog/drafts"))))
       "#+TITLE: %^{title}
      #+DATE: %t
      #+CATEGORY: %^{category}
      #+AUTHOR: Hex
      #+PROPERTY: LANGUAGE en
      #+PROPERTY: SUMMARY %^{summary}
      #+PROPERTY: SUBTITLE %^{subtitle}
      #+PROPERTY: TAGS %^{comma-separated tags}
      #+OPTIONS: num:nil
      #+OPTIONS: toc:nil
      %?
      " :jump-to-captured t)
    

    Suppose one of us comes up with an idea for a blog post. Wherever I am in Spacemacs, I can type SPC m c bn and type in the title of the post, then it asks me for the category, summary, subtitle, and any tags we may have in mind (each of these can be skipped and filled in later of course). I press Enter and have a fully set up skeleton file inside the drafts folder, and now we can concentrate on writing the content. The whole lambda part makes an anonymous function (just like a Python lambda function) that asks the user for a slug/filename instead of using a fixed one. You can ask the user for text with a prompt using %^{prompt} and get today’s date using %t. %? gives you the option to type in content in the capture buffer itself (you exit the capture buffer and save it to the file using CTRL-c CTRL-c). And :jump-to-captured t makes it open the new file.

  • Saving a link
    ("bu" "URL" entry
     (file+function "~/Dropbox/organizer/pelican_blog/content/pages/dailies.org"
    		org-reverse-datetree-goto-date-in-file)
     "* [[%^{URL}][%^{Description}]] %^g %?")
    

    This is what we use to make the Dailies page. Any time I come across a website that’s interesting I hit SPC m c bu in a Spacemacs buffer and file it away along with a description and some tags (with %^g). We still haven’t figured out a nice way to show the tags on Pelican though. This is also where the org-reverse-datetree package comes in handy. The file+function part says to put this captured note in dailies.org under today’s date. If the heading doesn’t exist it makes it (starting from a top-level heading for the year, second-level for month and third-level for the day) and then puts your note as a subheading under it. You can do the same thing with the built-in datetree (using file+datetree instead) but then the top of the file would be your oldest note and the bottom would be the latest which is a bit inconvenient, especially for a blog page. The org-reverse-datetree package also lets you specify the format of your dates. So this is what I have on top of the dailies.org file:

    #+TITLE: Dailies
    #+AUTHOR: Hex
    #+DATE: 2020-01-05
    #+PROPERTY: LANGUAGE en
    #+OPTIONS: toc:nil
    #+OPTIONS: tags:nil
    #+OPTIONS: num:nil
    #+PROPERTY: SUBTITLE Some links and resources found during breaks at work
    #+PROPERTY: META_ROBOTS noindex
    #+REVERSE_DATETREE_USE_WEEK_TREE: nil
    #+REVERSE_DATETREE_DATE_FORMAT: %d %A
    #+REVERSE_DATETREE_MONTH_FORMAT: %B
    #+REVERSE_DATETREE_YEAR_FORMAT: %Y
    
    • USE_WEEK_TREE - Setting this to true would make it store weeks instead of months and days
    • DATE_FORMAT - “%d” = day of the month, “%A” = day of the week
    • MONTH_FORMAT - “%B” = January, February, etc.
    • YEAR_FORMAT - “%Y” = 2020
  • Margin notes, side notes and collapsed notes

    The notes you see on the right (or if you click on the arrows from a phone) are side notes (and very rarely margin notes»Look, a margin note ) ala Edward Tufte and some CSS taken from Tufte-CSS. Using capture templates make it infinitely easy to add them into a blog post. There’s also a template for making collapsed notes that you can then click on to expand, such as the the code for these templates below. Notice that the file argument is empty - that’s because we want these templates to be inserted into the file from which we called org-capture at the location we called it from. To do this we call capture with CTRL-0 SPC m c instead of just SPC m c.

    Click to expand

Notes and Tasks

("n" "Notes" entry
 (file+function "~/Dropbox/organizer/phd.org" org-reverse-datetree-goto-date-in-file)
 "* %^{Description} %^g
  Added: %t
  %?

 ")

("t" "Task" entry
 (file+function "~/Dropbox/organizer/phd.org" org-reverse-datetree-goto-date-in-file)
 "* TODO %^{Description} %^gkanban:
  Added: %t
  %?

 ")

SPC m c n and SPC m c t add a note and a TODO respectively, to a reverse-datetree entry in my phd.org file, with a description, some tags, and a line that says the date it was added. I use tags to sort through different projects, with CTRL-c / m <tag name> - this folds everything and highlights only headings matching the tag. The phd.org file also has an org-kanban entry at the beginning, initialized via ALT-x-org-kanban/initialize-at-beginning, and configured with kanban :mirrored t :match "kanban" :range ("TODO" . "DONE"). This ensures I don’t go overboard with my scheduling and can easily shift between TODO, RUNNING and DONE. You’ll notice that “kanban” is automatically added as a tag to a task and only this tag is considered in the board, so at the end of the day I can get rid of this tag for the finished tasks and they won’t show up anymore in my board. »Needed an extra newline at the end of the templates otherwise Spacemacs started messing up the formatting everywhere.

Schedule meetings

("m" "Meeting" entry
 (file+headline "~/Dropbox/organizer/phd.org" "Meetings/People-related")
 "** MEETING %^{Description} %^g
  SCHEDULED: %^{Date}T
  %?

")

SPC m c m adds a new MEETING heading under the “Meetings/People-related” heading in the phd.org file (you specify this with “file+headline”). It asks for a description, tags, and a date (with %^{Date}T) that you can just click on in a tiny calendar popup.

Log activities

("l" "Log Time" entry
 (file+function "~/Dropbox/organizer/daily_notes.org" org-reverse-datetree-goto-date-in-file)
 "** %U - %^{Activity}  %^g"
 :immediate-finish t)
)))

A lot of org-enthusiasts use something called Clocking where you clock in / punch in when you start working on something and then clock out when you’re done. This can come in handy if you have to bill people based on how much time you spent on their project, or if you just want to see how you spend your time. I couldn’t really get into it though - too lazy I guess. So this is kind of my compromise - SPC m c l logs a single-sentence activity with tags and time to a daily notes file. I can see what days I worked on which projects with tag search, and keep track of small steps without worrying too much about forgetting to clock in/out. the “:immediate-finish t” means I just click Enter after typing in my Activity and entering tags, and it saves it to the file without any fuss.

Aesthetics

Olivetti mode

;; Text takes up 85% of the buffer
(setq olivetti-body-width 0.85)
;; Starts text files (like .org .txt .md) in olivetti mode
(add-hook 'text-mode-hook 'olivetti-mode)

Olivetti puts all the buffer text in the middle, so that there’s some breathing space around the edges, like a book. body-width makes the text take up 85% of the buffer and the add-hook makes all text-based files like .org, .md, and .txt open automatically in olivetti mode. You can also set this per buffer with ALT-x-olivetti-mode and ALT-x-olivetti-set-width.

Checkboxes

Got this piece of awesomeness from this post at JFT’s notes.

(add-hook 'org-mode-hook (lambda ()
			   "Beautify Org Checkbox Symbol"
			   (push '("[ ]" .  "☐") prettify-symbols-alist)
			   (push '("[X]" . "☑" ) prettify-symbols-alist)
			   (push '("[-]" . "❍" ) prettify-symbols-alist)
			   (prettify-symbols-mode)))
(defface org-checkbox-done-text
'((t (:foreground "#71696A")))
"Face for the text part of a checked org-mode checkbox.")

Look!

org-checkbox.png

Variable pitch

The default Spacemacs font should be set to something that’s fixed-pitch or fixed-width or monospace - i.e. each letter takes the same amount of horizontal space. This is pretty necessary for code and tables and looks better for things like TODO and SCHEDULED etc. But the normal text in an org file doesn’t have any restrictions and (to me) looks better with the kinds of fonts you find in books and newspapers and blog posts.

So I downloaded ETBembo, a font by Edward Tufte, the go to guy for visualization, and set it as my variable-pitch font (i.e. not fixed-pitch). Then I used ALT-x customize-group org-faces to decide which parts of an org-file should be fixed-pitch (by typing “fixed-pitch” in the Inherit box) and which parts should be variable-pitch. I went a bit crazy here and made some things italics and bold and purple etc. but this highlights one of the nice things about Spacemacs - you don’t have to type things in to your config file by hand. All of the settings so far could just as easily have been set via ALT-x customize-variable or ALT-x customize-face which opens up a buffer with options and dropdown boxes like a GUI tool would have. I like using it for things where I want to experiment with how different options look before setting them down in stone in .spacemacs.

(custom-set-faces
     ;; custom-set-faces was added by Custom.
     ;; If you edit it by hand, you could mess it up, so be careful.
     ;; Your init file should contain only one such instance.
     ;; If there is more than one, they won't work right.
     '(variable-pitch ((t (:weight normal :height 1.1 :width normal :family "ETBembo"))))
     '(fixed-pitch ((t (:family "Jetbrains Mono"))))
     '(org-block ((t (:inherit (shadow fixed-pitch)))))
     '(org-checkbox ((t (:foreground "Pink" :inherit (bold fixed-pitch)))))
     '(org-checkbox-statistics-done ((t (:inherit org-done))))
     '(org-code ((t (:inherit (shadow fixed-pitch)))))
     '(org-default ((t (:inherit variable-pitch :family "ETBembo"))))
     '(org-document-info ((t (:inherit fixed-pitch :foreground "pale turquoise"))))
     '(org-document-info-keyword ((t (:inherit (shadow fixed-pitch)))))
     '(org-document-title ((t (:inherit default :weight bold :foreground "#c0c5ce" :font "ETBembo" :height 1.5 :underline nil))))
     '(org-done ((t (:inherit fixed-pitch :foreground "PaleGreen" :weight bold))))
     '(org-footnote ((t (:inherit variable-pitch :foreground "Cyan" :underline t))))
     '(org-indent ((t (:inherit (org-hide fixed-pitch)))))
     '(org-level-1 ((t (:inherit variable-pitch :foreground "#c2c2b0" :slant italic :weight semi-light :height 1.75 :width normal :foundry "nil" :family "ETBembo"))))
     '(org-level-2 ((t (:inherit variable-pitch :foreground "#c2c2b0" :height 1.5 :width normal :foundry "nil" :family "ETBembo"))))
     '(org-level-3 ((t (:inherit variable-pitch :foreground "#b0a2e7" :slant italic :weight normal :height 1.25 :width normal :foundry "nil" :family "ETBembo"))))
     '(org-level-4 ((t (:inherit variable-pitch))))
     '(org-level-5 ((t (:inherit default :weight bold :foreground "#c0c5ce" :font "ETBembo"))))
     '(org-level-6 ((t (:inherit default :weight bold :foreground "#c0c5ce" :font "ETBembo"))))
     '(org-level-7 ((t (:inherit default :weight bold :foreground "#c0c5ce" :font "ETBembo"))))
     '(org-level-8 ((t (:inherit default :weight bold :foreground "#c0c5ce" :font "ETBembo"))))
     '(org-link ((t (:inherit (link variable-pitch) :slant normal))))
     '(org-list-dt ((t (:inherit fixed-pitch :foreground "#819cd6" :weight bold))))
     '(org-meta-line ((t (:inherit (font-lock-comment-face fixed-pitch)))))
     '(org-property-value ((t (:inherit fixed-pitch))) t)
     '(org-quote ((t (:background "#32353f" :family "ETBembo"))))
     '(org-todo ((t (:inherit fixed-pitch :foreground "Pink" :weight bold))))
     '(org-verbatim ((t (:inherit (shadow fixed-pitch)))))
     '(org-verse ((t (:inherit fixed-pitch))))
     )
)

This part still has some minor issues though. By itself it looks like this:

org-variable-pitch-off.png

So, the headings look good but the font for text under headings and in lists is still fixed-width. But when I turn on variable-pitch mode (ALT-x variable-pitch-mode) then it looks like this:

org-variable-pitch-on.png

The text is variable-pitch but the TODOs and SCHEDULED and stuff are suddenly variable-pitch too. No idea why this happens but I’ve grown fond of the first option for phd.org (since it’s mostly headings with short notes) and the second option for blog posts (since they usually don’t have TODOs) and both still look good so this is a problem for another day.

Other

Some settings I found here and there I think I got most of the aesthetics stuff from this post, but I did a lot of random searching when I was beautifying org so it’s very likely I’m forgetting to credit some people. that makes Org mode look better.

;; Makes some things look nicer
(setq org-startup-indented t
      org-pretty-entities t
      ;; show actually italicized text instead of /italicized text/
      org-hide-emphasis-markers t
      org-agenda-block-separator ""
      org-fontify-whole-heading-line t
      org-fontify-done-headline t
      org-fontify-quote-and-verse-blocks t)
  • org-startup-indented - Vertically aligns text under headings to the heading itself (like in the example here)
  • org-pretty-entities - For LaTeX symbols like α (typed as alpha with a “\” in front) and ∑. I thought this was pretty much only for math symbols but turns out there’s a ginormous list of entities you can use (run ALT-x-org-entities-help in a buffer). There’s even smileys ☻. You can even add your own!
  • The org-fontifys make it so that if you change the font / background color etc. of the heading / done / quote block / verse block then the change shows up for the whole line (across the buffer) instead of just the part with the text.

Next Steps

These options have made for a good workflow so far. There are plenty more packages to check out though. There’s things like grasp (a Firefox/Chrome add-on which lets you capture content from the web with capture templates) and org-download (which lets you drag and drop images from your computer or your browser into an org file) for making it easier to deal with the world outside of orgSpeaking of, I also use Orgzly synced to Dropbox for seeing my org files on my phone - it’s quite nice, let’s me make an agenda widget so I can track things I need to do while at lunch or somewhere without my laptop (though tbh I’m much more likely to have my laptop on me these days than my phone). . I’d also love to get something set up that downloads PDFs of publications from journal RSS feeds (with elfeed?) like Bioinformatics, Nature, eLife etc. so that it’s easier to read (pdf-tools) and annotate (org-noter) them right away.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK