#+TITLE: Emacs Configuration #+AUTHOR: Mars (@pupbrained) #+EMAIL: mars@pupbrained.xyz * Basic Setup ** Server #+begin_src emacs-lisp (require 'bind-key) (load "server") (unless (server-running-p) (server-start)) #+end_src ** Auto-Save *** Disable Built-In Auto-Save and Backup #+begin_src emacs-lisp (setq auto-save-default nil make-backup-files nil) #+end_src *** Enable Real Auto-Save #+begin_src emacs-lisp (use-package real-auto-save :ensure t :hook (prog-mode . real-auto-save-mode) :config (setq real-auto-save-interval 1)) #+end_src ** No Scratch On Open #+begin_src emacs-lisp (setq initial-scratch-message nil) (setq initial-buffer-choice nil) (add-hook 'emacs-startup-hook (lambda () (when (and (get-buffer "*scratch*") (not (eq (current-buffer) (get-buffer "*scratch*")))) (kill-buffer "*scratch*")))) #+end_src ** Dirvish #+begin_src emacs-lisp (add-hook 'dired-mode-hook 'dired-omit-mode) (use-package ethan-wspace :ensure t :config (setq mode-require-final-newline nil) (global-ethan-wspace-mode 1)) (defun my/dirvish-create-file () "Create a new file in the current directory." (interactive) (let ((new-file (read-file-name "New file name: " (dired-current-directory)))) (if (file-exists-p new-file) (message "File already exists!") (write-region "" nil new-file) (revert-buffer) ;; Refresh the directory listing (message "File created: %s" new-file)))) (use-package dirvish :ensure t :init (dirvish-override-dired-mode) :config (dirvish-peek-mode) (dirvish-side-follow-mode) (setq dired-listing-switches "-al --human-readable --group-directories-first" dired-mouse-drag-files t dired-omit-files (rx (or (seq bol (? ".") "#") (seq bol "." eol) (seq bol ".git" eol))) dirvish-emerge-groups '(("Recent files" (predicate . recent-files-2h)) ("Documents" (extensions "pdf" "tex" "bib" "epub")) ("Video" (extensions "mp4" "mkv" "webm")) ("Pictures" (extensions "jpg" "png" "svg" "gif")) ("Audio" (extensions "mp3" "flac" "wav" "ape" "aac")) ("Archives" (extensions "gz" "rar" "zip"))) dirvish-attributes '(vc-state subtree-state nerd-icons collapse git-msg file-time file-size) dirvish-mode-line-format '(:left (sort symlink) :right (omit yank index)) dirvish-mode-line-height 25 dirvish-subtree-state-style 'nerd mouse-drag-and-drop-region-cross-program t)) ;; Addtional syntax highlighting for dired (use-package diredfl :ensure t :hook ((dired-mode . diredfl-mode) (dirvish-directory-view-mode . diredfl-mode)) :config (set-face-attribute 'diredfl-dir-name nil :bold t)) (use-package nerd-icons :ensure t :custom (nerd-icons-font-family "Maple Mono NF")) (use-package ns-auto-titlebar :ensure t :config (when (eq system-type 'darwin) (ns-auto-titlebar-mode))) #+end_src ** Doom Modeline #+begin_src emacs-lisp (use-package doom-modeline :ensure t :config (doom-modeline-mode)) #+end_src ** Nix #+begin_src emacs-lisp (use-package nix-mode :mode "\\.nix\\'") #+end_src ** Org Mode Templates #+begin_src emacs-lisp ;; Inhibits autopairs from running for <> in org mode (add-hook 'org-mode-hook (lambda () (setq-local electric-pair-inhibit-predicate `(lambda (c) (if (char-equal c ?<) t (,electric-pair-inhibit-predicate c)))))) (require 'org-tempo) (add-to-list 'org-modules 'org-tempo t) (defun org-babel-edit-prep:emacs-lisp (babel-info) (setq-local buffer-file-name (->> babel-info caddr (alist-get :tangle))) (lsp)) #+end_src ** Fix Indents + Enable Autopairs #+begin_src emacs-lisp (electric-indent-mode -1) (electric-pair-mode 1) (setq-default tab-width 2) (setq-default indent-tabs-mode nil) (use-package evil :ensure t :init (setq evil-split-window-below t evil-undo-system 'undo-tree evil-vsplit-window-right t evil-want-C-i-jump nil evil-want-C-u-scroll t evil-want-integration t evil-want-integration t evil-want-keybinding nil) :config (evil-mode 1) (setq-default evil-shift-width 2) (evil-define-key 'insert 'global (kbd "TAB") 'tab-to-tab-stop) (evil-define-key 'normal 'global (kbd "gm") 'magit-status) (evil-define-key 'normal 'global (kbd "gp") 'diff-hl-show-hunk) (evil-define-key 'normal 'global (kbd "gr") 'diff-hl-revert-hunk) (evil-define-key 'normal 'global (kbd "gs") 'diff-hl-stage-current-hunk)) (defun my-set-indent-width () (setq-local tab-width 2) (setq-local evil-shift-width 2) (setq-local indent-tabs-mode nil)) (add-hook 'prog-mode-hook 'my-set-indent-width) (defun my-org-src-edit-hook () "Set indent width for Org source blocks." (setq indent-tabs-mode nil) ;; Use spaces instead of tabs (setq tab-width 2)) ;; Set tab width to your desired value (add-hook 'org-src-mode-hook 'my-org-src-edit-hook) (setq-default whitespace-style '(face spaces empty tabs trailing space-mark tab-mark)) (add-hook 'prog-mode-hook 'whitespace-mode) ;; Set whitespace actions. (setq-default whitespace-action '(cleanup auto-cleanup)) (use-package general :ensure t :config (general-define-key :states '(normal visual emacs))) (use-package evil-collection :ensure t :config (evil-collection-init)) (use-package evil-leader :ensure t :config (global-evil-leader-mode) (setq evil-leader/leader "") (evil-leader/set-key "bb" #'switch-to-buffer) (evil-leader/set-key "bd" #'kill-this-buffer) (evil-leader/set-key "e" #'dirvish-side) (evil-leader/set-key "N" #'lsp-bridge-diagnostic-jump-prev) (evil-leader/set-key "n" #'lsp-bridge-diagnostic-jump-next)) (use-package catppuccin-theme :ensure t :demand t :config (load-theme 'catppuccin t)) (setq auto-save-default nil make-backup-files nil) #+end_src ** LSP *** LSP-Bridge #+begin_src emacs-lisp (use-package yasnippet :ensure t :init (yas-global-mode 1)) (use-package lsp-bridge :ensure '(lsp-bridge :type git :host github :repo "manateelazycat/lsp-bridge" :files (:defaults "*")) :init (defun my/lsp-bridge-find-def () (interactive) (let ((prev-marker (point-marker))) (lsp-bridge-find-def) (xref-push-marker-stack prev-marker))) (defun lsp-bridge-mode-hook-func () (with-eval-after-load 'corfu (corfu-mode -1)) (local-set-key (kbd "M-[") #'lsp-bridge-return-from-def) (local-set-key (kbd "M-]") #'lsp-bridge-find-def) (local-set-key [remap xref-find-definitions] #'lsp-bridge-find-def) (local-set-key [remap xref-find-definitions-other-window] #'lsp-bridge-find-def-other-window) (local-set-key [remap xref-find-references] #'lsp-bridge-find-references) (evil-define-key 'normal 'local (kbd "gd") #'lsp-bridge-find-def) (evil-define-key 'normal 'local (kbd "gD") #'lsp-bridge-find-def-other-window) (evil-define-key 'normal 'local (kbd "gi") #'lsp-bridge-find-impl) (evil-define-key 'normal 'local (kbd "gI") #'lsp-bridge-find-impl-other-window) (evil-define-key 'normal 'local (kbd "gr") #'lsp-bridge-find-references) (evil-define-key 'normal 'local (kbd "K") #'lsp-bridge-popup-documentation)) (setq lsp-bridge-enable-log nil acm-enable-icon t acm-enable-doc t acm-enable-tabnine nil acm-enable-quick-access t) (require 'lsp-bridge) (evil-set-initial-state 'lsp-bridge-ref-mode 'insert) (add-hook 'lsp-bridge-mode-hook #'lsp-bridge-mode-hook-func) ;; Enable lsp-bridge. (add-hook 'c++-mode-hook #'lsp-bridge-mode)) #+end_src *** TreeSitter #+begin_src emacs-lisp (use-package tree-sitter :ensure t :hook (prog-mode . tree-sitter-hl-mode) :config (global-tree-sitter-mode)) (use-package tree-sitter-langs :ensure t) #+end_src ** Rainbow Delimiters #+begin_src emacs-lisp (use-package rainbow-delimiters :ensure t :config (add-hook 'prog-mode-hook 'rainbow-delimiters-mode)) #+end_src ** Disable Bars #+begin_src emacs-lisp (menu-bar-mode -1) (scroll-bar-mode -1) (tool-bar-mode -1) #+end_src ** Line Numbers #+begin_src emacs-lisp (global-display-line-numbers-mode t) (setq display-line-numbers-type 'relative) (dolist (mode '(term-mode-hook vterm-mode-hook shell-mode-hook org-mode-hook dirvish-setup-hook eshell-mode-hook)) (add-hook mode (lambda () (display-line-numbers-mode 0)))) #+end_src ** Vim-Style Scrolling #+begin_src emacs-lisp (setq scroll-step 3 scroll-conservatively 9999) #+end_src ** System-Specific Settings #+begin_src emacs-lisp (cond ((eq system-type 'darwin) (set-face-attribute 'default nil :font "Iosevka Comfy-14") (set-face-attribute 'fixed-pitch nil :font "Iosevka Comfy-14") (set-face-attribute 'variable-pitch nil :font "Iosevka Comfy Motion Duo-16") (setq default-frame-alist '((font . "Iosevka Comfy-14")))) ((eq system-type 'gnu/linux) (set-face-attribute 'default nil :font "Iosevka Comfy Medium-12") (set-face-attribute 'fixed-pitch nil :font "Iosevka Comfy Medium-12") (set-face-attribute 'variable-pitch nil :font "Iosevka Comfy Motion Duo Md-14") (setq default-frame-alist '((font . "Iosevka Comfy Medium-12") (undecorated . t))))) #+end_src ** Use Short Answers #+begin_src emacs-lisp (setq use-short-answers t) #+end_src ** Enable ctrl+c/ctrl+v #+begin_src emacs-lisp (cua-mode 1) #+end_src ** Undo Tree #+begin_src emacs-lisp (use-package undo-tree :ensure t :demand t :config (global-undo-tree-mode) (setq undo-tree-history-directory-alist '(("." . "~/.emacs.d/undo")))) #+end_src ** Dashboard #+begin_src emacs-lisp (use-package dashboard :ensure t :config (dashboard-setup-startup-hook) (setq dashboard-startup-banner 'logo dashboard-center-content t dashboard-vertically-center-content t dashboard-startup-banner 'logo initial-buffer-choice (lambda () (get-buffer-create "*dashboard*")))) #+end_src ** Git Integration #+begin_src emacs-lisp (use-package transient :ensure t) (use-package magit :ensure t :commands magit-status magit-blame magit-version :init (defadvice magit-status (around magit-fullscreen activate) (window-configuration-to-register :magit-fullscreen) ad-do-it (delete-other-windows)) :config (setq magit-branch-arguments nil magit-default-tracking-name-function 'magit-default-tracking-name-branch-only magit-push-always-verify nil magit-restore-window-configuration t)) (use-package diff-hl :ensure t :hook ((magit-post-refresh . diff-hl-magit-post-refresh)) :config (global-diff-hl-mode)) (use-package git-gutter :ensure t :config (global-git-gutter-mode +1)) #+end_src ** Direnv #+begin_src emacs-lisp (use-package envrc :ensure t :config (envrc-global-mode)) #+end_src ** Better M-x *** Ivy Mode (Completions) #+begin_src emacs-lisp (setq ivy-ignore-buffers '("\\` " "\\`\\*")) (use-package ivy :ensure t :config (ivy-mode) (setq ivy-use-virtual-buffers t enable-recursive-minibuffers t)) #+end_src *** Amx Mode (Better Interface) #+begin_src emacs-lisp (use-package amx :ensure t :config (amx-mode)) #+end_src ** Org Mode Improvements #+begin_src emacs-lisp (add-hook 'org-mode-hook 'visual-line-mode) (use-package mixed-pitch :hook (org-mode . mixed-pitch-mode)) (use-package org-modern :ensure t :hook (org-mode . org-modern-mode) :config (setq org-ellipsis "…") (setq org-modern-star 'replace)) (use-package org-modern-indent :ensure (org-modern-indent :type git :host github :repo "jdtsmith/org-modern-indent") :config (add-hook 'org-mode-hook #'org-modern-indent-mode 90)) #+end_src