Skip to content

My own Emacs configuration. Inspired by Doom Emacs.

Notifications You must be signed in to change notification settings

42LoCo42/emacs-config

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

72 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

My Emacs configuration

Package management

Load straight

straight is a purely functional package manager for Emacs. It enables 100% reproducible package management and makes editing packages very easy!

Initialization code taken directly from https://github.com/radian-software/straight.el#getting-started

(defvar bootstrap-version)
(let ((bootstrap-file
       (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
      (bootstrap-version 6))
  (unless (file-exists-p bootstrap-file)
    (with-current-buffer
        (url-retrieve-synchronously
         "https://raw.githubusercontent.com/radian-software/straight.el/develop/install.el"
         'silent 'inhibit-cookies)
      (goto-char (point-max))
      (eval-print-last-sexp)))
  (load bootstrap-file nil 'nomessage))

Load use-package

use-package is a tool to declaratively specify package configuration. This increases performance (not everything is loaded at once) and tidiness. use-package integrates with straight to fetch packages.

(straight-use-package 'use-package)
(use-package straight
  :custom (straight-use-package-by-default t))

Custom Functions

split-window fix

The default behaviour of the split-window functions is to just split, but not to select the new window. These functions are a fix for that. They also balance the window layout.

(defun my/split-switch-below ()
  "Split and switch to window below."
  (interactive)
  (split-window-below)
  (balance-windows)
  (other-window 1))

(defun my/split-switch-right ()
  "Split and switch to window on the right."
  (interactive)
  (split-window-right)
  (balance-windows)
  (other-window 1))

bspwm-like window splitting

Automatically selects the next split direction. Inspired by this post: https://www.reddit.com/r/tmux/comments/j7fcr7/tiling_in_tmux_as_in_bspwm

(defun my/autosplit ()
  (interactive)
  (if (greaterthan 0 (- (* 8 (window-total-width)) (* 20 (window-total-height))))
    (my/split-switch-below)
    (my/split-switch-right)))

Repeatably join a line

This wraps the standard function join-line by moving to the start of the next line, where it can be reapplied immediately to quickly join multiple lines.

(defun my/join-line ()
  (interactive)
  (join-line)
  (forward-line 1)
  (back-to-indentation))

A smarter C-a

This function allows jumping to the start of the line or the first non-whitespace character just by calling it repeatedly.

(defun my/smart-home ()
  "Jump to beginning of line or first non-whitespace."
  (interactive)
  (let ((oldpos (point)))
    (back-to-indentation)
    (and (= oldpos (point)) (beginning-of-line))))

Terminal functions

Some functions for terminal interaction. The first one just opens a terminal in the current buffer. The second one checks if we are already in the terminal buffer, then it does nothing. Otherwise, it opens a terminal buffer on the right. The third function resets the terminal.

(defun my/terminal ()
  "Open the terminal."
  (interactive)
  (eat "bash"))

(defun my/switch-to-terminal ()
  "Create or switch to the terminal buffer."
  (interactive)
  (let ((term-win (get-buffer-window "*eat*")))
    (if
        (eq term-win nil)
        (progn
          (my/split-switch-right)
          (my/terminal))
      (select-window term-win))))

(defun my/eat-reset ()
  "Reset eat and input newline."
  (interactive)
  (eat-reset)
  (eat-self-input 1 ?\x15)
  (eat-self-input 1 ?\n))

Dashboard

My dashboard is very minimalistic: a logo and some package load statistics. The logo should be centered both vertically and horizontally.

(defun my/dashboard ()
  "Switch to a custom dashboard buffer."
  (interactive)
  (switch-to-buffer (get-buffer-create "*my-dashboard*"))
  (read-only-mode 0)
  (centaur-tabs-local-mode 1) ; this *disables* the tab bar
  (setq-local mode-line-format nil
              cursor-type nil)
  (erase-buffer)
  (dashboard-insert-banner)
  (call-interactively #'beginning-of-buffer)
  (newline
   (/
    (-
     (window-height)
     (count-lines (point-min) (point-max))
     5)
    2))
  (cd "~")
  (read-only-mode 1)
  (message nil))

Haskell process reload

This function reloads the REPL of haskell-mode.

(defun my/haskell-reload ()
  (interactive)
  (haskell-process-file-loadish
   "reload" t
   (or haskell-interactive-previous-buffer (current-buffer))))

Open today’s Org file

This function lets the user select a project folder and opens the Org file with the current ISO 8601 date as the name.

(defun my/todays-org-file (directory)
  "Opens the Org file for today in DIRECTORY.
It has the filename year-month-day.org"
  (interactive "Ddirectory: ")
  (let* ((date  (calendar-current-date))
         (month (car   date))
         (day   (cadr  date))
         (year  (caddr date))
         (file  (format "%04d-%02d-%02d.org" year month day)))
    (find-file (expand-file-name file directory))))

General configuration

Some modes

We don’t want:

  • a blinking cursor
  • a menu, scroll, and tool bar
(blink-cursor-mode 0)
(menu-bar-mode     0)
(scroll-bar-mode   0)
(tool-bar-mode     0)

We want:

  • to automatically reload a buffer when its corresponding file changes
  • the current line to be highlighted
  • pretty symbols
(global-auto-revert-mode      1)
(global-hl-line-mode          1)
(global-prettify-symbols-mode 1)

More recentf items

(setq recentf-max-saved-items 100)

Spell checking

Aspell is a modern replacement for ispell with full UTF-8 support.

(setq ispell-program-name "aspell"
      ispell-dictionary "de_DE")

More miscellaneous settings

No startup screen (we have our own dashboard). No initial message in the scratch buffer. No bell, dialogs or long yes-or-no questions. And finally, no “when done with this frame…” message in emacsclient frames.

(setq inhibit-startup-screen t
      initial-scratch-message ""
      ring-bell-function 'ignore
      use-dialog-box nil)

(defalias 'yes-or-no-p 'y-or-n-p)

(use-package server :custom (server-client-instructions nil))

Appearance

Theme

Gruvbox medium dark is the supreme colorscheme and I will fight anyone who dare says otherwise. Link to repo

(use-package gruvbox-theme
  :custom (custom-safe-themes '("046a2b81d13afddae309930ef85d458c4f5d278a69448e5a5261a5c78598e012" default))
  :config (load-theme 'gruvbox-dark-medium))

Font

We use Iosevka as a basis for Nerd Fonts

(defvar my/default-font "Iosevka NFM")
(set-face-attribute 'default nil :font my/default-font)

Transparency

Since I use emacs-pgtk-29, this works perfectly!

(push '(alpha-background . 50) default-frame-alist)

Tab width

4 spaces by default.

(setq-default tab-width 4)

Line numbers

We use relative line numbers because they make relative jumps easier (no need to type the full line number, two digits are always enough).

(use-package display-line-numbers
  :custom (display-line-numbers-type 'relative)
  :config
  (set-face-foreground 'line-number "#ebdbb2")
  (set-face-background 'line-number nil)
  (global-display-line-numbers-mode 1))

Tab bar

centaur-tabs creates a nice tab bar at the top of a window. It groups buffers by type and project, has a “modified” indicator and other goodies.

(use-package centaur-tabs
  :custom
  (centaur-tabs-cycle-scope 'tabs)
  (centaur-tabs-modified-marker "")
  (centaur-tabs-set-bar 'under)
  (centaur-tabs-show-new-tab-button nil)
  (centaur-tabs-set-close-button nil)
  (centaur-tabs-set-icons t)
  (centaur-tabs-set-modified-marker t)
  (centaur-tabs-style "bar")
  (x-underline-at-descent-line 1)
  :config
  (centaur-tabs-mode 1)
  (centaur-tabs-change-fonts my/default-font 100)
  (centaur-tabs-headline-match))

Icons

All the icons for our tab bar!

(use-package all-the-icons
  :custom
  (all-the-icons-fonts-subdirectory "all-the-icons"))

Modeline

We use telephone-line, a pretty simple custom modeline.

(use-package telephone-line
  :custom
  (telephone-line-lhs
   '((accent . (telephone-line-vc-segment
                telephone-line-process-segment))
     (nil    . (telephone-line-project-segment
                telephone-line-buffer-segment))))
  :config (telephone-line-mode 1))

More dashboard setup

While the my/dashboard function sets up the buffer, this configuration describes the actual contents of the dashboard. This uses the dashboard package.

(use-package dashboard
  :custom
  (dashboard-banner-logo-title "Welcome to Emacs!")
  (dashboard-startup-banner (expand-file-name "splash.png" user-emacs-directory))
  :config
  (set-face-attribute 'dashboard-banner-logo-title nil :height 200))

(add-hook 'after-init-hook #'my/dashboard)

Selection and completion interface

vertico is a modern and minimalistic completion UI.

(use-package vertico
  :custom
  (vertico-count 30)
  (vertico-cycle t)
  :config (vertico-mode 1))

Better syntax highlighting

With tree-sitter, much more complex syntax highlighting is possible, even when we don’t have a language-specific mode installed!

;; better syntax highlighting
(use-package tree-sitter
  :config (global-tree-sitter-mode 1)
  :hook (tree-sitter-after-on . tree-sitter-hl-mode))

(use-package tree-sitter-langs)

Indent guides

A visual representation of where we are in an indented structure. highlight-indent-guides is very adaptive and thus a perfect fit for languages with weird, dynamic indentation (looking at you, Haskell).

;; indent guides
(use-package highlight-indent-guides
  :custom (highlight-indent-guides-responsive 'stack)
  :hook (prog-mode . highlight-indent-guides-mode))

Visible whitespace

I want to see tabs and trailing whitespace.

;; show whitespace
(use-package whitespace
  :config (global-whitespace-mode 1)
  :custom (whitespace-style '(face tab-mark trailing missig-newline-at-eof)))

Colored strings

With rainbow-mode, color strings like #bb77ff get a background of their color.

(use-package rainbow-mode
  :config
  (define-globalized-minor-mode my/global-rainbow-mode rainbow-mode
    (lambda () (rainbow-mode 1)))
  (my/global-rainbow-mode))

Colored parentheses

We need more rainbows. Or, in this case, gruv-bows? Link to repo

(use-package rainbow-delimiters
  :custom (rainbow-delimiters-max-face-count 6)
  :config
  (set-face-foreground 'rainbow-delimiters-depth-1-face "#cc241d")
  (set-face-foreground 'rainbow-delimiters-depth-2-face "#98971a")
  (set-face-foreground 'rainbow-delimiters-depth-3-face "#d79921")
  (set-face-foreground 'rainbow-delimiters-depth-4-face "#458588")
  (set-face-foreground 'rainbow-delimiters-depth-5-face "#b16286")
  (set-face-foreground 'rainbow-delimiters-depth-6-face "#689d6a")

  (define-globalized-minor-mode my/global-raindow-delims-mode rainbow-delimiters-mode
    (lambda () (rainbow-delimiters-mode 1)))
  (my/global-raindow-delims-mode 1))

Smooth scrolling

Default emacs “scrolling” behaviour sucks tbh.

(use-package smooth-scrolling
  :config (smooth-scrolling-mode 1))

Popup control

Popup windows can quickly become annoying. The popwin package allows closing them with just C-g.

(use-package popwin
  :config
  ;;(push "*undo-tree*" popwin:special-display-config)
  ;;(push "*Help*"      popwin:special-display-config)
  (push "*Backtrace*" popwin:special-display-config)
  (push "*hoogle*"    popwin:special-display-config)
  (push '("^[*]" :regex t) popwin:special-display-config)
  (popwin-mode 1))

Temporary files

Emacs leaves a lot of temporary files lying around, such as backups and autosaves. We shove all of them in a single directory next to the Emacs configuration.

(defvar my/temp-dir (concat user-emacs-directory "temp/"))
(setq backup-directory-alist         `(("." . ,my/temp-dir))
      auto-save-file-name-transforms `((".*"  ,my/temp-dir t))
      auto-save-list-file-prefix               my/temp-dir)

Helpers

Fill column

For a long time, terminals were only 80 columns wide. Today, such tight space constrains no longer exist, but it is still nice to not write overly long lines. The fill column shows up as a thin bar on the 80th column.

(add-hook 'display-fill-column-indicator-mode-hook
          (lambda () (set-fill-column 80)))
(global-display-fill-column-indicator-mode)

Show composite keybindings

which-key shows possible continuations of a multi-part keybind.

(use-package which-key
  :custom
  (which-key-idle-delay 0.5)
  (which-key-idle-secondary-delay 0)
  :config
  (which-key-mode 1)
  (which-key-setup-side-window-bottom))

Frecency-based sorting

prescient sorts possible completions by frequency and recency (“frecency”).

(use-package prescient
  :config (prescient-persist-mode 1)
  :custom (prescient-save-file (concat my/temp-dir "prescient-save.el")))

(use-package vertico-prescient :config (vertico-prescient-mode 1))

More selection functions

consult offers lots of search and navigation functions, such as

  • selecting buffers
  • grepping for text
  • jumping to lines, headings or bookmarks

and many more.

(use-package consult
  :init (recentf-mode 1)
  :custom (completion-in-region-function #'consult-completion-in-region))

More completion information

Marginalia are annotations at the margin of page. Here, they show e.g. file permissions, function names or buffer types in the respective selection menus.

(use-package marginalia :config (marginalia-mode 1))

Git line status

git-gutter shows the modification status of lines (added, changed, removed) in the “gutter” (left side of the window).

(use-package git-gutter
  :custom
  (git-gutter:added-sign    "+")
  (git-gutter:modified-sign "~")
  (git-gutter:deleted-sign  "-")
  (git-gutter:update-interval 2)
  :config
  (set-face-background 'git-gutter:added    nil)
  (set-face-background 'git-gutter:modified nil)
  (set-face-background 'git-gutter:deleted  nil)
  (global-git-gutter-mode 1))

Editing

Multiple cursors

For when you need to edit EVEN MORE! Pure magic

(use-package multiple-cursors)

Direct jumps

Another pretty crazy feature: With avy you can jump to any visible text with just a few keystrokes!

(use-package avy
  :custom
  (avy-keys
   (nconc
    (number-sequence ?a ?z)
    ;; (number-sequence ?A ?Z)
    (number-sequence ?0 ?9))))

Undo tree

Is this how timelords think? undo-tree can visualize the entire undo/redo tree of a buffer and even lets us move around in it!

(use-package undo-tree
  :custom (undo-tree-history-directory-alist `(("." . ,my/temp-dir)))
  :config (global-undo-tree-mode 1))

Terminal

eat: Emulate A Terminal, is by far the best terminal emulator for emacs. It’s faster than term, doesn’t flicker, has more features…

(use-package eat
  :custom (eat-term-inside-emacs "vterm")
  :bind (:map eat-semi-char-mode-map
              ("M-DEL" . #'eat-self-input)
              ("C-a"   . #'eat-self-input)
              ("C-u"   . #'eat-self-input)
              ("C-l"   . #'my/eat-reset)))

Programming basics

Trailing whitespace cleanup

We don’t like junk on our lines.

(add-hook 'before-save-hook #'delete-trailing-whitespace)

Projects

The builtin project package is enough for my requirements.

(use-package project)

Autocompletion

company-mode adds powerful autocompletion. We want to ignore casing and show it as soon as a word is typed.

(use-package company
  :hook (after-init . global-company-mode)
  :custom
  (company-dabbrev-downcase nil)
  (company-dabbrev-ignore-case t)
  (company-idle-delay 0)
  (company-minimum-prefix-length 1)
  (company-show-numbers t))

Language server support

lsp-mode integrates into installed language servers. We start them deferred, this reduces peak load.

(use-package lsp-mode
  :custom
  (eldoc-idle-delay 0)
  (lsp-headerline-breadcrumb-enable nil)
  (lsp-idle-delay 0)
  (lsp-inlay-hint-enable t)
  (lsp-log-io nil)
  (read-process-output-max (* 1024 1024))
  :hook
  (c-mode          . lsp-deferred)
  (elixir-mode     . lsp-deferred)
  (gleam-mode      . lsp-deferred)
  (go-mode         . lsp-deferred)
  (haskell-mode    . lsp-deferred)
  (javascript-mode . lsp-deferred)
  (nix-mode        . lsp-deferred)
  (python-mode     . lsp-deferred)
  (typescript-mode . lsp-deferred))

(use-package lsp-ui
  :custom
  (lsp-ui-sideline-show-code-actions t)
  (lsp-ui-sideline-show-diagnostics t)
  (lsp-ui-sideline-show-hover nil)
  (lsp-ui-sideline-delay 0)
  (lsp-ui-doc-delay 0)
  (lsp-ui-doc-show-with-cursor t))

xref setup

Consult provices a selection function for xref. We also disable the symbol selection in xref-find-references.

(setq xref-show-xrefs-function       #'consult-xref
      xref-show-definitions-function #'consult-xref
      xref-prompt-for-identifier     nil)

Formatting

Format all the code! Automatic formatting on save. For Haskell, I am currently using stylish-haskell, which is not the default setting.

(use-package format-all
  :hook (prog-mode . format-all-mode)
  (format-all-mode . format-all-ensure-formatter)
  :config
  (setq-default format-all-formatters '(("Haskell" stylish-haskell)
                                        ("HTML"    prettier))))

EditorConfig

EditorConfig automatically loads basic code formatting rules from a project’s rule file. The Emacs plugin is here.

(use-package editorconfig :config (editorconfig-mode 1))

Error checking

Flycheck provides on-the-fly syntax & error checking.

(use-package flycheck
  :custom (flycheck-display-errors-delay 0)
  :config (global-flycheck-mode 1))

Snippets

Yasnippet is a template/snippet system for emacs. It is required by some language’s autocompletion to correctly fill in function arguments and such things.

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

highlighting

hl-todo highlights TODO and some other keywords.

(use-package hl-todo :config (global-hl-todo-mode 1))

Electricity

Automatic indentation and completion of pair characters (brackets, quotation marks, …). Emacs calls this behaviour Electricity.

(electric-indent-mode 1)
(electric-pair-mode   1)

Direnv integration

direnv automatically loads project environments. Together with my nix-direnv setup on NixOS (dotfiles here), this loads entire Nix flakes and enables Emacs to use the packages declared within.

(use-package direnv
  :config (direnv-mode 1)
  :custom (direnv-always-show-summary nil))

Languages

Lisp

We use two packages for lisp:

  • lisp-extra-font-lock highlights local bindings and quoted expressions
  • parinfer makes writing Lisp easier by automatically adjusting parentheses and indentation
(put 'if 'lisp-indent-function 'defun) ; indent if normally
(use-package lisp-extra-font-lock :config (lisp-extra-font-lock-global-mode 1))

(use-package parinfer-rust-mode
  :hook emacs-lisp-mode
  :custom
  (parinfer-rust-library-directory my/temp-dir)
  (parinfer-rust-auto-download t))

Some problems due to parinfer

The magic of parinfer clashes with some other automatic adjustment modes, such as format-all-mode and the electric modes. Therefore, they need to be disabled.

(add-hook
 'emacs-lisp-mode-hook
 #'(lambda ()
     (format-all-mode 0)
     (indent-tabs-mode 0)
     (electric-indent-local-mode 0)
     (electric-pair-local-mode 0)))

C

Indents are 4 spaces wide.

(setq c-basic-offset 4)

Haskell

Define hotkeys for Haskell and its REPL and enable automatic reload on save. Link to repo

(use-package haskell-mode
  :bind (:map haskell-mode-map
              ("C-c C-h" . #'hoogle)
              ("C-c C-p" . #'haskell-interactive-switch))
  :hook
  (haskell-mode . (lambda () (add-hook 'after-save-hook #'my/haskell-reload)))
  (haskell-interactive-mode
   . (lambda ()
       (bind-key "C-a" #'haskell-interactive-mode-beginning        'haskell-interactive-mode-map)
       (bind-key "C-l" #'haskell-interactive-mode-clear            'haskell-interactive-mode-map)
       (bind-key "C-n" #'haskell-interactive-mode-history-next     'haskell-interactive-mode-map)
       (bind-key "C-p" #'haskell-interactive-mode-history-previous 'haskell-interactive-mode-map)
       (bind-key "C-r" #'my/haskell-reload                         'haskell-interactive-mode-map))))

(use-package lsp-haskell)

Go

Nothing fancy here. Link to repo

(use-package go-mode)

Rust

Instead of the official rust-mode, we use rustic. It wraps rust-mode with more features and provides automatic lsp-mode integration.

(use-package rustic
 :custom (lsp-rust-analyzer-cargo-watch-command "clippy"))

Elixir

(use-package elixir-mode)

Idris 2

(use-package idris2-mode
    :straight (:type git :host github :repo "idris-community/idris2-mode"))

Gleam

(use-package tree-sitter-indent)
(use-package gleam-mode
  :straight (:type git :host github :repo "gleam-lang/gleam-mode"
                   :files ("*.el" "tree-sitter-gleam")))

HTML

We need to explicitly set the indentation here again, since it uses a custom variable. sgml-mode is a builtin mode.

(use-package sgml-mode
  :custom (sgml-basic-offset 4))

Typescript

(use-package typescript-mode)

Org

The language this document is written in! We enable indentation of text under headers and syntax highlighting in the HTML export with htmlize.

(add-hook 'org-mode-hook #'org-indent-mode)
(use-package htmlize)

Typst

A modern typesetting language.

(use-package typst-mode
  :straight (:type git :host github :repo "Ziqi-Yang/typst-mode.el"))

Nix

Nothing fancy here too. Link to repo

(use-package nix-mode)

Structured data

JSON and YAML are data serialization languages (they describe data, not code).

(use-package json-mode)
(use-package yaml-mode)

Keybindings

A helper

To always override existing keybinds in some modes with my own, I have designed this little helper macro. It allows me to write my keybinds as one huge expression instead of many separate calls to bind-key*.

(defmacro my/bind-keys* (&rest body)
  "Globally bind all keys.
BODY: a list of alternating key-function arguments."
  `(progn
     ,@(cl-loop
        while body collecting
        `(bind-key* ,(pop body) ,(pop body)))))

Principles

  • When a modifier key is pressed, it is held for the rest of the keybind
  • C-x is for general actions
  • C-c is for code actions.
  • Very important actions have no prefix, they are a single hotkey
  • Meta (Alt) roughly corresponds to a “bigger” version of the same hotkey with Control

Menus

(my/bind-keys*
 "C-x C-b" #'consult-bookmark
 "C-x C-f" #'find-file
 "C-x C-r" #'consult-ripgrep
 "C-x C-i" #'consult-imenu
 "C-x C-m" #'consult-minor-mode-menu
 "C-x C-o" #'consult-outline
 "C-x C-s" #'consult-buffer
 "C-x C-u" #'undo-tree-visualize)

Window controls

(my/bind-keys*
 "C-<next>"     #'centaur-tabs-forward
 "C-<prior>"    #'centaur-tabs-backward
 "C-M-<return>" #'my/autosplit
 "C-x C-0"      #'delete-window
 "C-x C-1"      #'delete-other-windows
 "C-x C-2"      #'my/split-switch-below
 "C-x C-3"      #'my/split-switch-right
 "C-x C-4"      #'kill-buffer-and-window)

Movement

(bind-key "C-a" #'my/smart-home)
(my/bind-keys*
 "C-#"   (lambda () (interactive) (select-window (next-window)))
 "C-M-#" (lambda () (interactive) (select-window (previous-window)))
 "M-c"   #'avy-goto-char
 "M-e"   #'forward-word
 "M-f"   #'forward-to-word
 "M-l"   #'consult-goto-line
 "M-n"   #'scroll-up-command
 "M-p"   #'scroll-down-command
 "M-s"   #'consult-line)

Editing

(my/bind-keys*
 "C-,"             #'mc/mark-previous-like-this
 "C-."             #'mc/mark-next-like-this
 "C-<tab>"         #'format-all-buffer
 "C-M-<backspace>" #'my/join-line
 "C-s"             #'save-buffer
 "C-y"             #'undo-tree-redo
 "C-z"             #'undo-tree-undo
 "M-v"             #'consult-yank-from-kill-ring)

Language server actions

(my/bind-keys*
 "C-c C-a"     #'lsp-execute-code-action
 "C-c C-d"     #'lsp-ui-doc-focus-frame
 "C-c C-f C-d" #'xref-find-definitions
 "C-c C-f C-i" #'lsp-find-implementation
 "C-c C-f C-r" #'xref-find-references
 "C-c C-o"     #'lsp-organize-imports
 "C-c C-r"     #'lsp-rename)

Text scale adjustment

(my/bind-keys*
 "C-+" #'text-scale-increase
 "C--" #'text-scale-decrease
 "C-=" #'text-scale-mode)

Other utilities

(my/bind-keys*
 "C-M-i"   #'ispell-buffer
 "C-x C-a" #'mark-whole-buffer
 "C-x C-k" (lambda () (interactive) (kill-buffer (current-buffer)))
 "C-x C-t" #'my/switch-to-terminal)

Help

(my/bind-keys*
 "C-h C-b" #'describe-personal-keybindings
 "C-h C-f" #'describe-function
 "C-h C-k" #'describe-key
 "C-h C-m" #'consult-man
 "C-h C-v" #'describe-variable)

cua-mode

The Common User Access system (CUA) enables some keybindings found in standard text editors, such as

  • C-c for copying a region
  • C-x for cutting a region

These keybindings are only active when a region is selected, otherwise they are just prefixes to other keybindings. But for that to work, cua-mode must be enabled last. We also don’t want CUA do touch C-v, since we define it ourselves.

(setq cua-remap-control-v nil)
(cua-mode 1)

Paste

We want to use cua-paste everywhere except in the terminal.

(bind-key "C-v" #'cua-paste)
(bind-key "C-v" #'eat-yank 'eat-semi-char-mode-map)

Startup message

Send a notification when Emacs has started up.

(start-process
 "startup-notify" nil
 "notify-send" "emacs"
 (format "Startup took %s!" (emacs-init-time)))

About

My own Emacs configuration. Inspired by Doom Emacs.

Topics

Resources

Stars

Watchers

Forks