Skip to content

Emacs from Scratch

Source: My personal notes from System Crafter’s Emacs configuration video series

  • David Wilson - System Crafter’s own configuration
    • Use org file to manage configurations
    • Linux running GNU GUIX
  • Navigate files: find-files
  • Switch buffers: switch-to-buffer
  • Run emacs for first time: emacs -q
  • Run emacs for first time with your configuration: emacs -q -l init.el
  • In the video, we build a basic configuration init.el
  • See code
  • Open init.el below and reload changes to init.el within emacs to see immediate changes: M-x eval-buffer
  • Evaluate the current elisp expression with C-x C-e or eval-last-sexp

Source

  • Configuration from stream
  • Suggest replace Caps Locks with Control to improve ergonomics
  • Improve help, navigation, and command execution with ivy-rich, counsel, helpful, which-key and others. Bind keys and commands to better or easier versions.
  • Use general package for keybindings
  • Use check-parens for unbalance parentheses
  • Use evil-mode for vim keybindings
  • Run list-packages to refresh packages to prevent errors on update and use packages

Source

  • Global find file in project/projects: C-c p f

  • Projectile can run a command for project to:

    • Start project
    • Test
    • Compile
    • Set up local variables and settings for Emacs to use
  • Counsel-projectile-rg can grep inside a folder

  • Magit is a git interface for Emacs

    • Easily correct commits, branching
    • Move newer commits from master to a separate branch
    • Move new staged changes to older commits using commit menu and then instant fix up option
    • Combine commits using rebase menu and interactive rebase, then squash to combine commits
    • Active command line options by pressing keys in the menu (e.g. -f in push menu to force push)
    • Stash changes temporarily to get remote changes
  • Forge - package to improve magit abilities

Pointer to what I am listening to

Source

  • Org mode is an outliner, a note taking system, a task manager, a project management tool, a calendar, a diary, a publishing system, a markup language, and a literate programming environment.

and:

Interactive computing (source code blocks in org mode)

Task Management:

  • Default is TODO and DONE states. More can be customized with org-todo-keywords

6 - Organize your life with Org Mode - Project/task management

Section titled “6 - Organize your life with Org Mode - Project/task management”

Source

  • Set org-deadline-warning-days for deadline reminders
  • Can use queries to manage tasks (e.g. org-ql)
  • Can set up repeating tasks from org-time-stamp like birthdays
    • Notifications can be enabled using org-wild-notifier
  • Refile DONE tasks using: org-refile-targets
    • Set up autosave after refiling so all org files are saved
  • Quickly capture something without disrupting your flow
  • Use templates to capture tasks: with configuration org-capture-templates and activate using org-capture
  • Items like journal entries, tasks, notes, custom entries in a specific org file
  • Use define-key to bind org-capture to speed up captures

Source part of video:

  • Dashboard
  • Next actions
  • Tags with Tasks
    • Add tag with counsel-org-tag. Add multiple tags with M-Enter
    • Queries based on tags
    • In configuration, add your custom tags with org-tag-alist
    • Set multiple tags with hotkeys: org-set-tags-command
  • Set up a custom agenda - like a kanban board with org-agenda-custom-commands and configurations. See example:
;; Configure custom agenda views
(setq org-agenda-custom-commands
'(("d" "Dashboard"
((agenda "" ((org-deadline-warning-days 7)))
(todo "NEXT"
((org-agenda-overriding-header "Next Tasks")))
(tags-todo "agenda/ACTIVE" ((org-agenda-overriding-header "Active Projects")))))
("n" "Next Tasks"
((todo "NEXT"
((org-agenda-overriding-header "Next Tasks")))))
("W" "Work Tasks" tags-todo "+work-email")
;; Low-effort next actions
("e" tags-todo "+TODO=\"NEXT\"+Effort<15&+Effort>0"
((org-agenda-overriding-header "Low Effort Tasks")
(org-agenda-max-todos 20)
(org-agenda-files org-agenda-files)))
("w" "Workflow Status"
((todo "WAIT"
((org-agenda-overriding-header "Waiting on External")
(org-agenda-files org-agenda-files)))
(todo "REVIEW"
((org-agenda-overriding-header "In Review")
(org-agenda-files org-agenda-files)))
(todo "PLAN"
((org-agenda-overriding-header "In Planning")
(org-agenda-todo-list-sublevels nil)
(org-agenda-files org-agenda-files)))
(todo "BACKLOG"
((org-agenda-overriding-header "Project Backlog")
(org-agenda-todo-list-sublevels nil)
(org-agenda-files org-agenda-files)))
(todo "READY"
((org-agenda-overriding-header "Ready for Work")
(org-agenda-files org-agenda-files)))
(todo "ACTIVE"
((org-agenda-overriding-header "Active Projects")
(org-agenda-files org-agenda-files)))
(todo "COMPLETED"
((org-agenda-overriding-header "Completed Projects")
(org-agenda-files org-agenda-files)))
(todo "CANC"
((org-agenda-overriding-header "Cancelled Projects")
(org-agenda-files org-agenda-files)))))))
  • Uses org-habit
  • Check you are regularly doing habits by tracking it

