Skip to content

Latest commit

 

History

History
975 lines (917 loc) · 36.5 KB

config.org

File metadata and controls

975 lines (917 loc) · 36.5 KB

Pip Boy Emacs Configurations

Table of Contents

Preamble

Emacs Lisp Scripts

If you have file A, that calls load to load a file at B, and B calls load on file C using a relative path, then Emacs will complain about unable to find C. Because, emacs does not switch current directory with load.

The following function solves this problem.

;;; -*- lexical-binding: t; -*-
(defun leo-get-fullpath (@file-relative-path)
  "Return the full path of *file-relative-path, relative to caller's file location.

Example: If you have this line
 (xah-get-fullpath \"../xyz.el\")
in the file at
 /home/joe/emacs/emacs_lib.el
then the return value is
 /home/joe/xyz.el
Regardless how or where emacs_lib.el is called.

This function solves 2 problems.

① If you have file A, that calls the `load' on a file at B, and B calls `load' on file C using a relative path, then Emacs will complain about unable to find C. Because, emacs does not switch current directory with `load'.

To solve this problem, when your code only knows the relative path of another file C, you can use the variable `load-file-name' to get the current file's full path, then use that with the relative path to get a full path of the file you are interested.

② To know the current file's full path, emacs has 2 ways: `load-file-name' and `buffer-file-name'. If the file is loaded by `load', then `load-file-name' works but `buffer-file-name' doesn't. If the file is called by `eval-buffer', then `load-file-name' is nil. You want to be able to get the current file's full path regardless the file is run by `load' or interactively by `eval-buffer'."

  (concat (file-name-directory (or load-file-name buffer-file-name)) @file-relative-path))

Personal Information

  • Username comes from the environment.
  • Set the email address to my Gmail address.
    (setq! user-mail-address "[email protected]")
        

OS

Mac OS

Set ⌘ ⌥ ⌃ Keys

Set command, option, and alt key for both the left and the right part of the keyboard.

(setq! mac-option-modifier 'meta
       mac-right-option-modifier 'meta
       mac-command-modifier 'super
       mac-right-command-modifier 'super)

UI

Splash Image

Because it’s a Pip Boy Emacs ;)

(setq! fancy-splash-image (expand-file-name "splash/pipboy.png" doom-private-dir))

Main Theme

I’m obsessed with the dark solarized theme, but it looks blue in my terminal. So I use zenburn if I’m in the terminal.

(setq! doom-theme (if (display-graphic-p) 'doom-solarized-dark-high-contrast 'doom-monokai-ristretto))
(custom-set-faces '(default ((t (:background nil)))))

Mouse Cursor Color

(set-mouse-color "red")

Evil Cursor State Colors

Set the cursor colors in vi editing mode.

(setq! evil-default-cursor '("DodgerBlue1" box)
       evil-normal-state-cursor  '("gray" box)
       evil-emacs-state-cursor   '("orange" box)
       evil-motion-state-cursor  '("SeaGreen1" box)
       evil-insert-state-cursor  '("white" bar)
       evil-visual-state-cursor  '("white" hbar)
       evil-replace-state-cursor '("pink" hbar))

Menue Bar

(menu-bar-mode nil)

Modeline

Configure doom-modeline

(setq! doom-modeline-icon (display-graphic-p)
       doom-modeline-major-mode-icon t
       doom-modeline-hud t
       doom-modeline-lsp t
       doom-modeline-buffer-file-name-style 'truncate-with-project
       doom-modeline-buffer-encoding nil)

Show battery usage

Ignore any error here. If running on a PC or server there is no battery status to show.

(ignore-errors (display-battery-mode))

Disable buffer size

Who cares how many bytes this file has?

(setq! size-indication-mode nil)

Treemacs

  • Use the colorful treemacs theme and doom additions
    (setq! doom-themes-treemacs-theme "doom-colors")
    (doom-themes-treemacs-config)
        
  • hide files ignored by Git from treemacs
    (after! treemacs
      (add-to-list 'treemacs-pre-file-insert-predicates #'treemacs-is-file-git-ignored?))
        

Editor

Line Numbers

  • Setting the line number will cause slowdown when the LSP is used, display is large, or anytime the buffer is busy. The situation looks better using Emacs with metals support.
  • The relative line number fucks up variable pitch fonts.
(setq! display-line-numbers-type 'relative)

fill-column

Set column length to be 90 and enable fill-column indicator in the editors.

(global-display-fill-column-indicator-mode +1)

Font

  • Use IntelliJ fonts everywhere. They look gorgeous
  • Use Chalkboard as variable pitch font. It looks gorgeous.
(setq! doom-font (font-spec :family "JetBrainsMono Nerd Font" :size 12)
       doom-unicode-font (font-spec :family "JetBrainsMono Nerd Font" :size 13)
       doom-variable-pitch-font (font-spec :family "Chalkboard" :size 12)
       ivy-posframe-font (font-spec :family "JetBrains Mono Nerd Font" :size 13))

Terminal

tmux

Key Bindings

(map! :leader
      (:prefix-map ("a" . "applications")
       (:prefix ("t" . "tmux")
        :desc "cd to buffer dir in active tmux session" "c" #'+tmux/cd
        :desc "cd to project dir in active tmux session" "p" #'+tmux/cd-to-project
        :desc "cd to highlighted region in active tmux session" "C" #'+tmux:cd-here
        :desc "run highlighted region as comand in active tmux session" "x" #'+tmux:run
        :desc "run command in active tmux session" "t" #'+tmux/run
        :desc "re-run the last command in active tmux session" "r" #'+tmux/rerun)))

vterm

  • Set fish to be the default shell.
    (setq! vterm-shell "fish")
        

Tramp

From the tramp FAQ page:

(setq remote-file-name-inhibit-cache nil)
(setq vc-ignore-dir-regexp
      (format "%s\\|%s"
                    vc-ignore-dir-regexp
                    tramp-file-name-regexp))
(setq tramp-verbose 1)

Spell Checker

  • set personal ispell dictionary.
    (setq! ispell-personal-dictionary "~/Dropbox/Apps/ispell/english.pws")
        

dired

  • Enable the DWIM (Do What I Mean) mode, which makes life much easier when moving stuff around in the dired mode.
(setq! dired-dwim-target t)

Projectile

  • Set projectile search path to add new projects.
    (setq! projectile-project-search-path '("~/w"))
        

Dash API Browser

Search Dash GUI from Emacs. Pretty handy! It only works in MacOS.

(map! :leader
      (:prefix-map ("a" . "applications")
       (:prefix ("d" . "dash")
        :desc "dash at point" "d" #'dash-at-point
        :desc "dash at point with docset" "a" #'+tmux/cd-to-project)))

Org

I use Org for GTD, Zettelkasten workflows, and as a replacement for markdown and LaTeX whenever possible.

Aesthetics

Configure the aesthetics of the org-mode buffer.

(setq! org-hide-emphasis-markers t
       org-fontify-done-headline t
       org-fontify-whole-heading-line t
       org-fontify-todo-headline t
       org-fontify-emphasized-text t
       org-fontify-quote-and-verse-blocks t)

Inline Latex Fragment

Use org-fragtog to enable auto preview of latex fragments.

(use-package! org-fragtog
  :after org
  :hook (org-mode . org-fragtog-mode)
  )

Key Maps

(after! org
  (map! :map org-mode-map
        :n "M-j" #'org-metadown
        :n "M-k" #'org-metaup
        :n  )
  (map! :leader
        (:prefix-map ("a" . "applications")
         (:prefix ("o" . "org-mode")
          :desc "helm-bibtex" "h" #'helm-bibtex))))

Directory Structure

These paths are usually synced through a cloud provided or a git service. These paths include the followings:

  • org-roam and org-mode notes files.
  • Bibliography files generated by Zotero.
  • GTD workflow files.
(setq! pipboy/org-notes (expand-file-name "~/w/roam/")
       pipboy/bibtex-files (directory-files "~/Dropbox/Apps/bibliography/bib/" 'full ".bib")
       pipboy/pdf-directory (expand-file-name "~/Dropbox/Apps/bibliography/pdf/")
       pipboy/gtd-directory (expand-file-name "~/w//beorg"))

Get Things Done

Files

Here I set the files to be used by agenda and other task management functionalities of the org-mode. I follow the GTD workflow.

  1. I quick capture my tasks to my inbox.
  2. I use the gtd file to organize my projects.
  3. I use someday to backlog the tasks I don’t wish to complete in the short term.
(setq! org-inbox-file-name (expand-file-name "inbox.org" pipboy/gtd-directory) ;; TODO
       org-tickler-file-name (expand-file-name "tickler.org" pipboy/gtd-directory) ;; TODO
       org-someday-file-name (expand-file-name "someday.org" pipboy/gtd-directory) ;; TODO
       org-gtd-file-name (expand-file-name "gtd.org" pipboy/gtd-directory) ;; TODO

       org-notes-file-name (expand-file-name "notes.org" pipboy/gtd-directory) )

State Keywords

Set both the keywords and the face of GTD workflow.

(after! org
  (setq! org-todo-keywords '((sequence "TODO(t)" "NOW(z)" "NEXT(n)" "WAIT(w)" "SOMEDAY(s) HOLD(h)" "PROJECT(p)"
                                       "|" "DONE(d)" "CANCEL(c)")
                             (sequence "[ ](T)" "[?](W)" "[-](N)"
                                       "|" "[X](x)"))

         org-todo-keyword-faces '(("NOW" . (:foreground "magenta" :reight "bold"))
                                  ("NEXT" . (:foreground "violet" :weight "bold"))
                                  ("WAIT" . +org-todo-onhold)
                                  ("HOLD" . +org-todo-onhold)
                                  ("SOMEDAY" . +org-todo-onhold)
                                  ("PROJECT". +org-todo-project)
                                  ("ABORT" . (+org-todo-inactive))
                                  ("[-]" . +org-todo-active)
                                  ("[?]" . +org-todo-onhold))))

Tags

These are the tags that I use with my task management workflow.

(after! org
  (setq! org-tag-alist '((:startgroup . nil)
                         ("@work" . ?w)
                         ("@home" . ?h)
                         ("@business" . ?b)
                         ("@university" . ?u)
                         ("@travel" . ?t)
                         (:endgroup)

                         (:startgroup . nil)
                         ("@errand". ?r)
                         ("@phone" . ?p)
                         ("@email" . ?e)
                         (:endgroup . nil)

                         (:startgroup . nil)
                         ("emacs")
                         ("tools")
                         ("server")
                         (:endgroup . nil)

                         (:startgroup . nil)
                         ("read")
                         ("write")
                         ("study")
                         ("implement")
                         ("research")
                         (:endgroup . nil)

                         (:startgroup . nil)
                         ("TOC_1" . ?1)
                         ("TOC_2" . ?2)
                         ("TOC_3" . ?3)
                         ("TOC_4" . ?4)
                         (:endgroup . nil))))

org-agenda

Files

(after! org
  (setq! org-agenda-files (list pipboy/gtd-directory)
         org-agenda-show-inherited-tags t
         org-default-notes-file org-inbox-file-name))

org-super-agenda

(use-package! org-super-agenda
  :defer
  :after (org org-mode org-super-agenda)
  :commands (org-super-agenda-mode))

(after! org-agenda
  (org-super-agenda-mode))

Agenda View

(after! org
  (setq! org-agenda-skip-scheduled-if-done t
         org-agenda-skip-deadline-if-done t
         org-agenda-include-deadlines t
         org-agenda-block-separator nil
         org-agenda-tags-column 100 ;; from testing this seems to be a good value
         org-agenda-compact-blocks t)

  (setq! org-agenda-custom-commands
         '(("o" "Overview"
            ((agenda "" ((org-agenda-span 'day)))
             (todo "" ((org-agenda-overriding-header "")
                       (org-super-agenda-groups
                        '((:name "Next" :todo "NEXT" :order 1)
                          (:name "Important" :priority "A" :order 6)
                          (:name "Due Today" :deadline today :order 2)
                          (:name "Due Soon" :deadline future :order 8)
                          (:name "Overdue" :deadline past :face error :order 7)
                          (:name "Inbox" :category "inbox" :order 10)
                          (:name "To read" :tag "Read" :order 30)
                          (:name "Waiting" :todo "WAIT" :order 20)
                          (:discard (:anything t))))))))

           ("a" "dashboard"
            ((agenda "" ((org-agenda-span 'week)))
             (todo "" ((org-agenda-overriding-header "")
                       (org-super-agenda-groups
                        '((:name "Now" :todo "NOW" :order 1)
                          (:name "Next" :todo "NEXT" :order 10)
                          (:name "Due Today" :deadline today :order 20)
                          (:name "Due Soon" :deadline future :order 30)
                          (:name "Overdue" :deadline past :face error :order 70)
                          (:name "Inbox"  :category "inbox" :order 80)
                          (:name "Errands" :tag ("@errand") :order 100)
                          (:discard (:anything t))))))))
           ("p" "Projects"
            ((todo "" ((org-agenda-overriding-header "All Projects")
                       (org-agenda-remove-tags 1)
                       (org-super-agenda-groups
                        '((:auto-parent t :todo "TODO")))))))

           ("h" "@home Projects"
            ((todo "" ((org-agenda-overriding-header "Personal Projects")
                       (org-agenda-remove-tags 1)
                       (org-super-agenda-groups
                        '((:discard (:not (:tag ("@home"))))
                          (:auto-parent t :tag "@home")))))))

           ("w" "@work Projects"
            ((todo "" ((org-agenda-overriding-header "Work Projects")
                       (org-agenda-remove-tags 1)
                       (org-super-agenda-groups
                        '((:discard (:not (:tag ("@work"))))
                          (:auto-parent t)))))))

           ("r" "Errands"
            ((alltodo "" ((org-agenda-overriding-header "Errands")
                          (org-super-agenda-groups
                           '((:discard (:not (:tag "@errand")))))))))

           ("i" "Inbox"
            ((alltodo "" ((org-agenda-overriding-header "Inbox")
                          (org-super-agenda-groups
                           '((:name "Inbox" :category "inbox")
                             (:discard (:anything t)))))))))))

org-refile

Set the refile targets to be my project, someday, and tickler files.

(after! org
  (setq! org-refile-targets '((org-gtd-file-name :maxlevel . 3)
                              (org-someday-file-name :level . 1)
                              (org-tickler-file-name :maxlevel . 2))
         org-refile-allow-creating-parent-nodes 'confirm))

org-capture

(after! org
  (setq!
   org-capture-templates `(("i" "Inbox" entry
                            (file+headline org-inbox-file-name "Tasks")
                            "* TODO %i%?\n%U")

                           ("I" "Inbox This Line" entry
                            (file+headline org-inbox-file-name "Tasks")
                            "* TODO %i%?\n%U\n%a")

                           ("t" "Tickler" entry
                            (file+headline org-tickler-file-name "Tickler")
                            "* %i%?\n%U")

                           ("T" "Tickler This Line" entry
                            (file+headline org-tickler-file-name "Tickler")
                            "* %i%?\n%U\n%a")
                           ("p"
                            "Protocol"
                            entry
                            (file+headline ,org-notes-file-name "Notes")
                            "* %? [[%:link][%:description]]\n%U\n#+BEGIN_QUOTE\n%i\n#+END_QUOTE\n\n\n")
                           ("L"
                            "Protocol Link"
                            entry
                            (file+headline ,org-notes-file-name "Notes")
                            "* %?[[%:link][%:description]]\n%U\n"))))

org archive

(after! org
  (setq! org-archive-location (concat (expand-file-name "archive.org" pipboy/gtd-directory) "::")))

Zettelkasten

This section contains the configurations enabling me to take notes using org-roam. I also take notes on papers and books using org-roam. I configure bibtex related packages to be able to use my bibs generated by Zotero in org-roam.

org-roam

It’s better to read this from the environment instead. I am moving to a pure org-roam workflow; set org-directory to be the org-roam files also.

(setq! org-roam-directory pipboy/org-notes
       org-directory pipboy/org-notes)

org-ref

Most of these configurations are inspired by this link.

(use-package! org-ref
  :defer
  :after org-mode
  :config
  (setq! org-ref-bibliography-notes (concat pipboy/org-notes "/bibnotes.org") ;; TODO make this more explicit
         org-ref-notes-directory pipboy/org-notes
         org-ref-bibliography-files pipboy/bibtex-files
         reftex-default-bibliography pipboy/bibtex-files
         org-ref-default-bibliography pipboy/bibtex-files
         org-ref-pdf-directory pipboy/pdf-directory
         org-ref-completion-library 'org-ref-ivy-cite
         org-ref-get-pdf-filename-function 'org-ref-get-pdf-filename-helm-bibtex
         org-ref-note-title-format "* TODO %y - %t\n :PROPERTIES:\n  :Custom_ID: %k\n  :NOTER_DOCUMENT: %F\n :ROAM_KEY: cite:%k\n  :AUTHOR: %9a\n  :JOURNAL: %j\n  :YEAR: %y\n  :VOLUME: %v\n  :PAGES: %p\n  :DOI: %D\n  :URL: %U\n :END:\n\n"
         org-ref-notes-function 'orb-edit-notes))
;; TODO Rewrite title formats using the (concat ...) function

See examples in helm-bibtex section.

helm-bibtex & ivy-bibtex

(setq! bibtex-completion-notes-path pipboy/org-notes
       bibtex-completion-bibliography pipboy/bibtex-files
       bibtex-completion-pdf-field "file"
       bibtex-completion-notes-template-multiple-files (concat
                                                        "#+TITLE: ${title}\n"
                                                        "#+ROAM_KEY: cite:${=key=}\n"
                                                        "* TODO Notes\n"
                                                        ":PROPERTIES:\n"
                                                        ":Custom_ID: ${=key=}\n"
                                                        ":NOTER_DOCUMENT: %(orb-process-file-field \"${=key=}\")\n"
                                                        ":AUTHOR: ${author-abbrev}\n"
                                                        ":JOURNAL: ${journaltitle}\n"
                                                        ":DATE: ${date}\n"
                                                        ":YEAR: ${year}\n"
                                                        ":DOI: ${doi}\n"
                                                        ":URL: ${url}\n"
                                                        ":END:\n\n"))

org-noter

I use org-noter to take notes on PDF and EPUB documents.

(setq! org-noter-notes-search-path (list pipboy/org-notes)
       org-noter-notes-window-location 'horizontal-split)

org-pdftools

(use-package! org-pdftools
  :defer
  :after org-mode
  :hook
  (org-mode . org-pdftools-setup-link))

org-noter-pdftools

(use-package! org-noter-pdftools
  :after org-noter
  :defer
  :config
  ;; Add a function to ensure precise note is inserted
  (defun org-noter-pdftools-insert-precise-note (&optional toggle-no-questions)
    (interactive "P")
    (org-noter--with-valid-session
     (let ((org-noter-insert-note-no-questions (if toggle-no-questions
                                                   (not org-noter-insert-note-no-questions)
                                                 org-noter-insert-note-no-questions))
           (org-pdftools-use-isearch-link t)
           (org-pdftools-use-freestyle-annot t))
       (org-noter-insert-note (org-noter--get-precise-info)))))

  ;; fix https://github.com/weirdNox/org-noter/pull/93/commits/f8349ae7575e599f375de1be6be2d0d5de4e6cbf
  (defun org-noter-set-start-location (&optional arg)
    "When opening a session with this document, go to the current location.
With a prefix ARG, remove start location."
    (interactive "P")
    (org-noter--with-valid-session
     (let ((inhibit-read-only t)
           (ast (org-noter--parse-root))
           (location (org-noter--doc-approx-location (when (called-interactively-p 'any) 'interactive))))
       (with-current-buffer (org-noter--session-notes-buffer session)
         (org-with-wide-buffer
          (goto-char (org-element-property :begin ast))
          (if arg
              (org-entry-delete nil org-noter-property-note-location)
            (org-entry-put nil org-noter-property-note-location
                           (org-noter--pretty-print-location location))))))))
  (with-eval-after-load 'pdf-annot
    (add-hook 'pdf-annot-activate-handler-functions #'org-noter-pdftools-jump-to-note)))

org-roam-bibtex

org-roam-bibtex is a library which offers a tighter integration between org-roam, helm-bibtex, and org-ref.

(use-package! org-roam-bibtex
  :defer
  :after org-roam
  :hook (org-roam-mode . org-roam-bibtex-mode)
  :config
  (setq orb-preformat-keywords
        '("=key=" "title" "url" "file" "author-or-editor" "keywords"))
  (setq orb-templates
        '(("r" "ref" plain (function org-roam-capture--get-point)
           ""
           :file-name "${slug}"
           :head "#+TITLE: ${=key=}: ${title}\n#+ROAM_KEY: ${ref}
- tags ::
- keywords :: ${keywords}
\n* ${title}\n  :PROPERTIES:\n  :Custom_ID: ${=key=}\n  :URL: ${url}\n  :AUTHOR: ${author-or-editor}\n  :NOTER_DOCUMENT: %(orb-process-file-field \"${=key=}\")\n  :NOTER_PAGE: \n  :END:\n\n"
           :unnarrowed t))))

deft

deft user interface

(defun my-deft/strip-quotes (str)
  (cond ((string-match "\"\\(.+\\)\"" str) (match-string 1 str))
        ((string-match "'\\(.+\\)'" str) (match-string 1 str))
        (t str)))

(defun my-deft/parse-title-from-front-matter-data (str)
  (if (string-match "^title: \\(.+\\)" str)
      (let* ((title-text (my-deft/strip-quotes (match-string 1 str)))
             (is-draft (string-match "^draft: true" str)))
        (concat (if is-draft "[DRAFT] " "") title-text))))

(defun my-deft/deft-file-relative-directory (filename)
  (file-name-directory (file-relative-name filename deft-directory)))

(defun my-deft/title-prefix-from-file-name (filename)
  (let ((reldir (my-deft/deft-file-relative-directory filename)))
    (if reldir
        (concat (directory-file-name reldir) " > "))))

(defun my-deft/parse-title-with-directory-prepended (orig &rest args)
  (let ((str (nth 1 args))
        (filename (car args)))
    (concat
      (my-deft/title-prefix-from-file-name filename)
      (let ((nondir (file-name-nondirectory filename)))
        (if (or (string-prefix-p "README" nondir)
                (string-suffix-p ".txt" filename))
            nondir
          (if (string-prefix-p "---\n" str)
              (my-deft/parse-title-from-front-matter-data
               (car (split-string (substring str 4) "\n---\n")))
            (apply orig args)))))))

(provide 'my-deft-title)
(require 'my-deft-title)
(advice-add 'deft-parse-title :around #'my-deft/parse-title-with-directory-prepended)

deft directory

I use deft to search the notes I take using org roam.

(setq! deft-directory pipboy/org-notes
       deft-recursive t)

Enable minor modes

(add-hook! 'org-mode-hook #'auto-fill-mode)

CV & Resume

org-export functions

(defun pipboy/org-export-altacv ()
  "export buffer to altacv resume"
  (interactive)
  (let ((outfile (org-export-output-file-name ".tex")))
    (org-export-to-file 'altacv outfile)
    (org-latex-compile outfile)))

Keybindings

(map! :leader
      (:prefix-map ("a" . "applications")
       (:prefix ("o" . "org")
        :desc "org export altacv resume" "r" #'pipboy/org-export-altacv)))

Export Backends

(use-package! ox-moderncv :after org)
(use-package! ox-altacv :after org)

org-export

LaTex

  • Enable bibtex compilation
  • Set log files to intermediate files generated by the exporter so org-export delete these after exporting
(setq org-latex-pdf-process
      '("%latex -interaction nonstopmode -output-directory %o %f"
        "bibtex %b"
        "%latex -interaction nonstopmode -output-directory %o %f"
        "%latex -interaction nonstopmode -output-directory %o %f")
      org-latex-logfiles-extensions
      '("lof" "lot" "tex" "aux" "idx" "log" "out" "toc" "nav" "snm" "vrb"
        "dvi" "fdb_latexmk" "blg" "brf" "fls" "entoc" "ps" "spl" "bbl"
        "pygtex" "pygstyle"))
  • [ ] Set LaTex export engine to be XeLaTex
    (setq org-latex-packages-alist 'nil)
    (setq org-latex-default-packages-alist
          '(("AUTO" "inputenc"  t ("pdflatex"))
            ("T1"   "fontenc"   t ("pdflatex"))
            (""     "graphicx"  t)
            (""     "grffile"   t)
            (""     "minted"   t)
            (""     "longtable" nil)
            (""     "wrapfig"   nil)
            (""     "rotating"  nil)
            ("normalem" "ulem"  t)
            (""     "amsmath"   t)
            (""     "amssymb"   t)
            (""     "unicode-math"   t)
            (""     "mathtools"   t)
            (""     "textcomp"  t)
            (""     "capt-of"   nil)
            (""     "hyperref"  nil)))
    
    ;; (plist-put org-format-latex-options :scale 2.2)
    ;; (add-to-list 'org-preview-latex-process-alist '(dvixelatex :programs
    ;;                                                            ("xetex" "convert")
    ;;                                                            :description "pdf > png" :message "you need to install the programs: xetex and imagemagick." :image-input-type "pdf" :image-output-type "png" :image-size-adjust
    ;;                                                            (1.0 . 1.0)
    ;;                                                            :latex-compiler
    ;;                                                            ("xelatex -no-pdf -interaction nonstopmode -output-directory %o %f")
    ;;                                                            :image-converter
    ;;                                                            ("dvisvgm %f -n -b min -c %S -o %O")))
    
    ;; (add-to-list 'org-preview-latex-process-alist '(imagexetex :programs
    ;;                                                            ("xelatex" "convert")
    ;;                                                            :description "pdf > png" :message "you need to install the programs: xelatex and imagemagick." :image-input-type "pdf" :image-output-type "png" :image-size-adjust
    ;;                                                            (1.0 . 1.0)
    ;;                                                            :latex-compiler
    ;;                                                            ("xelatex -interaction nonstopmode -output-directory %o %f")
    ;;                                                            :image-converter
    ;;                                                            ("convert -density %D -trim -antialias %f -quality 100 %O")))
        

org-babel

Prolog

(use-package! ob-prolog
  :defer
  :after org-mod)

org-drill

(after! org
  (require 'cl)
  (require 'org-drill))

LaTeX

  • Use xalatex by default
    (setq-default TeX-engine 'xetex)
        
  • Always Generate PDF for TeX files
    (setq-default TeX-PDF-mode t)
        
  • Use luatex in latex-preview-pate
    (setq pdf-latex-command "xetex")
        

Flycheck

  • Check syntax automatically.
    (after! flycheck
      (setq flycheck-check-syntax-automatically '(mode-enabled save idle-change)))
        

Languages

LSP

Configuration

  • Set a ridiculous limit on number of file watch. This is needed for Python virtual environments which reside inside the project worktree.
(setq! lsp-file-watch-threshold 100000)

Autocompletion

(after! lsp
  (setq company-minimum-prefix-length   1
        company-idle-delay              0.0
        company-tooltip-idle-delay      0.0
        lsp-eldoc-render-all            nil
        lsp-lens-enable                 t))

LSP UI Configurations

(after! lsp-ui
  (setq! lsp-ui-doc-show-with-cursor nil
         lsp-ui-sideline-enable      t
         lsp-ui-doc-max-height       15
         lsp-ui-doc-max-width        100
         lsp-ui-doc-position         'at-point
         lsp-ui-peek-always-show     t
         lsp-ui-peek-fontify         'always)

  (set-face-attribute 'lsp-face-highlight-textual nil
                      :weight 'bold
                      :background "#0A2933"
                      :foreground "#C61C6F"))

DAP

UI

  • Enable Hydra when hitting a breakpoint
;; (after! dap-mode
;;   (add-hook 'dap-stopped-hook
;;             (lambda (arg) (call-interactively #'dap-hydra))))

Python

It’s recommended to use debugpy over ptvsd.

(after! dap-mode
  (setq dap-python-debugger 'debugpy))

Keybindings

(after! dap-mode
  (map! :map dap-mode-map
        :leader
        :prefix ("d" . "dap")
        ;; basics
        :desc "dap next"          "n" #'dap-next
        :desc "dap step in"       "i" #'dap-step-in
        :desc "dap step out"      "o" #'dap-step-out
        :desc "dap continue"      "c" #'dap-continue
        :desc "dap hydra"         "h" #'dap-hydra
        :desc "dap debug restart" "r" #'dap-debug-restart
        :desc "dap debug"         "s" #'dap-debug
        :desc "dap ui repl"       "R" #'dap-ui-repl

        ;; debug
        :prefix ("dd" . "Debug")
        :desc "dap debug recent"  "r" #'dap-debug-recent
        :desc "dap debug last"    "l" #'dap-debug-last

        ;; eval
        :prefix ("de" . "Eval")
        :desc "eval"                "e" #'dap-eval
        :desc "eval region"         "r" #'dap-eval-region
        :desc "eval thing at point" "s" #'dap-eval-thing-at-point
        :desc "add expression"      "a" #'dap-ui-expressions-add
        :desc "remove expression"   "d" #'dap-ui-expressions-remove

        :prefix ("db" . "Breakpoint")
        :desc "dap breakpoint toggle"      "b" #'dap-breakpoint-toggle
        :desc "dap breakpoint condition"   "c" #'dap-breakpoint-condition
        :desc "dap breakpoint hit count"   "h" #'dap-breakpoint-hit-condition
        :desc "dap breakpoint log message" "l" #'dap-breakpoint-log-message))

Python

Editor

  • Enable rainbow mode
(after! python
  (rainbow-delimiters-mode t))

Debugger

(after! python (require 'dap-python))

REPL

(setq +python-ipython-repl-args '("-i" "--simple-prompt" "--no-color-info"))
(setq +python-jupyter-repl-args '("--simple-prompt"))

Poetry

Key Bindings

(map! :leader
      (:prefix-map ("a" . "applications")
       (:prefix ("p" . "poetry")
        :desc "add poetry dependency" "d" #'poetry-add
        :desc "add poetry dev dependency" "D" #'poetry-add-dev-dep
        :desc "poetry run" "r" #'poetry-run
        :desc "poetry build" "b" #'poetry-build
        :desc "poetry install" "i" #'poetry-install
        :desc "poetry install-install" "I" #'poetry-install-install)))

Pyright Language Server

(after! python
  (setq! lsp-pyright-venv-path (expand-file-name "~/.venv/")))

sphinx-doc

  • Enable sphinx-doc, which generate Python docstrings for function and methods.
  • It does not work with python type hints.
(use-package! sphinx-doc
  :defer
  :after python
  :config
  (sphinx-doc-mode t))

Prolog

ediprolog

  • Set the Prolog interpreter to swipl.
(use-package! ediprolog
  :defer
  :custom
  (ediprolog-system 'swi))

Scala

(setq create-lockfiles nil)
(setq backup-directory-alist `((".*" . ,temporary-file-directory))
      auto-save-file-name-transforms `((".*" ,temporary-file-directory t)))

AI & Assistant

(use-package! gptel)