Emacs configuration for writing

(quail-set-keyboard-layout "jp106")

1. Emacs native configuration

1.1. UI

1.1.1. Disable unnecessary UIs

(tool-bar-mode -1)
(menu-bar-mode -1)
(scroll-bar-mode -1)
(setq inhibit-startup-message t)

1.1.2. fill-column

(setq-default fill-column 79)
(global-display-fill-column-indicator-mode 1)

1.1.3. Fringe

(set-fringe-mode 0)

1.1.4. Line numbering

(global-display-line-numbers-mode t)
(global-set-key (kbd "M-o l") 'display-line-numbers-mode)
(global-set-key (kbd "M-o L") 'global-display-line-numbers-mode)

1.1.5. Line wrapping

(global-visual-line-mode t)

1.1.6. Cursor

(global-hl-line-mode 1)
(blink-cursor-mode -1)

1.1.7. tab-width

(setq-default tab-width 2)
(setq-default indent-tabs-mode nil)
(setq-default c-basic-offset 2)

1.1.8. column-number

(setq column-number-indicator-zero-based nil)
(column-number-mode t)

1.2. Behaviour

1.2.1. savehist

(savehist-mode 1)

1.2.2. Backups and lockfiles

(setq backup-directory-alist '(("." . "~/.cache/emacs/")))

(setq backup-inhibited t)
(setq make-backup-files nil)
(setq auto-save-visited-interval 2)
(auto-save-visited-mode)

(setq create-lockfiles nil)
(setq kill-buffer-delete-auto-save-files t)

1.2.3. window

(setq window-min-height 5)
  1. Interactive toggle functions
    (defun window-toggle-no-delete-other-windows ()
      (interactive)
      (if (window-parameter (selected-window) 'no-delete-other-windows)
          (progn (set-window-parameter (selected-window) 'no-delete-other-windows nil)
                 (message "Set `no-delete-other-windows' to nil"))
        (progn (set-window-parameter (selected-window) 'no-delete-other-windows t)
               (message "Set `no-delete-other-windows' to t"))))
    
    (defun window-toggle-no-other-windows ()
      (interactive)
      (if (window-parameter (selected-window) 'no-other-windows)
          (progn (set-window-parameter (selected-window) 'no-other-windows nil)
                 (message "Set `no-other-windows' to nil"))
        (progn (set-window-parameter (selected-window) 'no-other-windows t)
               (message "Set `no-other-windows' to t"))))
    
    (global-set-key (kbd "C-x w k") 'window-toggle-no-delete-other-windows)
    (global-set-key (kbd "C-x w o") 'window-toggle-no-other-windows)
    

1.2.4. Terminal mouse support

(unless (display-graphic-p)
  (xterm-mouse-mode 1))

1.3. Personal setups

1.3.1. Registers

(set-register ?i (cons 'file (file-truename "~/giabao.xyz/org/notes/emacs-configuration-for-writing.org")))
(global-set-key (kbd "C-c r") 'jump-to-register)

1.4. dired

(require 'dired)

(setq dired-dwim-target t)
(defun my/dired-mode-hook ()
  (display-line-numbers-mode -1)
        (display-fill-column-indicator-mode -1)
  (dired-hide-details-mode 1))

(add-hook 'dired-mode-hook #'my/dired-mode-hook)
(defun dired-recursive-toggle ()
  "Toggle the `-R' switch of `ls'."
  (interactive)
  (if (eq (dired-switches-recursive-p dired-actual-switches)
          nil)
      (dired-sort-other "-Rl")
    (dired-sort-other "-al")))

(define-key dired-mode-map (kbd "r") #'dired-recursive-toggle)

2. Convenience functions

2.1. zathura

(defvar zathura-found-service
  "Stores found Zathura session PID.")

(defun zathura--check-file-opened (file)
  (let* ((services (dbus-list-known-names :session))
         (zathura-services (seq-filter
                            (lambda (s)
                              (string-prefix-p "org.pwmt.zathura.PID-" s))
                            services)))
    (when zathura-services
      (setq zathura-found-service nil)
      (let ((zathura-services-matched
             (mapcar
              (lambda (service)
                (if (equal file (dbus-get-property :session service
                                                   "/org/pwmt/zathura"
                                                   "org.pwmt.zathura"
                                                   "filename"))
                    (setq zathura-found-service service)))
              zathura-services)))
        (when zathura-found-service
          (remove nil zathura-services-matched))))))

3. Packages

(require 'package)
(setq package-archives '(("gnu"    . "https://elpa.gnu.org/packages/")
                                                                                                 ("nongnu" . "https://elpa.nongnu.org/nongnu/")
                                                                                                 ("melpa"  . "https://melpa.org/packages/")))

(package-initialize)

(unless package-archive-contents
  (package-refresh-contents))

(require 'use-package)
(setq use-package-always-ensure t)

3.1. org-mode

(use-package org
  :vc (:url "https://code.tecosaur.net/tec/org-mode.git"
       :branch "dev"
       :lisp-dir "lisp"))

3.1.1. General setup

(setq org-special-ctrl-a/e t)
(setq org-hide-leading-stars nil)
(setq org-startup-indented t)
(setq org-use-tag-inheritance nil)
(setq org-tags-sort-function 'org-string-collate-lessp)
(setq org-tags-column 0)
(setq org-use-property-inheritance t)
(setq org-enforce-todo-dependencies t)
(setq org-deadline-warning-days 0)
(setq org-property-format "%-11s %s")
(setq org-highlight-latex-and-related '(native))
(setq org-file-apps
      '((auto-mode . emacs)
        ("\\.pdf\\'" . "zathura \"%s\"")))
(setq org-blank-before-new-entry
      '((heading . nil)
        (plain-list-item . nil)))

(setq org-list-allow-alphabetical 1)

3.1.2. org-id

(setq org-id-method 'ts
      org-id-ts-format "%Y%m%dT%H%M%S"
      org-id-link-to-org-use-id nil)

(defun my/org-heading-insert-id ()
  (interactive)
  (save-excursion
    (org-back-to-heading)
    (org-set-property "ID" (org-id-new))))

(define-key org-mode-map (kbd "M-o H") #'my/org-heading-insert-id)

;; (add-hook 'org-insert-heading-hook #'my/org-heading-insert-id)
(defun my/org-heading-kill-ring-save-id ()
  (interactive)
  (kill-new (org-entry-get (point) "ID" t)))

(define-key org-mode-map (kbd "M-o h") #'my/org-heading-kill-ring-save-id)
  1. Create and insert new id
    (defun my/org-insert-org-id-new-at-point ()
      (interactive)
      (insert (org-id-new)))
    
    (define-key org-mode-map (kbd "M-o i") #'my/org-insert-org-id-new-at-point)
    

3.1.3. General org-mode keybinds

3.1.4. org-num

(require 'org-num)

(setq org-num-skip-tags '("unnumbered"))
(setq org-num-skip-unnumbered t)
(define-key org-mode-map (kbd "M-o n") #'org-num-mode)
(defun my/org-num-format (numbering)
  (concat
   "["
   (apply 'concat
          (cl-loop for n in numbering
                   for i from 1 to (length numbering)
                   if (cl-oddp i) collect (number-to-string n)
                   else collect (downcase (org-number-to-letters n))))
   "] "))

(setq org-num-format-function #'my/org-num-format)

3.1.5. ol

(setq org-image-max-width 'fill-column)

(define-key org-mode-map (kbd "C-c l") #'org-store-link)
(define-key org-mode-map (kbd "M-o c") #'org-toggle-link-display)

3.1.6. org-fold

(define-key org-mode-map (kbd "M-o b") #'org-fold-hide-block-all)
(define-key org-mode-map (kbd "M-o d") #'org-fold-hide-drawer-all)
  1. Toggling headline content at current position

    https://emacs.stackexchange.com/questions/26827/test-whether-org-mode-heading-or-list-is-folded

    (defun my/org-headline-content-toggle ()
      (interactive)
      (if (eq
           (and (or (org-at-heading-p)
                    (org-at-item-p))
                (invisible-p (point-at-eol)))
           nil)
          (org-fold-hide-entry)
        (org-fold-show-entry)))
    
    (define-key org-mode-map (kbd "M-s") #'my/org-headline-content-toggle)
    

3.1.7. org-babel

(org-babel-do-load-languages
 'org-babel-load-languages
 '((emacs-lisp . t)
         (C . t)
   (sqlite . t)
   (shell . t)
   (latex . t)
   (matlab . t)
   (lua . t)
   (python . t)
   (gnuplot . t)))

3.1.8. org-cite

(require 'oc)

(setq org-cite-global-bibliography
      (mapcar 'file-truename
              (directory-files-recursively "~/documents/bibliographies/" "\\.bib$")))
(defun org-cite-basic--get-offset (citekey)
  (org-cite-basic--get-field 'offset citekey))

3.1.9. org-latex-preview

(setq org-latex-preview-process-default 'dvisvgm)

3.1.10. org-entities

(setq org-entities-user
      '(("bigl"  "\\bigl"  t "" "" "" "◔")
        ("Bigl"  "\\Bigl"  t "" "" "" "◑")
        ("biggl" "\\biggl" t "" "" "" "◕")
        ("Biggl" "\\Biggl" t "" "" "" "●")
        ("bigr"  "\\bigl"  t "" "" "" "◔")
        ("Bigr"  "\\Bigl"  t "" "" "" "◑")
        ("biggr" "\\biggl" t "" "" "" "◕")
        ("Biggr" "\\Biggl" t "" "" "" "●")))

(setq org-pretty-entities-include-sub-superscripts nil)
(add-hook 'org-mode-hook #'org-toggle-pretty-entities)

(defun my/prettify-symbols-setup-org ()
  (push '("[note:" . "[") prettify-symbols-alist)
  (push '("eqref" . "⮴") prettify-symbols-alist)
  (setq-local prettify-symbols-unprettify-at-point nil)
  (prettify-symbols-mode))

(add-hook 'org-mode-hook #'my/prettify-symbols-setup-org)
(global-set-key (kbd "M-o p") #'prettify-symbols-mode)

3.1.11. hook

(defun my/org-mode-hook ()
  (display-line-numbers-mode -1)
  (org-num-mode 1))

(add-hook 'org-mode-hook #'my/org-mode-hook)

3.2. org-visual-outline

(use-package org-visual-outline
  :vc (:url "https://github.com/legalnonsense/org-visual-outline.git"
       :branch "master"
       :rev :newest)
  :defer t
  :load-path (lambda () (expand-file-name "elpa/org-visual-outline" user-emacs-directory)))
(require 'org-visual-indent)

(defun org-visual-indent-apply ()
  (interactive)
  (progn
    (face-spec-set 'org-visual-indent-blank-pipe-face
                   `((t ( :foreground ,(face-background 'default)
                          :background ,(face-background 'default)
                          :height .1))))
    (setq org-visual-indent-color-indent
          (cl-loop for x from 1 to 8
                   with color = nil
                   do (setq color (or (face-foreground
                                       (intern 
                                        (concat "outline-"
                                                (number-to-string x))))
                                      (face-foreground 'org-level-1)))
                   collect `(,x ,(list
                                  :background color
                                  :foreground color
                                  :height .1))))
    (org-mode-restart)))

(add-hook 'org-mode-hook #'org-visual-indent-mode)
(require 'org-dynamic-bullets)

;; (setq org-dynamic-bullets-folded-body-text-bullet    "*")
;; (setq org-dynamic-bullets-folded-no-body-text-bullet   "*")
;; (setq org-dynamic-bullets-unfolded-body-text-bullet    "*")
;; (setq org-dynamic-bullets-unfolded-no-body-text-bullet "*")
;; (setq org-dynamic-bullets-leaf-body-text-bullet      "*")
;; (setq org-dynamic-bullets-leaf-no-body-text-bullet     "*")

(setq org-dynamic-bullets-folded-body-text-bullet       "▶"
      org-dynamic-bullets-folded-no-body-text-bullet    "▷"
      org-dynamic-bullets-unfolded-body-text-bullet     "▼"
      org-dynamic-bullets-unfolded-no-body-text-bullet  "▽"
      org-dynamic-bullets-leaf-body-text-bullet "▬"
      org-dynamic-bullets-leaf-no-body-text-bullet      "▭")

(add-hook 'org-mode-hook #'org-dynamic-bullets-mode)

3.3. org-mem

(use-package inspector)
(use-package emacsql)

(use-package org-mem)
(setq org-mem-watch-dirs '("~/giabao.xyz/org/")
      org-mem-do-sync-with-org-id t)
(org-mem-updater-mode)
(org-mem-roamy-db-mode)

3.4. org-node

(use-package org-node)
(org-node-cache-mode)

(setq org-node-backlink-drawer-formatter
      #'org-node-backlink-format-as-bullet-with-time)
(global-set-key (kbd "M-n n") 'org-node-find)
(define-key org-mode-map (kbd "M-n i") #'org-node-insert-link)
(defun org-node-time-stamp (with-time inactive &optional time zone)
  "Make a timestamp passing WITH-TIME, INACTIVE to `org-time-stamp-format'.
Pass TIME, ZONE to `format-time-string'."
  (format-time-string (org-time-stamp-format with-time inactive)
                      time zone))

(setq org-node-property-crtime "CREATED")
(setq org-node-property-mtime "MODIFIED")
(add-hook 'org-node-modification-hook
          #'org-node-update-mtime-property)
(defun org-node-backlink--fix-nearby-drawer (&optional remove)
  "Update nearby backlinks drawer so it reflects current reality.
If REMOVE non-nil, remove it instead."
  (if remove
      (org-node--delete-drawer "BACKLINKS")
    (let* ((id (org-entry-get nil "ID"))
           (entry (org-mem-entry-by-id id))
           (portal-ids (mapcar #'car
                               (emacsql (org-mem-roamy-db)
                                        [:select node_id
                                                 :from tags
                                                 :where (in tag $v1)]
                                        (vconcat org-excluded-tags))))
           (all-origin-ids (when entry
                         (thread-last
                           (append (org-mem-id-links-to-entry entry)
                                   (org-mem-roam-reflinks-to-entry entry))
                           (seq-keep #'org-mem-link-nearby-id)
                           (delete id)
                           (delete-dups)
                           ;; Shouldn't be necessary if tables are correct, but
                           ;; don't assume `org-mem-updater-mode' is flawless
                           (seq-filter #'org-mem-entry-by-id))))
           (origin-ids (seq-difference all-origin-ids portal-ids))
           (org-node-backlink--inhibit-flagging t))
      (if (null origin-ids)
          (org-node--delete-drawer "BACKLINKS")
        (save-excursion
          (save-restriction
            (org-node-narrow-to-drawer-create
             "BACKLINKS" org-node-backlink-drawer-positioner)
            (let* ((col (current-indentation))
                   (lines (split-string (buffer-string) "\n" t))
                   (already-present-ids
                    (seq-keep #'org-node-backlink--extract-id lines))
                   (to-add      (seq-difference   origin-ids already-present-ids))
                   (to-remove   (seq-difference   already-present-ids origin-ids))
                   (to-reformat (seq-intersection already-present-ids origin-ids)))
              ;; Add new, remove stale, reformat the rest
              (dolist (id to-remove)
                (save-excursion
                  (search-forward id)
                  (delete-line)))
              (dolist (id to-reformat)
                (save-excursion
                  (search-forward id)
                  (back-to-indentation)
                  (let* ((line (buffer-substring-no-properties (point) (pos-eol)))
                         (reformatted (org-node-backlink--reformat-line line)))
                    (unless (equal line reformatted)
                      (atomic-change-group
                        (delete-region (point) (pos-eol))
                        (insert reformatted))))))
              (dolist (id to-add)
                (let ((title (org-mem-title-maybe (org-mem-entry-by-id id))))
                  (insert (funcall org-node-backlink-drawer-formatter id title))
                  (newline)
                  (indent-to col)))
              ;; Membership is correct, now re-sort
              (let ((sorted-lines (sort (split-string (buffer-string) "\n" t)
                                        org-node-backlink-drawer-sorter)))
                (when org-node-backlink-drawer-sort-in-reverse
                  (setq sorted-lines (nreverse sorted-lines)))
                (unless (equal lines sorted-lines)
                  (atomic-change-group
                    (delete-region (point-min) (point-max))
                    (insert (string-join sorted-lines "\n"))))))))))))

3.5. tex-mode

(setq tex-fontify-script nil
      font-latex-fontify-script nil)

3.6. citar

(use-package citar)

(setq citar-bibliography org-cite-global-bibliography
      org-cite-insert-processor 'citar
      org-cite-follow-processor 'citar
      org-cite-activate-processor 'citar
      citar-library-paths-recursive t
      citar-library-paths '("~/documents/books/"
                            "~/documents/articles/"
                            "~/documents/other/")
      citar-notes-paths '("~/notes/bibliography/")
      citar-file-variable "file")

(setq citar-file-open-functions
        (list
         (cons "html" #'citar-file-open-external)
         (cons "pdf" #'citar-file-open-external)
         (cons "epub" #'citar-file-open-external)
         (cons "djvu" #'citar-file-open-external)
       (cons t #'find-file)))

(add-hook 'LaTeX-mode-hook #'citar-capf-setup)
(add-hook 'org-mode-hook #'citar-capf-setup)

(global-set-key (kbd "M-n o") #'citar-open)
(global-set-key (kbd "M-n c") #'citar-insert-citation)
(setq citar-templates
      '((main . "${date year issued}, ${author editor:%sn}, ${title}")
        (suffix . " (${=type=}) [${=key= id}] ${tags keywords keywords:*}")
        (preview . "${author editor:%etal} (${year issued date}) ${title}, ${journal journaltitle publisher container-title collection-title}.")
        (note . "Notes on ${author editor:%etal}, ${title}")))

3.6.1. Integrate with zathura

Integrate citar links with zathura. See 2.1. Open specified page in "p. page" of citar links in zathura.

(defun zathura-citar-parse-offset-string (offset-string)
  "Return a list of cons cells, where each cons cell is (PDF_PAGE . REAL_PAGE)."
  (let (parsed-labels)
    (dolist (pair-str (split-string offset-string "," t))
      (when (string-match "\\([0-9]+\\):\\([0-9]+\\)" pair-str)
        (let* ((pdf-page (string-to-number (match-string 1 pair-str)))
               (real-page (string-to-number (match-string 2 pair-str))))
          (push (cons pdf-page real-page) parsed-labels))))
    (sort parsed-labels (lambda (a b) (< (cdr a) (cdr b))))))
(defun zathura-citar-get-pdf-pagenumber-from-real-pagenumber (offset-string real-page-num)
  "Return pdf page number."
  (if (not (equal offset-string nil))
      (let* ((parsed-labels (zathura-citar-parse-offset-string offset-string))
             (best-match nil))
        (cl-block nil
          (dolist (segment parsed-labels)
            (let ((real-start (cdr segment)))
              (when (<= real-start real-page-num)
                (setq best-match segment))
              (when (and (> real-start real-page-num) best-match)
                (cl-return nil)))))
        (if best-match
            (let* ((pdf-start (car best-match))
                   (real-start (cdr best-match))
                   (offset (- real-page-num real-start)))
              (+ pdf-start offset))
          (progn
            (message "No mapping found for real page %d" real-page-num)
            nil)))
    (message "Offset string is nil.")
    nil))
(defun zathura-org-follow-cite-link-with-page-number-at-point ()
  (interactive)
  (thing-at-point-looking-at "@\\([a-z0-9-.]*\\) p\\. \\([0-9]*\\)\\(-[0-9]*\\)?")
  (let* ((citekey (org-match-string-no-properties 1))
         (page (string-to-number (org-match-string-no-properties 2)))
         (file (car (gethash citekey (citar-get-files citekey))))
         (offset (org-cite-basic--get-field 'offset citekey))
         (pagenumber (zathura-citar-get-pdf-pagenumber-from-real-pagenumber offset page))
         (zathura-selected-pid (car (zathura--check-file-opened file))))
    (if zathura-selected-pid
        (dbus-call-method :session
                          zathura-selected-pid
                          "/org/pwmt/zathura"
                          "org.pwmt.zathura"
                          "GotoPage"
                          :uint32 (1- pagenumber))
      (start-process "zathura-viewer" nil "zathura" file "-P" (number-to-string pagenumber)))))

(define-key org-mode-map (kbd "M-o f") #'zathura-org-follow-cite-link-with-page-number-at-point)

3.7. AUCTeX and CDLaTeX

(use-package auctex)
(use-package cdlatex)
(add-hook 'org-mode-hook #'org-cdlatex-mode)
(setq cdlatex-insert-auto-labels-in-env-templates nil)

3.8. braket

(use-package bratex
  :vc (:url "https://github.com/sbrisard/bratex.git"
            :branch "master"))

(add-hook 'org-shiftup-final-hook #'bratex-cycle-size)
(add-hook 'org-shiftdown-final-hook #'bratex-cycle-size-reverse)
(add-hook 'org-shiftright-final-hook #'bratex-cycle-bracket)
(add-hook 'org-shiftleft-final-hook #'bratex-cycle-bracket-reverse)

3.9. yasnippet

(use-package yasnippet)
(yas-global-mode 1)

3.10. transpose-frame

(use-package transpose-frame)
(global-set-key (kbd "C-x w t") 'transpose-frame)  

3.11. clipetty

(use-package clipetty)
(global-clipetty-mode 1)

3.12. ebib

(use-package ebib
  :bind ("C-c e" . ebib))
(setq ebib-bibtex-dialect 'biblatex)

3.13. vertico

(use-package vertico)
(setq vertico-scroll-margin 0
      vertico-count 20
      vertico-resize t
      vertico-cycle t)
(vertico-mode 1)
(vertico-mouse-mode 1)

3.14. orderless

(use-package orderless)
(setq completion-styles '(orderless basic)
      completion-category-defaults nil
      completion-category-overrides '((file (styles partial-completion))))

3.15. marginalia

(use-package marginalia)
(define-key minibuffer-local-map (kbd "M-A") #'marginalia-cycle)
(marginalia-mode 1)

3.16. consult

(use-package consult
  :hook (completion-list-mode . consult-preview-at-point-mode)
  :init
  (advice-add #'register-preview :override #'consult-register-window)
  (setq register-preview-delay 0.5)
  (setq xref-show-xrefs-function #'consult-xref
        xref-show-definitions-function #'consult-xref)
  :config
  (consult-customize
   consult-theme :preview-key '(:debounce 0.2 any)
   consult-ripgrep consult-git-grep consult-grep consult-man
   consult-bookmark consult-recent-file consult-xref
   consult--source-bookmark consult--source-file-register
   consult--source-recent-file consult--source-project-recent-file
   ;; :preview-key "M-."
   :preview-key '(:debounce 0.4 any)))

3.16.1. consult-org

(define-key org-mode-map (kbd "M-o o") #'consult-org-heading)

3.17. embark

(use-package embark)

3.17.1. embark-consult

(use-package embark-consult
  :bind
  (("C-." . embark-act)
   ("C-;" . embark-dwim)
   ("C-h B" . embark-bindings)))

4. Appearance

4.1. Font

(set-face-attribute 'default nil :family "Aporetic Sans Mono" :height 120)

4.2. Theme

4.2.1. doom-themes

(use-package doom-themes)
(load-theme 'doom-one-light t)

4.2.2. org-visual-indent hook

(org-visual-indent-apply)
(add-hook 'load-theme-hook #'org-visual-indent-apply)

4.2.3. leuvenizer

Everyone loves the theme Leuven because of its colorful org headings. Why not make it every where :)))

  1. colormixer

    https://emacs.stackexchange.com/a/69051/44287

    (defun my/color-blend-names (color-a color-b factor)
      "Tint between COLOR-A and COLOR-B by FACTOR in (0..1).
    Use for mixing face colors."
      (let ((value-a (color-values color-a))
            (value-b (color-values color-b))
            (ifactor (- 1.0 factor)))
        (apply 'format
               (cons
                "#%02x%02x%02x"
                (mapcar
                 (lambda (n)
                   ;; Shift by -8 to map the value returned by `color values':
                   ;; 0..65535 to 0..255 for `#RRGGBB` string formatting.
                   (ash (truncate (+ (* (nth n value-a) ifactor)
                                     (* (nth n value-b) factor))) -8))
                 (number-sequence 0 2))))))
    
  2. org headings
    (defun leuvenize-org-levels (to-level factor)
      "Set org-level-* according to loaded theme's colors"
      (cl-loop
       for x from 1 to to-level
       do (set-face-attribute
           (intern
            (concat "org-level-" (number-to-string x))) nil
           :weight 'regular
           :box nil
           :overline t
           :underline nil
           :background (my/color-blend-names
                        (face-foreground
                         (intern
                          (concat "org-level-" (number-to-string x))) nil t)
                        (face-background 'default nil t)
                        factor))))
    
    (defun unleuvenize-org-levels ()
      "Set org-level-* according to loaded theme's colors"
      (cl-loop
       for x from 1 to 8
       do (set-face-attribute (intern
                               (concat "org-level-" (number-to-string x))) nil
                               :box 'unspecified
                               :overline 'unspecified
                               :underline 'unspecified
                               :background 'unspecified)))
    
  3. leuvenize!
    (setq leuvenize-org-factor 0.75)
    
    (defun leuvenize ()
      (interactive)
      (progn
        (setq org-fontify-whole-heading-line t)
        (leuvenize-org-levels 3 leuvenize-org-factor)))
    
    (leuvenize)
    (add-hook 'load-theme-hook #'leuvenize)
    

Backlinks

Created: 2026-08-23 Sun 15:23

Validate