Source

  • Org babel allows you to be put code blocks into your org files and execute and see results

  • Turn on/off ask for confirmation on code execution using: org-confirm-babel-evaluate

  • Use org tangle to output source to files. After configuration in org file, use org-babel-tangle to output files, can concatenate output into one file.

    • e.g. #+begin_src elisp :tangle ~/emacs-scratch/init-new.el
  • You can define output tangle file for org file using org file property at top of file

  • Output all tangles from an org in an automated way:

(org-babel-tangle)
(org-babel-tangle-file "~/Projects/Code/emacs-from-scratch/Emacs.org")
  • Use tangle to output to different files like #+begin_src conf :tangle ~/.gitconfig :mkdirp yes. :mkdirp yes says to create the directory if the source file doesn’t exist yet.

  • Allows you to pass variables into babel using noweb

  • Use imenu to navigate to org headings

Source

  • Langauge Server Protocop (LSP)-mode addresses multiple language editing in different editors
  • Emacs LSP
  • History is OmniSharp came up with idea and VS Code developed it
  • Each langauge server (LS) allows different messages to editor. Some LS have more features than others.
  • Emacs LSP-mode is a package to allow Emacs to be a client to LSPs
  • For video, will use TypeScript language:
    • Prerequisite: Install LS of the target language. For TypeScript which requires npm installed.
    • Restart Emacs after LS is installed and open file to see LSP starting

LSP features:

  • Default completion in Emacs - suggestions at cursor: completion-at-point
  • Information about methods, variables when highlighted or using completions
  • Highlighting text provides feedback like highlight variable throughout code
  • Find references: C-c l g r
  • Find definitions: C-c l g g
  • Refactor like rename: C-c l r
  • Diagnostics - problem checks
    • Flymake tracks problems in file: flymake-show-buffer-diagnostics
      • Modeline will display lightbulb for quick fixes
  • Code formatting C-c l = =
  • Comment line with comment...
  • Integrate with other packages to enhance:
    • Ivy for search of symbols and other
    • Treemacs for references, symbols, messages, files

