#+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 (set-frame-font "Monoid 12" nil t) (add-to-list '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-treemacs-config) (doom-themes-org-config)) #+end_src ** Configure Selectrum Enable selectrum #+begin_src emacs-lisp (use-package selectrum :config (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 #+begin_src emacs-lisp (use-package orderless :after selectrum :config (setq completion-styles '(orderless basic)) (savehist-mode) (setq orderless-skip-highlighting (lambda () selectrum-is-active) 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 (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 *** Miscellaneous evil related packages #+begin_src emacs-lisp (use-package evil-terminal-cursor-changer) #+end_src ** Treemacs *** Configure treemacs #+begin_src emacs-lisp (use-package treemacs) #+end_src #+begin_src emacs-lisp (use-package treemacs-evil) (use-package treemacs-magit) (use-package treemacs-projectile) (use-package treemacs-all-the-icons) #+end_src ** LSP *** Configure lsp-mode #+begin_src emacs-lisp (use-package lsp-mode :defer 0 :commands lsp :custom (lsp-rust-analyzer-server-display-inlay-hints t) (lsp-rust-analyzer-display-chaining-hints t) (lsp-rust-analyzer-display-closure-return-type-hints t)) #+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) (use-package lsp-grammarly) #+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)) #+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\\'") (add-to-list 'lsp-language-id-configuration '(nix-mode . "nix")) (lsp-register-client (make-lsp-client :new-connection (lsp-stdio-connection '("rnix-lsp")) :major-modes '(nix-mode) :server-id 'nix)) (use-package hcl-mode :mode "\\.hcl\\'" "\\.nomad\\'") (use-package go-mode) #+end_src ** Magit #+begin_src emacs-lisp (use-package magit) #+end_src * VTerm ** Configure vterm #+begin_src emacs-lisp (use-package vterm :config (evil-define-key 'normal vterm-mode-map (kbd "p") 'vterm-yank) (evil-define-key 'insert vterm-mode-map (kbd "C-y") 'vterm-yank) (setq vterm-timer-delay 0.005)) (use-package vterm-toggle :config (setq vterm-toggle-fullscreen-p nil) (add-to-list 'display-buffer-alist '((lambda (buffer-or-name _) (let ((buffer (get-buffer buffer-or-name))) (with-current-buffer buffer (or (equal major-mode 'vterm-mode) (string-prefix-p vterm-buffer-name (buffer-name buffer)))))) (display-buffer-reuse-window display-buffer-in-side-window) (side . bottom) (reusable-frames . visible) (window-height . 0.4)))) #+end_src ** Centaur Tabs #+begin_src emacs-lisp (use-package centaur-tabs :demand :config (setq centaur-tabs-style "rounded" centaur-tabs-height 18 centaur-tabs-set-modified-marker t centaur-tabs-set-icons t) (centaur-tabs-group-by-projectile-project) (centaur-tabs-headline-match) (centaur-tabs-mode nil) (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 :config (define-key projectile-mode-map (kbd "C-x p") 'projectile-command-map) (projectile-mode +1)) (use-package rainbow-delimiters :hook (prog-mode . rainbow-delimiters-mode)) (use-package flex-autopair) #+end_src * Org ** Add org-mode #+begin_src emacs-lisp (use-package org :after evil :config (setq evil-want-C-i-jump nil org-adapt-indentation t 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) (define-key org-mode-map (kbd "RET") 'org-return-and-maybe-indent) (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) (setq org-confirm-babel-evaluate nil) (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 * Random eye candy stuff #+begin_src emacs-lisp (use-package pretty-mode :config (global-pretty-mode t)) #+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 * Custom Functions #+begin_src emacs-lisp (defun detach-process () "Run processes but detached from the parent" (interactive) (let ((command (read-string "Enter command:"))) (call-process-shell-command (concat command " &") nil 0))) #+end_src * Keybinds ** General *** Colemak translations #+begin_src emacs-lisp (use-package general) (setq evil-states '(visual normal motion)) (with-eval-after-load 'general (general-translate-key evil-states 'global "m" "h" "n" "j" "N" "J" "e" "k" "i" "l" "u" "i" "l" "u" "k" "n" "f" "e" "t" "f" "j" "t" "K" "N" ) #+end_src *** Misc binds #+begin_src emacs-lisp (general-define-key :states evil-states "M-c" 'comment-line "C-c M-c" 'comment-box) (general-define-key :states '(normal insert) "M-C-f" 'lsp-format-buffer "C-S-v" 'yank) (general-define-key :keymaps '(global override vterm-mode-map) :states evil-states "M-o" 'treemacs "M-v" 'split-window-vertically "M-h" 'split-window-horizontally "M-m" 'windmove-left "M-n" 'windmove-down "M-e" 'windmove-up "M-i" 'windmove-right "M-C-m" 'shrink-window-horizontally "M-C-i" 'enlarge-window-horizontally "M-C-e" 'shrink-window "M-C-n" 'enlarge-window "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 :keymaps '(global override vterm-mode-map) :states evil-states "" (lambda () (interactive) (vterm t)) "C-" 'vterm-toggle-cd "" 'vterm-toggle "" (lambda () (interactive) (run-in-vterm (candrun)))) (general-define-key :keymaps 'vterm-mode-map "" 'vterm-toggle-forward "" 'vterm-toggle-backward)) #+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