- Acknowledgements
- Safe files
- Doom configuration files
- Me
- Customize the look and feel
- Magit
- Line numbers
- Ansible
- Org Mode Configuration
- Grammarly
- Jenkinsfile
- Custom keybindings
- Debugging
- Languages
- Workspaces and Projects
- Github Copilot
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.
- zzamboni - the first two sections are copies from here with a few word changes.
- daviwil - he has a youtube channel with lots of great content.
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
.
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 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))
(setq native-comp-deferred-compilation nil)
(after! (doom-packages straight)
(setq straight--native-comp-available t))
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)
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]")
;; 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)
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)
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)
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)
)
For some reason I like my editor to be somewhat see through so let’s adjust the opacity.
(doom/set-frame-opacity 90)
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)
Line numbers are helpful and relative line numbers are even better.
(setq display-line-numbers-type `relative)
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)
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.
We want a default file location for our org files. Let’s define that here.
(setq org-directory "~/org/")
There are some keywords I want.
;; (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)
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 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)
)
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)
))
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"))))
(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)
))))
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
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)
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)))
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))
I really like the presentations from SystemCrafters so this is an exact replication of the configuration he uses.
;; (package! org-present)
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)
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)
;; ;; 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))
;; ;; )
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.
A couple of UI tweaks to make things a little more friendly in org-mode.
(after! org
(setq org-fontify-done-headline nil))
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))
(after! org
(setq org-log-done t)
(setq org-log-into-drawer t))
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")))
I can never remember the keybindings so this is a place for me to quickly find them.
Function | Description | Keybinding |
org-clock-in | Starts the clock on current item. | SPC m c i |
org-clock-out | Stops the running clock on current item. | SPC m c o |
org-set-tags-command | Set the tags for the currently visible item. | SPC m q |
org-tags-view | Show all headlines for all org-agenda-files matching a TAGS criterion. | SPC n m |
org-insert-link | Insert a link. | SPC m l g |
org-todo | Change the TODO state of an item. | SPC m t |
(package! lsp-grammarly)
(use-package! lsp-grammarly
:hook (text-mode . (lambda()
(require 'lsp-grammarly)
(lsp))))
(setq langtool-bin "/opt/homebrew/bin/languagetool")
(package! jenkinsfile-mode :recipe
(:host github
:repo "john2x/jenkinsfile-mode"
:branch "master"))
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.
(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))
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))
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
- 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
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
.
Lets put these useful commands in easy to use keybindings. SPC d
Function | Description | Keybinding |
dap-debug | Select a template to execute | SPC d d n |
dap-debug-last | Run last executed template | SPC d d l |
dap-debug-recent | Select a template from the most recently ran templates | SPC d d r |
dap-disconnect | Disconnect the current debug session | SPC d d d |
dap-delete-session | Remove the current debug session buffer | SPC d s d |
dap-delete-all-sessions | Terminate/Remove all the sessions and buffers | SPC d s D |
dap-breakpoint-add | Add a breakpoint on the current line | SPC d b a |
dap-breakpoint-toggle | Toggle breakpoint on current line | SPC d b t |
dap-breakpoint-condition | Set breakpoint condition for the breakpoint at cursor | SPC d b c |
dap-breakpoint-hit-condition | Set breakpoint hit condition for the breakpoint at point. | SPC d b h |
dap-breakpoint-log-message | Set breakpoint log message for the breakpoint at point. | SPC d b l |
dap-breakpoint-delete | Delete breakpoint on the current line. | SPC d b d |
dap-breakpoint-delete-all | Delete all breakpoints. | SPC d b D |
dap-hydra | Runs dap-hydra | SPC 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)))
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")
;; )
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.
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))
;; 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)
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))
(use-package! python-mode
:mode "\\.py\\'"
:hook (python-mode . lsp-deferred))
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
)
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))
;; 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"])
Configure Vue.js
(package! vue-mode)
(use-package! vue-mode
:mode "\\.vue\\'"
:hook (vue-mode . lsp-deferred)
:config
(require 'dap-node)
(dap-node-setup))
#+begin _src emacs-lisp (add-to-list ‘auto-mode-alist ‘(“\.bash_aliases\’” . sh-mode)) (add-to-list ‘auto-mode-alist ‘(“\.bash_colors\’” . sh-mode))
I want to disable the autoformat on save.
;; (add-to-list '+format-on-save-enabled-modes (not ("yaml-mode")))
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)
(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)))
(package! copilot
:recipe (:host github :repo "chep/copilot-chat.el" :files ("*.el")))
(use-package! copilot-chat)