#+TITLE: My Emacs Configuration #+AUTHOR: Amneesh Singh #+PROPERTY: header-args:emacs-lisp :tangle yes * Color Variables idk random variables to match my color theme #+begin_src emacs-lisp ; -*- lexical-binding: t; -*- (setq c-bg "#073642" c-fg "#eee8d5" c-red "#dc322f" c-green "#859900" c-yellow "#b58900" c-blue "#268bd2" c-magenta "#d33682" c-cyan "#2aa198" c-white "#eee8d5" c-black "#002b36" c-red-2 "#cb4b16" c-green-2 "#586e75" c-yellow-2 "#657b83" c-blue-2 "#839496" c-magenta-2 "#6c71c4" c-cyan-2 "#93a1a1" c-white-2 "#fdf6e3") #+end_src * Settings ** Setting the default face #+begin_src emacs-lisp (setq default-frame-alist '((font . "Monoid-12"))) #+end_src ** Some mode settings based on personal preferences #+begin_src emacs-lisp (global-hl-line-mode 1) (scroll-bar-mode 0) (tool-bar-mode 0) (menu-bar-mode 0) (fringe-mode 0) ;(cua-mode 1) (global-display-line-numbers-mode 1) (xterm-mouse-mode 1) #+end_src ** Setting some variables #+begin_src emacs-lisp (setq initial-major-mode 'emacs-lisp-mode frame-resize-pixelwise t auto-window-vscroll nil scroll-step 1 display-line-numbers-type 'relative confirm-kill-processes nil dark-theme t inhibit-startup-screen t) (setq-default tab-width 2 indent-tabs-mode nil) #+end_src ** Emacs startup hook #+begin_src emacs-lisp (add-hook 'emacs-startup-hook (lambda () (delete-other-windows)) t) #+end_src * Packages ** Add Melpa to package archives #+begin_src emacs-lisp (require 'package) (add-to-list 'package-archives '("melpa" . "http://melpa.org/packages/")) (package-initialize) (require 'use-package) #+end_src ** Visual packages *** Add solaire mode #+begin_src emacs-lisp (use-package solaire-mode :config (solaire-mode)) #+end_src *** Set theme #+begin_src emacs-lisp (use-package doom-themes :config (setq doom-themes-enable-bold t doom-themes-enable-italic t doom-themes-treemacs-theme "doom-colors") (load-theme 'doom-solarized-dark t) (doom-themes-visual-bell-config) (doom-themes-treemacs-config) (doom-themes-org-config)) #+end_src ** Configure Selectrum Enable selectrum #+begin_src emacs-lisp (use-package selectrum :config (define-key selectrum-minibuffer-map (kbd "C-n") #'selectrum-next-candidate) (define-key selectrum-minibuffer-map (kbd "C-e") #'selectrum-previous-candidate) (define-key selectrum-minibuffer-map (kbd "C-i") #'selectrum-select-current-candidate) (selectrum-mode +1)) #+end_src Add selectrum-prescient #+begin_src emacs-lisp (use-package selectrum-prescient :config (selectrum-prescient-mode +1) (prescient-persist-mode +1)) #+end_src Add orderless for selectrum #+begin_src emacs-lisp (use-package orderless :after selectrum :config (setq completion-styles '(orderless basic)) (add-to-list 'orderless-matching-styles 'orderless-flex) (savehist-mode) (setq orderless-skip-highlighting (lambda () selectrum-is-active)) (setq selectrum-highlight-candidates-function #'orderless-highlight-matches)) #+end_src ** Evil *** Configure evil mode #+begin_src emacs-lisp (defun my/evil-shift-right () (interactive) (evil-shift-right evil-visual-beginning evil-visual-end) (evil-normal-state) (evil-visual-restore)) (defun my/evil-shift-left () (interactive) (evil-shift-left evil-visual-beginning evil-visual-end) (evil-normal-state) (evil-visual-restore)) (use-package evil :init (setq-default evil-shift-width 2) :config (setq org-src-fontify-natively t org-src-strip-leading-and-trailing-blank-lines t org-src-preserve-indentation t org-src-tab-acts-natively t) (evil-set-initial-state 'vterm-mode 'insert) (evil-set-undo-system 'undo-tree) (evil-define-key 'visual global-map (kbd ">") 'my/evil-shift-right) (evil-define-key 'visual global-map (kbd "<") 'my/evil-shift-left) (evil-mode 1)) #+end_src *** Configure undo tree To undo and redo easily like vi #+begin_src emacs-lisp (use-package undo-tree :config (global-undo-tree-mode 1)) #+end_src *** Configure evil-colemak-basics To get colemak-dh bindings in evil mode #+begin_src emacs-lisp (use-package evil-colemak-basics :init (setq evil-colemak-basics-layout-mod 'mod-dh) :config (global-evil-colemak-basics-mode 1)) #+end_src *** Miscellaneous evil related packages #+begin_src emacs-lisp (use-package evil-terminal-cursor-changer) #+end_src ** Treemacs *** Dependencies #+begin_src emacs-lisp (use-package cfrs) #+end_src *** Configure treemacs #+begin_src emacs-lisp (use-package treemacs :atfer cfrs :config (treemacs-filewatch-mode 1) (treemacs-display-current-project-exclusively) (treemacs-git-mode 'simple)) #+end_src *** Configure treemacs-evil Configure treemacs-evil to get colemak-dh bindings #+begin_src emacs-lisp (use-package treemacs-evil :config (define-key evil-treemacs-state-map (kbd "j") nil) (define-key evil-treemacs-state-map (kbd "k") nil) (define-key evil-treemacs-state-map (kbd "n") #'treemacs-next-line) (define-key evil-treemacs-state-map (kbd "e") #'treemacs-previous-line) (define-key evil-treemacs-state-map (kbd "M-n") #'treemacs-next-neighbour) (define-key evil-treemacs-state-map (kbd "M-e") #'treemacs-previous-neighbour) (define-key evil-treemacs-state-map (kbd "M-N") #'treemacs-next-line-other-window) (define-key evil-treemacs-state-map (kbd "M-E") #'treemacs-previous-line-other-window) (define-key evil-treemacs-state-map (kbd "M") #'treemacs-collapse-parent-node) (evil-define-key 'treemacs treemacs-mode-map (kbd "m") #'treemacs-COLLAPSE-action) (evil-define-key 'treemacs treemacs-mode-map (kbd "i") #'treemacs-RET-action) ) #+end_src ** LSP *** Configure lsp-mode #+begin_src emacs-lisp (use-package lsp-mode :defer 0 :init (setq ) :config (lsp-mode 1)) #+end_src *** Configure lsp-treemacs #+begin_src emacs-lisp (use-package lsp-treemacs :defer 0 :config (lsp-treemacs-sync-mode 1)) #+end_src *** Configure lsp-ui #+begin_src emacs-lisp (use-package lsp-ui :defer 0 :init (setq lsp-ui-doc-show-with-cursor t) :config (lsp-ui-peek-enable 1) (lsp-ui-doc-enable 1)) #+end_src *** Language specific LSP packages #+begin_src emacs-lisp (use-package lsp-haskell) #+end_src *** Configure flycheck #+begin_src emacs-lisp (use-package flycheck) #+end_src *** Configure dap-mode #+begin_src emacs-lisp (use-package dap-mode) #+end_src ** Company *** Configure company For autocomplete #+begin_src emacs-lisp (use-package company :defer 0 :after lsp-mode :config (add-to-list 'company-backends 'company-dabbrev) (setq company-backends (cons 'company-files (remove 'company-files company-backends))) (company-mode 1) (define-key company-active-map (kbd "C-n") 'company-select-next) (define-key company-active-map (kbd "C-e") 'company-select-previous) (define-key company-search-map (kbd "C-n") 'company-select-next) (define-key company-search-map (kbd "C-e") 'company-select-previous)) #+end_src *** Configure company-quickhelp #+begin_src emacs-lisp (use-package company-quickhelp :hook (company-mode . company-quickhelp-mode)) #+end_src ** Treesitter #+begin_src emacs-lisp (use-package tree-sitter-langs) (use-package tree-sitter :after tree-sitter-langs :config (global-tree-sitter-mode) :init (add-to-list 'tree-sitter-major-mode-language-alist '(fundamental-mode . bash)) (add-hook 'tree-sitter-after-on-hook #'tree-sitter-hl-mode)) #+end_src ** Lang support #+begin_src emacs-lisp (use-package haskell-mode) (use-package rustic) (use-package nix-mode :mode "\\.nix\\'") (use-package hcl-mode :mod "\\.hcl\\'" "\\.nomad\\'") #+end_src ** Magit #+begin_src emacs-lisp (use-package magit) #+end_src * VTerm ** Configure vterm #+begin_src emacs-lisp (use-package vterm :config (setq vterm-timer-delay 0.005)) (use-package vterm-toggle :config (setq vterm-toggle-fullscreen-p nil) (add-to-list 'display-buffer-alist '((lambda(bufname _) (with-current-buffer bufname (equal major-mode 'vterm-mode))) (display-buffer-reuse-window display-buffer-at-bottom) (reusable-frames . visible) (window-height . 0.4)))) #+end_src ** Centaur Tabs #+begin_src emacs-lisp (use-package centaur-tabs :config (setq centaur-tabs-style "box" ; centaur-tabs-set-bar 'left centaur-tabs-height 18 centaur-tabs-set-modified-marker t centaur-tabs-set-icons t) (centaur-tabs-group-buffer-groups) (add-hook 'server-after-make-frame-hook 'centaur-tabs-mode) (centaur-tabs-headline-match) (set-face-attribute 'tab-line nil :inherit 'centaur-tabs-unselected)) #+end_src ** Misc packages #+begin_src emacs-lisp (use-package elcord :defer 0) (use-package projectile) (use-package rainbow-delimiters :hook (prog-mode . rainbow-delimiters-mode)) (use-package flex-autopair :config (flex-autopair-mode 1)) (use-package rainbow-mode :config (rainbow-mode 1)) (use-package treemacs-all-the-icons) (use-package general) #+end_src * Org ** Add org-mode #+begin_src emacs-lisp (use-package org :after evil :config (define-key org-mode-map (kbd "RET") 'org-return-and-maybe-indent) (setq evil-want-C-i-jump nil) (evil-define-key 'normal org-mode-map (kbd "TAB") 'org-cycle)) #+end_src ** Add org-bullets #+begin_src emacs-lisp (use-package org-bullets :config (add-hook 'org-mode-hook (lambda () (org-bullets-mode 1)))) #+end_src ** Babel and exports #+begin_src emacs-lisp (use-package htmlize) (add-to-list 'org-latex-packages-alist '("" "minted")) (setq org-latex-listings 'minted) (setq org-latex-pdf-process '("pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f" "pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f" "pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f")) (setq org-src-fontify-natively t) (org-babel-do-load-languages 'org-babel-load-languages '((awk . t) (python . t) (C . t) (shell . t) (sql . t) (latex . t))) #+end_src * Mode specific hooks #+begin_src emacs-lisp (add-hook 'c-mode-hook 'lsp) (add-hook 'c++-mode-hook 'lsp) (add-hook 'haskell-mode-hook #'lsp) (add-hook 'haskell-literate-mode-hook #'lsp) #+end_src * Custom mode line #+begin_src emacs-lisp (defface mode-line-buf-name `((t :foreground ,c-fg :background ,c-bg :weight bold )) "Custom face for buffer name" :group 'mode-line-faces ) (defface mode-line-maj-mode `((t :foreground ,c-fg :background ,c-bg )) "Custom face for major mode" :group 'mode-line-faces ) (defface mode-line-vc `((t :foreground ,c-fg :background ,c-red-2 :weight bold )) "Custom face for VC" :group 'mode-line-faces ) (defface mode-line-info `((t :foreground ,c-bg :background ,c-cyan :weight bold )) "For showing line and column number" :group 'mode-line-faces ) (setq-default mode-line-format '((:propertize " %b " face mode-line-buf-name) (vc-mode (:propertize (" " vc-mode " " ) face mode-line-vc)) (:propertize (" " mode-name " ") face mode-line-maj-mode) (:propertize (" [[ %l | %c || %p . %+%@ ]] ") face mode-line-info))) (setq exclude-ln '(term-mode-hook eshell-mode-hook shell-mode-hook)) (while exclude-ln (add-hook (car exclude-ln) (lambda () (display-line-numbers-mode 0))) (setq exclude-ln (cdr exclude-ln))) (let ((default-color (cons (face-background 'mode-line) (face-foreground 'mode-line)))) (add-hook 'post-command-hook (lambda () (let ((color (cond ((minibufferp) default-color) ((evil-insert-state-p) (cons c-magenta c-fg)) ((evil-visual-state-p) (cons c-cyan c-fg)) ((evil-normal-state-p) (cons c-fg c-bg)) ((buffer-modified-p) (cons c-blue c-fg)) (t default-color)))) (set-face-background 'mode-line-buf-name (car color)) (set-face-foreground 'mode-line-buf-name (cdr color)) )))) #+end_src * Pop-up terminal Stolen from [[https://www.reddit.com/r/emacs/comments/ft84xy/run_shell_command_in_new_vterm/][this]] reddit post #+begin_src emacs-lisp (defun run-in-vterm-kill (process event) "A process sentinel. Kills PROCESS's buffer if it is live." (let ((b (process-buffer process))) (and (buffer-live-p b) (kill-buffer b)))) (defun run-in-vterm (command) (interactive (list (let* ((f (cond (buffer-file-name) ((eq major-mode 'dired-mode) (dired-get-filename nil t)))) (filename (concat " " (shell-quote-argument (and f (file-relative-name f)))))) (read-shell-command "Terminal command: " (cons filename 0) (cons 'shell-command-history 1) (list filename))))) (with-current-buffer (vterm-toggle) (set-process-sentinel vterm--process #'run-in-vterm-kill) (vterm-send-string (concat command)) (vterm-send-return))) #+end_src This returns the command to run in the terminal #+begin_src emacs-lisp (defun candrun () (let ((full buffer-file-name) (file (file-name-sans-extension buffer-file-name))) (pcase (file-name-extension full) ("c" (concat "gcc " full "-lm -pthread -o " file " && " file " && rm " file)) ("java" (concat "java" full)) ("py" (concat "python" full)) ("cpp" (concat "g++ " full " -o " file " && " file " && rm " file)) ("hs" (concat "ghc -dynamic" full " && " file " && rm " file " " file ".o")) ("sh" (concat "sh" full)) ("js" (concat "node" full)) ("ts" (concat "tsc" full " && node " file ".js && rm " file ".js" )) ("rs" (concat "rustc" full " -o " file " && " file " && rm " file))))) #+end_src * Keybinds ** General #+begin_src emacs-lisp (with-eval-after-load 'general (general-define-key :states '(normal emacs visual motion treemacs Eshell override) "M-o" 'treemacs "M-v" 'split-window-vertically "M-h" 'split-window-horizontally "M-C-m" 'shrink-window-horizontally "M-C-i" 'enlarge-window-horizontally "M-C-e" 'shrink-window "M-C-n" 'enlarge-window "C-m" 'windmove-left "C-i" 'windmove-right "C-n" 'windmove-down "C-e" 'windmove-up "M-," 'centaur-tabs-backward "M-." 'centaur-tabs-forward "C-q" 'delete-window "M-C-S-q" 'kill-buffer-and-window "M-w" 'centaur-tabs--kill-this-buffer-dont-ask "M-S-w" 'kill-window) #+end_src Pop-up terminal specific keybinds #+begin_src emacs-lisp (with-eval-after-load 'vterm-toggle (general-define-key :states '(override insert normal visual treemacs motion) "M-f" 'lsp-format-buffer "" (lambda () (interactive) (vterm t)) "C-" 'vterm-toggle-cd "" 'vterm-toggle "" (lambda () (interactive) (run-in-vterm (candrun)))) (define-key vterm-mode-map (kbd "") 'vterm-toggle-forward) (define-key vterm-mode-map (kbd "") 'vterm-toggle-backward) (general-define-key :states '(normal insert) :keymaps 'VTerm "C-S-v" 'vterm-yank ) ) #+end_src Toggle Appearance #+begin_src emacs-lisp (defun toggle-theme-shade () (if (symbol-value dark-theme) (progn (disable-theme 'doom-solarized-dark) (load-theme 'doom-solarized-light t)) (progn (disable-theme 'doom-solarized-light) (load-theme 'doom-solarized-dark t))) (setq-local dark-theme (not dark-theme)) (centaur-tabs-display-update) (centaur-tabs-headline-match) ) (general-define-key :states '(normal) "" (lambda () (interactive) (toggle-theme-shade))) ) #+end_src