Source

  • Learn and configure terminal and shell modes in Emacs

  • term: Terminal emulator in emacs lisp, will be slower then other terminals and is available in default emacs. It emulates being on a console and interrupts control codes and sends and share input/output.

    • term-char-mode: Send keys directly to emulators
    • term-line-mod: Regular mode, all Emacs commands, buffer manipulation are enabled
    • Opening it again will return you to same terminal unless you rename first terminal buffer
  • ansi-term: automatically opens a new terminal each time

  • Term and ansi-term is hardcoded to using sh. It is not possible to use is easily in Windows. If on Windows, use shell instead.

  • vterm: uses native compiled library and requires dependencies and allows it to be faster

  • shell: like in between terminal and eshell.

    • Not terminal emulator, just a shell with buffer I/O is managed by emacs

    • Disadvantages: certain commands like htop will not work

    • Advantages:

      • Emacs buffer editing and commands can work. E.g. shell history
    • For Windows, configure powershell as default is an option

      (when (eq system-type 'windows-nt)
      (setq explicit-shell-file-name "powershell.exe")
      (setq explicit-powershell.exe-args '()))
  • eshell: native, consistent, bash like, emacs lisp shell and provides full access and integration with Emacs

    • Pros:
      • Bash shell replication
      • Support aliases
      • Consistent shell across operating systems
      • Can run Elisp REPL and Emacs commands like dired
      • Can redirect output to buffers
    • Cons compared to terminal:
      • Less completions
      • Slower
      • Syntax differences
      • Some tools do not work like nvm, virtualenv
  • Recommendations:

    • Use ansi-term and vterm for terminal emulation
    • Use shell for native shells
    • Use eshell for cross platform consistency and Emacs lisp. Has potential.

10 - Effortless File Management with Dired

Section titled “10 - Effortless File Management with Dired”

Source:

Emacs From Scratch #10 - Effortless File Management with Dired

  • C-x d to open dired
    • Looks like ls output
  • Configure with dired-listing-switches
    • dired-listing-switches "-alh" to show hidden files and human readable sizes
    • dired-listing-switches "-alh --group-directories-first" to group directories first
    • dired-listing-switches "-alh --group-directories-first --color=always" to show colors
  • Use package “dired single” to prevent multiple dired buffers remaining
    • Use package “dired-hide-dotfiles” to toggle showing dot (hidden) files

11 - Keeping Your Emacs Packages Up to Date

Section titled “11 - Keeping Your Emacs Packages Up to Date”

Source:

  • Keeping Your Emacs Packages Up To Date - Emacs From Scratch #11

  • Emacs won’t remind you to update your packages, it won’t do background checks. You have to do it manually.

  • List packages: M-x list-packages

    • U to mark for update
    • x to execute update
    • i to mark for install
    • d to mark for delete
    • r to refresh
    • g to refresh and update
    • q to quit
  • Manual update:

    • Use list-packages
    • U to mark ones ready for update
    • x get upgrades
    • Restart Emacs
  • Automatic update:

    • Can use a package auto-package-update
    • M-x auto-package-update-now to update
  • Should you auto update?

    • Updates could break your Emacs

12 - How to Cut Emacs Start Up Time in Half

Section titled “12 - How to Cut Emacs Start Up Time in Half”

Source:

  • Emacs start up time can get slow as you configure and use more packages.

  • It is not daemon mode related where Emacs and always running as daemon

  • Does Emacs actually start slow? no, try emacs -Q to start without any configuration and see it is instant.

You can track start up times with dashboard package or example:

;; Track start up time and number of garbage collections
(defun efs/display-startup-time ()
(message "Emacs loaded in %s with %d garbage collections."
(format "%.2f seconds"
(float-time
(time-subtract after-init-time before-init-time)))
gcs-done))
(add-hook 'emacs-startup-hook #'efs/display-startup-time)

All start up stuff can be seen in function normal-top-level and/or read list of Summary: Sequence of Actions at Startup.

See tips

use-package gives you a few different ways to defer package loading:

  • :hook - Package will be loaded the first time one of the hooks is invoked
  • :bind - Package will be loaded the first time one of the key bindings is used
  • :commands - Package will be loaded when one of the commands are used
  • :mode - Package will be loaded the first time a file with a particular extension is opened
    • Regexp pattern on file before a mode is loaded
  • :after - Load this package after other specific packages are loaded
  • :defer - If you don’t use any of the other options, this one will defer loading until after startup
    • Defer to later or number of seconds after startup
    • Determine if packages needs to be there at startup, otherwise defer
  • :demand t - If you want to load a package at startup despite other options, use demand
  • Load stuff after other things using with-eval-after-load
  • Adjust garbage collection. See also package gcmh that adjusts garbage collections during run time

Emacs from Scratch Old Series - Final Init.el

Section titled “Emacs from Scratch Old Series - Final Init.el”

See my dotfiles

The Basics of Emacs Configuration

  • Edit Emacs configuration in a file in Emacs Lisp language
    • ~/.emacs or ~/.emacs.d/init.el
    • Recommendation for Linux ~/.config/emacs/init.el

Common use cases:

  • Set variables
  • Change features
;; Do not show splash screen
;; Flash on warnings
(setq inhibit-startup-message t
visble-bell t) ;; Comment at end of line
;; t = true
;; nil = false
  • This is a lisp expression (wrapped in parentheses) that is a “call” to a function called setq. The function setq takes two arguments, the first is the variable name and the second is the value to set it to.
  • Variable and function names in Emacs are usually form some-variable-name = lower case words with hyphen characters between them.
  • You can evaluate Emacs configuration as it is running.
;; Disable tool bar
(tool-bar-mode -1)
  • -1 in this case means false
  1. Setting Theme

    ;; Set theme to Modus Vivendi (Emacs 28 and later)
    (load-theme 'modus-vivendi t)

    ' before modus-vivendi tells lisp to not evaluate the theme’s name and just read it as a name

Get documentation

  • describe-symbol - documentation on any

Can read from cursor:

  • describe-variable - documentation on any variable
  • describe-function - documentation on any function

N2 The 6 Emacs Settings Every User Should Consider

Section titled “N2 The 6 Emacs Settings Every User Should Consider”

The 6 Emacs Settings Every User Should Consider

  • (recentf-mode 1) - recall recently opened file

  • (savehist-mode 1) - save history of minibuffer

    • I use package amx instead which saves recent commands and recalls them during M-x
  • (save-place-mode 1) - remember the last place you visited in a file

  • Save customization variables to a different place instead of your init.el

(setq custom-file (locate-user-emacs-file "custom-vars.el")
(load custom-file 'noerror 'nomessage)
  • use-dialog-box nil - disable graphical dialog boxes
  • (global-auto-revert-mode 1) - automatically check for changes on disk. To manually update files if this mode is not on in the buffer, use revert-buffer
    • (setq global-auto-revert-non-file-buffers t) - check for changes in non-file buffers

Sources: Video Series from System Crafters

Section titled “Sources: Video Series from System Crafters”
  • Emacs from Scratch Series - customization, UI, Bindings, Projectile, Magit, Org Mode, IDE and LSP-mode, Terminal, File Management with Dired, Update packages, Cut start up times
  • Configuration with Org Babel (configuration)