Skip to content

Latest commit

 

History

History
1193 lines (1038 loc) · 51.1 KB

doom.org

File metadata and controls

1193 lines (1038 loc) · 51.1 KB

Literate Configuration

Table Of Contents

Acknowledgements

As the dwarfs can see further on the shoulders of giants. I am where I am because of those who came before me. There is some pieces borrowed and other inspired from many sources. Here are a few of them, this is by no means a comprehensive list.

Safe files

Doom configuration files

Doom uses 3 config files:

  • init.el defines which of the existing Doom modules are loaded. A Doom module is a bundle of packages, configurations and commands, organized into a unit that can be toggled easily from this file.
  • packages.el defines which packages should be installed, beyond those that are installed and loaded as part of the enabled modules.
  • config.el contains all custom configuration and code.

Other files can be loaded, but these are the main ones. The load order of different files is defined depending on the type of session being started.

All the config files are generated from this Org file, to try and make its meaning as clear as possible. All package! declarations are written to packages.el, all other LISP code is written to config.el.

Config file headers

We start by simply defining the standard headers used by the three files. These headers come from the initial files generated by doom install and contain either some Emacs-LISP relevant indicators like lexical-binding, or instructions about the contents of the file.

init.el
;;; init.el -*- lexical-binding: t; -*-

;; DO NOT EDIT THIS FILE DIRECTLY!
;; This file is auto-generated from ../doom.org

;; This file controls what Doom modules are enabled and in what order they load
;; in. Remember to run 'doom sync' after modifying it!

;; NOTE Press 'SPC h d h' (or 'C-h d h' for non-vim users) to access Doom's
;;      documentation. There you'll find a "Module Index" link where you'll find
;;      a comprehensive list of Doom's modules and what flags they support.

;; NOTE Move your cursor over a module's name (or its flags) and press 'K' (or
;;      'C-c c k' for non-vim users) to view its documentation. This works on
;;      flags as well (those symbols that start with a plus).
;;
;;      Alternatively, press 'gd' (or 'C-c c d') on a module to browse its
;;      directory (for easy access to its source code).
packages.el
;; -*- no-byte-compile: t; -*-
;;; $DOOMDIR/packages.el

;; DO NOT EDIT THIS FILE DIRECTLY!
;; This file is auto-generated from ../doom.org

;; To install a package with Doom you must declare them here and run 'doom sync'
;; on the command line, then restart Emacs for the changes to take effect -- or
;; use 'M-x doom/reload'.

;; To install SOME-PACKAGE from MELPA, ELPA or emacsmirror:
                                        ;(package! some-package)
;; To install a package directly from a remote git repo, you must specify a
;; `:recipe'. You'll find documentation on what `:recipe' accepts here:
;; https://github.com/raxod502/straight.el#the-recipe-format
                                        ;(package! another-package
                                        ;  :recipe (:host github :repo "username/repo"))

;; If the package you are trying to install does not contain a PACKAGENAME.el
;; file, or is located in a subdirectory of the repo, you'll need to specify
;; `:files' in the `:recipe':
                                        ;(package! this-package
                                        ;  :recipe (:host github :repo "username/repo"
                                        ;           :files ("some-file.el" "src/lisp/*.el")))

;; If you'd like to disable a package included with Doom, you can do so here
;; with the `:disable' property:
                                        ;(package! builtin-package :disable t)

;; You can override the recipe of a built-in package without having to specify
;; all the properties for `:recipe'. These will inherit the rest of its recipe
;; from Doom or MELPA/ELPA/Emacsmirror:
                                        ;(package! builtin-package :recipe (:nonrecursive t))
                                        ;(package! builtin-package-2 :recipe (:repo "myfork/package"))

;; Specify a `:branch' to install a package from a particular branch or tag.
;; This is required for some packages whose default branch isn't 'master' (which
;; our package manager can't deal with; see raxod502/straight.el#279)
                                        ;(package! builtin-package :recipe (:branch "develop"))

;; Use `:pin' to specify a particular commit to install.
                                        ;(package! builtin-package :pin "1a2b3c4d5e")


