This is a collection of dotfiles and scripts for my bspwm setup
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

9.2 KiB

Org Mode

LaTeX Configuration

(use-package tex-mode
  :ensure nil ; built-in
  :defer t
  :hook (latex-mode . (lambda ()
						(setq indent-tabs-mode t)
						(setq tab-width 4)
						(setq tex-indent-basic 4)))
  :config

  (with-eval-after-load 'project
	(defun compile-latex ()
	  "Compile LaTeX project."
	  (interactive)
	  (let ((default-directory (dot/find-project-root)))
		(dot/project-save-project-buffers)
		(shell-command "make")))))

Org Configuration

Base Org.

(use-package org
  :config
  (setq org-adapt-indentation nil)
  (setq org-default-notes-file (expand-file-name "notes.org" org-directory))
  (setq org-directory (concat (getenv "HOME") "/documents/org"))
  (setq org-ellipsis "⤵")
  (setq org-image-actual-width nil)

  ;; Enable structured template completion
  (add-to-list 'org-modules 'org-tempo t)
  (add-to-list 'org-structure-template-alist
			   '("el" . "src emacs-lisp")))

Org agenda.

(use-package org-agenda
  :ensure nil ; built-in
  :defer t
  :config
  (setq org-agenda-files `(,org-directory ,user-emacs-directory))
  (setq org-agenda-span 14)
  (setq org-agenda-window-setup 'current-window)
  (evil-set-initial-state 'org-agenda-mode 'motion))

Org capture.

(use-package org-capture
  :ensure nil ; built-in
  ;; Org-capture in new tab, rather than split window
  :hook (org-capture-mode . delete-other-windows))

Org keys.

(use-package org-keys
  :ensure nil ; built-in
  :config
  (setq org-return-follows-link t))

Org links.

(use-package ol
  :ensure nil ; built-in
  :config
  ;; Do not open links to .org files in a split window
  (add-to-list 'org-link-frame-setup '(file . find-file)))

Org source code blocks.

(use-package org-src
  :ensure nil ; built-in
  :config
  (setq org-edit-src-content-indentation 0)
  (setq org-src-fontify-natively t)
  (setq org-src-preserve-indentation t)
  (setq org-src-tab-acts-natively t)
  (setq org-src-window-setup 'current-window))

Org exporter.

(use-package ox
  :ensure nil ; built-in
  :defer t
  :config
  (setq org-export-coding-system 'utf-8-unix))

Org latex exporter.

(use-package ox-latex
  :ensure nil ; built-in
  :defer t
  :config
  ;; Define how minted (highlighted src code) is added to src code blocks
  (setq org-latex-listings 'minted)
  (setq org-latex-minted-options '(("frame" "lines") ("linenos=true")))
  ;; Set 'Table of Contents' layout
  (setq org-latex-toc-command "\\newpage \\tableofcontents \\newpage")
  ;; Add minted package to every LaTeX header
  (add-to-list 'org-latex-packages-alist '("" "minted"))
  ;; Add -shell-escape so pdflatex exports minted correctly
  (setcar org-latex-pdf-process (replace-regexp-in-string
								 "-%latex -interaction"
								 "-%latex -shell-escape -interaction"
								 (car org-latex-pdf-process))))

Org Functions

(with-eval-after-load 'evil-commands
  (defun dot/org-ret-at-point ()
	"Org return key at point.

If point is on:
  checkbox   -- toggle it
  link       -- follow it
  otherwise  -- run the default (evil-ret) expression"
	(interactive)
	(let ((type (org-element-type (org-element-context))))
	  (pcase type
		('link (if org-return-follows-link (org-open-at-point) (evil-ret)))
		((guard (org-at-item-checkbox-p)) (org-toggle-checkbox))
		(_ (evil-ret))
		))))

Org Bullets

(use-package org-bullets
  :hook (org-mode . org-bullets-mode))

Org Export Packages

HTML exporter.

(use-package htmlize
  :defer t
  :config (setq org-export-html-postamble nil))
;;org-export-html-postamble-format ; TODO

GitHub flavored Markdown exporter.

(use-package ox-gfm
  :defer t)

Org Roam

Setup org-roam.

(use-package org-roam
  :defer 1
  :init
  (setq org-roam-v2-ack t)
  :config
  (setq org-roam-db-location (expand-file-name "org-roam.db" dot-cache-dir))
  (setq org-roam-directory org-directory)
  ;; Exclude Syncthing backup directory
  (setq org-roam-file-exclude-regexp "\\.stversions")
  (setq org-roam-verbose nil)

  (setq org-roam-capture-templates
		'(("d" "default" plain
		   "%?"
		   :target (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+TITLE: ${title}\n#+FILETAGS: %^{File tags}\n")
		   :unnarrowed t)))

  (defun dot/org-roam-node-insert-immediate (arg &rest args)
	(interactive "P")
	(let ((args (push arg args))
          (org-roam-capture-templates (list (append (car org-roam-capture-templates)
													'(:immediate-finish t)))))
      (apply #'org-roam-node-insert args)))

  (cl-defmethod org-roam-node-slug ((node org-roam-node))
	"Return the slug of NODE, strip out common words."
	(let* ((title (org-roam-node-title node))
		   (words (split-string title " "))
		   (common-words '("a" "an" "and" "as" "at" "by" "is" "it" "of" "the" "to"))
		   (title (string-join (seq-remove (lambda (element) (member element common-words)) words) "_"))
		   (pairs '(("c\\+\\+" . "cpp")             ;; convert c++ -> cpp
					("c#" . "cs")                   ;; convert  c# -> cs
					("[^[:alnum:][:digit:]]" . "_") ;; convert anything not alphanumeric
					("__*" . "_")                   ;; remove sequential underscores
					("^_" . "")                     ;; remove starting underscore
					("_$" . ""))))                  ;; remove ending underscore
	  (cl-flet ((cl-replace (title pair)
							(replace-regexp-in-string (car pair) (cdr pair) title)))
		(downcase (-reduce-from #'cl-replace title pairs)))))

  ;; Right-align org-roam-node-tags in the completion menu without a length limit
  ;; Source: https://github.com/org-roam/org-roam/issues/1775#issue-971157225
  (setq org-roam-node-display-template "${title} ${tags:0}")
  (setq org-roam-node-annotation-function #'dot/org-roam-annotate-tag)
  (defun dot/org-roam-annotate-tag (node)
	(let ((tags (mapconcat 'identity (org-roam-node-tags node) " #")))
      (unless (string-empty-p tags)
		(concat
		 (propertize " " 'display `(space :align-to (- right ,(+ 2 (length tags)))))
		 (propertize (concat "#" tags) 'face 'bold)))))

  (org-roam-setup))

