# #+TITLE: My Emacs Configuration # #+AUTHOR: Amneesh Singh #+PROPERTY: header-args:emacs-lisp :tangle yes * Settings ** Setting the default face #+begin_src emacs-lisp ; -*- lexical-binding: t; -*- (set-frame-font "Fira Code 13" nil t) (add-to-list 'default-frame-alist '(font . "Fira Code-13")) #+end_src ** Some mode settings based on personal preferences #+begin_src emacs-lisp (add-hook 'prog-mode-hook #'hl-line-mode) (add-hook 'text-mode-hook #'hl-line-mode) (scroll-bar-mode 0) (tool-bar-mode 0) (menu-bar-mode 0) (fringe-mode 0) (global-display-line-numbers-mode 1) (xterm-mouse-mode 1) (setq ring-bell-function 'ignore gc-cons-threshold most-positive-fixnum initial-major-mode 'fundamental-mode) #+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 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) (use-package benchmark-init :ensure t :config ;; To disable collection of benchmark data after init is done. (add-hook 'after-init-hook 'benchmark-init/deactivate)) #+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 catppuccin-theme :config (load-theme 'catppuccin t) (setq dark-theme t)) #+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) (use-package evil-anzu :after evil) #+end_src ** Treemacs *** Configure treemacs #+begin_src emacs-lisp (use-package treemacs) #+end_src #+begin_src emacs-lisp (use-package treemacs-evil :defer t) (use-package treemacs-magit :defer t) (use-package treemacs-projectile :defer t) (use-package treemacs-all-the-icons :defer t) #+end_src ** LSP *** Configure lsp-mode #+begin_src emacs-lisp (use-package lsp-mode :commands lsp) #+end_src *** Configure lsp-ui #+begin_src emacs-lisp (use-package lsp-ui :init (setq lsp-ui-doc-delay 1.0 lsp-ui-doc-show-with-mouse t pgtk-wait-for-event-timeout nil 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 :after lsp-mode :config (add-to-list 'company-backends 'company-dabbrev) (setq company-backends (cons 'company-files (remove 'company-files company-backends))) (add-to-list 'company-backends 'company-emoji) (company-mode 1)) #+end_src *** Configure company-quickhelp #+begin_src emacs-lisp (use-package company-quickhelp :hook (company-mode . company-quickhelp-mode)) #+end_src *** Extra company packages #+begin_src emacs-lisp (use-package company-emoji) #+end_src ** Treesitter #+begin_src emacs-lisp (use-package tree-sitter-langs :defer t) (use-package tree-sitter :after tree-sitter-langs :defer t :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 ** Direnv #+begin_src emacs-lisp (use-package direnv :defer t :config (direnv-mode)) #+end_src ** STM32 #+begin_src emacs-lisp (use-package stm32-emacs) #+end_src ** Lang support #+begin_src emacs-lisp (use-package haskell-mode) (use-package lsp-latex) (use-package rustic) (use-package typescript-mode) (use-package yuck-mode) (use-package wgsl-mode) (use-package nix-mode :mode "\\.nix\\'") (use-package hcl-mode :mode "\\.hcl\\'" "\\.nomad\\'") (use-package go-mode) #+end_src ** Magit #+begin_src emacs-lisp (use-package magit :defer t) #+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 :after vterm :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 :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-mode nil) (set-face-attribute 'tab-line nil :inherit 'centaur-tabs-unselected) (centaur-tabs-headline-match)) #+end_src ** Misc packages #+begin_src emacs-lisp (use-package all-the-icons :if (display-graphic-p)) (use-package elcord :defer t) (use-package projectile :defer t :config (define-key projectile-mode-map (kbd "C-x p") 'projectile-command-map) (projectile-mode +1)) (use-package rainbow-mode :defer t) (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 :defer t :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 :defer t :config (add-hook 'org-mode-hook (lambda () (org-bullets-mode 1)))) #+end_src ** Babel and exports #+begin_src emacs-lisp (use-package htmlize :defer t) (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 * Custom mode line switched to doom modeline after using my own modeline for a while #+begin_src emacs-lisp (use-package doom-modeline :ensure t :hook (after-init . doom-modeline-mode)) #+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 Compilation shortcuts for standalone files #+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 "runhaskell " full)) ("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 not using this anymore #+begin_src emacs-lisp :tangle no (use-package evil-colemak-basics :init (setq evil-colemak-basics-layout-mod 'mod-dh) :config (global-evil-colemak-basics-mode)) #+end_src *** Misc binds #+begin_src emacs-lisp (use-package general) (setq evil-states '(visual normal motion)) (with-eval-after-load 'general (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-S-v" 'split-window-vertically "M-S-h" 'split-window-horizontally "M-h" 'windmove-left "M-j" 'windmove-down "M-k" 'windmove-up "M-l" 'windmove-right "M-C-h" 'shrink-window-horizontally "M-C-j" 'enlarge-window-horizontally "M-C-k" 'shrink-window "M-C-l" '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