;; Doom's packages are pinned to a specific commit and updated from release to
;; release. The `unpin!' macro allows you to unpin single packages...
                                        ;(unpin! pinned-package)
;; ...or multiple packages
                                        ;(unpin! pinned-package another-pinned-package)
;; ...Or *all* packages (NOT RECOMMENDED; will likely break things)
                                        ;(unpin! t)
config.el
;;; $DOOMDIR/config.el -*- lexical-binding: t; -*-

;; DO NOT EDIT THIS FILE DIRECTLY!
;; This file is auto-generated from ../doom.org

;; Here are some additional functions/macros that could help you configure Doom:
;;
;; - `load!' for loading external *.el files relative to this one
;; - `use-package!' for configuring packages
;; - `after!' for running code after a package has loaded
;; - `add-load-path!' for adding directories to the `load-path', relative to
;;   this file. Emacs searches the `load-path' when you load packages with
;;   `require' or `use-package'.
;; - `map!' for binding new keys
;;
;; To get information about any of these functions/macros, move the cursor over
;; the highlighted symbol at press 'K' (non-evil users must press 'C-c c k').
;; This will open documentation for it, including demos of how they are used.
;;
;; You can also try 'gd' (or 'C-c c d') to jump to their definition and see how
;; they are implemented.

Doom Modules

Doom ships with a lot of modules out of the box and these are configured in the init.el. The setup is clear and concise.

(doom! :input
       ;;chinese
       ;;japanese
       ;;layout            ; auie,ctsrnm is the superior home row

       :completion
       (company +childframe)          ; the ultimate code completion backend
       helm              ; the *other* search engine for love and life
       ;;ido               ; the other *other* search engine...
       ivy               ; a search engine for love and life

       :ui
       ;;deft              ; notational velocity for Emacs
       doom              ; what makes DOOM look the way it does
       doom-dashboard    ; a nifty splash screen for Emacs
       doom-quit         ; DOOM quit-message prompts when you quit Emacs
       ;;(emoji +unicode)  ; 🙂
       ;;fill-column       ; a `fill-column' indicator
       hl-todo           ; highlight TODO/FIXME/NOTE/DEPRECATED/HACK/REVIEW
       ;;hydra
       ;;indent-guides     ; highlighted indent columns
       ;;ligatures         ; ligatures and symbols to make your code pretty again
       ;;minimap           ; show a map of the code on the side
       modeline          ; snazzy, Atom-inspired modeline, plus API
       ;;nav-flash         ; blink cursor line after big motions
       ;;neotree           ; a project drawer, like NERDTree for vim
       ophints           ; highlight the region an operation acts on
       (popup +defaults)   ; tame sudden yet inevitable temporary windows
       ;;tabs              ; a tab bar for Emacs
       treemacs          ; a project drawer, like neotree but cooler
       ;;unicode           ; extended unicode support for various languages
       vc-gutter         ; vcs diff in the fringe
       vi-tilde-fringe   ; fringe tildes to mark beyond EOB
       ;;window-select     ; visually switch windows
       workspaces        ; tab emulation, persistence & separate workspaces
       ;;zen               ; distraction-free coding or writing

       :editor
       (evil +everywhere); come to the dark side, we have cookies
       file-templates    ; auto-snippets for empty files
       fold              ; (nigh) universal code folding
       ;; (format +onsave)  ; automated prettiness
       ;;god               ; run Emacs commands without modifier keys
       ;;lispy             ; vim for lisp, for people who don't like vim
       ;;multiple-cursors  ; editing in many places at once
       ;;objed             ; text object editing for the innocent
       ;;parinfer          ; turn lisp into python, sort of
       ;;rotate-text       ; cycle region at point between text candidates
       snippets          ; my elves. They type so I don't have to
       word-wrap         ; soft wrapping with language-aware indent

       :emacs
       dired             ; making dired pretty [functional]
       electric          ; smarter, keyword-based electric-indent
       ;;ibuffer         ; interactive buffer management
       undo              ; persistent, smarter undo for your inevitable mistakes
       vc                ; version-control and Emacs, sitting in a tree

       :term
       eshell            ; the elisp shell that works everywhere
       shell             ; simple shell REPL for Emacs
       ;;term              ; basic terminal emulator for Emacs
       ;;vterm             ; the best terminal emulation in Emacs

       :checkers
       syntax              ; tasing you for every semicolon you forget
       spell             ; tasing you for misspelling mispelling
       grammar           ; tasing grammar mistake every you make

       :tools
       ansible
       debugger          ; FIXME stepping through code, to help you add bugs
       ;;direnv
       ;;docker
       editorconfig      ; let someone else argue about tabs vs spaces
       ;;ein               ; tame Jupyter notebooks with emacs
       (eval +overlay)     ; run code, run (also, repls)
       gist              ; interacting with github gists
       lookup              ; navigate your code and its documentation
       lsp
       (magit +forge)             ; a git porcelain for Emacs
       make              ; run make tasks from Emacs
       ;;pass              ; password manager for nerds
       ;;pdf               ; pdf enhancements
       ;;prodigy           ; FIXME managing external services & code builders
       ;;rgb               ; creating color strings
       ;;taskrunner        ; taskrunner for all your projects
       terraform         ; infrastructure as code
       ;;tmux              ; an API for interacting with tmux
       ;;upload            ; map local to remote projects via ssh/ftp

       :os
       (:if IS-MAC macos)  ; improve compatibility with macOS
       ;;tty               ; improve the terminal Emacs experience

       :lang
       ;;agda              ; types of types of types of types...
       ;;cc                ; C/C++/Obj-C madness
       ;;clojure           ; java with a lisp
       ;;common-lisp       ; if you've seen one lisp, you've seen them all
       ;;coq               ; proofs-as-programs
       ;;crystal           ; ruby at the speed of c
       csharp            ; unity, .NET, and mono shenanigans
       ;;data              ; config/data formats
       ;;(dart +flutter)   ; paint ui and not much else
       ;;elixir            ; erlang done right
       ;;elm               ; care for a cup of TEA?
       emacs-lisp        ; drown in parentheses
       ;;erlang            ; an elegant language for a more civilized age
       ;;ess               ; emacs speaks statistics
       ;;faust             ; dsp, but you get to keep your soul
       ;;fsharp            ; ML stands for Microsoft's Language
       ;;fstar             ; (dependent) types and (monadic) effects and Z3
       ;;gdscript          ; the language you waited for
       (go +lsp)         ; the hipster dialect
       ;;(haskell +dante)  ; a language that's lazier than I am
       ;;hy                ; readability of scheme w/ speed of python
       ;;idris             ; a language you can depend on
       json              ; At least it ain't XML
       ;;(java +meghanada) ; the poster child for carpal tunnel syndrome
       (javascript +lsp)        ; all(hope(abandon(ye(who(enter(here))))))
       ;;julia             ; a better, faster MATLAB
       ;;kotlin            ; a better, slicker Java(Script)
       ;;latex             ; writing papers in Emacs has never been so fun
       ;;lean
       ;;factor
       ;;ledger            ; an accounting system in Emacs
       ;;lua               ; one-based indices? one-based indices
       markdown          ; writing docs for people to ignore
       ;;nim               ; python + lisp at the speed of c
       ;;nix               ; I hereby declare "nix geht mehr!"
       ;;ocaml             ; an objective camel
       (org +pretty +journal +pandoc +roam2)               ; organize your plain life in plain text
       ;;php               ; perl's insecure younger brother
       ;;plantuml          ; diagrams for confusing people more
       ;;purescript        ; javascript, but functional
       (python +lsp)            ; beautiful is better than ugly
       ;;qt                ; the 'cutest' gui framework ever
       ;;racket            ; a DSL for DSLs
       ;;raku              ; the artist formerly known as perl6
       ;;rest              ; Emacs as a REST client
       ;;rst               ; ReST in peace
       ;;(ruby +rails)     ; 1.step {|i| p "Ruby is #{i.even? ? 'love' : 'life'}"}
       ;;rust              ; Fe2O3.unwrap().unwrap().unwrap().unwrap()
       ;;scala             ; java, but good
       ;;scheme            ; a fully conniving family of lisps
       (sh +powershell +lsp)                ; she sells {ba,z,fi}sh shells on the C xor
       ;;sml
       ;;solidity          ; do you need a blockchain? No.
       ;;swift             ; who asked for emoji variables?
       ;;terra             ; Earth and Moon in alignment for performance.
       ;;web               ; the tubes
       yaml              ; JSON, but readable

       :email
       ;;(mu4e +gmail)
       ;;notmuch
       ;;(wanderlust +gmail)

       :app
       calendar
       ;;irc               ; how neckbeards socialize
       ;;(rss +org)        ; emacs as an RSS reader
       ;;twitter           ; twitter client https://twitter.com/vnought

       :config
       ;;literate
       (default +bindings +smartparens))

