commit c706962ff08c10066c929e7c2376e13813b6c751
Author: Lukas Henkel <lh@entf.net>
Date: Fri, 9 Jul 2021 13:30:30 +0200
Emacs config redone!
Diffstat:
3 files changed, 347 insertions(+), 0 deletions(-)
diff --git a/config.org b/config.org
@@ -0,0 +1,344 @@
+#+TITLE: Emacs config
+#+AUTHOR: Lukas Henkel
+
+* Setup
+** load path
+Add a local directory to the load path to be able to load custom local libraries.
+#+begin_src emacs-lisp
+ (push
+ (let ((lisp-path (expand-file-name "lisp" user-emacs-directory)))
+ (unless (file-exists-p lisp-path)
+ (make-directory lisp-path))
+ lisp-path)
+ load-path)
+#+end_src
+** straight.el
+#+begin_src emacs-lisp
+ (setq straight-use-package-by-default t)
+ (defvar bootstrap-version)
+ (let ((bootstrap-file
+ (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
+ (bootstrap-version 5))
+ (unless (file-exists-p bootstrap-file)
+ (with-current-buffer
+ (url-retrieve-synchronously
+ "https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el"
+ 'silent 'inhibit-cookies)
+ (goto-char (point-max))
+ (eval-print-last-sexp)))
+ (load bootstrap-file nil 'nomessage))
+#+end_src
+** use-package
+#+begin_src emacs-lisp
+ (straight-use-package 'use-package)
+#+end_src
+** diminish
+diminish removes modes from the modeline, to make it a bit more clean. It's called via use-packages =diminish=.
+#+begin_src emacs-lisp
+ (use-package diminish
+ :straight t)
+#+end_src
+** System independent directories
+Here we figure out some directories later used in this config in a (hopefully) system independent way.
+#+begin_src emacs-lisp
+ (defun lh/xdg-dir (name default)
+ (let ((v (string-trim (shell-command-to-string "xdg-user-dir DOCUMENTS"))))
+ (if (null v)
+ default
+ v)))
+
+ (setq lh/dir-documents (expand-file-name
+ (cond ((eq system-type 'gnu/linux) (lh/xdg-dir "XDG_DOCUMENTS_DIR" "~/Documents"))
+ ((eq system-type 'windows-nt) "~/Documents"))))
+
+ (setq lh/dir-data-home (expand-file-name
+ (cond ((eq system-type 'gnu/linux) (or (getenv "XDG_DATA_HOME") "~/.local/share"))
+ ((eq system-type 'windows-nt) (getenv "APPDATA")))))
+#+end_src
+* Basic settings
+** Cursor
+I prefer the bar cursor.
+#+begin_src emacs-lisp
+ (setq-default cursor-type 'bar)
+#+end_src
+** Fonts
+#+begin_src emacs-lisp
+ (set-face-attribute 'default nil
+ :font "Go Mono"
+ :height 110)
+ (set-face-attribute 'fixed-pitch nil
+ :height 110)
+ (set-face-attribute 'variable-pitch nil
+ :font "IBM Plex Serif"
+ :height 120)
+#+end_src
+** Scrolling
+Scrolling in Emacs is weird, this fixes it.
+#+begin_src emacs-lisp
+ (setq scroll-conservatively 100)
+#+end_src
+** Disable the bell
+Begone!
+#+begin_src emacs-lisp
+ (setq ring-bell-function 'ignore)
+#+end_src
+** Consistent yes/no prompts
+Sometimes Emacs asks you to enter y/n, other times yes/no. Why?
+#+begin_src emacs-lisp
+ (defalias 'yes-or-no-p 'y-or-n-p)
+#+end_src
+** Focus newly created windows
+#+begin_src emacs-lisp
+ (defadvice split-window-below (after lh/split-window-below activate)
+ (other-window 1))
+ (defadvice split-window-right (after lh/split-window-right activate)
+ (other-window 1))
+#+end_src
+** Delete the selection when you type
+By default Emacs does not delete the current selection when you type. I like this, saves me one keypress.
+#+begin_src emacs-lisp
+ (delete-selection-mode 1)
+#+end_src
+** Backup files
+Who likes to have backup files scattered around all over your file system? A lot of people seem to disable these, but I think they are very useful and have saved me a couple of times in the past. We just need to move them to some place where we don't constantly see them.
+#+begin_src emacs-lisp
+ (let ((backup-dir (concat user-emacs-directory "backup")))
+ (unless (file-exists-p backup-dir)
+ (make-directory backup-dir t))
+ (setq backup-directory-alist `(("." . ,backup-dir))))
+ (setq backup-by-copying t
+ version-control t
+ delete-old-versions t
+ kept-new-versions 10
+ kept-old-versions 5)
+#+end_src
+** Fullscreen
+On fullscreen I want to hide all UI elements (toolbar and menu bar) and reenable them when I leave fullscreen.
+#+begin_src emacs-lisp
+ (defadvice toggle-frame-fullscreen (before lh/toggle-frame-fullscreen-bars activate)
+ (menu-bar-mode (if menu-bar-mode -1 1))
+ (tool-bar-mode (if tool-bar-mode -1 1))
+ (scroll-bar-mode (if scroll-bar-mode -1 1)))
+#+end_src
+** transpose regions
+Doesn't have a default keybinding.
+#+begin_src emacs-lisp
+ (global-set-key (kbd "C-x C-M-t") #'transpose-regions)
+#+end_src
+* Basic QOL Packages
+** which-key
+Shows the possible keybindings in a neat menu.
+#+begin_src emacs-lisp
+ (use-package which-key
+ :straight t
+ :diminish which-key-mode
+ :config (which-key-mode 1))
+#+end_src
+** Selectrum
+Selectrum replaces Emacs default =completing-read=, which is a bit cumbersome to use. We also enable prescient for smart recommendations.
+#+begin_src emacs-lisp
+ (use-package selectrum
+ :straight t
+ :config (selectrum-mode 1))
+ (use-package selectrum-prescient
+ :straight t
+ :after selectrum
+ :config
+ (selectrum-prescient-mode 1)
+ (prescient-persist-mode 1))
+#+end_src
+** Marginalia
+Marginalia adds additional information to =M-x=, such as keybindings and command descriptions.
+#+begin_src emacs-lisp
+ (use-package marginalia
+ :straight t
+ :init
+ (setq marginalia-annotators '(marginalia-annotators-heavy))
+ :config
+ (marginalia-mode 1))
+#+end_src
+** Consult
+Consult improves on a lot of default Emacs functionality and adds a lot more. I use the keybindings from the Consult Readme.
+#+begin_src emacs-lisp
+ (use-package consult
+ :straight t
+ :bind (;; C-c bindings (mode-specific-map)
+ ("C-c h" . consult-history)
+ ("C-c m" . consult-mode-command)
+ ("C-c b" . consult-bookmark)
+ ("C-c k" . consult-kmacro)
+ ;; C-x bindings (ctl-x-map)
+ ("C-x M-:" . consult-complex-command) ;; orig. repeat-complex-command
+ ("C-x b" . consult-buffer) ;; orig. switch-to-buffer
+ ("C-x 4 b" . consult-buffer-other-window) ;; orig. switch-to-buffer-other-window
+ ("C-x 5 b" . consult-buffer-other-frame) ;; orig. switch-to-buffer-other-frame
+ ;; Custom M-# bindings for fast register access
+ ("M-#" . consult-register-load)
+ ("M-'" . consult-register-store) ;; orig. abbrev-prefix-mark (unrelated)
+ ("C-M-#" . consult-register)
+ ;; Other custom bindings'
+ ("M-y" . consult-yank-pop) ;; orig. yank-pop
+ ("<help> a" . consult-apropos) ;; orig. apropos-command
+ ;; M-g bindings (goto-map)
+ ("M-g e" . consult-compile-error)
+ ("M-g f" . consult-flymake) ;; Alternative: consult-flycheck
+ ("M-g g" . consult-goto-line) ;; orig. goto-line
+ ("M-g M-g" . consult-goto-line) ;; orig. goto-line
+ ("M-g o" . consult-outline) ;; Alternative: consult-org-heading
+ ("M-g m" . consult-mark)
+ ("M-g k" . consult-global-mark)
+ ("M-g i" . consult-imenu)
+ ("M-g I" . consult-project-imenu)
+ ;; M-s bindings (search-map)
+ ("M-s f" . consult-find)
+ ("M-s L" . consult-locate)
+ ("M-s g" . consult-grep)
+ ("M-s G" . consult-git-grep)
+ ("M-s r" . consult-ripgrep)
+ ("M-s l" . consult-line)
+ ("M-s m" . consult-multi-occur)
+ ("M-s k" . consult-keep-lines)
+ ("M-s u" . consult-focus-lines)
+ ;; Isearch integration
+ ("M-s e" . consult-isearch)
+ :map isearch-mode-map
+ ("M-e" . consult-isearch) ;; orig. isearch-edit-string
+ ("M-s e" . consult-isearch) ;; orig. isearch-edit-string
+ ("M-s l" . consult-line)) ;; needed by consult-line to detect isearch
+ :config
+ (setq consult-project-root-function
+ (lambda ()
+ (when-let (project (project-current))
+ (car (project-roots project))))))
+#+end_src
+** project-x
+Improves on the inbuilt project.el, also needed by popper.
+#+begin_src emacs-lisp
+ (use-package project-x
+ :straight (project-x :type git :host github :repo "karthink/project-x"))
+#+end_src
+** popper
+Popper turns chosen buffers into popups, which can be shown or hidden quickly.
+#+begin_src emacs-lisp
+ (use-package popper
+ :straight t
+ :bind
+ ("C-." . popper-toggle-latest)
+ ("M-." . popper-cycle)
+ ("C-M-." . popper-toggle-type)
+ :init
+ (setq popper-group-function #'popper-group-by-project)
+ (setq popper-reference-buffers
+ '("\\*Messages\\*"
+ "\\*scratch\\*"
+ "^\\*straight-"))
+ :config (popper-mode 1))
+#+end_src
+** expand-region
+Smart expand selection with one keypress.
+#+begin_src emacs-lisp
+ (use-package expand-region
+ :straight t
+ :bind ("C-+" . er/expand-region))
+#+end_src
+** ace-window
+Makes it easy to switch windows.
+#+begin_src emacs-lisp
+ (use-package ace-window
+ :straight t
+ :bind ("M-o" . ace-window)
+ :init
+ (setq aw-keys '(?a ?s ?d ?f ?g ?h ?j ?k ?l)
+ aw-scope 'frame
+ aw-dispatch-always t))
+#+end_src
+* Org
+#+begin_src emacs-lisp
+ (use-package org
+ :straight t
+ :hook
+ (org-mode . visual-line-mode)
+ :init
+ (setq org-startup-indented nil
+ org-src-window-setup 'current-window
+ org-support-shift-select t))
+#+end_src
+* Code
+** Autocomplete
+#+begin_src emacs-lisp
+ (use-package company
+ :straight t
+ :diminish company-mode
+ :init (setq company-idle-delay 0)
+ :config (global-company-mode 1))
+#+end_src
+Company prescient for smart completions.
+#+begin_src emacs-lisp
+ (use-package company-prescient
+ :straight t
+ :config
+ (company-prescient-mode 1))
+#+end_src
+** Lisp
+#+begin_src emacs-lisp
+ (use-package sly
+ :straight t
+ :init (setq inferior-lisp-program "sbcl"))
+#+end_src
+** Go
+#+begin_src emacs-lisp
+ (use-package go-mode
+ :straight t)
+#+end_src
+** LSP and DAP
+Using the language server protocol, we can support a lot of different programming languages
+#+begin_src emacs-lisp
+ (use-package lsp-mode
+ :straight t
+ :init
+ (setq lsp-keymap-prefix "C-c l")
+ :hook ((go-mode . lsp-mode)
+ (lsp-mode . lsp-enable-which-key-integration))
+ :commands lsp)
+
+ (use-package lsp-ui
+ :straight t
+ :commands lsp-ui-mode
+ :init
+ (setq lsp-ui-sideline-show-diagnostics t)
+ :bind (:map lsp-mode-map
+ ("M-ß" . lsp-ui-peek-find-definitions)
+ ("M-?" . lsp-ui-peek-find-references)))
+
+ (use-package dap-mode
+ :straight t)
+#+end_src
+* Other packages
+** Magit
+Magit is a git UI for Emacs.
+#+begin_src emacs-lisp
+ (use-package magit
+ :straight t)
+#+end_src
+** elfeed
+A tag based news reader for emacs.
+#+begin_src emacs-lisp
+ (use-package elfeed
+ :straight t
+ :config
+ (setq elfeed-db-directory (let ((data-dir (expand-file-name "elfeed" lh/dir-data-home)))
+ (unless (file-exists-p data-dir)
+ (make-directory data-dir))
+ data-dir))
+ (let ((feeds (expand-file-name "feeds.el" user-emacs-directory)))
+ (when (file-exists-p feeds)
+ (load feeds))))
+#+end_src
+
+** nov.el
+Emacs EPub reader.
+#+begin_src emacs-lisp
+ (use-package nov
+ :straight t
+ :mode ("\\.epub\\'" . nov-mode))
+#+end_src
diff --git a/early-init.el b/early-init.el
@@ -0,0 +1,2 @@
+(setq gc-cons-threshold most-positive-fixnum)
+(setq package-enable-at-startup nil)
diff --git a/init.el b/init.el
@@ -0,0 +1 @@
+(org-babel-load-file (expand-file-name "config.org" user-emacs-directory))