#+TITLE: Emacs Config * General Settings =cl-lib= adds a few things from common-lisp emulation, adding things like =cl-loop= #+begin_src emacs-lisp (use-package cl-lib) #+end_src ** Sane defaults Typing =:ensure t= everywhere is very bothersome so I'd rather *not* do that. This automatically adds =:ensure t= everyhwere! #+BEGIN_SRC emacs-lisp (require 'use-package-ensure) (setq use-package-always-ensure t) #+END_SRC Don't create all the custom things. #+BEGIN_SRC emacs-lisp (defconst custom-file "/dev/null") #+END_SRC I don't want my Emacs to create loads of backup files, swap files, etc. #+BEGIN_SRC emacs-lisp (setq make-backup-files nil) (setq auto-save-default nil) #+END_SRC Nor do I need all the (Windows 2000-esque) UI. #+BEGIN_SRC emacs-lisp (scroll-bar-mode -1) (tool-bar-mode -1) (tooltip-mode -1) (menu-bar-mode -1) #+END_SRC When I fire up Emacs I want to be greeted with an empty =*scratch*= buffer, not the weird GNU screen. #+BEGIN_SRC emacs-lisp (setq inhibit-splash-screen t initial-scratch-message "") #+END_SRC The whole yes or no prompt takes too much time to type out. y and n is much better. #+BEGIN_SRC emacs-lisp (defalias 'yes-or-no-p 'y-or-n-p) #+END_SRC UTF-8 is good and should be the default for everything. #+BEGIN_SRC emacs-lisp (setq locale-coding-system 'utf-8) (set-terminal-coding-system 'utf-8) (set-keyboard-coding-system 'utf-8) (set-selection-coding-system 'utf-8) (prefer-coding-system 'utf-8) #+END_SRC Disable the bell, as the audible bell is highly anoying and pointless #+begin_src emacs-lisp (setq visible-bell 1) #+end_src ** Restart emacs Restarting emacs from within emacs! #+BEGIN_SRC emacs-lisp (use-package restart-emacs :config (setq restart-emacs-restore-frames t)) #+END_SRC ** disable clipboard whatever Clipboard shit is fucked, so this is necessary to unfuck. #+BEGIN_SRC emacs-lisp (setq x-select-enable-clipboard-manager nil) #+END_SRC ** Store recent files #+BEGIN_SRC emacs-lisp (recentf-mode 1) (setq recentf-max-menu-items 25) (setq recentf-max-saved-items 25) ;; (run-at-time nil (* 5 60) 'recentf-save-list) #+END_SRC ** Which-key Which key makes Emacs self documenting. #+BEGIN_SRC emacs-lisp (use-package which-key :config (setq which-key-idle-delay 0.25) (which-key-mode 1)) #+END_SRC ** VTerm #+begin_src emacs-lisp (use-package vterm) #+end_src * Looks ** indentation #+BEGIN_SRC emacs-lisp (setq-default tab-width 4) (setq-default indent-tabs-mode nil) #+END_SRC ** Font #+BEGIN_SRC emacs-lisp (add-to-list 'default-frame-alist '(font . "Iosevka Medium")) #+END_SRC ** COMMENT Line numbers #+BEGIN_SRC emacs-lisp (use-package linum-relative :config (setq linum-relative-backend 'display-line-numbers-mode) (linum-relative-global-mode 1)) #+END_SRC ** Color Theme #+BEGIN_SRC emacs-lisp (use-package gruvbox-theme :config (load-theme 'gruvbox-dark-medium t)) #+END_SRC ** Beacon Highlights the cursor each time I switch windows. #+BEGIN_SRC emacs-lisp (use-package beacon :config (beacon-mode 1)) #+END_SRC ** Fringe Ugly. #+BEGIN_SRC emacs-lisp (fringe-mode '(10 . 10)) #+END_SRC ** Line-wrapping Line wrapping is confusing, more than anything else. Thus, let's disable it! #+begin_src emacs-lisp (setq-default truncate-lines 1) #+end_src ** Org-mode codeblocks Let's make org-mode codeblocks look good! For this, we first set the code-block background and make it extend to the full width. #+begin_src emacs-lisp (set-face-attribute 'org-block nil :background "#1d2021" :extend t) #+end_src Additionally, we make the top and bottom lines of the block smaller and darker. #+begin_src emacs-lisp (cl-loop for face in '(org-block-begin-line org-block-end-line) do (set-face-attribute face nil :foreground "#504945" :background "#1a1d1e" :height 0.8 :extend t)) #+end_src ** COMMENT Mode-line #+begin_src emacs-lisp (use-package telephone-line :config (setq telephone-line-lhs '((evil . (telephone-line-evil-tag-segment)) (blue . (telephone-line-vc-segment telephone-line-process-segment)) (nil . (telephone-line-buffer-segment)))) (setq telephone-line-rhs '((nil . (telephone-line-misc-info-segment)) (accent . (telephone-line-major-mode-segment)) (evil . (telephone-line-airline-position-segment)))) (setq telephone-line-primary-left-separator 'telephone-line-cubed-left telephone-line-secondary-left-separator 'telephone-line-cubed-hollow-left telephone-line-primary-right-separator 'telephone-line-cubed-right telephone-line-secondary-right-separator 'telephone-line-cubed-hollow-right) (setq telephone-line-height 24 telephone-line-evil-use-short-tag t) (telephone-line-mode t)) #+end_src ** COMMENT doom-modeline #+begin_src emacs-lisp (use-package doom-modeline :config (setq doom-modeline-icon (display-graphic-p)) (setq doom-modeline-env-version t) (setq doom-modeline-project-detection 'project) (setq doom-modeline-height 1) (doom-modeline-mode t)) #+end_src #+begin_src emacs-lisp (use-package highlight-parentheses :config (highlight-parentheses-mode 1)) #+end_src * Ivy Ivy for completing stuff, etc. is huge. #+BEGIN_SRC emacs-lisp (use-package counsel :config (ivy-mode) (setq ivy-re-builders-alist '((t . ivy--regex-fuzzy))) (setq ivy-initial-inputs-alist nil) :bind ("C-s" . swiper) ("M-x". counsel-M-x)) #+END_SRC Flx does fancy fuzzy matching with good sorting #+BEGIN_SRC emacs-lisp (use-package flx) #+END_SRC * Projectile #+begin_src emacs-lisp (use-package projectile :config (projectile-mode t)) (use-package counsel-projectile :after projectile counsel) #+end_src fix the naming for which-key #+begin_src emacs-lisp (add-to-list 'which-key-replacement-alist '((nil . "projectile-\\([[:alnum:]-]+\\)") . (nil . "\\1"))) #+end_src * general.el #+BEGIN_SRC emacs-lisp (use-package general :config (general-evil-setup) (general-def :states '(normal motion) "SPC" nil) (general-create-definer elk-noleader-def :states '(normal motion) :keymaps 'override) (general-create-definer elk-leader-def :prefix "SPC" :states '(normal motion) :keymaps 'override) (elk-leader-def "a" 'org-agenda "s" 'org-store-link "t" '((lambda () (interactive) (org-capture nil "t")) :wk "org-capture whatever") "f" '(counsel-find-file :wk "open a file") "1" 'delete-other-windows "0" 'delete-window "p" '(:keymap projectile-command-map :wk "Project") ) (which-key-add-key-based-replacements "SPC y" "Emacs stuff") (elk-leader-def :prefix "SPC y" "c" '((lambda () (interactive) (find-file "~/.emacs.d/config.org")) :wk "open config.org") "r" '((lambda () (interactive) (load-file "~/.emacs.d/init.el")) :wk "reload config.org"))) #+END_SRC * Window management #+BEGIN_SRC emacs-lisp (which-key-add-key-based-replacements "SPC b" "Window management") (elk-leader-def :prefix "SPC b" "c" '(kill-buffer-and-window :wk "close window and buffer") "w" '(delete-window :wk "close window") "f" '(counsel-buffer-or-recentf :wk "Switch to file") "b" '(counsel-switch-buffer :wk "Switch buffer") "o" '(counsel-switch-buffer-other-window :wk "Switch buffer in other window") "d" '(kill-buffer :wk "close buffer") "s" '(split-window-below :wk "h-split") "v" '(split-window-right :wk "v-split")) #+END_SRC * Editing ** evil-mode Emacs is lacks a good editor. #+BEGIN_SRC emacs-lisp (use-package evil :init (setq evil-want-keybinding nil) (setq evil-want-C-u-scroll t) (setq evil-want-fine-undo 'fine) (setq evil-undo-system 'undo-tree) :config (evil-mode 1)) #+END_SRC *** evil-org-mode #+BEGIN_SRC emacs-lisp (use-package evil-org :after org :config (add-hook 'org-mode-hook 'evil-org-mode) (add-hook 'evil-org-mode-hook (lambda () (evil-org-set-key-theme))) (require 'evil-org-agenda) (evil-org-agenda-set-keys)) #+END_SRC *** evil-collection Keybinds for common modes. Makes evil work everywhere. #+BEGIN_SRC emacs-lisp (use-package evil-collection :after evil :config (evil-collection-init)) #+END_SRC *** evil-surround #+BEGIN_SRC emacs-lisp (use-package evil-surround :after evil :config (global-evil-surround-mode t)) #+END_SRC ** Undo-tree Undo tree is based. #+BEGIN_SRC emacs-lisp (use-package undo-tree :config (global-undo-tree-mode t) (setq undo-tree-auto-save-history t) (push '("." . "~/.emacs.d/undo-tree-history") undo-tree-history-directory-alist)) #+END_SRC ** ace-jump Jump through the code faster than ever before! #+BEGIN_SRC emacs-lisp (use-package ace-jump-mode) (elk-leader-def "x" 'ace-jump-mode) #+END_SRC ** Multicursor Install the package and set up some binds! #+begin_src emacs-lisp (use-package evil-mc :config (evil-mc-mode 1)) (which-key-add-key-based-replacements "SPC d" "Multicursor") (elk-leader-def :prefix "SPC d" "j" '(evil-mc-make-cursor-move-next-line :wk "cursor below") "u" '(evil-mc-undo-last-added-cursor :wk "undo cursor") "d" '(evil-mc-undo-all-cursors :wk "remove all cursors") "n" '(evil-mc-make-and-goto-next-match :wk "next match") "m" '(evil-mc-skip-and-goto-next-match :wk "skip and next match") "s" '(evil-mc-make-cursor-in-visual-selection-beg :wk "cursor at selection")) #+end_src * Git integration ** Diff-hl gitgutter #+BEGIN_SRC emacs-lisp (use-package diff-hl :config (diff-hl-mode t)) #+END_SRC ** Magit #+BEGIN_SRC emacs-lisp (use-package magit) (use-package evil-magit) (which-key-add-key-based-replacements "SPC g" "Git shit") (elk-leader-def :prefix "SPC g" "s" '(magit-status :wk "status")) #+END_SRC * Code stuff ** general builtin stuff enable highlighting matching parentheses #+begin_src emacs-lisp (show-paren-mode 1) (setq show-paren-delay 0) #+end_src let's also turn lambdas into _actual_ lambdas: #+begin_src emacs-lisp (global-prettify-symbols-mode t) #+end_src ** Rainbow everything! because rainbows are fabulous! #+BEGIN_SRC emacs-lisp (use-package rainbow-delimiters :config (rainbow-delimiters-mode t)) (use-package rainbow-blocks :config (rainbow-blocks-mode t)) #+END_SRC ** Nerdcommenter #+BEGIN_SRC emacs-lisp (use-package evil-nerd-commenter) (which-key-add-key-based-replacements "SPC c" "Commenting") (elk-leader-def :prefix "SPC c" "SPC" '(evilnc-comment-or-uncomment-lines :wk "toggle comment") "c" '(evilnc-copy-and-comment-lines :wk "copy and comment")) #+END_SRC * Language support ** LSP-mode #+begin_src emacs-lisp (use-package lsp-mode :hook (;; replace XXX-mode with concrete major-mode(e. g. python-mode) (rustic . lsp) (lsp-mode . lsp-enable-which-key-integration)) :commands lsp) (use-package company) (use-package lsp-ui :commands lsp-ui-mode) (use-package lsp-ivy :commands lsp-ivy-workspace-symbol) (use-package lsp-treemacs :commands lsp-treemacs-errors-list) (use-package dap-mode) ;; (use-package dap-LANGUAGE) to load the dap adapter for your language #+end_src ** Rust #+begin_src emacs-lisp (use-package rustic) #+end_src ** Lisp *** parinfer Install the plugin #+BEGIN_SRC emacs-lisp (use-package parinfer :ensure t :init (progn (setq parinfer-lighters '("Parinfer:Indent" . "Parinfer:Paren")) (setq parinfer-auto-switch-indent-mode t) (setq parinfer-extensions '(defaults pretty-parens evil smart-tab smart-yank)) (add-hook 'emacs-lisp-mode-hook #'parinfer-mode))) #+END_SRC and set up some keybinds! #+BEGIN_SRC emacs-lisp (elk-leader-def :prefix "SPC m" "-" '(parinfer-toggle-mode :wk "toggle parinfer mode")) #+END_SRC Also, let's integrate it with out bar: - TODO Fix this #+BEGIN_SRC emacs-lisp (defun update-parinfer-mode-status (x) (setq global-mode-string (format "%s" x parinfer--mode))) (add-hook 'parinfer-switch-mode-hook 'update-parinfer-mode-status) #+END_SRC