libgccjit error

(setq native-comp-deferred-compilation nil)
(after! (doom-packages straight)
  (setq straight--native-comp-available t))

Formater

I don’t want to format things in the `nxml-mode`

;; Or set it to `:none' to disable formatting
(setq-hook! 'nxml-mode-hook +format-with :none)

Me

It’s nice to know who you are especially for git commits and such. It’s recommended to fill out this section

;; Place your private configuration here! Remember, you do not need to run 'doom
;; sync' after modifying this file!

;; Some functionality uses this to identify you, e.g. GPG configuration, email
;; clients, file templates and snippets.
;; (setq user-full-name "John Doe"
;;      user-mail-address "[email protected]")
(setq user-full-name "Tom Monck"
      user-mail-address "[email protected]")

Customize the look and feel

Fonts

;; Doom exposes five (optional) variables for controlling fonts in Doom. Here
;; are the three important ones:
;;
;; + `doom-font'
;; + `doom-variable-pitch-font'
;; + `doom-big-font' -- used for `doom-big-font-mode'; use this for
;;   presentations or streaming.
;;
;; They all accept either a font-spec, font string ("Input Mono-12"), or xlfd
;; font string. You generally only need these two:
;; (setq doom-font (font-spec :family "monospace" :size 12 :weight 'semi-light)
;;  doom-variable-pitch-font (font-spec :family "sans" :size 13))
;; (setq doom-font (font-spec :family "JetBrains Mono")
;;       doom-variable-pitch-font (font-spec :family "DejaVu Sans"))
(use-package! nerd-icons)
(package! nerd-icons)
(package! nerd-icons-dired)
(package! treemacs-nerd-icons)
(package! treemacs-icons-dired)

Theme

Let’s make the theme look like we want and we like it dark!

;; There are two ways to load a theme. Both assume the theme is installed and
;; available. You can either set `doom-theme' or manually load a theme with the
;; `load-theme' function. The is the default: doom-one
(setq doom-theme 'doom-one)
;; (setq doom-theme 'doom-acario-dark)
;; (setq doom-theme 'doom-material-dark)
;; (setq doom-theme 'doom-ir-black)
;; (setq doom-theme 'doom-moonlight)
;; (setq doom-theme 'doom-challenger-deep)
;; (setq doom-theme 'doom-dracula)
;; (setq doom-theme 'doom-oksolar-dark)
;; (setq doom-theme 'doom-badger)
;; (setq doom-theme 'doom-Iosvkem)

treemacs

Since we use treemacs lets add some icon flare here

;; (package! treemacs-all-the-icons)
;; Treemacs
(use-package! lsp-treemacs :after treemacs) ;; this needs to be setup before treemacs-nerd-icons other wise it messes up the icons

(use-package! treemacs-nerd-icons
  :config
  (treemacs-load-theme "nerd-icons"))

(setq treemacs-width 43)

Fullscreen

I like to have my emacs open to full screen on startup.

(if (eq initial-window-system 'x)                 ; if started by emacs command or desktop file
    (toggle-frame-maximized)
  (toggle-frame-maximized)
  )

Opacity

For some reason I like my editor to be somewhat see through so let’s adjust the opacity.

(doom/set-frame-opacity 90)

Magit

Let’s do some magit. I prefer it to be in fullscreen to make things easier to read.

;; Set magit to full screen
(setq magit-display-buffer-function `magit-display-buffer-fullframe-status-v1)

Forge

Line numbers

Line numbers are helpful and relative line numbers are even better.

(setq display-line-numbers-type `relative)

Ansible

Since I want ansible to use the identities file since I have multiple ansible vault passwords I need to set the ansible-vault-password-file to nil.

;; (setq ansible-vault-password-file 'nil)

Org Mode Configuration

Let’s organize our life. Org mode is wonderful. There are so many great tutorials out there on how to maximize your efficiency with org-mode. I personal use it track my daily work using journals and org-agenda.

Default directory

We want a default file location for our org files. Let’s define that here.

(setq org-directory "~/org/")

todo-keywords

There are some keywords I want.

Org-Agenda

;; (setq org-agenda-files (directory-files-recursively "~/org" "\\`\\\(\\.org\\\|[0-9]\\\{8\\\}\\\(\\.gpg\\\)?\\\)\\'"))
;; (setq org-agenda-file-regexp "\\.org$")
(require 'org-faces)

;; (dolist (face '((org-level-1 . 1.2)
;;                 (org-level-2 . 1.1)
;;                 (org-level-3 . 1.05)
;;                 (org-level-4 . 1.0)
;;                 (org-level-5 . 1.1)
;;                 (org-level-6 . 1.1)
;;                 (org-level-7 . 1.1)
;;                 (org-level-8 . 1.1)))
  ;; (set-face-attribute (car face) nil :font "DejaVu Sans" :weight 'medium :height (cdr face)))
;; Make the document title a bit bigger
;; (set-face-attribute 'org-document-title nil :font "DejaVu Sans" :weight 'bold :height 1.3)

;; Make sure certain org faces use the fixed-pitch face when variable-pitch-mode is on
;; (set-face-attribute 'org-block nil :foreground nil :inherit 'fixed-pitch)
;; (set-face-attribute 'org-table nil :inherit 'fixed-pitch)
;; (set-face-attribute 'org-formula nil :inherit 'fixed-pitch)
;; (set-face-attribute 'org-code nil :inherit '(shadow fixed-pitch))
;; (set-face-attribute 'org-verbatim nil :inherit '(shadow fixed-pitch))
;; (set-face-attribute 'org-special-keyword nil :inherit '(font-lock-comment-face fixed-pitch))
;; (set-face-attribute 'org-meta-line nil :inherit '(font-lock-comment-face fixed-pitch))
;; (set-face-attribute 'org-checkbox nil :inherit 'fixed-pitch)

Org-Journal

Lets start by defining the directory where we want to store our journals

(setq org-journal-dir "~/org/journal/")

Now we can start modifying some of the org journal variables. Some of the variables are using in the journal templates as such I recommend looking at what each variable means.

(after! org
  (setq org-journal-file-format "%Y%m%d"
      org-journal-date-format "%A, %d %B %Y"
      org-journal-time-format 'nil ;; this is the defau;t entry. I set it to nil since I like to have one file for the whole day and don't use timestamps in my entry
      org-journal-file-header "#+TITLE: %A, %d %B %Y Daily Journal\nTreat yourself better today\n* Daily Questions\n1. On a scale of 1-10 how positive am I feeling?\n2. What is today's Goal?\n** Thinks to remember\nYou don't have to do something you get to.\nYou don't need todo something you want to.\nEnsure you understand the What and the Why, then have a generalized plan."
      ;; org-journal-file-header "#+TITLE: Daily Journal\nTreat yourself better today\n* Daily Questions\n1. On a scale of 1-10 how positive am I feeling?\n2. What is today's Goal?\n** Thinks to remember\nYou don't have to do something you get to.\nYou don't need todo something you want to.\nEnsure you understand the What and the Why, then have a generalized plan.\n* [/] TODOs\n** TODO\n* Meetings"
      org-journal-enable-agenda-integration 't))

Lets add some keybindings to make creation of journal entries a little easier. You can go full bore with this and add all org-journal commands you frequently use below.

(after! org
  (map! :leader
        (:prefix-map ("j" . "org-journal")
         (:prefix-map ("n" . "new entries")
          :desc "New journal entry" "n" #'org-journal-new-entry
          :desc "New date journal entry" "d" #'org-journal-new-date-entry
          :desc "New scheduled journal entry" "s" #'org-journal-new-scheduled-entry)
         (:prefix-map ("o" . "open entries")
          :desc "Current journal entry" "c" #'org-journal-open-current-journal-file
          :desc "Previous journal entry" "p" #'org-journal-open-previous-entry
          :desc "Next journal entry" "n" #'org-journal-open-next-entry)
         :desc "Search journal entry" "s" #'org-journal-search-entry)))

org-roam

org-roam enchances org capture and allows you to quickly and efficiently search and find notes. It also allows linking an finding what a note is linked to much faster.

Depending on your flavor of Emacs there is a few different ways to install this org-roam and I would point you the repo to the repository for information on how to install.

First thing to do is to set this in our packages.el

(package! org-roam)

Now lets setup the org-roam directory. On my home system I want to store my notes on different default directory

(use-package! org-roam
  :init
  (setq org-roam-directory roamdir)
  (setq org-roam-v2-ack 't)
  )

Capture templates

To make life easier we are going to make some custom templates that will allow us to work a little faster.

(setq org-roam-capture-templates
'(("d" "default" plain
   "%?"
   :target (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}\n#+category: ${title}")
  :unnarrowed t)
 ("l" "programing languages" plain
   "* Characteristics\n\n- Family: %?\n- Inspired by: \n\n*Reference:\n\n"
  :target (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}")
  :unnarrowed t)
 ("p" "project" plain
  "* Goals\n\n%?\n* Tasks\n\n** TODO Add initial tasks\n\n* Dates"
  :target (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}\n#+category: ${title}\n#+filetags: Project")
  :unnarrowed t)
 ))

Dailies (Replacing org-journals)

Lets setup org-roam-dailies

(setq org-roam-dailies-directory "journals/")
(setq org-roam-dailies-capture-templates
      '(("d" "default" entry "* %<%I:%M %p>: %?"
         :if-new (file+head "%<%Y-%m-%d>.org" "#+TITLE: %<%A, %d %B %Y>\n#+filetags: journal\nTreat yourself better today\n* Daily Questions\n1. On a scale of 1-10 how positive am I feeling?\n2. What is today's Goal?\n** Thinks to remember\nYou don't have to do something you get to.\nYou don't need todo something you want to.\nEnsure you understand the What and the Why, then have a generalized plan.\n* [/] TODOs\n** TODO\n* Meetings"))))

Lets setup some keybindings for org-roam that will make life easier.

(after! org-roam
  (map! :leader
        (:prefix-map ("r" . "org-roam")
         (:prefix-map ("n" . "new")
          (:prefix-map ("d" . "dailies")
           :desc "Today" "c" #'org-roam-dailies-capture-today
           :desc "Tomorrow" "t" #'org-roam-dailies-capture-tomorrow
           :desc "Yesterday" "y" #'org-roam-dailies-capture-yesterday)
          (:prefix-map ("n" . "notes")
           :desc "Find" "f" #'org-roam-node-find
           :desc "Insert" "i" #'org-roam-node-insert)
          ))))

Auto tangle org mode files

While it’s easy to use the `org-babel-tangle` function or it’s keybinding `C-c C-v t`. This requires me to remember to do this each time I make a modification to my org file. It would be nice if it was done on save automatically. There is useful package specifically designed for this purpose org-auto-tangle.

(package! org-auto-tangle)
(use-package! org-auto-tangle
  :defer t
  :hook (org-mode . org-auto-tangle-mode)
  :config
  (setq org-auto-tangle-default t))

To disable auto tangle on specific files just place `#+auto_tangle: nil` at the top of the org file

Export to confluence

Since we all know Atlassian products, while good, just don’t support org files nor do they really like markdown in Confluence. Thank to https://github.com/aspiers/orgmode/blob/master/contrib/lisp/ox-confluence.el there is an option to now write your Confluence pages in org and have limited formating issues.

(require 'ox-confluence)

org-jira

This seems like it might be useful but need to play around with it some before determining that.

(package! org-jira)

Let’s go ahead and use the package and define the directory we want our jira items stored.

(use-package! org-jira)
(setq org-jira-working-dir "~/org/jira")

The jira URL will be different for each place I work

;;(setq jiralib-url "https://bandwidth-jira.atlassian.net")
(after! auth-source
  (setq auth-sources (nreverse auth-sources)))

org-tree-mode

Due to some issues with the present.el in doom emac’s configurations we are did not add +present for the easy installation. However we are still going to install org-tree-mode. Along the way I’ll call out the issues I ran into with Doom’s setup.

First let’s set it up in the packages.el

;; (package! org-tree-slide)

Now let’s setup some default configurations for it. The file that ships with Doom has a function that causes an issue with sub headings and doesn’t allow you to go to the next sub heading. This functionality works out of the box with org-tree-macs by default. There is a few things that Doom’s setup did have which was kind of nice and we will be replicating that ourselves.

;; (defun efs/presentation-setup ()
;;   ;; Hide the mode line
;;   ;; (hide-mode-line-mode 1)

;;   ;; Display images inline
;;   (org-display-inline-images) ;; Can also use org-startup-with-inline-images

;;   ;; Scale the text.  The next line is for basic scaling:
;;   (setq text-scale-mode-amount 3)
;;   (text-scale-mode 1))
;; (defun efs/presentation-end ()
;;   ;; Show the mode line again
;;   ;; (hide-mode-line-mode 0)

;;   ;; Turn off text scale mode (or use the next line if you didn't use text-scale-mode)
;;   (text-scale-mode 0))

;;   ;; If you use face-remapping-alist, this clears the scaling:
;;   ;; (setq-local face-remapping-alist '((default variable-pitch default))))
;; (use-package! org-tree-slide
;;   :hook ((org-tree-slide-play . efs/presentation-setup)
;;          (org-tree-slide-stop . efs/presentation-end))
;;   ;; (add-hook 'org-tree-slide-play-hook #'+org-present-hide-blocks-h)
;;   :config
;;   (when (featurep! :editor evil)
;;     (map! :map org-tree-slide-mode-map
;;           :n [C-right] #'org-tree-slide-move-next-tree
;;           :n [C-left]  #'org-tree-slide-move-previous-tree)
;;     (add-hook 'org-tree-slide-mode-hook #'evil-normalize-keymaps))
;;   :custom
;;   (org-tree-slide-slide-in-effect t)
;;   (org-tree-slide-activate-message "Presentation started!")
;;   (org-tree-slide-deactivate-message "Presentation finished!")
;;   (org-tree-slide-header t)
;;   (org-tree-slide-breadcrumbs " > ")
;;   (org-image-actual-width nil))

org-present

I really like the presentations from SystemCrafters so this is an exact replication of the configuration he uses.

First up is install org-present

;; (package! org-present)

Styling

Next up to make things centered lets install a helpful package

;; (package! visual-fill-column)

Let’s make some quick setting for visual-fill-column

;; Configure fill width
;; (setq visual-fill-column-width 110
;;       visual-fill-column-center-text t)

functional

SystemCrafters Code

Here is the code from SystemCrafters as is but we are going to convert this to use-package

(defun my/org-present-start ()
  ;; Center the presentation and wrap lines
  (visual-fill-column-mode 1)
  (visual-line-mode 1))

(defun my/org-present-end ()
  ;; Stop centering the document
  (visual-fill-column-mode 0)
  (visual-line-mode 0))

;; Register hooks with org-present
(add-hook 'org-present-mode-hook 'my/org-present-start)
(add-hook 'org-present-mode-quit-hook 'my/org-present-end)

My Config

;; ;; Function to house the modifications for org-present to make it look nice when it starts
;; (defun my/org-present-start ()
;;   ;; Tweak font sizes
;;   (setq-local face-remapping-alist '((default (:height 1.5) variable-pitch)
;;                                      (header-line (:height 4.0) variable-pitch)
;;                                      (org-document-title (:height 1.75) org-document-title)
;;                                      (org-code (:height 1.55) org-code)
;;                                      (org-verbatim (:height 1.55) org-verbatim)
;;                                      (org-block (:height 1.25) org-block)
;;                                      (org-block-begin-line (:height 0.7) org-block)))

;;   ;; Set a blank header line string to create blank space at the top
;;   (setq header-line-format " ")

;;   ;; Since we are presenting let's hide the emphasis markers to make things a little prettier
;;   (setq org-hide-emphasis-markers t)

;;   ;; Display inline images automatically
;;   (org-display-inline-images)

;;   ;; Center the presentation and wrap lines
;;   (visual-fill-column-mode 1)
;;   (visual-line-mode 1))

;; ;; Undo the presentation setup when we end the presentation
;; (defun my/org-present-end ()
;;   ;; Reset font customizations
;;   (setq-local face-remapping-alist '((default variable-pitch default)))

;;   ;; Clear the header line string so that it isn't displayed
;;   (setq header-line-format nil)

;;   ;; Stop displaying inline images
;;   (org-remove-inline-images)
;;   ;; Stop centering the document
;;   (visual-fill-column-mode 0)
;;   (visual-line-mode 0))

;; ;; Register hooks with org-present
;; (use-package! org-present
;;   :commands org-present-mode
;;   ;; :bind-keymap
;;   ;; ("SPC" . org-present-mode-keymap)
;;   :hook ((org-present-mode . my/org-present-start)
;;          (org-present-mode-quit . my/org-present-end)))
;; ;; (after! org-present-mode
;; ;;   (when (featurep! :editor evil)
;; ;;     (map! :map org-present-mode-keymap
;; ;;           :n [C-right] #'org-present-next
;; ;;           :n [C-left]  #'org-present-prev))
;; ;;   )

Pandoc

org-pandoc-import has a dependency of pandoc. This is available via brew and most package managers. You can find installation information in the Pandoc install documentation.

(package! org-pandoc-import
  :recipe (:host github
           :repo "tecosaur/org-pandoc-import"
           :files ("*.el" "filters" "preprocessors")))
(use-package! org-pandoc-import :after org)

Some helpful functions to know

  • org-pandoc-import-to-org: Parses the file to an `org-mode` file and opens.
  • org-pandoc-import-as-org: Parses the file to an `org-mode` file and opens ina new buffer.

After org loads

Org mode styling

A couple of UI tweaks to make things a little more friendly in org-mode.

(after! org
  (setq org-fontify-done-headline nil))

Hide the Org mark up indicators

I like seeing the emphasis markers but if you don’t just uncomment this block. This will hide the prefix and suffix characters used when making items bold, italic, etc

;; (after! org (setq org-hide-emphasis-markers t))

Enable logging of done tasks, and log stuff into the LOGBOOK drawer by default

(after! org
  (setq org-log-done t)
  (setq org-log-into-drawer t))

Custom structure templates

In order to work around the update with org-version 9.2 change to the structure template expansion

Change in the structure template expansion

Org 9.2 comes with a new template expansion mechanism, combining org-insert-structure-template bound to C-c C-,.

If you customized the org-structure-template-alist option manually, you probably need to udpate it, see the docstring for accepted values.

If you prefer using previous patterns, e.g. <s, you can activate them again by requiring Org Tempo library:

(when (version<= "9.2" (org-version))
    (require 'org-tempo))

Adding some handy structure templates to save a few keystrokes when adding code blocks in org mode.

(after! org
  (add-to-list 'org-structure-template-alist '("sh" . "src sh"))
  (add-to-list 'org-structure-template-alist '("js" . "src js"))
  (add-to-list 'org-structure-template-alist '("el" . "src emacs-lisp"))
  (add-to-list 'org-structure-template-alist '("py" . "src python")))

Helpful Keybindings

I can never remember the keybindings so this is a place for me to quickly find them.

FunctionDescriptionKeybinding
org-clock-inStarts the clock on current item.SPC m c i
org-clock-outStops the running clock on current item.SPC m c o
org-set-tags-commandSet the tags for the currently visible item.SPC m q
org-tags-viewShow all headlines for all org-agenda-files matching a TAGS criterion.SPC n m
org-insert-linkInsert a link.SPC m l g
org-todoChange the TODO state of an item.SPC m t

Grammarly

(package! lsp-grammarly)
(use-package! lsp-grammarly
  :hook (text-mode . (lambda()
                       (require 'lsp-grammarly)
                       (lsp))))
(setq langtool-bin "/opt/homebrew/bin/languagetool")

Jenkinsfile

(package! jenkinsfile-mode :recipe
  (:host github
   :repo "john2x/jenkinsfile-mode"
   :branch "master"))

Custom keybindings

Just in case I need some short cuts to a actions that don’t already have bindings and don’t belong any other areas. Most of the keybindings should be defined by their corresponding modes.

Flycheck

(map! :leader
        (:prefix-map ("e" . "errors")
        :desc "flycheck list errors" "l" #'flycheck-list-errors
        :desc "flycheck list errors" "n" #'flycheck-next-error
        :desc "flycheck list errors" "p" #'flycheck-previous-error))

Debugging

One thing that is great is the ability to step through some code when encountering an issue. In order for this to work in emacs there is some configuration required. Lets go ahead and do that now.

First up is dap-mode. dap-mode does need lsp-mode running in order to work but we will configure lsp in a later section when we get to programming languages.

Let’s install the package this will be placed into the packages.el file.

(package! dap-mode)

Now let’s configure it some. I use the default configurations while I am playing around with dap-mode but you can customize the items you want to see.

  • sessions - adds the sessions buffer to the window layout on the right hand side.
  • locals - adds the locals buffer to the window layout on the right hand side.
  • controls - adds a floating control bar that provides you buttons you can click to perform actions like step into, step over, continue, and stop NOTE this requires emacs 26+
  • tooltip - adds tooltips on mouse hover.
(use-package! dap-mode)
(setq dap-auto-configure-features '(sessions locals controls tooltip))

Launching the debugger

To launch the debugger using dap mode the following commands are available. Descriptions of the functions can be found in the table below where I specific the keybindings I’m going to setup.

  • dap-debug
  • dap-debug-last
  • dap-debug-recent
  • dap-disconnect
  • dap-delete-session
  • dap-delete-all-sessions

Adding breakpoints

  • dap-breakpoint-add
  • dap-breakpoint-toggle

Some other breakpoint commands which may come in handy as time goes on.

  • dap-breakpoint-hit-condtion
  • dap-breakpoint-condtion
  • dap-breakpoint-log-message
  • dap-breakpoint-delete
  • dap-breakpoint-delete-all

dap-hydra

Running dap-hydra allows you to use keys to perform several of the normal debugging actions you would take in most IDEs like step in, step over (next), continue, etc. It will pop open a menu in the modeline showing you all the commands and their corresponding keys. This is extremely useful.

When dap-hydra is running it will receive all keystrokes so make sure when you are done with it you press q this will quit dap-hydra.

Keybindings

Lets put these useful commands in easy to use keybindings. SPC d

FunctionDescriptionKeybinding
dap-debugSelect a template to executeSPC d d n
dap-debug-lastRun last executed templateSPC d d l
dap-debug-recentSelect a template from the most recently ran templatesSPC d d r
dap-disconnectDisconnect the current debug sessionSPC d d d
dap-delete-sessionRemove the current debug session bufferSPC d s d
dap-delete-all-sessionsTerminate/Remove all the sessions and buffersSPC d s D
dap-breakpoint-addAdd a breakpoint on the current lineSPC d b a
dap-breakpoint-toggleToggle breakpoint on current lineSPC d b t
dap-breakpoint-conditionSet breakpoint condition for the breakpoint at cursorSPC d b c
dap-breakpoint-hit-conditionSet breakpoint hit condition for the breakpoint at point.SPC d b h
dap-breakpoint-log-messageSet breakpoint log message for the breakpoint at point.SPC d b l
dap-breakpoint-deleteDelete breakpoint on the current line.SPC d b d
dap-breakpoint-delete-allDelete all breakpoints.SPC d b D
dap-hydraRuns dap-hydraSPC d h
(after! dap-mode
  (map! :leader
        (:prefix-map ("d" . "dap commands")
        (:prefix-map ("d" . "dap-debug commands")
         :desc "Select a debug template to execute" "n" #'dap-debug
         :desc "Run most recently executed templated" "l" #'dap-debug-last
         :desc "Select a recent template to run" "r" #'dap-debug-recent
         :desc "Disconnect from current session" "d" #'dap-disconnect)
        (:prefix-map ("s" . "dap-debug session commands")
         :desc "Delete current session bufer" "d" #'dap-delete-session
         :desc "Delete all session buffers" "D" #'dap-delete-all-sessions)
        (:prefix-map ("b" . "dap-breakpoint commands")
         :desc "Add breakpoint" "a" #'dap-breakpoint-added
         :desc "Toggle breakpoint" "t" #'dap-breakpoint-toggle
         :desc "Add breakpoint condition" "c" #'dap-breakpoint-condition
         :desc "Add breakpoint hit condition" "h" #'dap-breakpoint-hit-condition
         :desc "Add breadkpoint log message" "l" #'dap-breakpoint-log-message
         :desc "Delete breakpoint" "d" #'dap-breakpoint-delete
         :desc "Delete all breakpoints" "D" #'dap-breakpoint-delete-all)
        :desc "dap-hydra" "h" #'dap-hydra)))

Customizing debug template

We can change our debug templates manually by way of `dap-debug-edit-template`. These are globally defined which may not be helpful in most cases. The below is an example of how to configure a template. It would be best if you added a debug.el file to your project root and define the custom templates there.

Look at the dap-mode documentation for further information regarding configuration as this changes based upon language.

;; (dap-register-debug-template
;;  "Debug Server"
;;  (list :type "node"
;;        :request "launch"
;;        :program "${workspaceFolder}/path/to/program"
;;        :outFiles ["${workspaceFolder/path/to/out/files}"]
;;        :name "Debug Server")
;;  )

VSCode launch.json

If you have already have a .vscode directory with existing launch.json files which contain run commands. These will automatically be visiable in the list of templates when you run dap-debug.

Languages

lsp-mode

Text description borrowed from daviwil/emacs-from-scratch

We use the excellent lsp-mode to enable IDE-like functionality for many different programming languages via “language servers” that speak the Language Server Protocol. Before trying to set up lsp-mode for a particular language, check out the documentation for your language so that you can learn which language servers are available and how to install them.

The lsp-keymap-prefix setting enables you to define a prefix for where lsp-mode’s default keybindings will be added. I highly recommend using the prefix to find out what you can do with lsp-mode in a buffer.

The which-key integration adds helpful descriptions of the various keys so you should be able to learn a lot just by pressing C-c l in a lsp-mode buffer and trying different things that you find there.

(defun efs/lsp-mode-setup ()
  (setq lsp-headerline-breadcrumb-segments '(path-up-to-project file symbols))
  (lsp-headerline-breadcrumb-mode 't))

(use-package! lsp-mode
  :commands (lsp lsp-deferred)
  :hook (lsp-mode . efs/lsp-mode-setup)
  :init
  (setq lsp-keymap-prefix "C-c l")
  :config
  (lsp-enable-which-key-integration t))

gha

;; Use shopify-cli / theme-check-language-server for Shopify's liquid syntax
;; (with-eval-after-load 'lsp-mode
;;   (add-to-list 'lsp-language-id-configuration
;;     '(shopify-mode . "shopify"))

  ;; (lsp-register-client
  ;;   (make-lsp-client :new-connection (lsp-stdio-connection "actions-languageserver")
  ;;                    :activation-fn (lsp-activate-on "yaml")
  ;;                    :server-id 'actions-languageserver))
;;(lsp-generate-settings "/Users/tmonck/code/languageservices/package.json" 'lsp-gha)

lsp-ui

Is this something we want? More than likely the answer is yes. This is adds some ui compliments on top of lsp-mode

(use-package! lsp-ui
  :hook (lsp-mode . lsp-ui-mode)
  :custom
  (lsp-ui-doc-position 'bottom))

Python

(use-package! python-mode
  :mode "\\.py\\'"
  :hook (python-mode . lsp-deferred))

Typescript

Configure typescript mode to make things better

(use-package! typescript-mode
  :mode "\\.ts\\'"
  :hook (typescript-mode . lsp-deferred)
  :config
  (setq typescript-indent-level 2)
  (require 'dap-node)
  (dap-node-setup) ;; Automatically installs Node debug adapter if needed
)

Javascript

Configure javascript and enable debugging for it.

(use-package! js2-mode
  :mode "\\.js\\'"
  :hook (js2-mode . lsp-deferred)
  :config
  (require 'dap-node)
  (dap-node-setup))

golang

;; Add a hook?
(use-package! go-mode
  :mode "\\.go\\'"
  ;; :hook (go-mode . #'lsp-deferred)
  :config
  (require 'dap-go)
  (dap-go-setup))

Lets setup the lsp-mode for golang based upon their recommendations

;; (defun lsp-go-install-save-hooks ()
;;   (add-hook 'before-save-hook #'lsp-format-buffer t t)
;;   (add-hook 'before-save-hook #'lsp-organize-imports t t))
;; (add-hook 'go-mode-hook #'lsp-go-install-save-hooks)
(setq lsp-go-build-flags '["-tags=integration"])

Vue

Configure Vue.js

(package! vue-mode)
(use-package! vue-mode
  :mode "\\.vue\\'"
  :hook (vue-mode . lsp-deferred)
  :config
  (require 'dap-node)
  (dap-node-setup))

shell

#+begin _src emacs-lisp (add-to-list ‘auto-mode-alist ‘(“\.bash_aliases\’” . sh-mode)) (add-to-list ‘auto-mode-alist ‘(“\.bash_colors\’” . sh-mode))

yaml

I want to disable the autoformat on save.

;; (add-to-list '+format-on-save-enabled-modes (not ("yaml-mode")))

Workspaces and Projects

Workspaces are nice for isolating work and projects are extremely helpful for debugging purposes. I like having my projects in their own workspaces.

(setq workspaces-on-switch-project-behavior 't)

Github Copilot

Copilot Completion

(package! copilot
  :recipe (:host github :repo "zerolfx/copilot.el" :files ("*.el" "dist")))
(use-package! copilot
  :hook (prog-mode . copilot-mode)
  :bind (:map copilot-completion-map
              ("M-]" . 'copilot-next-completion)
              ("<tab>" . 'copilot-accept-completion)
              ("TAB" . 'copilot-accept-completion)
              ("C-TAB" . 'copilot-accept-completion-by-word)
              ("C-<tab>" . 'copilot-accept-completion-by-word)))

Copilot Chat

(package! copilot
  :recipe (:host github :repo "chep/copilot-chat.el" :files ("*.el")))
(use-package! copilot-chat)