;;; init.el --- Configuration entry point -*- lexical-binding: t -*- ;;; Commentary: ;;; Code: ;; Set package dir to follow no-littering conventions (setq package-user-dir "~/.emacs.d/var/elpa") ;; Use melpa (require 'package) (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t) (package-initialize) ;; Ensure use-package is installed (unless (package-installed-p 'use-package) (package-refresh-contents) (package-install 'use-package)) ;; use-package (eval-when-compile (setq use-package-always-ensure t package-user-dir "~/.emacs.d/var/elpa") (require 'use-package)) ;; no-littering (use-package no-littering :config (no-littering-theme-backups) (setq custom-file (no-littering-expand-etc-file-name "custom.el"))) ;; diminish (use-package diminish :config (diminish 'visual-line-mode) (diminish 'abbrev-mode)) ;; basic stuff (use-package emacs :hook ((emacs-lisp-mode . my/-emacs-lisp-mode-setup-evil-lookup) (prog-mode . my/enable-electric-pair-mode)) :init (defun my/-emacs-lisp-mode-setup-evil-lookup () (setq-local evil-lookup-func #'my/describe-symbol-at-point)) (defun my/enable-electric-pair-mode () (electric-pair-local-mode 1)) (defun my/describe-symbol-at-point () "Calls `describe-symbol' on the return value of `form-at-point'." (interactive) (let ((form (form-at-point))) (if (consp form) (describe-symbol (cadr form)) (describe-symbol form)))) ;; Terminal mouse support (xterm-mouse-mode 1) ;; Make show paren instant (setq show-paren-delay 0) (show-paren-mode 1) ;; Display line numbers (global-display-line-numbers-mode 1) ;; Show some more context arround the point (setq scroll-margin 2) ;; Allow the frame to be any size (setq frame-resize-pixelwise t) ;; Disable startup screen (setq inhibit-startup-screen t) ;; show column numbers (column-number-mode 1) ;; Disable the menu and tool bars (menu-bar-mode -1) (tool-bar-mode -1) ;; No scroll bars (scroll-bar-mode -1) ;; Some better scrolling (pixel-scroll-mode 1) ;; Visual line mode (global-visual-line-mode 1) ;; Set fonts (add-to-list 'default-frame-alist '(font . "FiraCode Nerd Font Mono-12")) ;; Some settings for programming (setq-default indent-tabs-mode nil tab-width 4) ;; Tree sitter download locations (setq treesit-language-source-alist '((c "https://github.com/tree-sitter/tree-sitter-c") (cpp "https://github.com/tree-sitter/tree-sitter-cpp") (java "https://github.com/tree-sitter/tree-sitter-java") (python "https://github.com/tree-sitter/tree-sitter-python") (rust "https://github.com/tree-sitter/tree-sitter-rust") (json "https://github.com/tree-sitter/tree-sitter-json"))) ;; Tree sitter major mode conversions (setq major-mode-remap-alist '((c-mode . c-ts-mode) (c++-mode . c++-ts-mode) (c-or-c++-mode . c-or-c++-ts-mode) (objc-mode . objc-ts-mode) (java-mode . java-ts-mode) (rust-mode . rust-ts-mode) (json-mode . json-ts-mode)))) ;; c-ts-mode (use-package c-ts-mode :init (setq-default c-ts-mode-indent-offset 4)) ;; recentf (use-package recentf :config (recentf-mode 1)) ;; evil (use-package evil :init (setq evil-want-integration t evil-want-keybinding nil evil-undo-system 'undo-redo evil-search-module 'isearch) :config (evil-mode 1) (evil-define-key '(normal visual motion) proced-mode-map "u" #'proced-unmark) (evil-define-key '(normal visual motion) dired-mode-map "u" #'dired-unmark)) (use-package evil-collection :diminish evil-collection-unimpaired-mode :config (evil-collection-init)) (use-package evil-surround :config (evil-define-key 'operator evil-surround-mode-map "z" #'evil-surround-edit "Z" #'evil-Sunrround-edit) (evil-define-key 'visual evil-surround-mode-map "g z" #'evil-surround-region "g Z" #'evil-Surround-region) (global-evil-surround-mode 1)) (use-package evil-terminal-cursor-changer :config (evil-terminal-cursor-changer-activate)) ;; which-key (use-package which-key :diminish which-key-mode :config (which-key-mode 1)) ;; avy (use-package avy :bind (("C-c C-j" . avy-resume) ("M-s s" . evil-avy-goto-char-2) ("M-s S" . evil-avy-goto-line)) :init (define-minor-mode my/evil-avy-mode "A minor mode for binding avy commands to s and S in evil's normal and visual states." :keymap (make-sparse-keymap)) (evil-define-key '(normal visual operator motion) my/evil-avy-mode-map "s" #'evil-avy-goto-char-2 "S" #'evil-avy-goto-line) (define-globalized-minor-mode my/evil-avy-global-mode my/evil-avy-mode (lambda () (my/evil-avy-mode 1)) :predicate '((not magit-mode dired-mode proced-mode) t)) (my/evil-avy-global-mode 1) :config (avy-setup-default)) ;; ace-window (use-package ace-window :diminish ace-window-mode :bind ("M-o" . ace-window) :init (setq aw-scope 'frame aw-minibuffer-flag t)) ;; savehist (use-package savehist :config (savehist-mode 1)) ;; vertico (use-package vertico :bind (:map vertico-map ("C-S-k" . kill-line) ("C-k" . vertico-previous) ("C-j" . vertico-next) ("RET" . vertico-directory-enter) ("DEL" . vertico-directory-delete-char) ("M-DEL" . vertico-directory-delete-word)) :hook (minibuffer-setup . cursor-intangible-mode) :init (setq vertico-cycle t enable-recursive-minibuffers t read-extended-command-predicate #'command-completion-default-include-p minibuffer-prompt-properties '(read-only t cursor-intangible t face minibuffer-prompt)) (vertico-mode 1)) ;; orderless (use-package orderless :autoload orderless-define-completion-style :hook (text-mode . my/-setup-text-mode-completion-styles) :init (defun my/-setup-text-mode-completion-styles () (setq-local completion-styles '(basic))) (orderless-define-completion-style my/orderless-with-initialism (orderless-matching-styles '(orderless-initialism orderless-literal orderless-regexp))) (setq completion-styles '(orderless basic) completion-category-defaults nil completion-category-overrides '((file (styles basic partial-completion)) (command (my/orderless-with-initialism basic)) (eglot (orderless basic))))) ;; marginalia (use-package marginalia :bind (:map minibuffer-local-map ("M-a" . marginalia-cycle)) :init (marginalia-mode 1)) ;; embark (use-package embark :bind (("C-." . embark-act) ("C-;" . embark-dwim)) :init (setq embark-quit-after-action nil) (add-to-list 'display-buffer-alist '("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*" nil (window-parameters (mode-line-format . none))))) ;; consult (use-package consult :bind (("C-s" . consult-line) ("C-x b" . consult-buffer) ("C-S-s" . consult-ripgrep) ("C-x C-S-f" . consult-fd) ("C-x C-m" . consult-man) ("C-h TAB" . consult-info) ("C-h C-m" . my/consult-emacs-info) ("C-x c k" . consult-keep-lines) ("C-x c f" . consult-focus-lines) ("C-x c r" . consult-recent-file) ("C-x c b" . consult-bookmark) ("M-g i" . consult-imenu) ("M-g I" . consult-imenu-multi) ("M-g r" . consult-imenu-multi)) :hook (minibuffer-setup . my/consult-setup-minibuffer-completion) :init (defun my/consult-setup-minibuffer-completion () (setq-local completion-in-region-function #'consult-completion-in-region)) (defun my/consult-emacs-info () "`consult-info' for emacs specific pages." (interactive) (consult-info "emacs" "efaq" "cl" "compat" "elisp")) (evil-declare-motion #'consult-line)) ;; integration for embark and consult (use-package embark-consult :hook (embark-collect-mode . consult-preview-at-point-mode)) ;; corfu (autocomplete) (use-package corfu :bind (("M-" . completion-at-point) :map corfu-map ("M-SPC" . corfu-insert-separator) ("M-m" . my/corfu-move-to-minibuffer)) :init (defun my/corfu-move-to-minibuffer () (interactive) (when completion-in-region--data (let ((completion-extra-properties corfu--extra) completion-cycle-threshold completion-cycling) (apply #'consult-completion-in-region completion-in-region--data)))) (setq corfu-cycle t corfu-auto t corfu-on-exact-match nil completion-cycle-threshold 3) (global-corfu-mode 1) (corfu-popupinfo-mode 1) :config (add-to-list 'corfu-continue-commands #'corfu-move-to-minibuffer)) (use-package corfu-terminal :init (corfu-terminal-mode 1)) ;; cape (a bunch of capfs!) (use-package cape :bind (("M-p" . cape-dabbrev) ("M-P" . cape-line)) :hook (text-mode . my/-cape-setup-text-mode) :init (defun my/-cape-setup-text-mode () (setq-local completion-at-point-functions '(cape-dict cape-dabbrev))) (add-to-list 'completion-at-point-functions #'cape-file)) ;; xref (use-package xref :init (evil-define-key '(normal motion) 'global "gr" #'xref-find-references) (setq xref-show-xrefs-function #'consult-xref xref-show-definitions-function #'consult-xref)) ;; popup.el (use-package popup) ;; flymake (use-package flymake :bind (:map flymake-mode-map ("C-c e" . my/flymake-show-diagnostic-at-point) ("C-c C-e" . consult-flymake)) :hook (emacs-lisp-mode . my/enable-flymake-mode) :init (defun my/flymake-show-diagnostic-at-point () (interactive) (if-let ((pos (point)) (diag (and flymake-mode (get-char-property pos 'flymake-diagnostic))) (message (flymake--diag-text diag))) (popup-tip message))) (defun my/enable-flymake-mode () (flymake-mode 1))) ;; eldoc (use-package eldoc :diminish eldoc-mode :init (set eldoc-echo-area-use-multiline-p nil)) ;; eglot (use-package eglot :hook (((c-ts-mode c++-ts-mode java-ts-mode rust-ts-mode python-ts-mode latex-mode) . eglot-ensure) (eglot-managed-mode . my/-eglot-setup)) :init (defun my/-eglot-setup () "Setup eldoc variables for `eglot-managed-mode-hook'." (setq-local eldoc-echo-area-use-multiline-p nil) (eglot-inlay-hints-mode -1)) (advice-add 'eglot-completion-at-point :around #'cape-wrap-buster) (setq eglot-autoshutdown t)) ;; rust (use-package rust-mode) ;; json (use-package json-mode) ;; sly (use-package sly :hook (lisp-mode . my/common-lisp-autoconnect-sly) :autoload sly-connected-p :init (defun my/common-lisp-autoconnect-sly () (unless (sly-connected-p) (save-excursion (sly)))) (setq inferior-lisp-program "/usr/bin/sbcl")) ;; vterm (use-package vterm :bind ("C-x C-a" . vterm)) ;; proced (use-package proced :bind ("C-x o" . proced) :init (setq proced-auto-update-flag t proced-auto-update-interval 1)) ;; dired (use-package dired :ensure nil :init (evil-define-key '(normal visual motion) dired-mode-map "u" #'dired-unmark "U" #'dired-unmark-all-marks) (evil-define-key '(normal visual motion) wdired-mode-map "u" #'dired-unmark "U" #'dired-unmark-all-marks)) ;; magit (use-package magit :bind ("C-x C-m" . magit) :init (evil-define-key '(normal visual motion) magit-mode-map "s" #'magit-stage-file "S" #'magit-stage-modified)) ;; rainbow-delimiters (use-package rainbow-delimiters :hook (prog-mode . rainbow-delimiters-mode)) ;; Theme (doom-themes) (use-package doom-themes :config (load-theme 'doom-molokai t) (doom-themes-org-config)) ;; solaire-mode (use-package solaire-mode :config (solaire-global-mode 1)) ;; icons (use-package nerd-icons) (use-package nerd-icons-completion :config (nerd-icons-completion-mode)) (use-package nerd-icons-dired :hook (dired-mode . nerd-icons-dired-mode)) (use-package kind-icon :after corfu :init (setq kind-icon-default-face 'corfu-default kind-icon-default-style '(:padding -1 :stroke 0 :margin 0 :radius 0 :height 0.5 :scale 1)) :config (add-to-list 'corfu-margin-formatters #'kind-icon-margin-formatter)) ;; modeline (doom-modeline) (use-package doom-modeline :init (setq doom-modeline-support-imenu t) (doom-modeline-mode 1))