Enable Roam Protocol, needed to process org-protocol:// links

(use-package org-roam-protocol
  :ensure nil ; org-roam-protocol.el is part of org-roam
  :after org-roam
  :config

  ;; Templates used when creating a new file from a bookmark
  (setq org-roam-capture-ref-templates
		'(("r" "ref" plain
		   "%?"
		   :target (file+head "${slug}.org" "#+TITLE: ${title}\n \n${body}")
		   :unnarrowed t))))

The roam-ref protocol bookmarks to add:

javascript:location.href =
	'org-protocol://roam-ref?template=r'
	+ '&ref=' + encodeURIComponent(location.href)
	+ '&title=' + encodeURIComponent(document.title)
	+ '&body=' + encodeURIComponent(window.getSelection())

Setup org-roam-ui, runs at http://127.0.0.1:35901.

(use-package org-roam-ui
  :after org-roam
  :config
  (setq org-roam-ui-follow t)
  (setq org-roam-ui-open-on-start t)
  (setq org-roam-ui-sync-theme nil) ;; FIXME: Make this work (org-roam-ui-get-theme)
  (setq org-roam-ui-update-on-save t))

Easily searchable .org files via Deft.

(use-package deft
  :after org
  :hook (deft-mode . dot/hook-disable-line-numbers)
  :config
  (setq deft-auto-save-interval 0)
  (setq deft-default-extension "org")
  (setq deft-directory org-directory)
  (setq deft-file-naming-rules '((noslash . "-")
								 (nospace . "-")
								 (case-fn . downcase)))
  (setq deft-new-file-format "%Y%m%d%H%M%S-deft")
  (setq deft-recursive t)
  ;; Exclude Syncthing backup directory
  (setq deft-recursive-ignore-dir-regexp (concat "\\.stversions\\|" deft-recursive-ignore-dir-regexp))
  ;; Remove file variable -*- .. -*- and Org Mode :PROPERTIES: lines
  (setq deft-strip-summary-regexp (concat "\\(^.*-\\*-.+-\\*-$\\|^:[[:alpha:]_]+:.*$\\)\\|" deft-strip-summary-regexp))
  (setq deft-use-filename-as-title nil)
  (setq deft-use-filter-string-for-filename t)

  (add-to-list 'deft-extensions "tex")

  ;; Start filtering immediately
  (evil-set-initial-state 'deft-mode 'insert)

  (defun deft-parse-title (file contents)
	"Parse the given FILE and CONTENTS and determine the title."
	(org-element-property
	 :value
	 (car
	  (org-element-map
		  (with-temp-buffer
			(insert contents)
			(org-element-parse-buffer 'greater-element))
		  'keyword
		(lambda (e) (when (string-match "TITLE" (org-element-property :key e)) e)))))))

Org "Table of Contents"

Generate table of contents without exporting.

(use-package toc-org
  :hook (org-mode . toc-org-mode))