#+TITLE: Materus Emacs Cfg #+AUTHOR: materus #+DESCRIPTION: materus emacs configuration #+STARTUP: overview #+PROPERTY: header-args :tangle no :noweb yes #+OPTIONS: \n:t #+auto_tangle: t * Table of Contents :noexport:TOC_3: - [[#early-init][Early Init]] - [[#init-core][Init Core]] - [[#prepare][Prepare]] - [[#elpaca][Elpaca]] - [[#functions][Functions]] - [[#custom-file][Custom File]] - [[#font--text][Font & Text]] - [[#frame][Frame]] - [[#mouse][Mouse]] - [[#packages--settings][Packages & Settings]] - [[#visual][Visual]] - [[#theme][Theme]] - [[#rainbow-mode][Rainbow mode]] - [[#delimiters][Delimiters]] - [[#modeline][Modeline]] - [[#dashboard][Dashboard]] - [[#highlight-indent-guides][Highlight Indent Guides]] - [[#terminal][Terminal]] - [[#eat][Eat]] - [[#vterm][Vterm]] - [[#navigation-and-completion][Navigation and Completion]] - [[#helm][HELM]] - [[#comapny][Comapny]] - [[#dirvish][Dirvish]] - [[#treemacs][Treemacs]] - [[#programming][Programming]] - [[#general][General]] - [[#snippets][Snippets]] - [[#cc][C/C++]] - [[#java][Java]] - [[#python][Python]] - [[#nix][Nix]] - [[#lisp--scheme][Lisp / Scheme]] - [[#shell][Shell]] - [[#version-control][Version Control]] - [[#diff-highlight][Diff Highlight]] - [[#magit][Magit]] - [[#git-timemachine][Git Timemachine]] - [[#notes--organization][Notes & Organization]] - [[#org-mode][Org Mode]] - [[#other--misc][Other & Misc]] - [[#undo-tree][Undo-tree]] - [[#which-key][which-key]] - [[#projectile][projectile]] - [[#perspective][Perspective]] - [[#elcord][Elcord]] - [[#drag-stuff][drag-stuff]] - [[#popper][popper]] - [[#visual-fill-column][visual-fill-column]] - [[#so-long][so-long]] - [[#vlf][vlf]] - [[#crux][crux]] - [[#no-littering][No Littering]] - [[#libraries][Libraries]] - [[#nerd-icons][Nerd Icons]] - [[#svg-lib][SVG Lib]] - [[#transient][Transient]] - [[#keybindings][Keybindings]] - [[#final-code][Final Code]] - [[#links][Links]] - [[#archive][Archive]] - [[#minibuffer-orderless-vertico-marginalia-consult][minibuffer (orderless, vertico, marginalia, consult)]] - [[#code-completion-cape-corfu][Code completion (Cape, corfu)]] * Early Init #+begin_src emacs-lisp :tangle (expand-file-name "early-init.el" user-emacs-directory) :noweb-ref early-init ;;; -*- lexical-binding: t; -*- ;;; VARIABLES (setenv "LSP_USE_PLISTS" "true") ; Make lsp-mode use plists (setq c-default-style nil) ; Clear default styles for languages, will set them up later (setq default-input-method nil) ; Disable default input method, I'm not using them anyway so far (setq initial-major-mode 'fundamental-mode) ; Use fundamental mode in scratch buffer, speed up loading, not really important when emacs used as daemon (setq auto-save-default nil) ; TODO: configure auto saves, disable for now (setq backup-directory-alist `((".*" . ,(concat user-emacs-directory "var/backups/")))) ; Set backup location (setq auto-save-file-name-transforms `((".*" ,(concat user-emacs-directory "var/recovery/") t))) ; Set auto-save location (setq auto-save-list-file-prefix (concat user-emacs-directory "var/auto-save/sessions/")) ; Set auto-save-list location (setq load-prefer-newer t) ; Prefer newer files to load (setq package-enable-at-startup nil) (setq package-quickstart nil) ; Disable package quickstart (setq inhibit-startup-screen t) (setq inhibit-compacting-font-caches t) ; Don't compact fonts (set-language-environment "UTF-8") ; Use UTF-8 (setq-default buffer-file-coding-system 'utf-8-unix) (setq custom-file (concat user-emacs-directory "etc/custom.el")) ; Set custom file location, don't want clutter in main directory (setq custom-theme-directory (concat user-emacs-directory "/etc/materus/themes" )) ; Set custom themes location (setq ring-bell-function 'ignore) ; Disable bell (defvar materus/emacs-gc-cons-threshold (* 64 1024 1024) "The value of `gc-cons-threshold' after Emacs startup.") ; Define after init garbage collector threshold ;;; GARBAGE COLLECTOR (setq gc-cons-threshold most-positive-fixnum) ; Set `gc-cons-threshold' so it won't collectect during initialization (add-hook 'emacs-startup-hook (lambda () (setq gc-cons-threshold materus/emacs-gc-cons-threshold))) ; Set `gc-cons-threshold' to desired value after startup ;;; FRAMES (setq frame-inhibit-implied-resize t) (setq frame-resize-pixelwise t) (setq window-resize-pixelwise t) ; Allow pixelwise resizing of window and frame (unless (daemonp) (add-to-list 'initial-frame-alist '(fullscreen . maximized))) ; Start first frame maximized if not running as daemon, daemon frame are set up later in config (setq default-frame-alist ; Set default size for frames '((width . 130) (height . 40))) (advice-add #'tty-run-terminal-initialization :override #'ignore) (add-hook 'window-setup-hook (lambda () (unless (display-graphic-p) (advice-remove #'tty-run-terminal-initialization #'ignore) (tty-run-terminal-initialization (selected-frame) nil t) ))) ;;; NATIVE COMPILATION (setq native-comp-async-report-warnings-errors nil) ; Silence warnings (setq native-comp-speed 3) ; Set native-comp speed (setq native-comp-jit-compilation t ;;native-comp-deferred-compilation t package-native-compile t) ;; Setting up native-comp cache location (when (and (fboundp 'startup-redirect-eln-cache) (fboundp 'native-comp-available-p) (native-comp-available-p)) (startup-redirect-eln-cache (convert-standard-filename (concat user-emacs-directory "var/eln-cache/")))) #+end_src * Init Core :PROPERTIES: :header-args: :tangle no :END: ** Prepare #+begin_src emacs-lisp :noweb-ref init ;; Prepare (require 'materus-nix nil t) (require 'elec-pair) (when (not emacs-build-time) (print "WARN: emacs-build-time not set up, using current time") (setq emacs-build-time (decode-time (current-time)))) (add-to-list 'load-path (concat user-emacs-directory "etc/pkgs/")) ; Extra load path for packages (setq read-process-output-max (* 1024 1024 3)) #+END_src ** Elpaca #+begin_src emacs-lisp :noweb-ref init-elpaca ;; Elpaca Init (defvar elpaca-installer-version 0.11) (defvar elpaca-directory (expand-file-name "var/elpaca/" user-emacs-directory)) (defvar elpaca-builds-directory (expand-file-name (concat "builds/" emacs-version "/") elpaca-directory)) (defvar elpaca-repos-directory (expand-file-name "repos/" elpaca-directory)) (defvar elpaca-order '(elpaca :repo "https://github.com/progfolio/elpaca.git" :ref nil :depth 1 :inherit ignore :files (:defaults "elpaca-test.el" (:exclude "extensions")) :build (:not elpaca--activate-package))) (let* ((repo (expand-file-name "elpaca/" elpaca-repos-directory)) (build (expand-file-name "elpaca/" elpaca-builds-directory)) (order (cdr elpaca-order)) (default-directory repo)) (add-to-list 'load-path (if (file-exists-p build) build repo)) (unless (file-exists-p repo) (make-directory repo t) (when (<= emacs-major-version 28) (require 'subr-x)) (condition-case-unless-debug err (if-let* ((buffer (pop-to-buffer-same-window "*elpaca-bootstrap*")) ((zerop (apply #'call-process `("git" nil ,buffer t "clone" ,@(when-let* ((depth (plist-get order :depth))) (list (format "--depth=%d" depth) "--no-single-branch")) ,(plist-get order :repo) ,repo)))) ((zerop (call-process "git" nil buffer t "checkout" (or (plist-get order :ref) "--")))) (emacs (concat invocation-directory invocation-name)) ((zerop (call-process emacs nil buffer nil "-Q" "-L" "." "--batch" "--eval" "(byte-recompile-directory \".\" 0 'force)"))) ((require 'elpaca)) ((elpaca-generate-autoloads "elpaca" repo))) (progn (message "%s" (buffer-string)) (kill-buffer buffer)) (error "%s" (with-current-buffer buffer (buffer-string)))) ((error) (warn "%s" err) (delete-directory repo 'recursive)))) (unless (require 'elpaca-autoloads nil t) (require 'elpaca) (elpaca-generate-autoloads "elpaca" repo) (let ((load-source-file-function nil)) (load "./elpaca-autoloads")))) (add-hook 'after-init-hook #'elpaca-process-queues) (elpaca `(,@elpaca-order)) (elpaca elpaca-use-package (elpaca-use-package-mode) (setq elpaca-use-package-by-default t)) #+END_src ** Functions #+begin_src emacs-lisp :noweb-ref init-functions ;; Use package preffering built-in / nix packages (defmacro materus/use-package (package &rest body) (if (locate-library (symbol-name `,package)) `(progn (cl-pushnew (quote ,package) elpaca-ignored-dependencies) (use-package ,package :ensure nil ,@body)) `(use-package ,package ,@body))) #+END_src ** Custom File #+begin_src emacs-lisp :noweb-ref init-custom-file ;; Custom File (add-hook 'elpaca-after-init-hook (lambda () (load custom-file 'noerror))) #+end_src ** Font & Text #+begin_src emacs-lisp :noweb-ref init-extra ;; Font & Text init (when (display-graphic-p) (set-frame-font "Hack Nerd Font" nil t)) (setq-default cursor-type '(bar . 2)) (setq truncate-string-ellipsis "…") (setq text-mode-ispell-word-completion nil) ; Disable ispell (global-completion-preview-mode 1) (electric-pair-mode 1) (electric-indent-mode -1) #+end_src ** Frame #+begin_src emacs-lisp :noweb-ref init-extra ;; Frame Init (when (daemonp) (add-hook 'after-make-frame-functions (lambda (frame) (when (= (length (frame-list)) 2) (set-frame-parameter frame 'fullscreen 'maximized)) (select-frame-set-input-focus frame) ))) (global-tab-line-mode 1) (setq window-divider-default-bottom-width 1) (setq window-divider-default-right-width 1) (window-divider-mode 1) (tool-bar-mode -1) (setq-default display-line-numbers-width 3) (setq-default display-line-numbers-widen t) (defun startup-screen-advice (orig-fun &rest args) (when (= (seq-count #'buffer-file-name (buffer-list)) 0) (apply orig-fun args))) (advice-add 'display-startup-screen :around #'startup-screen-advice) ; Hide startup screen if started with file #+end_src ** Mouse Setting up mouse #+begin_src emacs-lisp :noweb-ref init-extra ;; Mouse Init (context-menu-mode 1) (setq mouse-wheel-follow-mouse 't) (setq scroll-step 1) (setq mouse-drag-and-drop-region t) (xterm-mouse-mode 1) (pixel-scroll-precision-mode 1) (setq-default pixel-scroll-precision-large-scroll-height 10.0) #+end_src * Packages & Settings :PROPERTIES: :header-args: :tangle no :noweb-ref packages :END: ** Visual *** Theme #+begin_src emacs-lisp (use-package dracula-theme :config (if (daemonp) (add-hook 'after-make-frame-functions (lambda (frame) (with-selected-frame frame (load-theme 'dracula t)))) (load-theme 'dracula t))) #+end_src *** Rainbow mode #+begin_src emacs-lisp (use-package rainbow-mode :hook ((org-mode . rainbow-mode) (prog-mode . rainbow-mode))) #+end_src *** Delimiters #+begin_src emacs-lisp (use-package rainbow-delimiters :hook (prog-mode . rainbow-delimiters-mode) :config (set-face-attribute 'rainbow-delimiters-depth-1-face nil :foreground "#FFFFFF") (set-face-attribute 'rainbow-delimiters-depth-2-face nil :foreground "#FFFF00") (set-face-attribute 'rainbow-delimiters-depth-5-face nil :foreground "#6A5ACD") (set-face-attribute 'rainbow-delimiters-unmatched-face nil :foreground "#FF0000")) #+end_src *** Modeline #+begin_src emacs-lisp ;; (use-package doom-modeline ;; :init (setq doom-modeline-support-imenu t) ;; :hook (elpaca-after-init . doom-modeline-mode) ;; :config ;; (setq doom-modeline-icon t) ;; (setq doom-modeline-project-detection 'auto) ;; (setq doom-modeline-height 20) ;; (setq doom-modeline-enable-word-count t) ;; (setq doom-modeline-minor-modes t) ;; (setq display-time-24hr-format t) ;; (display-time-mode 1) ;; (column-number-mode 1) ;; (line-number-mode 1)) (use-package minions :hook (elpaca-after-init . minions-mode)) #+end_src *** Dashboard #+begin_src emacs-lisp (use-package dashboard :after (nerd-icons projectile) :config (setq dashboard-center-content t) (setq dashboard-display-icons-p t) (setq dashboard-icon-type 'nerd-icons) (setq dashboard-projects-backend 'projectile) (setq dashboard-items '((recents . 5) (bookmarks . 5) (projects . 5) (agenda . 5) (registers . 5))) (when (or (daemonp) (< (length command-line-args) 2)) (add-hook 'elpaca-after-init-hook #'dashboard-insert-startupify-lists) (add-hook 'elpaca-after-init-hook #'dashboard-initialize) (dashboard-setup-startup-hook))) (when (daemonp) (setq initial-buffer-choice (lambda () (get-buffer "*dashboard*")))) ; Show dashboard when emacs is running as daemon) #+end_src #+begin_src emacs-lisp :tangle no :noweb-ref keybindings ;; Dashboard (define-key dashboard-mode-map (kbd "C-r") #'dashboard-refresh-buffer) #+end_src *** Highlight Indent Guides [[https://github.com/DarthFennec/highlight-indent-guides][highlight-indent-guides]] #+begin_src emacs-lisp (use-package highlight-indent-guides :hook ((prog-mode . highlight-indent-guides-mode))) #+end_src ** Terminal *** Eat #+begin_src emacs-lisp (use-package eat) #+end_src #+begin_src emacs-lisp :tangle no :noweb-ref keybindings ;; Eat (defvar cua--eat-semi-char-keymap (copy-keymap cua--cua-keys-keymap) "EAT semi-char mode CUA keymap") (defvar cua--eat-char-keymap (copy-keymap cua--cua-keys-keymap) "EAT char mode CUA keymap") (define-key cua--eat-semi-char-keymap (kbd "C-v") #'eat-yank) (define-key cua--eat-char-keymap (kbd "C-S-v") #'eat-yank) (define-key cua--eat-semi-char-keymap (kbd "C-c") #'copy-region-as-kill) (define-key cua--eat-char-keymap (kbd "C-S-c") #'copy-region-as-kill) (define-key eat-mode-map (kbd "C-") #'eat-self-input) (define-key eat-mode-map (kbd "C-") #'eat-self-input) (defun cua--eat-semi-char-override-keymap () (setq-local cua--keymap-alist (copy-tree cua--keymap-alist)) (setf (alist-get 'cua--ena-cua-keys-keymap cua--keymap-alist) cua--eat-semi-char-keymap)) (defun cua--eat-char-override-keymap () (setq-local cua--keymap-alist (copy-tree cua--keymap-alist)) (setf (alist-get 'cua--ena-cua-keys-keymap cua--keymap-alist) cua--eat-char-keymap)) (advice-add 'eat-semi-char-mode :after #'cua--eat-semi-char-override-keymap) (advice-add 'eat-char-mode :after #'cua--eat-char-override-keymap) (add-hook 'eat-char-mode-hook #'cua--eat-char-override-keymap) #+end_src *** Vterm #+begin_src emacs-lisp (materus/use-package vterm) #+end_src ** Navigation and Completion *** HELM #+begin_src emacs-lisp (use-package helm :config (setq helm-x-icons-provider 'nerd-icons) (setq helm-move-to-line-cycle-in-source nil) (helm-mode 1) ) (use-package helm-projectile :after (helm projectile)) (use-package helm-ag :after (helm)) (use-package helm-rg :after (helm)) (use-package helm-ls-git :after (helm)) #+end_src #+begin_src emacs-lisp :tangle no :noweb-ref keybindings ;; Helm (global-set-key (kbd "M-x") 'helm-M-x) (global-set-key (kbd "C-x r b") #'helm-filtered-bookmarks) (global-set-key (kbd "C-x C-f") #'helm-find-files) (global-set-key (kbd "C-x b") #'helm-mini) #+end_src *** Comapny #+begin_src emacs-lisp (use-package company :hook ((prog-mode . company-mode))) (use-package slime-company :if (executable-find "sbcl") :after (company slime)) #+end_src *** Dirvish #+begin_src emacs-lisp (use-package dirvish :after (nerd-icons) :config (setq dired-mouse-drag-files t) (dirvish-override-dired-mode 1) (setq dirvish-attributes '(vc-state subtree-state nerd-icons collapse git-msg file-time file-size))) #+end_src *** Treemacs #+begin_src emacs-lisp (use-package treemacs) (use-package treemacs-projectile :after (projectile treemacs)) (use-package treemacs-nerd-icons :after (nerd-icons treemacs)) (use-package treemacs-perspective :after (treemacs)) (use-package treemacs-mouse-interface :after (treemacs) :ensure nil) #+end_src #+begin_src emacs-lisp :tangle no :noweb-ref keybindings ;; Treemacs (define-key global-map (kbd "C-H-t") 'treemacs) #+end_src ** Programming *** General **** Settings #+begin_src emacs-lisp :noweb-ref init-extra (add-to-list 'c-default-style '(awk-mode . "awk")) (add-to-list 'c-default-style '(other . "bsd")) (setq-default tab-width 4) (setq-default indent-tabs-mode nil) (setq-default c-basic-offset 4) (setq-default c-indent-level 4) (setq-default c-ts-mode-indent-offset 4) (setq-default c-ts-mode-indent-style 'bsd) (setq-default c-hungry-delete-key t) (add-hook 'prog-mode-hook 'display-line-numbers-mode) (add-hook 'prog-mode-hook 'electric-indent-local-mode) #+end_src **** LSP #+begin_src emacs-lisp (use-package lsp-ui :after (lsp-mode)) (use-package lsp-mode ;; :custom ;; (lsp-completion-provider :none) ;; we use Corfu! :config (setq lsp-keep-workspace-alive nil) (defun lsp-booster--advice-json-parse (old-fn &rest args) "Try to parse bytecode instead of json." (or (when (equal (following-char) ?#) (let ((bytecode (read (current-buffer)))) (when (byte-code-function-p bytecode) (funcall bytecode)))) (apply old-fn args))) (advice-add (if (progn (require 'json) (fboundp 'json-parse-buffer)) 'json-parse-buffer 'json-read) :around #'lsp-booster--advice-json-parse) (defun lsp-booster--advice-final-command (old-fn cmd &optional test?) "Prepend emacs-lsp-booster command to lsp CMD." (let ((orig-result (funcall old-fn cmd test?))) (if (and (not test?) ; for check lsp-server-present? (not (file-remote-p default-directory)) ; see lsp-resolve-final-command, it would add extra shell wrapper lsp-use-plists (not (functionp 'json-rpc-connection)) ; native json-rpc (executable-find "emacs-lsp-booster")) (progn (when-let* ((command-from-exec-path (executable-find (car orig-result)))) ; resolve command from exec-path (in case not found in $PATH) (setcar orig-result command-from-exec-path)) (message "Using emacs-lsp-booster for %s!" orig-result) (cons "emacs-lsp-booster" orig-result)) orig-result))) (advice-add 'lsp-resolve-final-command :around #'lsp-booster--advice-final-command)) (use-package lsp-treemacs :after (lsp-mode treemacs) :config (lsp-treemacs-sync-mode 1)) #+end_src **** Debug #+begin_src emacs-lisp (use-package dap-mode :after (lsp-mode) :config (require 'dap-lldb) (require 'dap-gdb-lldb) (require 'dap-cpptools) (setq dap-gdb-lldb-extension-version "0.27.0") (dap-auto-configure-mode 1)) #+end_src *** Snippets #+begin_src emacs-lisp (use-package yasnippet :config (yas-global-mode 1)) #+end_src *** C/C++ #+begin_src emacs-lisp (use-package lsp-clangd :ensure nil :after (lsp-mode) :config (setq lsp-clients-clangd-args '("--fallback-style=microsoft")) (add-hook 'c-mode-hook 'lsp-deferred) (add-hook 'c-mode-hook 'display-line-numbers-mode) (add-hook 'c-ts-mode-hook 'lsp-deferred) (add-hook 'c-ts-mode-hook 'display-line-numbers-mode) (add-hook 'c++-mode-hook 'lsp-deferred) (add-hook 'c++-mode-hook 'display-line-numbers-mode) (add-hook 'c++-ts-mode-hook 'lsp-deferred) (add-hook 'c++-ts-mode-hook 'display-line-numbers-mode) ;(when (treesit-language-available-p 'c) (push '(c-mode . c-ts-mode) major-mode-remap-alist)) ;(when (treesit-language-available-p 'cpp) (push '(c++-mode . c++-ts-mode) major-mode-remap-alist)) (add-to-list 'c-default-style '(c-mode . "bsd")) (add-to-list 'c-default-style '(c++-mode . "bsd")) (add-to-list 'c-default-style '(c-ts-mode . "bsd")) (add-to-list 'c-default-style '(c++-ts-mode . "bsd"))) #+end_src *** Java #+begin_src emacs-lisp (use-package lsp-java :after (lsp-mode) :config (setq lsp-java-vmargs '("-XX:+UseParallelGC" "-XX:GCTimeRatio=4" "-XX:AdaptiveSizePolicyWeight=90" "-Dsun.zip.disableMemoryMapping=true" "-Xmx4G" "-Xms512m")) ;;(add-hook 'java-mode-hook (lambda () (when (getenv "JDTLS_PATH") (setq lsp-java-server-install-dir (getenv "JDTLS_PATH"))))) (add-hook 'java-mode-hook 'lsp-deferred) (add-hook 'java-mode-hook 'display-line-numbers-mode) ;;(add-hook 'java-ts-mode-hook (lambda () (when (getenv "JDTLS_PATH") (setq lsp-java-server-install-dir (getenv "JDTLS_PATH"))))) (add-hook 'java-ts-mode-hook 'lsp-deferred) (add-hook 'java-ts-mode-hook 'display-line-numbers-mode) (when (treesit-language-available-p 'java) (push '(java-mode . java-ts-mode) major-mode-remap-alist)) (add-to-list 'c-default-style '(java-mode . "java")) (add-to-list 'c-default-style '(java-ts-mode . "java"))) #+end_src *** Python #+begin_src emacs-lisp (use-package lsp-pyright :after (lsp-mode) :if (executable-find "python") :config (setq lsp-pyright-langserver-command "pyright") (add-hook 'python-mode-hook 'lsp-deferred) (add-hook 'python-ts-mode-hook 'lsp-deferred) (when (treesit-language-available-p 'python) (push '(python-mode . python-ts-mode) major-mode-remap-alist))) #+end_src *** Nix #+begin_src emacs-lisp (use-package nix-mode) (use-package nix-ts-mode) (use-package lsp-nix :after (lsp-mode nix-mode nix-ts-mode) :ensure nil :config (add-to-list 'lsp-disabled-clients '(nix-mode . nix-nil)) (setq lsp-nix-nixd-server-path "nixd") (when (executable-find "nixfmt") (setq lsp-nix-nixd-formatting-command [ "nixfmt" ]) ) (unless lsp-nix-nixd-nixos-options-expr (setq lsp-nix-nixd-nixos-options-expr (concat "(builtins.getFlake \"/etc/nixos\").nixosConfigurations." (system-name) ".options"))) (unless lsp-nix-nixd-nixpkgs-expr (setq lsp-nix-nixd-nixpkgs-expr (concat "(builtins.getFlake \"/etc/nixos\").nixosConfigurations." (system-name) ".pkgs"))) (add-hook 'nix-mode-hook 'lsp-deferred) (add-hook 'nix-mode-hook 'display-line-numbers-mode) (add-hook 'nix-ts-mode-hook 'lsp-deferred) (add-hook 'nix-ts-mode-hook 'display-line-numbers-mode) (when (treesit-language-available-p 'nix) (push '(nix-mode . nix-ts-mode) major-mode-remap-alist))) #+end_src *** Lisp / Scheme #+begin_src emacs-lisp (use-package paredit) #+end_src **** Emacs Lisp #+begin_src emacs-lisp #+end_src **** Common Lisp #+begin_src emacs-lisp (use-package slime :if (executable-find "sbcl") :config (setq inferior-lisp-program "sbcl") (slime-setup '(slime-fancy slime-company))) #+end_src *** Shell **** Bash [[https://github.com/szermatt/emacs-bash-completion][Bash-completion]] #+begin_src emacs-lisp (use-package bash-completion) #+end_src ** Version Control *** Diff Highlight [[https://github.com/dgutov/diff-hl][diff-hl]] #+begin_src emacs-lisp (use-package diff-hl :config (setq diff-hl-side 'right) (global-diff-hl-mode 1) (diff-hl-margin-mode 1) (diff-hl-flydiff-mode 1) (global-diff-hl-show-hunk-mouse-mode 1)) #+end_src *** Magit [[https://magit.vc][Magit]] #+begin_src emacs-lisp (use-package magit :after (transient)) #+end_src *** Git Timemachine #+begin_src emacs-lisp (use-package git-timemachine :defer t) #+end_src ** Notes & Organization *** Org Mode #+begin_src emacs-lisp (use-package org :mode (("\\.org$" . org-mode)) :hook ((org-mode . org-indent-mode) (org-mode . display-line-numbers-mode) ) :config (require 'org-mouse) (require 'org-tempo) (setq org-src-window-setup 'current-window) (setq org-latex-pdf-process '("latexmk -xelatex -quiet -shell-escape -f -output-directory=%o %f")) (org-babel-do-load-languages 'org-babel-load-languages '((latex . t) (emacs-lisp . t) (shell . t) (css . t) (C . t) (calc . t) (awk . t) (sql . t) (sqlite . t))) (add-hook 'org-mode-hook (lambda () (setq-local electric-pair-inhibit-predicate `(lambda (c) (if (char-equal c ?<) t (,electric-pair-inhibit-predicate c))))))) #+end_src #+begin_src emacs-lisp (use-package org-modern :after (org) :hook (org-indent-mode . org-modern-mode) (org-agenda-finalize . org-modern-agenda) :config (setq org-modern-block-name '("▼ " . "▲ "))) #+end_src #+begin_src emacs-lisp (use-package org-auto-tangle :after (org) :hook (org-mode . org-auto-tangle-mode) ) #+end_src #+begin_src emacs-lisp (use-package toc-org :after (org) :hook ((org-mode . toc-org-mode ) (markdown-mode . toc-org-mode))) #+end_src #+begin_src emacs-lisp (use-package org-transclusion :after (org)) #+end_src #+begin_src emacs-lisp (use-package org-roam :after (org)) #+end_src ** Other & Misc *** Undo-tree #+begin_src emacs-lisp (use-package undo-tree :config (global-undo-tree-mode 1) (defvar materus/undo-tree-dir (concat user-emacs-directory "var/undo-tree/")) (unless (file-exists-p materus/undo-tree-dir) (make-directory materus/undo-tree-dir t)) (setq undo-tree-visualizer-diff t) (setq undo-tree-history-directory-alist `(("." . ,materus/undo-tree-dir ))) (setq undo-tree-visualizer-timestamps t)) #+end_src *** which-key #+begin_src emacs-lisp (use-package which-key :config (which-key-mode 1)) #+end_src *** projectile #+begin_src emacs-lisp (use-package projectile :config (projectile-mode 1)) #+end_src *** Perspective #+begin_src emacs-lisp (use-package perspective :config (setq persp-mode-prefix-key (kbd "C-c M-p")) (setq persp-modestring-short t) (persp-mode 1) ) #+end_src *** Elcord #+begin_src emacs-lisp (defun materus/elcord-toggle (&optional _frame) "Toggle elcord based on visible frames" (if (> (length (frame-list)) 1) (elcord-mode 1) (elcord-mode -1)) ) (use-package elcord :config (unless (daemonp) (elcord-mode 1)) (add-hook 'after-delete-frame-functions 'materus/elcord-toggle) (add-hook 'server-after-make-frame-hook 'materus/elcord-toggle)) #+end_src *** drag-stuff #+begin_src emacs-lisp (use-package drag-stuff) #+end_src *** popper #+begin_src emacs-lisp (use-package popper) #+end_src *** visual-fill-column #+begin_src emacs-lisp (use-package visual-fill-column) #+end_src *** so-long #+begin_src emacs-lisp (use-package so-long :defer t) #+end_src *** vlf #+begin_src emacs-lisp (use-package vlf :defer t) #+end_src *** crux #+begin_src emacs-lisp (use-package crux) #+end_src *** No Littering #+begin_src emacs-lisp :noweb-ref package-no-littering (use-package no-littering :ensure (:wait t) :config (require 'recentf) (setq package-quickstart-file (concat user-emacs-directory "var/quickstart/package-quickstart-" emacs-version ".el" )) (add-to-list 'recentf-exclude (recentf-expand-file-name no-littering-var-directory)) (add-to-list 'recentf-exclude (recentf-expand-file-name no-littering-etc-directory))) #+END_src ** Libraries *** Nerd Icons #+begin_src emacs-lisp (use-package nerd-icons) #+end_src *** SVG Lib #+begin_src emacs-lisp (use-package svg-lib) #+end_src *** Transient #+begin_src emacs-lisp (use-package transient) #+end_src * Keybindings #+begin_src emacs-lisp :noweb-ref keys ;; Keybindings (defun materus/keybind-set () (require 'cua-base) ;; CUA-like global (define-key global-map (kbd "C-s") 'save-buffer) (define-key global-map (kbd "C-r") 'query-replace) (define-key global-map (kbd "C-S-r") 'replace-string) (define-key global-map (kbd "M-r") 'query-replace-regexp) (define-key global-map (kbd "M-S-r") 'replace-regexp) (define-key global-map (kbd "C-a") 'mark-whole-buffer) (define-key global-map (kbd "C-f") 'isearch-forward) (define-key global-map (kbd "C-S-f") 'isearch-backward) (define-key isearch-mode-map (kbd "C-f") 'isearch-repeat-forward) (define-key isearch-mode-map (kbd "C-S-f") 'isearch-repeat-backward) ;; CUA (define-key cua--cua-keys-keymap (kbd "C-z") 'undo-tree-undo) (define-key cua--cua-keys-keymap (kbd "C-y") 'undo-tree-redo) (define-key cua-global-keymap (kbd "C-SPC") 'completion-at-point) (define-key cua-global-keymap (kbd "C-M-SPC") 'cua-set-mark) (cua-mode 1) ;; TAB (define-key global-map (kbd "C-") #'indent-rigidly-left) (define-key global-map (kbd "C-") #'indent-rigidly-right) ;; Hyper (define-key key-translation-map (kbd "") 'event-apply-hyper-modifier ) (define-key key-translation-map (kbd "") 'event-apply-hyper-modifier ) (define-key key-translation-map (kbd "∇") 'event-apply-hyper-modifier ) ;; Unbind (define-key isearch-mode-map (kbd "C-s") nil) (define-key isearch-mode-map (kbd "C-r") nil) <>) (add-hook 'elpaca-after-init-hook #'materus/keybind-set ) #+end_src * Final Code #+begin_src emacs-lisp :tangle (expand-file-name "init.el" user-emacs-directory) :noweb-ref final ;;; -*- lexical-binding: t; -*- <> <> <> <> <> <> <> <> #+end_src Make copy in this repository #+begin_src emacs-lisp :tangle ./early-init.el <> #+end_src #+begin_src emacs-lisp :tangle ./init.el <> #+end_src * Links [[https://github.com/emacs-tw/awesome-emacs][awesome-emacs]] * Archive :PROPERTIES: :header-args: :tangle no :END: ** minibuffer (orderless, vertico, marginalia, consult) #+begin_src emacs-lisp (use-package orderless :init ;; Tune the global completion style settings to your liking! ;; This affects the minibuffer and non-lsp completion at point. (setq completion-styles '(basic partial-completion orderless) completion-category-defaults nil completion-category-overrides nil)) (use-package consult) (use-package marginalia) (use-package vertico :after (consult marginalia) :config (setq completion-in-region-function (lambda (&rest args) (apply (if vertico-mode #'consult-completion-in-region #'completion--in-region) args))) (vertico-mode 1) (marginalia-mode 1)) (use-package vertico-mouse :config (vertico-mouse-mode 1) :ensure nil :after (vertico)) #+end_src ** Code completion (Cape, corfu) #+begin_src emacs-lisp (use-package cape) (use-package corfu :after (lsp-mode cape) ;; Optional customizations :custom (corfu-cycle nil) ;; Enable cycling for `corfu-next/previous' (corfu-auto t) ;; Enable auto completion (global-corfu-minibuffer nil) ;; (corfu-quit-at-boundary nil) ;; Never quit at completion boundary ;; (corfu-quit-no-match nil) ;; Never quit, even if there is no match (corfu-preview-current nil) ;; Disable current candidate preview ;; (corfu-preselect 'prompt) ;; Preselect the prompt ;; (corfu-on-exact-match nil) ;; Configure handling of exact matches ;; Enable Corfu only for certain modes. See also `global-corfu-modes'. ;; :hook ((prog-mode . corfu-mode) ;; (shell-mode . corfu-mode) ;; (eshell-mode . corfu-mode)) ;; Recommended: Enable Corfu globally. This is recommended since Dabbrev can ;; be used globally (M-/). See also the customization variable ;; `global-corfu-modes' to exclude certain modes. :init (global-corfu-mode 1) (corfu-popupinfo-mode 1) (corfu-history-mode 1) (defun materus/orderless-dispatch-flex-first (_pattern index _total) (and (eq index 0) 'orderless-flex)) (defun materus/lsp-mode-setup-completion () (setf (alist-get 'styles (alist-get 'lsp-capf completion-category-defaults)) '(orderless)) ;; Optionally configure the first word as flex filtered. (add-hook 'orderless-style-dispatchers #'materus/orderless-dispatch-flex-first nil 'local) ;; Optionally configure the cape-capf-buster. (setq-local completion-at-point-functions (list (cape-capf-buster #'lsp-completion-at-point)))) :hook (lsp-completion-mode . materus/lsp-mode-setup-completion)) (use-package corfu-terminal :after (corfu) :config (when (or (daemonp) (not (display-graphic-p))) (corfu-terminal-mode))) ;; (use-package corfu-mouse ;; :after (corfu) ;; :config ;; :ensure nil ;; (corfu-mouse-mode) ;; (keymap-set corfu--mouse-ignore-map "" 'ignore) ;; (keymap-set corfu-map "" 'ignore)) (use-package kind-icon :after (corfu) :config (add-to-list 'corfu-margin-formatters #'kind-icon-margin-formatter)) #+end_src