1397 lines
53 KiB
Org Mode
1397 lines
53 KiB
Org Mode
#+title: Emacs — Packages — Org Mode
|
||
#+setupfile: ../../headers
|
||
#+property: header-args:emacs-lisp :mkdirp yes :lexical t :exports code
|
||
#+property: header-args:emacs-lisp+ :tangle ~/.config/emacs/lisp/org.el
|
||
#+property: header-args:emacs-lisp+ :mkdirp yes :noweb no-export
|
||
|
||
* Org-mode
|
||
#+name: general-keybindings-gen
|
||
#+header: :tangle no :exports none :results value :cache yes
|
||
#+begin_src emacs-lisp :var table=org-keybinds-babel prefix=""
|
||
(mapconcat (lambda (line)
|
||
(let* ((key (nth 0 line))
|
||
(function (nth 1 line))
|
||
(comment (or (nth 2 line) ""))
|
||
(package (or (nth 3 line) "")))
|
||
(format "\"%s%s\" %s"
|
||
prefix
|
||
key
|
||
(if (string= "" comment)
|
||
(if (member function '("" "nil")) "nil" (concat "#'" function))
|
||
(format "'(%s :wk %s%s)"
|
||
(if (member function '("" "nil")) ":ignore t" function)
|
||
(if (member function '("none" "nil")) "t" (concat "\"" comment "\""))
|
||
(if (string-blank-p package) "" (concat ":package " package)))))))
|
||
table
|
||
"\n")
|
||
#+end_src
|
||
|
||
Since recently, in order to make ~org-cite~ compile properly, we need
|
||
the ~citeproc~ package, a citation processor.
|
||
#+begin_src emacs-lisp
|
||
(use-package citeproc
|
||
:after (org)
|
||
:defer t
|
||
:straight (:build t))
|
||
#+end_src
|
||
|
||
Org is the main reason I am using Emacs. It is an extremely powerful
|
||
tool when you want to write anything that is not necessarily primarily
|
||
programming-related, though it absolutely can be! Org can be a
|
||
replacement for anything similar to LibreOffice Writer, LibreOffice
|
||
Calc, and LibreOffice Impress. It is a much more powerful (and older)
|
||
version of Markdown which can be exported to LaTeX and HTML at least,
|
||
rendering writing web pages and technical, scientific documents much
|
||
simpler than writing manually HTML and LaTeX code, especially when a
|
||
single document source is meant to be exported for both formats. And
|
||
since org is an Emacs package, that also means it can be greatly
|
||
extended however we like!
|
||
#+begin_src emacs-lisp
|
||
(use-package org
|
||
:straight t
|
||
:defer t
|
||
:after engrave-faces
|
||
:commands (orgtbl-mode)
|
||
:hook ((org-mode . visual-line-mode)
|
||
(org-mode . org-num-mode))
|
||
:custom-face
|
||
(org-macro ((t (:foreground "#b48ead"))))
|
||
:init
|
||
(auto-fill-mode -1)
|
||
:config
|
||
<<org-hydra-babel>>
|
||
(require 'ox-beamer)
|
||
(require 'org-protocol)
|
||
(setq org-hide-leading-stars nil
|
||
org-hide-macro-markers t
|
||
org-ellipsis " ⤵"
|
||
org-image-actual-width 600
|
||
org-redisplay-inline-images t
|
||
org-display-inline-images t
|
||
org-startup-with-inline-images "inlineimages"
|
||
org-pretty-entities t
|
||
org-fontify-whole-heading-line t
|
||
org-fontify-done-headline t
|
||
org-fontify-quote-and-verse-blocks t
|
||
org-startup-indented t
|
||
org-startup-align-all-tables t
|
||
org-use-property-inheritance t
|
||
org-list-allow-alphabetical t
|
||
org-M-RET-may-split-line nil
|
||
org-src-window-setup 'split-window-below
|
||
org-src-fontify-natively t
|
||
org-src-tab-acts-natively t
|
||
org-src-preserve-indentation t
|
||
org-log-done 'time
|
||
org-directory "~/org"
|
||
org-default-notes-file (expand-file-name "notes.org" org-directory))
|
||
(with-eval-after-load 'oc
|
||
(setq org-cite-global-bibliography '("~/org/bibliography/references.bib")))
|
||
<<org-agenda-files>>
|
||
<<org-behavior-electric>>
|
||
<<org-capture-target-files>>
|
||
<<org-capture-templates>>
|
||
<<org-create-emphasis-functions()>>
|
||
<<org-babel-load-languages>>
|
||
<<org-use-sub-superscripts>>
|
||
<<org-latex-compiler>>
|
||
<<org-latex-src-block-backend>>
|
||
<<org-latex-default-packages>>
|
||
<<org-export-latex-hyperref-format>>
|
||
<<org-latex-pdf-process>>
|
||
<<org-latex-logfiles-add-extensions>>
|
||
<<org-re-reveal>>
|
||
<<org-html-validation>>
|
||
<<org-latex-classes>>
|
||
<<org-publish-projects>>
|
||
<<org-mode-visual-prettify-symbols>>
|
||
:general
|
||
(phundrak/evil
|
||
:keymaps 'org-mode-map
|
||
:packages 'org
|
||
"RET" 'org-open-at-point)
|
||
(phundrak/major-leader-key
|
||
:keymaps 'org-mode-map
|
||
:packages 'org
|
||
<<general-keybindings-gen(table=org-keybinds-various)>>
|
||
<<general-keybindings-gen(table=org-keybinds-babel)>>
|
||
<<general-keybindings-gen(table=org-keybinds-dates)>>
|
||
<<general-keybindings-gen(table=org-keybinds-insert)>>
|
||
<<general-keybindings-gen(table=org-keybinds-jump)>>
|
||
<<general-keybindings-gen(table=org-keybinds-tables)>>
|
||
<<general-keybindings-gen(table=org-keybinds-toggles)>>)
|
||
<<org-capture-keybinds>>
|
||
(phundrak/major-leader-key
|
||
:packages 'org
|
||
:keymaps 'org-src-mode-map
|
||
"'" #'org-edit-src-exit
|
||
"k" #'org-edit-src-abort))
|
||
#+end_src
|
||
|
||
The main feature from ~evil-org~ that I love is how easy it is to modify
|
||
some keybindings for keyboards layouts that do not have ~hjkl~, such as
|
||
the bépo layout (or Dvorak or Colemak if you are into that). But it
|
||
also adds a ton of default keybindings which are just much more
|
||
comfortable than the default ones you get with evil and org naked.
|
||
#+begin_src emacs-lisp
|
||
(use-package evil-org
|
||
:straight (:build t)
|
||
:after (org)
|
||
:hook (org-mode . evil-org-mode)
|
||
:config
|
||
(setq-default evil-org-movement-bindings
|
||
'((up . "s")
|
||
(down . "t")
|
||
(left . "c")
|
||
(right . "r")))
|
||
(evil-org-set-key-theme '(textobjects navigation calendar additional shift operators))
|
||
(require 'evil-org-agenda)
|
||
(evil-org-agenda-set-keys))
|
||
#+end_src
|
||
|
||
This package is a small package I’ve written that helps me when
|
||
writing conlanging documents, with features such as creating syntax
|
||
trees, converting translitterated text to its native script, etc…
|
||
#+begin_src emacs-lisp
|
||
(use-package conlanging
|
||
:straight (conlanging :build t
|
||
:type git
|
||
:repo "https://labs.phundrak.com/phundrak/conlanging.el")
|
||
:after org
|
||
:defer t)
|
||
#+end_src
|
||
|
||
Since very recently, the ~contrib/lisp/~ directory of org moved out of
|
||
the main repository to [[https://git.sr.ht/~bzg/org-contrib][this repository]]. On the other hand,
|
||
~contrib/scripts/~ moved to [[https://code.orgmode.org/bzg/worg/src/master/code][the worg repository]], but I don’t need
|
||
it. The main reason I want ~org-contrib~ is due to ~ox-extra~ that allow
|
||
the usage of the ~:ignore:~ tag in org.
|
||
#+begin_src emacs-lisp
|
||
(use-package org-contrib
|
||
:after (org)
|
||
:defer t
|
||
:straight (:build t)
|
||
:init
|
||
(require 'ox-extra)
|
||
(ox-extras-activate '(latex-header-blocks ignore-headlines)))
|
||
#+end_src
|
||
|
||
** Agenda
|
||
#+name: org-agenda-files
|
||
#+begin_src emacs-lisp :tangle no
|
||
(setq org-agenda-files (list "~/org/agenda" "~/org/notes.org"))
|
||
#+end_src
|
||
|
||
#+begin_src emacs-lisp
|
||
(use-package org-caldav
|
||
:straight (:build t)
|
||
:defer t
|
||
:config
|
||
(setq org-caldav-url "https://nextcloud.phundrak.com/remote.php/dav/calendars/phundrak"
|
||
org-icalendar-timezone "Europe/Paris"
|
||
org-caldav-calendars
|
||
`((:calendar-id "personal" :files ("~/org/agenda/private.org")
|
||
:inbox "~/org/agenda/private.org")
|
||
(:calendar-id "contact_birthdays" :files ("~/org/agenda/birthdays.org")
|
||
:inbox "~/org/agenda/birthdays.org"))))
|
||
#+end_src
|
||
|
||
** Babel
|
||
One of the amazing features of org-mode is its literary programming capacities
|
||
by running code blocks from within Org-mode itself. But for that, only a couple
|
||
of languages are supported directly by Org-mode itself, and they need to be
|
||
activated. Here are the languages I activated in my Org-mode configuration:
|
||
#+NAME: org-babel-languages-table
|
||
| C |
|
||
| emacs-lisp |
|
||
| gnuplot |
|
||
| latex |
|
||
| makefile |
|
||
| plantuml |
|
||
| python |
|
||
| sass |
|
||
| shell |
|
||
| sql |
|
||
|
||
#+NAME: org-babel-languages-gen
|
||
#+header: :cache yes :results replace
|
||
#+header: :var languages=org-babel-languages-table[,0]
|
||
#+BEGIN_SRC emacs-lisp :exports none :tangle no
|
||
(format "'(%s)"
|
||
(mapconcat (lambda ($language)
|
||
(format "(%s . t)" $language))
|
||
languages
|
||
"\n "))
|
||
#+END_SRC
|
||
|
||
#+RESULTS[b0a5bea13e6ba99525ad166ea5538e74ba4c6ddc]: org-babel-languages-gen
|
||
#+begin_example
|
||
'((C . t)
|
||
(emacs-lisp . t)
|
||
(gnuplot . t)
|
||
(latex . t)
|
||
(makefile . t)
|
||
(plantuml . t)
|
||
(python . t)
|
||
(sass . t)
|
||
(shell . t)
|
||
(sql . t))
|
||
#+end_example
|
||
|
||
The corresponding code is as follows:
|
||
#+NAME: org-babel-load-languages
|
||
#+BEGIN_SRC emacs-lisp :noweb yes :tangle no
|
||
(org-babel-do-load-languages
|
||
'org-babel-load-languages
|
||
<<org-babel-languages-gen()>>)
|
||
#+END_SRC
|
||
|
||
Some languages can run asynchronously with the help of ~ob-async~.
|
||
#+begin_src emacs-lisp
|
||
(use-package ob-async
|
||
:straight (:build t)
|
||
:defer t
|
||
:after (org ob))
|
||
#+end_src
|
||
|
||
A package I use from time to time is ~ob-latex-as-png~ which allows me
|
||
to easily convert a LaTeX snippet into a PNG, regardless of the
|
||
exporter I use afterwards. Its installation is pretty simple:
|
||
#+begin_src emacs-lisp
|
||
(use-package ob-latex-as-png
|
||
:after org
|
||
:straight (:build t))
|
||
#+end_src
|
||
|
||
A nice thing to have when working with REST APIs is to have a REST
|
||
client. Even better if it can work inside org-mode!
|
||
#+begin_src emacs-lisp
|
||
(use-package ob-restclient
|
||
:straight (:build t)
|
||
:defer t
|
||
:after (org ob)
|
||
:init
|
||
(add-to-list 'org-babel-load-languages '(restclient . t)))
|
||
#+end_src
|
||
|
||
** Behavior
|
||
A useful package I like is ~toc-org~ which creates automatically a table
|
||
of contents. My main usage for this however is not just to create a
|
||
table of content of my files to quickly jump around my file (I have
|
||
~counsel-org-goto~ for that), but it is for creating table of contents
|
||
for org files that will be hosted and viewable on GitHub.
|
||
#+begin_src emacs-lisp
|
||
(use-package toc-org
|
||
:after (org markdown-mode)
|
||
:straight (:build t)
|
||
:init
|
||
(add-to-list 'org-tag-alist '("TOC" . ?T))
|
||
:hook (org-mode . toc-org-enable)
|
||
:hook (markdown-mode . toc-org-enable))
|
||
#+end_src
|
||
~electric-mode~ also bothers me a lot when editing org files, so let’s deactivate it:
|
||
#+name: org-behavior-electric
|
||
#+begin_src emacs-lisp :tangle no
|
||
(add-hook 'org-mode-hook (lambda ()
|
||
(interactive)
|
||
(electric-indent-local-mode -1)))
|
||
#+end_src
|
||
|
||
As explained in my [[https://blog.phundrak.com/better-custom-ids-orgmode/][blog post]], org-mode is terrible with coming up with
|
||
meaningful IDs for its headings. I actually wrote a package for this!
|
||
#+begin_src emacs-lisp
|
||
(use-package org-unique-id
|
||
:straight (org-unique-id :build t
|
||
:type git
|
||
:host github
|
||
:repo "Phundrak/org-unique-id")
|
||
:defer t
|
||
:after org
|
||
:init (add-hook 'before-save-hook #'org-unique-id-maybe))
|
||
#+end_src
|
||
|
||
** Capture
|
||
Org capture is an amazing tool for taking quick notes, be it simple
|
||
text, links, resources, or reminders. They are all organised is
|
||
specified org files which are described below.
|
||
#+name: org-capture-target-files
|
||
#+begin_src emacs-lisp :tangle no
|
||
(defvar org-conlanging-file "~/org/conlanging.org")
|
||
(defvar org-notes-file "~/org/notes.org")
|
||
(defvar org-journal-file "~/org/journal.org")
|
||
(defvar org-linguistics-file "~/org/linguistics.org")
|
||
(defvar org-novel-file "~/org/novel.org")
|
||
(defvar org-agenda-file "~/org/agenda/private.org")
|
||
(defvar org-school-file "~/org/agenda/school.org")
|
||
(defvar org-worldbuilding-file "~/org/worldbuilding.org")
|
||
#+end_src
|
||
|
||
Let me describe a keybind to invoke org-capture from anywhere within
|
||
Emacs.
|
||
#+name: org-capture-keybinds
|
||
#+begin_src emacs-lisp :tangle no
|
||
(phundrak/leader-key
|
||
:packages 'org
|
||
:infix "o"
|
||
"" '(:ignore t :which-key "org")
|
||
"c" #'org-capture)
|
||
#+end_src
|
||
|
||
When ~org-capture~ is invoked, it will ask which template we wish to
|
||
use. In the table [[org-capture-shortcuts-table]], the /key/ column
|
||
represents which keychord we need to hit, titled with /name/, we need to
|
||
hit in order to use the /template/, inserted in the designated /file/ in
|
||
the manner described by /insertion mode/.
|
||
#+name: org-capture-shortcuts-table
|
||
| Shortcut | Name | Title | Insertion mode | file | template |
|
||
|----------+---------------+-----------+----------------+-------------------------+--------------------------|
|
||
| e | Email | | | | |
|
||
| ew | Write Email | Emails | file+headline | org-default-notes-file | email.orgcaptmpl |
|
||
| j | Journal | | file+datetree | org-journal-file | journal.orgcaptmpl |
|
||
| l | Link | | | | |
|
||
| ll | General | | file+headline | org-default-notes-file | link.orgcaptmpl |
|
||
| ly | YouTube | | file+headline | org-default-notes-file | youtube.orgcaptmpl |
|
||
| L | Protocol Link | Link | file+headline | org-default-notes-file | protocol-link.orgcaptmpl |
|
||
| n | Notes | | | | |
|
||
| nc | Conlanging | Note | file+headline | org-conlanging-file | notes.orgcaptmpl |
|
||
| nn | General | | file+headline | org-default-notes-file | notes.orgcaptmpl |
|
||
| nN | Novel | Note | file+headline | org-novel-notes-file | notes.orgcaptmpl |
|
||
| nq | Quote | | file+headline | org-default-notes-file | notes-quote.orgcaptmpl |
|
||
| nw | Worldbuilding | Note | file+headline | org-wordbuilding-file | notes.orgcaptmpl |
|
||
| N | Novel | | | | |
|
||
| Ni | Ideas | | file+headline | org-novel-notes-file | notes.orgcaptmpl |
|
||
| p | Protocol | Link | file+headline | org-default-notes-file | protocol.orgcaptmpl |
|
||
| r | Resources | | | | |
|
||
| rc | Conlanging | Resources | file+headline | org-conlanging-file | resource.orgcaptmpl |
|
||
| re | Emacs | | file+headline | org-default-notes-file | resource.orgcaptmpl |
|
||
| ri | Informatique | | file+headline | org-default-notes-file | resource.orgcaptmpl |
|
||
| rl | Linguistics | | file+headline | org-default-notes-file | resource.orgcaptmpl |
|
||
| rL | Linux | | file+headline | org-default-notes-file | resource.orgcaptmpl |
|
||
| rw | Worldbuilding | Resources | file+headline | org-wordbuilding-file | resource.orgcaptmpl |
|
||
| t | Tasks | | | | |
|
||
| tb | Birthday | | file+headline | org-private-agenda-file | birthday.orgcaptmpl |
|
||
| te | Event | | file+headline | org-private-agenda-file | event.orgcaptmpl |
|
||
| th | Health | | file+headline | org-private-agenda-file | health.orgcaptmpl |
|
||
| ti | Informatique | | file+headline | org-private-agenda-file | informatique.orgcaptmpl |
|
||
|
||
All templates can be found [[https://labs.phundrak.com/phundrak/dotfiles/src/branch/master/org/capture][in my dotfiles’ repository]].
|
||
|
||
#+name: org-capture-shortcuts-gen
|
||
#+header: :exports none :cache yes :tangle no
|
||
#+begin_src emacs-lisp :var entries=org-capture-shortcuts-table
|
||
(mapconcat (lambda (entry)
|
||
(let ((key (nth 0 entry))
|
||
(name (nth 1 entry))
|
||
(title (nth 2 entry))
|
||
(ins-mode (nth 3 entry))
|
||
(file (nth 4 entry))
|
||
(template (nth 5 entry)))
|
||
(if (string= "" ins-mode)
|
||
(format "%S" `(,key ,name))
|
||
(format "(\"%s\" \"%s\" entry\n %S\n %S)"
|
||
key name
|
||
`(,(intern ins-mode) ,(intern file) ,(if (string= "file+datetree" ins-mode)
|
||
(intern "")
|
||
(if (string= title "")
|
||
name
|
||
title)))
|
||
`(file ,(concat "~/org/capture/" template))))))
|
||
entries
|
||
"\n")
|
||
#+end_src
|
||
|
||
#+RESULTS[9f565c3dd73becfad0a99c0cfaf4521762334b40]: org-capture-shortcuts-gen
|
||
#+begin_example
|
||
("e" "Email")
|
||
("ew" "Write Email" entry
|
||
(file+headline org-default-notes-file "Emails")
|
||
(file "~/org/capture/email.orgcaptmpl"))
|
||
("j" "Journal" entry
|
||
(file+datetree org-journal-file ##)
|
||
(file "~/org/capture/journal.orgcaptmpl"))
|
||
("l" "Link")
|
||
("ll" "General" entry
|
||
(file+headline org-default-notes-file "General")
|
||
(file "~/org/capture/link.orgcaptmpl"))
|
||
("ly" "YouTube" entry
|
||
(file+headline org-default-notes-file "YouTube")
|
||
(file "~/org/capture/youtube.orgcaptmpl"))
|
||
("L" "Protocol Link" entry
|
||
(file+headline org-default-notes-file "Link")
|
||
(file "~/org/capture/protocol-link.orgcaptmpl"))
|
||
("n" "Notes")
|
||
("nc" "Conlanging" entry
|
||
(file+headline org-conlanging-file "Note")
|
||
(file "~/org/capture/notes.orgcaptmpl"))
|
||
("nn" "General" entry
|
||
(file+headline org-default-notes-file "General")
|
||
(file "~/org/capture/notes.orgcaptmpl"))
|
||
("nN" "Novel" entry
|
||
(file+headline org-novel-notes-file "Note")
|
||
(file "~/org/capture/notes.orgcaptmpl"))
|
||
("nq" "Quote" entry
|
||
(file+headline org-default-notes-file "Quote")
|
||
(file "~/org/capture/notes-quote.orgcaptmpl"))
|
||
("nw" "Worldbuilding" entry
|
||
(file+headline org-wordbuilding-file "Note")
|
||
(file "~/org/capture/notes.orgcaptmpl"))
|
||
("N" "Novel")
|
||
("Ni" "Ideas" entry
|
||
(file+headline org-novel-notes-file "Ideas")
|
||
(file "~/org/capture/notes.orgcaptmpl"))
|
||
("p" "Protocol" entry
|
||
(file+headline org-default-notes-file "Link")
|
||
(file "~/org/capture/protocol.orgcaptmpl"))
|
||
("r" "Resources")
|
||
("rc" "Conlanging" entry
|
||
(file+headline org-conlanging-file "Resources")
|
||
(file "~/org/capture/resource.orgcaptmpl"))
|
||
("re" "Emacs" entry
|
||
(file+headline org-default-notes-file "Emacs")
|
||
(file "~/org/capture/resource.orgcaptmpl"))
|
||
("ri" "Informatique" entry
|
||
(file+headline org-default-notes-file "Informatique")
|
||
(file "~/org/capture/resource.orgcaptmpl"))
|
||
("rl" "Linguistics" entry
|
||
(file+headline org-default-notes-file "Linguistics")
|
||
(file "~/org/capture/resource.orgcaptmpl"))
|
||
("rL" "Linux" entry
|
||
(file+headline org-default-notes-file "Linux")
|
||
(file "~/org/capture/resource.orgcaptmpl"))
|
||
("rw" "Worldbuilding" entry
|
||
(file+headline org-wordbuilding-file "Resources")
|
||
(file "~/org/capture/resource.orgcaptmpl"))
|
||
("t" "Tasks")
|
||
("tb" "Birthday" entry
|
||
(file+headline org-private-agenda-file "Birthday")
|
||
(file "~/org/capture/birthday.orgcaptmpl"))
|
||
("te" "Event" entry
|
||
(file+headline org-private-agenda-file "Event")
|
||
(file "~/org/capture/event.orgcaptmpl"))
|
||
("th" "Health" entry
|
||
(file+headline org-private-agenda-file "Health")
|
||
(file "~/org/capture/health.orgcaptmpl"))
|
||
("ti" "Informatique" entry
|
||
(file+headline org-private-agenda-file "Informatique")
|
||
(file "~/org/capture/informatique.orgcaptmpl"))
|
||
#+end_example
|
||
|
||
The capture templates are set like so:
|
||
#+name: org-capture-templates
|
||
#+begin_src emacs-lisp :tangle no :results silent
|
||
(setq org-capture-templates
|
||
'(
|
||
<<org-capture-shortcuts-gen()>>))
|
||
#+end_src
|
||
|
||
** Custom functions
|
||
*** Emphasize text
|
||
Sometimes, I want to emphasize some text in my org-mode documents.
|
||
It’s very possible to just go to the beginning of the chosen text, add
|
||
the marker, then go to the end of the text than needs emphasis and add
|
||
another marker, and I’m sure most people are fine with that. But I
|
||
also like being able to select a region and hit a keybind to emphasize
|
||
it that way. The table [[org-emphasis-character]] lists the emphasis
|
||
characters in org-mode, their role, and the character code of each
|
||
emphasis character. From that, creating functions that emphasize a
|
||
selected text is quite easy.
|
||
|
||
#+name: org-emphasis-character
|
||
| Emphasis | Character | Character code |
|
||
|----------------+-----------+----------------|
|
||
| bold | ~*~ | 42 |
|
||
| italic | ~/~ | 47 |
|
||
| underline | ~_~ | 95 |
|
||
| verbatim | ~=~ | 61 |
|
||
| code | ~~~ | 126 |
|
||
| strike-through | ~+~ | 43 |
|
||
|
||
#+name: org-create-emphasis-functions
|
||
#+header: :tangle no :exports results :cache yes
|
||
#+header: :wrap "src emacs-lisp :tangle no :exports code"
|
||
#+begin_src emacs-lisp :var emphasis-list=org-emphasis-character
|
||
(mapconcat (lambda (emphasis)
|
||
(let ((type (car emphasis))
|
||
(code (nth 2 emphasis)))
|
||
(format "(defun org-emphasize-%s ()
|
||
\"Emphasize as %s the current region.\"
|
||
(interactive)
|
||
(org-emphasize %s))"
|
||
type
|
||
type
|
||
code)))
|
||
emphasis-list
|
||
"\n")
|
||
#+end_src
|
||
|
||
#+RESULTS[dbd10cce4ae05a046838214784f0f4c16765e728]: org-create-emphasis-functions
|
||
#+begin_src emacs-lisp :tangle no :exports code
|
||
(defun org-emphasize-bold ()
|
||
"Emphasize as bold the current region."
|
||
(interactive)
|
||
(org-emphasize 42))
|
||
(defun org-emphasize-italic ()
|
||
"Emphasize as italic the current region."
|
||
(interactive)
|
||
(org-emphasize 47))
|
||
(defun org-emphasize-underline ()
|
||
"Emphasize as underline the current region."
|
||
(interactive)
|
||
(org-emphasize 95))
|
||
(defun org-emphasize-verbatim ()
|
||
"Emphasize as verbatim the current region."
|
||
(interactive)
|
||
(org-emphasize 61))
|
||
(defun org-emphasize-code ()
|
||
"Emphasize as code the current region."
|
||
(interactive)
|
||
(org-emphasize 126))
|
||
(defun org-emphasize-strike-through ()
|
||
"Emphasize as strike-through the current region."
|
||
(interactive)
|
||
(org-emphasize 43))
|
||
#+end_src
|
||
|
||
You can find the keybinds for these functions [[file:./org#keybindings][here]].
|
||
|
||
*** ~phundrak/toggle-org-src-window-split~
|
||
#+begin_src emacs-lisp
|
||
(defun phundrak/toggle-org-src-window-split ()
|
||
"This function allows the user to toggle the behavior of
|
||
`org-edit-src-code'. If the variable `org-src-window-setup' has
|
||
the value `split-window-right', then it will be changed to
|
||
`split-window-below'. Otherwise, it will be set back to
|
||
`split-window-right'"
|
||
(interactive)
|
||
(if (equal org-src-window-setup 'split-window-right)
|
||
(setq org-src-window-setup 'split-window-below)
|
||
(setq org-src-window-setup 'split-window-right))
|
||
(message "Org-src buffers will now split %s"
|
||
(if (equal org-src-window-setup 'split-window-right)
|
||
"vertically"
|
||
"horizontally")))
|
||
#+end_src
|
||
|
||
** Exporters
|
||
I want to disable by default behaviour of ~^~ and ~_~ for only one
|
||
character, making it compulsory to use instead ~^{}~ and ~_{}~
|
||
respectively. This is due to my frequent usage of the underscore in my
|
||
org files as a regular character and not a markup one, especially when
|
||
describing phonetics evolution. So, let’s disable it:
|
||
#+NAME: org-use-sub-superscripts
|
||
#+BEGIN_SRC emacs-lisp :tangle no
|
||
(setq org-use-sub-superscripts (quote {}))
|
||
#+END_SRC
|
||
|
||
*** Epub
|
||
A backend for exporting files through org I like is ~ox-epub~ which, as
|
||
you can guess, exports org files to the [[https://www.w3.org/publishing/epub32/][Epub format]].
|
||
#+begin_src emacs-lisp
|
||
(use-package ox-epub
|
||
:after (org ox)
|
||
:straight (:build t))
|
||
#+end_src
|
||
|
||
*** Gemini
|
||
Gemini is a lightweight protocol for creating lightweight websites
|
||
that are basically text-only websites with maybe some images. I’m
|
||
currently maintaining my own fork of Justin Abrahms’ =ox-gemini= which
|
||
fixes two issues I had with the original package.
|
||
#+begin_src emacs-lisp
|
||
(use-package ox-gemini
|
||
:defer t
|
||
:straight (ox-gemini :build t
|
||
:fork (:type git
|
||
:host nil
|
||
:repo "https://labs.phundrak.com/phundrak/ox-gemini"))
|
||
:after (ox org))
|
||
#+end_src
|
||
|
||
*** HTML
|
||
On HTML exports, Org-mode tries to include a validation link for the
|
||
exported HTML. Let’s disable that since I never use it.
|
||
#+NAME: org-html-validation
|
||
#+BEGIN_SRC emacs-lisp :tangle no
|
||
(setq org-html-validation-link nil)
|
||
#+END_SRC
|
||
|
||
This package allows for live-previewing the HTML export of an org
|
||
buffer in an XWidget Webkit browser window. But when testing it, it’s
|
||
not great for large org files, I should keep its usage for smaller org
|
||
files.
|
||
#+begin_src emacs-lisp
|
||
(use-package preview-org-html-mode
|
||
:defer t
|
||
:after (org)
|
||
:straight (preview-org-html-mode :build t
|
||
:type git
|
||
:host github
|
||
:repo "jakebox/preview-org-html-mode")
|
||
:general
|
||
(phundrak/major-leader-key
|
||
:keymaps 'org-mode-map
|
||
:packages 'preview-org-html-mode
|
||
:infix "P"
|
||
"" '(:ignore t :which-key "preview")
|
||
"h" #'preview-org-html-mode
|
||
"r" #'preview-org-html-refresh
|
||
"p" #'preview-org-html-pop-window-to-frame)
|
||
:config
|
||
(setq preview-org-html-refresh-configuration 'save))
|
||
#+end_src
|
||
|
||
*** Hugo
|
||
I manage [[https://blog.phundrak.com][my blog]] with [[https://gohugo.io/][Hugo]]. Although it natively supports the org
|
||
format, it’s not great compared to its markdown support. So, instead,
|
||
let’s directly export our org files as markdown files and let Hugo do
|
||
the rest of the job for us!
|
||
#+begin_src emacs-lisp
|
||
(use-package ox-hugo
|
||
:defer t
|
||
:after ox
|
||
:straight t)
|
||
#+end_src
|
||
|
||
I also have a function for publishing my blog once I exported my
|
||
articles with ~ox-hugo~. It will compile blog into a ~public/~ directory
|
||
and copy its content over to my remote server.
|
||
#+begin_src emacs-lisp
|
||
(defun phundrak/blog-publish ()
|
||
"Publish my blog through Hugo to my remote server."
|
||
(interactive)
|
||
(let* ((default-directory (expand-file-name "~/org/blog"))
|
||
(public-path (concat default-directory "/public"))
|
||
(target-path "/rsync:Tilo:/home/phundrak/www/phundrak.com/blog"))
|
||
(compile "hugo")
|
||
(let ((files (mapcar (lambda (file)
|
||
(f-relative file public-path))
|
||
(f-files public-path nil t))))
|
||
(dolist (file files)
|
||
(copy-file (concat public-path "/" file)
|
||
(concat target-path "/" file)
|
||
t nil t)))))
|
||
#+end_src
|
||
|
||
*** LaTeX
|
||
When it comes to exports, I want the LaTeX and PDF exports to be done
|
||
with XeTeX only. I also want LaTeX exports to use my labels rather
|
||
than org-generated labels.
|
||
#+NAME: org-latex-compiler
|
||
#+BEGIN_SRC emacs-lisp :tangle no
|
||
(setq org-latex-compiler "xelatex"
|
||
org-latex-prefer-user-labels t)
|
||
#+END_SRC
|
||
|
||
A new backend that was introduced in org-mode for LaTeX source block
|
||
coloring is ~engraved~.
|
||
#+BEGIN_SRC emacs-lisp
|
||
(use-package engrave-faces
|
||
:straight (:build t))
|
||
#+END_SRC
|
||
|
||
#+name: org-latex-src-block-backend
|
||
#+begin_src emacs-lisp :tangle no
|
||
(require 'engrave-faces)
|
||
(setq org-latex-src-block-backend 'engraved)
|
||
#+end_src
|
||
|
||
The default packages break my LaTeX exports: for some reason, images
|
||
are not loaded and exported in PDFs, so I needed to redefine the
|
||
default packages excluding the one that broke my exports; namely, I
|
||
need to remove ~inputenc~, ~fontenc~ and ~grffile~. I also added some
|
||
default packages:
|
||
- ~cleveref~ for better references to various elements.
|
||
- ~svg~ for inserting SVG files in PDF outputs
|
||
- ~booktabs~ for nicer tables
|
||
- and ~tabularx~ for tabulars with adjustable columns
|
||
#+NAME: org-latex-default-packages
|
||
#+BEGIN_SRC emacs-lisp :tangle no
|
||
(dolist (package '(("AUTO" "inputenc" t ("pdflatex"))
|
||
("T1" "fontenc" t ("pdflatex"))
|
||
("" "grffile" t)))
|
||
(delete package org-latex-default-packages-alist))
|
||
|
||
(dolist (package '(("AUTO" "babel" nil ("pdflatex"))
|
||
("AUTO" "polyglossia" nil ("xelatex" "lualatex"))
|
||
("capitalize" "cleveref")
|
||
("" "booktabs")
|
||
("" "tabularx")))
|
||
(add-to-list 'org-latex-default-packages-alist package t))
|
||
|
||
(setq org-latex-reference-command "\\cref{%s}")
|
||
#+END_SRC
|
||
|
||
By the way, reference links in LaTeX should be written in this format,
|
||
since we are using ~cleveref~:
|
||
#+NAME: org-export-latex-hyperref-format
|
||
#+BEGIN_SRC emacs-lisp :tangle no
|
||
(setq org-export-latex-hyperref-format "\\ref{%s}")
|
||
#+END_SRC
|
||
|
||
[[https://tectonic-typesetting.github.io/en-US/][Tectonic]] is awesome for processing LaTeX documents! Look how simple it
|
||
is!
|
||
#+NAME: org-latex-pdf-process
|
||
#+BEGIN_SRC emacs-lisp :tangle no
|
||
(setq org-latex-pdf-process
|
||
'("tectonic -Z shell-escape --synctex --outdir=%o %f"))
|
||
#+END_SRC
|
||
|
||
Finally, org-mode is supposed to automatically clean logfiles after it
|
||
exports an org file to LaTeX. However, it misses a few, so I need to
|
||
add their extension like so:
|
||
#+name: org-latex-logfiles-add-extensions
|
||
#+begin_src emacs-lisp :tangle no
|
||
(dolist (ext '("bbl" "lot"))
|
||
(add-to-list 'org-latex-logfiles-extensions ext t))
|
||
#+end_src
|
||
|
||
*** Reveal.js
|
||
#+NAME: org-re-reveal
|
||
#+begin_src emacs-lisp
|
||
(use-package org-re-reveal
|
||
:defer t
|
||
:after org
|
||
:straight (:build t)
|
||
:init
|
||
(add-hook 'org-mode-hook (lambda () (require 'org-re-reveal)))
|
||
:config
|
||
(setq org-re-reveal-root "https://cdn.jsdelivr.net/npm/reveal.js"
|
||
org-re-reveal-revealjs-version "4"))
|
||
#+end_src
|
||
|
||
*** SSH Config
|
||
Yet another exporter I enjoy is [[https://github.com/dantecatalfamo/ox-ssh][~ox-ssh~]] with which I manage my
|
||
~$HOME/.ssh/config~ file. You won’t find my org file for managing my
|
||
servers on my repos though.
|
||
#+begin_src emacs-lisp
|
||
(use-package ox-ssh
|
||
:after (ox org)
|
||
:straight (:build t))
|
||
#+end_src
|
||
|
||
** Keybindings
|
||
Be prepared, I have a lot of keybindings for org-mode! They are all
|
||
prefixed with a comma ~,~ in normal mode.
|
||
#+name: org-keybinds-various
|
||
| Key chord | Function | Description |
|
||
|-----------+---------------------+-------------|
|
||
| RET | org-ctrl-c-ret | |
|
||
| * | org-ctrl-c-star | |
|
||
| , | org-ctrl-c-ctrl-c | |
|
||
| ' | org-edit-special | |
|
||
| - | org-ctrl-c-minus | |
|
||
| a | org-agenda | |
|
||
| c | org-capture | |
|
||
| C | org-columns | |
|
||
| e | org-export-dispatch | |
|
||
| l | org-store-link | |
|
||
| p | org-priority | |
|
||
| r | org-reload | |
|
||
|
||
I then have a couple of babel-related functions.
|
||
#+name: org-keybinds-babel
|
||
| Key chord | Function | Description |
|
||
|-----------+-------------------------------------+-------------|
|
||
| b | nil | babel |
|
||
| b. | org-babel-transient/body | |
|
||
| bb | org-babel-execute-buffer | |
|
||
| bc | org-babel-check-src-block | |
|
||
| bC | org-babel-tangle-clean | |
|
||
| be | org-babel-execute-maybe | |
|
||
| bf | org-babel-tangle-file | |
|
||
| bn | org-babel-next-src-block | |
|
||
| bo | org-babel-open-src-block-result | |
|
||
| bp | org-babel-previous-src-block | |
|
||
| br | org-babel-remove-result-one-or-many | |
|
||
| bR | org-babel-goto-named-result | |
|
||
| bt | org-babel-tangle | |
|
||
| bi | org-babel-view-src-block-info | |
|
||
|
||
The ~org-babel-transient~ hydra allows me to quickly navigate between
|
||
code blocks and interact with them. This code block was inspired by
|
||
one you can find in Spacemacs.
|
||
#+name: org-hydra-babel
|
||
#+begin_src emacs-lisp :tangle no
|
||
(defhydra org-babel-transient ()
|
||
"
|
||
^Navigate^ ^Interact
|
||
^^^^^^^^^^^------------------------------------------
|
||
[_t_/_s_] navigate src blocs [_x_] execute src block
|
||
[_g_]^^ goto named block [_'_] edit src block
|
||
[_z_]^^ recenter screen [_q_] quit
|
||
"
|
||
("q" nil :exit t)
|
||
("t" org-babel-next-src-block)
|
||
("s" org-babel-previous-src-block)
|
||
("g" org-babel-goto-named-src-block)
|
||
("z" recenter-top-bottom)
|
||
("x" org-babel-execute-maybe)
|
||
("'" org-edit-special :exit t))
|
||
#+end_src
|
||
|
||
We next have keybindings related to org-mode’s agenda capabilities. We
|
||
can schedule a todo header for some dates, or set a deadline.
|
||
#+name: org-keybinds-dates
|
||
| Key chord | Function | Description |
|
||
|-----------+-------------------------+-------------|
|
||
| d | nil | dates |
|
||
| dd | org-deadline | |
|
||
| ds | org-schedule | |
|
||
| dt | org-time-stamp | |
|
||
| dT | org-time-stamp-inactive | |
|
||
|
||
Let’s now define some keybinds for inserting stuff in our org buffer:
|
||
#+name: org-keybinds-insert
|
||
| Key chord | Function | Description |
|
||
|-----------+-------------------------------+-------------|
|
||
| i | nil | insert |
|
||
| ib | org-insert-structure-template | |
|
||
| id | org-insert-drawer | |
|
||
| ie | nil | emphasis |
|
||
| ieb | org-emphasize-bold | |
|
||
| iec | org-emphasize-code | |
|
||
| iei | org-emphasize-italic | |
|
||
| ies | org-emphasize-strike-through | |
|
||
| ieu | org-emphasize-underline | |
|
||
| iev | org-emphasize-verbatim | |
|
||
| iE | org-set-effort | |
|
||
| if | org-footnote-new | |
|
||
| ih | org-insert-heading | |
|
||
| iH | counsel-org-link | |
|
||
| ii | org-insert-item | |
|
||
| il | org-insert-link | |
|
||
| in | org-add-note | |
|
||
| ip | org-set-property | |
|
||
| is | org-insert-subheading | |
|
||
| it | org-set-tags-command | |
|
||
|
||
There isn’t a lot of stuff I can jump to yet, but there’s still some:
|
||
#+name: org-keybinds-jump
|
||
| Key chord | Function | Description |
|
||
|-----------+----------------------+-------------|
|
||
| j | nil | jump |
|
||
| ja | counsel-org-goto-all | |
|
||
| jh | counsel-org-goto | |
|
||
|
||
Tables get a bit more love:
|
||
#+name: org-keybinds-tables
|
||
| Key chord | Function | Description |
|
||
|-----------+--------------------------------------+-------------|
|
||
| t | nil | tables |
|
||
| tc | org-table-move-column-left | |
|
||
| tt | org-table-move-row-down | |
|
||
| ts | org-table-move-row-up | |
|
||
| tr | org-table-move-column-right | |
|
||
| ta | org-table-align | |
|
||
| te | org-table-eval-formula | |
|
||
| tf | org-table-field-info | |
|
||
| tF | org-table-edit-formulas | |
|
||
| th | org-table-convert | |
|
||
| tl | org-table-recalculate | |
|
||
| tp | org-plot/gnuplot | |
|
||
| tS | org-table-sort-lines | |
|
||
| tw | org-table-wrap-region | |
|
||
| tx | org-table-shrink | |
|
||
| tN | org-table-create-with-table.el | |
|
||
| td | nil | delete |
|
||
| tdc | org-table-delete-column | |
|
||
| tdr | org-table-kill-row | |
|
||
| ti | nil | insert |
|
||
| tic | org-table-insert-column | |
|
||
| tih | org-table-insert-hline | |
|
||
| tir | org-table-insert-row | |
|
||
| tiH | org-table-hline-and-move | |
|
||
| tt | nil | toggle |
|
||
| ttf | org-table-toggle-formula-debugger | |
|
||
| tto | org-table-toggle-coordinate-overlays | |
|
||
|
||
Finally, let’s make enabling and disabling stuff accessible:
|
||
#+name: org-keybinds-toggles
|
||
| Key chord | Function | Description |
|
||
|-----------+--------------------------------------+-------------|
|
||
| T | nil | toggle |
|
||
| Tc | org-toggle-checkbox | |
|
||
| Ti | org-toggle-inline-images | |
|
||
| Tl | org-latex-preview | |
|
||
| Tn | org-num-mode | |
|
||
| Ts | phundrak/toggle-org-src-window-split | |
|
||
| Tt | org-show-todo-tree | |
|
||
| TT | org-todo | |
|
||
|
||
** LaTeX formats
|
||
:PROPERTIES:
|
||
:header-args:emacs-lisp: :tangle no :exports code :results silent
|
||
:END:
|
||
I currently have two custom formats for my Org-mode exports: one for
|
||
general use (initially for my conlanging files, hence its ~conlang~
|
||
name), and one for beamer exports.
|
||
|
||
Below is the declaration of the ~conlang~ LaTeX class:
|
||
#+NAME: org-latex-class-conlang
|
||
#+BEGIN_SRC emacs-lisp
|
||
'("conlang"
|
||
"\\documentclass{book}"
|
||
("\\chapter{%s}" . "\\chapter*{%s}")
|
||
("\\section{%s}" . "\\section*{%s}")
|
||
("\\subsection{%s}" . "\\subsection*{%s}")
|
||
("\\subsubsection{%s}" . "\\subsubsection*{%s}"))
|
||
#+END_SRC
|
||
|
||
And here is the declaration of the ~beamer~ class:
|
||
#+NAME: org-latex-class-beamer
|
||
#+BEGIN_SRC emacs-lisp
|
||
`("beamer"
|
||
,(concat "\\documentclass[presentation]{beamer}\n"
|
||
"[DEFAULT-PACKAGES]"
|
||
"[PACKAGES]"
|
||
"[EXTRA]\n")
|
||
("\\section{%s}" . "\\section*{%s}")
|
||
("\\subsection{%s}" . "\\subsection*{%s}")
|
||
("\\subsubsection{%s}" . "\\subsubsection*{%s}"))
|
||
#+END_SRC
|
||
|
||
Both these classes have to be added to ~org-latex-classes~ like so:
|
||
#+NAME: org-latex-classes
|
||
#+BEGIN_SRC emacs-lisp :noweb yes
|
||
(eval-after-load "ox-latex"
|
||
'(progn
|
||
(add-to-list 'org-latex-classes
|
||
<<org-latex-class-conlang>>)
|
||
(add-to-list 'org-latex-classes
|
||
<<org-latex-class-beamer>>)))
|
||
#+END_SRC
|
||
|
||
** Projects
|
||
:PROPERTIES:
|
||
:header-args:emacs-lisp: :tangle no :exports code :results silent
|
||
:END:
|
||
Another great features of Org-mode is the Org projects that allow the user to
|
||
easily publish a bunch of org files to a remote location. Here is the current
|
||
declaration of my projects, which will be detailed later:
|
||
#+NAME: org-publish-projects
|
||
#+BEGIN_SRC emacs-lisp :noweb yes :noweb-prefix no
|
||
<<org-proj-config-setup>>
|
||
(setq org-publish-project-alist
|
||
`(<<org-proj-config-html>>
|
||
<<org-proj-config-static>>
|
||
<<org-proj-config>>))
|
||
#+END_SRC
|
||
|
||
*** Configuration website
|
||
This is my configuration for exporting my dotfiles to my website in a web format
|
||
only. No PDFs or anything, just HTML. Please note that I do not use that often
|
||
anymore, I much prefer the automatic script that I have which deploys through my
|
||
Drone instance my website on git pushes.
|
||
|
||
And before we get into the actual configuration, I would like to introduce a
|
||
couple of variables. This is a bit more verbose than if I declared everything
|
||
manually, but now I can change all three values at the same time without a
|
||
hasle.
|
||
#+NAME: org-proj-config-setup
|
||
#+BEGIN_SRC emacs-lisp
|
||
(defvar phundrak//projects-config-target
|
||
"/ssh:Tilo:~/www/phundrak.com/config"
|
||
"Points to where exported files for config.phundrak.com should be put.")
|
||
(defvar phundrak//projects-config-source
|
||
"~/org/config/"
|
||
"Points to where the sources for config.phundrak.com are.")
|
||
(defvar phundrak//projects-config-language
|
||
"en"
|
||
"Language of the website config.phundrak.com.")
|
||
(defvar phundrak//projects-config-recursive
|
||
t
|
||
"Defines whether subdirectories should be parsed for config.phundrak.com.")
|
||
#+END_SRC
|
||
|
||
Now, here is my configuration. In this snippet, my org files located in my
|
||
source directory get exported in the HTML format and published to my target
|
||
directory on my remote server through RSYNC via TRAMP. A sitemap is
|
||
automatically generated, which comes in handy with the online sitemap that is
|
||
available through the navigation bar.
|
||
#+NAME: org-proj-config-html
|
||
#+BEGIN_SRC emacs-lisp
|
||
("config-website-html"
|
||
:base-directory ,phundrak//projects-config-source
|
||
:base-extension "org"
|
||
:publishing-directory ,phundrak//projects-config-target
|
||
:recursive ,phundrak//projects-config-recursive
|
||
:language ,phundrak//projects-config-language
|
||
:publishing-function org-html-publish-to-html
|
||
:headline-levels 5
|
||
:auto-sitemap t
|
||
:auto-preamble t)
|
||
#+END_SRC
|
||
|
||
We also have the component for all the static files needed to run the website
|
||
(mostly images tbh).
|
||
#+NAME: org-proj-config-static
|
||
#+BEGIN_SRC emacs-lisp
|
||
("config-website-static"
|
||
:base-directory ,phundrak//projects-config-source
|
||
:base-extension "png\\|jpg\\|gif\\|webp\\|svg\\|jpeg\\|ttf\\|woff\\|txt\\|epub\\|md"
|
||
:publishing-directory ,phundrak//projects-config-target
|
||
:recursive ,phundrak//projects-config-recursive
|
||
:language ,phundrak//projects-config-language
|
||
:publishing-function org-publish-attachment)
|
||
#+END_SRC
|
||
|
||
The project is then defined like so:
|
||
#+NAME: org-proj-config
|
||
#+BEGIN_SRC emacs-lisp
|
||
("config-website"
|
||
:components ("config-website-org"
|
||
"config-website-static"))
|
||
#+END_SRC
|
||
|
||
** Org-roam
|
||
After hearing about it for so many years and thinking I really should
|
||
install it one day, 2023 is finally the year I installed org-roam! For
|
||
those unaware of it, org-roam is a Zettelkasten-style knowledge
|
||
management system based on org-mode.
|
||
|
||
#+begin_src emacs-lisp
|
||
(use-package org-roam
|
||
:straight (:build t)
|
||
:defer t
|
||
:custom
|
||
(org-roam-directory (expand-file-name "org/roam/" (getenv "HOME")))
|
||
(org-roam-completion-everywhere t)
|
||
:config
|
||
(org-roam-db-autosync-mode 1)
|
||
:general
|
||
(phundrak/leader-key
|
||
:packages '(org org-roam)
|
||
:infix "o"
|
||
"r" '(:ignore t :which-key "roam")
|
||
"rb" '(org-mark-ring-goto :which-key "back")
|
||
"rB" #'org-roam-buffer-toggle
|
||
"rn" '(:ignore t :which-key "nodes")
|
||
"rnf" #'org-roam-node-find
|
||
"rni" #'org-roam-node-insert
|
||
"rno" #'org-roam-node-open
|
||
"rnr" #'org-roam-node-random
|
||
"rnv" #'org-roam-node-visit
|
||
"rs" '(:ignore t :which-key "sync")
|
||
"rsa" #'org-roam-db-autosync-mode
|
||
"rsc" #'org-roam-db-clear-all
|
||
"rsd" #'org-roam-db-diagnose-node
|
||
"rss" #'org-roam-db-sync
|
||
"ru" '(:ignore t :which-key "ui")
|
||
"rua" #'org-roam-ui-add-to-local-graph
|
||
"ruo" #'org-roam-ui-open)
|
||
(phundrak/major-leader-key
|
||
:keymaps 'org-mode-map
|
||
:packages '(org org-roam)
|
||
"h" #'org-id-get-create
|
||
"r" '(:ignore t :which-key "roam")
|
||
"ra" '(:ignore t :which-key "alias")
|
||
"raa" #'org-roam-alias-add
|
||
"rar" #'org-roam-alias-remove))
|
||
#+end_src
|
||
|
||
#+begin_src emacs-lisp
|
||
(use-package org-roam-ui
|
||
:straight (:build t)
|
||
:defer t
|
||
:after org-roam
|
||
:config
|
||
(setq org-roam-ui-sync-theme t
|
||
org-roam-ui-follow t
|
||
org-roam-ui-update-on-save t
|
||
org-roam-ui-open-on-start t))
|
||
#+end_src
|
||
|
||
** Org-ref and Bibtex configuration
|
||
#+begin_src emacs-lisp
|
||
(use-package reftex
|
||
:commands turn-on-reftex
|
||
:init (setq reftex-default-bibliography "~/org/bibliography/references.bib"
|
||
reftex-plug-into-AUCTeX t))
|
||
#+end_src
|
||
|
||
#+begin_src emacs-lisp
|
||
(use-package org-ref
|
||
;; :after (org ox-bibtex pdf-tools)
|
||
:after org
|
||
:defer t
|
||
:straight (:build t)
|
||
:custom-face
|
||
(org-ref-cite-face ((t (:weight bold))))
|
||
:init
|
||
(setq org-ref-completion-library 'org-ref-ivy-cite
|
||
org-latex-logfiles-extensions '("lof" "lot" "aux" "idx" "out" "log" "fbd_latexmk"
|
||
"toc" "nav" "snm" "vrb" "dvi" "blg" "brf" "bflsb"
|
||
"entoc" "ps" "spl" "bbl" "pygtex" "pygstyle"))
|
||
(add-hook 'org-mode-hook (lambda () (require 'org-ref)))
|
||
:config
|
||
(setq bibtex-completion-pdf-field "file"
|
||
bibtex-completion-notes-path "~/org/bibliography/notes/"
|
||
bibtex-completion-bibliography "~/org/bibliography/references.bib"
|
||
bibtex-completion-library-path "~/org/bibliography/bibtex-pdfs/"
|
||
bibtex-completion-pdf-symbol "⌘"
|
||
bibtex-completion-notes-symbol "✎")
|
||
:general
|
||
(phundrak/evil
|
||
:keymaps 'bibtex-mode-map
|
||
:packages 'org-ref
|
||
"C-t" #'org-ref-bibtex-next-entry
|
||
"C-s" #'org-ref-bibtex-previous-entry
|
||
"gt" #'org-ref-bibtex-next-entry
|
||
"gs" #'org-ref-bibtex-previous-entry)
|
||
(phundrak/major-leader-key
|
||
:keymaps '(bibtex-mode-map)
|
||
:packages 'org-ref
|
||
;; Navigation
|
||
"t" #'org-ref-bibtex-next-entry
|
||
"s" #'org-ref-bibtex-previous-entry
|
||
|
||
;; Open
|
||
"b" #'org-ref-open-in-browser
|
||
"n" #'org-ref-open-bibtex-notes
|
||
"p" #'org-ref-open-bibtex-pdf
|
||
|
||
;; Misc
|
||
"h" #'org-ref-bibtex-hydra/body
|
||
"i" #'org-ref-bibtex-hydra/org-ref-bibtex-new-entry/body-and-exit
|
||
"s" #'org-ref-sort-bibtex-entry
|
||
|
||
"l" '(:ignore t :which-key "lookup")
|
||
"la" #'arxiv-add-bibtex-entry
|
||
"lA" #'arxiv-get-pdf-add-bibtex-entry
|
||
"ld" #'doi-utils-add-bibtex-entry-from-doi
|
||
"li" #'isbn-to-bibtex
|
||
"lp" #'pubmed-insert-bibtex-from-pmid)
|
||
(phundrak/major-leader-key
|
||
:keymaps 'org-mode-map
|
||
:pakages 'org-ref
|
||
"ic" #'org-ref-insert-link
|
||
"iL" #'org-ref-insert-ref-link
|
||
"ir" #'org-ref-insert-link-hydra/body
|
||
"iB" #'org-ref-bibtex-hydra/body))
|
||
#+end_src
|
||
|
||
#+begin_src emacs-lisp
|
||
(use-package ivy-bibtex
|
||
:defer t
|
||
:straight (:build t)
|
||
:config
|
||
(setq bibtex-completion-pdf-open-function #'find-file)
|
||
:general
|
||
(phundrak/leader-key
|
||
:keymaps '(bibtex-mode-map)
|
||
:packages 'ivy-bibtex
|
||
"m" #'ivy-bibtex))
|
||
#+end_src
|
||
|
||
** Org-present
|
||
~org-present~ allows its user to create presentations through ~org-mode~,
|
||
which is really nice! However, most of my configuration will be stolen
|
||
[[https://config.daviwil.com/emacs#org-present][from Daviwil’s]] with minor changes.
|
||
#+begin_src emacs-lisp
|
||
(defun my/org-present-prepare-slide ()
|
||
(org-overview)
|
||
(org-show-entry)
|
||
(org-show-children)
|
||
(org-present-hide-cursor))
|
||
|
||
(defun my/org-present-init ()
|
||
(setq header-line-format " ")
|
||
(org-display-inline-images)
|
||
(my/org-present-prepare-slide))
|
||
|
||
(defun my/org-present-quit ()
|
||
(setq header-line-format nil)
|
||
(org-present-small)
|
||
(org-present-show-cursor))
|
||
|
||
(defun my/org-present-prev ()
|
||
(interactive)
|
||
(org-present-prev)
|
||
(my/org-present-prepare-slide))
|
||
|
||
(defun my/org-present-next ()
|
||
(interactive)
|
||
(org-present-next)
|
||
(my/org-present-prepare-slide))
|
||
|
||
(use-package org-present
|
||
:after org
|
||
:defer t
|
||
:straight (:build t)
|
||
:general
|
||
(phundrak/major-leader-key
|
||
:packages 'org-present
|
||
:keymaps 'org-mode-map
|
||
"P" #'org-present)
|
||
(phundrak/evil
|
||
:states 'normal
|
||
:packages 'org-present
|
||
:keymaps 'org-present-mode-keymap
|
||
"+" #'org-present-big
|
||
"-" #'org-present-small
|
||
"<" #'org-present-beginning
|
||
">" #'org-present-end
|
||
"«" #'org-present-beginning
|
||
"»" #'org-present-end
|
||
"c" #'org-present-hide-cursor
|
||
"C" #'org-present-show-cursor
|
||
"n" #'org-present-next
|
||
"p" #'org-present-prev
|
||
"r" #'org-present-read-only
|
||
"w" #'org-present-read-write
|
||
"q" #'org-present-quit)
|
||
:hook ((org-present-mode . my/org-present-init)
|
||
(org-present-mode-quit . my/org-present-quit)))
|
||
#+end_src
|
||
|
||
** Visual Configuration
|
||
While most modes of Emacs are dedicated to development, and therefore
|
||
are much more comfortable with a fixed-pitch font, more literary modes
|
||
such as org-mode are much more enjoyable if you have a variable pitch
|
||
font enabled. *BUT*, these modes can also require some fixed-pitch fonts
|
||
for some elements of the buffer, such as code blocks with
|
||
org-mode. ~mixed-pitch~ comes to the rescue!
|
||
#+begin_src emacs-lisp
|
||
(use-package mixed-pitch
|
||
:after org
|
||
:straight (:build t)
|
||
:hook
|
||
(org-mode . mixed-pitch-mode)
|
||
(emms-browser-mode . mixed-pitch-mode)
|
||
(emms-playlist-mode . mixed-pitch-mode)
|
||
:config
|
||
(add-hook 'org-agenda-mode-hook (lambda () (mixed-pitch-mode -1))))
|
||
#+end_src
|
||
|
||
I have an issue with org-mode’s emphasis markers: I find them ugly. I
|
||
can of course hide them if I simply set ~org-hide-emphasis-markers~ to
|
||
~t~, but it makes editing hard since I never know whether I am before or
|
||
after the emphasis marker when editing near the beginning/end of an
|
||
emphasized region. ~org-appear~ fixes this issue so that it shows the
|
||
emphasis markers only when the cursor is in the emphasized region,
|
||
otherwise they will remain hidden! Very cool!
|
||
#+begin_src emacs-lisp
|
||
(use-package org-appear
|
||
:after org
|
||
:straight (:build t)
|
||
:hook (org-mode . org-appear-mode)
|
||
:config
|
||
(setq org-appear-autoemphasis t
|
||
org-hide-emphasis-markers t
|
||
org-appear-autolinks t
|
||
org-appear-autoentities t
|
||
org-appear-autosubmarkers t)
|
||
(run-at-time nil nil #'org-appear--set-elements))
|
||
#+end_src
|
||
|
||
Similarly, LaTeX fragments previews are nice and all, but if I have my
|
||
cursor on it, I want to see the LaTeX source code and modify it, not
|
||
just the generated image!
|
||
#+begin_src emacs-lisp
|
||
(use-package org-fragtog
|
||
:defer t
|
||
:after org
|
||
:straight (:build t)
|
||
:hook (org-mode . org-fragtog-mode))
|
||
#+end_src
|
||
|
||
Org-modern modernizes a bit the appearance of org buffers, including
|
||
tables, source blocks, and tags, and it applies settings similar to
|
||
~org-superstar~ which I used to use.
|
||
#+begin_src emacs-lisp
|
||
(use-package org-modern
|
||
:straight (:build t)
|
||
:after org
|
||
:defer t
|
||
:custom (org-modern-table nil)
|
||
:hook (org-mode . org-modern-mode)
|
||
:hook (org-agenda-finalize . org-modern-agenda))
|
||
#+end_src
|
||
~org-fancy-priorities~ change the priority of an org element such as ~#A~
|
||
to anything user-defined. Let’s all-the-iconify this!
|
||
#+begin_src emacs-lisp
|
||
(use-package org-fancy-priorities
|
||
:after (org all-the-icons)
|
||
:straight (:build t)
|
||
:hook (org-mode . org-fancy-priorities-mode)
|
||
:hook (org-agenda-mode . org-fancy-priorities-mode)
|
||
:config
|
||
(setq org-fancy-priorities-list `(,(all-the-icons-faicon "flag" :height 1.1 :v-adjust 0.0)
|
||
,(all-the-icons-faicon "arrow-up" :height 1.1 :v-adjust 0.0)
|
||
,(all-the-icons-faicon "square" :height 1.1 :v-adjust 0.0))))
|
||
#+end_src
|
||
/Org Outline Tree/ is a better way of managing my org files’ outline.
|
||
#+begin_src emacs-lisp
|
||
(use-package org-ol-tree
|
||
:after (org avy)
|
||
:defer t
|
||
:straight (org-ol-tree :build t
|
||
:host github
|
||
:type git
|
||
:repo "Townk/org-ol-tree")
|
||
:general
|
||
(phundrak/major-leader-key
|
||
:packages 'org-ol-tree
|
||
:keymaps 'org-mode-map
|
||
"O" #'org-ol-tree))
|
||
#+end_src
|
||
|
||
#+name: org-mode-visual-prettify-symbols
|
||
#+begin_src emacs-lisp
|
||
(add-hook 'org-mode-hook
|
||
(lambda ()
|
||
(dolist (pair '(("[ ]" . ?☐)
|
||
("[X]" . ?☑)
|
||
("[-]" . ?❍)
|
||
("#+title:" . ?📕)
|
||
("#+TITLE:" . ?📕)
|
||
("#+author:" . ?✎)
|
||
("#+AUTHOR:" . ?✎)
|
||
("#+email:" . ?📧)
|
||
("#+EMAIL:" . ?📧)
|
||
("#+include" . ?⭳)
|
||
("#+INCLUDE" . ?⭳)
|
||
("#+begin_src" . ?λ)
|
||
("#+BEGIN_SRC" . ?λ)
|
||
("#+end_src" . ?λ)
|
||
("#+END_SRC" . ?λ)))
|
||
(add-to-list 'prettify-symbols-alist pair))
|
||
(prettify-symbols-mode)))
|
||
#+end_src
|
||
|
||
** Misc
|
||
~org-tree-slide~ is a presentation tool for org-mode.
|
||
#+begin_src emacs-lisp
|
||
(use-package org-tree-slide
|
||
:defer t
|
||
:after org
|
||
:straight (:build t)
|
||
:config
|
||
(setq org-tree-slide-skip-done nil)
|
||
:general
|
||
(phundrak/evil
|
||
:keymaps 'org-mode-map
|
||
:packages 'org-tree-slide
|
||
"<f8>" #'org-tree-slide-mode)
|
||
(phundrak/major-leader-key
|
||
:keymaps 'org-tree-slide-mode-map
|
||
:packages 'org-tree-slide
|
||
"d" (lambda () (interactive (setq org-tree-slide-skip-done (not org-tree-slide-skip-done))))
|
||
"p" #'org-tree-slide-move-next-tree
|
||
"n" #'org-tree-slide-move-previous-tree
|
||
"t" #'org-tree-slide-move-next-tree
|
||
"s" #'org-tree-slide-move-previous-tree
|
||
"u" #'org-tree-slide-content))
|
||
#+end_src
|
||
~org-roll~ is a simple package for tabletop RPGs for rolling dice.
|
||
#+begin_src emacs-lisp
|
||
(use-package org-roll
|
||
:defer t
|
||
:after org
|
||
:straight (:build t :type git :host github :repo "zaeph/org-roll"))
|
||
#+end_src
|