#+TITLE:LM's Emacs Config #+Author: Liam Malone (LM) #+DESCRIPTION: LM's personal Emacs config #+STARTUP: showeverything #+OPTIONS: toc:2 * TABLE OF CONTENTS :toc: - [[#important-programs-to-load-first][IMPORTANT PROGRAMS TO LOAD FIRST]] - [[#elpaca-package-manager][Elpaca Package Manager]] - [[#load-evil-mode][Load Evil Mode]] - [[#general-keybindings][General Keybindings]] - [[#all-the-icons][ALL THE ICONS]] - [[#autosave][AUTOSAVE]] - [[#company][COMPANY]] - [[#dashboard][DASHBOARD]] - [[#diminish][DIMINISH]] - [[#drag-stuff][DRAG-STUFF]] - [[#flycheck][FLYCHECK]] - [[#fonts][FONTS]] - [[#setting-the-font-face][Setting The Font Face]] - [[#zoom-inout][Zoom In/Out]] - [[#gnuplot][GNUPLOT]] - [[#image-dir-ed][IMAGE DIR-ED]] - [[#indentingtabs][INDENTING/TABS]] - [[#ligatures][LIGATURES]] - [[#markdown-mode][MARKDOWN MODE]] - [[#org-download][ORG DOWNLOAD]] - [[#pulse][PULSE]] - [[#pdf-tools][PDF TOOLS]] - [[#projectile][PROJECTILE]] - [[#rainbow-mode][RAINBOW MODE]] - [[#reload-emacs][RELOAD EMACS]] - [[#shells-and-terminals][SHELLS AND TERMINALS]] - [[#eshell][Eshell]] - [[#sudo-edit][SUDO EDIT]] - [[#theme][THEME]] - [[#transparency][TRANSPARENCY]] - [[#gui-tweaks][GUI TWEAKS]] - [[#disable-menubar-toolbars-and-scrollbars][Disable Menubar, Toolbars and Scrollbars]] - [[#display-line-numbers-and-truncated-lines][Display Line Numbers and Truncated Lines]] - [[#ivy-counsel][IVY (COUNSEL)]] - [[#language-support][LANGUAGE SUPPORT]] - [[#org-mode][ORG MODE]] - [[#enabling-table-of-contents][Enabling Table of Contents]] - [[#enabling-org-bullets][Enabling Org Bullets]] - [[#source-code-block-tag-expansion][Source Code Block Tag Expansion]] - [[#which-key][WHICH-KEY]] * IMPORTANT PROGRAMS TO LOAD FIRST ** Elpaca Package Manager #+begin_src emacs-lisp (defvar elpaca-installer-version 0.6) (defvar elpaca-directory (expand-file-name "elpaca/" user-emacs-directory)) (defvar elpaca-builds-directory (expand-file-name "builds/" elpaca-directory)) (defvar elpaca-repos-directory (expand-file-name "repos/" elpaca-directory)) (defvar elpaca-order '(elpaca :repo "https://github.com/progfolio/elpaca.git" :ref nil :files (:defaults (:exclude "extensions")) :build (:not elpaca--activate-package))) (let* ((repo (expand-file-name "elpaca/" elpaca-repos-directory)) (build (expand-file-name "elpaca/" elpaca-builds-directory)) (order (cdr elpaca-order)) (default-directory repo)) (add-to-list 'load-path (if (file-exists-p build) build repo)) (unless (file-exists-p repo) (make-directory repo t) (when (< emacs-major-version 28) (require 'subr-x)) (condition-case-unless-debug err (if-let ((buffer (pop-to-buffer-same-window "*elpaca-bootstrap*")) ((zerop (call-process "git" nil buffer t "clone" (plist-get order :repo) repo))) ((zerop (call-process "git" nil buffer t "checkout" (or (plist-get order :ref) "--")))) (emacs (concat invocation-directory invocation-name)) ((zerop (call-process emacs nil buffer nil "-Q" "-L" "." "--batch" "--eval" "(byte-recompile-directory \".\" 0 'force)"))) ((require 'elpaca)) ((elpaca-generate-autoloads "elpaca" repo))) (kill-buffer buffer) (error "%s" (with-current-buffer buffer (buffer-string)))) ((error) (warn "%s" err) (delete-directory repo 'recursive)))) (unless (require 'elpaca-autoloads nil t) (require 'elpaca) (elpaca-generate-autoloads "elpaca" repo) (load "./elpaca-autoloads"))) (add-hook 'after-init-hook #'elpaca-process-queues) (elpaca `(,@elpaca-order)) ;; Install use-package support (elpaca elpaca-use-package ;; Enable :elpaca use-package keyword. (elpaca-use-package-mode) ;; Assume :elpaca t unless otherwise specified. (setq elpaca-use-package-by-default t)) ;; Block until current queue processed. (elpaca-wait) ;;When installing a package which modifies a form used at the top-level ;;(e.g. a package which adds a use-package key word), ;;use `elpaca-wait' to block until that package has been installed/configured. ;;For example: ;;(use-package general :demand t) ;;(elpaca-wait) ;;Turns off elpaca-use-package-mode current declartion ;;Note this will cause the declaration to be interpreted immediately (not deferred). ;;Useful for configuring built-in emacs features. ;;(use-package emacs :elpaca nil :config (setq ring-bell-function #'ignore)) ;; Don't install anything. Defer execution of BODY ;;(elpaca nil (message "deferred")) #+end_src ** Load Evil Mode #+begin_src emacs-lisp ;; Expands to: (elpaca evil (use-package evil :demand t)) (use-package evil :bind (:map evil-normal-state-map ("" . evil-scroll-page-up)) :init ;; tweak evil's configuration before loading it (setq evil-want-integration t) ;; This is optional since it's already set to t by default. (setq evil-respect-visual-line-mode t) (setq evil-want-keybinding nil) (setq evil-vsplit-window-right t) (setq evil-split-window-below t) (evil-mode)) (use-package evil-collection :after evil :config (setq evil-collection-mode-list '(dashboard dired ibuffer)) (evil-collection-init)) #+end_src ** General Keybindings #+begin_src emacs-lisp (use-package general :config (general-evil-setup) ;; set 'SPC' as global leader key (general-create-definer lm/leader-keys :states '(normal insert visual emacs) :keymaps 'override :prefix "SPC" ;; set leader :global-prefix "M-SPC") ;; access leader in insert mode (lm/leader-keys "b" '(:ignore t :wk "buffer") "b b" '(switch-to-buffer :wk "Switch buffer") "b i" '(ibuffer :wk "Ibuffer") "b k" '(kill-this-buffer :wk "Kill this buffer") "b n" '(next-buffer :wk "Next buffer") "b p" '(previous-buffer :wk "Previous buffer") "b r" '(revert-buffer :wk "Reload buffer")) (lm/leader-keys "e" '(:ignore t :wk "Eshell/Evaluate") "e b" '(eval-buffer :wk "Evaluate elisp in buffer") "e d" '(eval-defun :wk "Evaluate defun containing or after point") "e e" '(eval-expression :wk "Evaluate an elisp expression") "e l" '(eval-last-sexp :wk "Evaluate elisp expression before point") "e r" '(eval-region :wk "Evaluate elisp in region") "e h" '(counsel-esh-history :wk "Eshell history") "e s" '(eshell :wk "Eshell")) (lm/leader-keys "SPC" '(counsel-M-x :wk "Counsel M-x") "." '(find-file :wk "Find file") "f c" '((lambda () (interactive) (find-file "~/nixos/modules/old_configs/emacs/config.org")) :wk "Edit emacs config") "f r" '(counsel-recentf :wk "Find recent files") "TAB TAB" '(comment-line :wk "Comment lines")) (lm/leader-keys "h" '(:ignore t :wk "Help") "h f" '(describe-function :wk "Describe function") "h v" '(describe-variable :wk "Describe variable") "h r r" '(reload-init-file :wk "Reload emacs config")) ;; "h r r" '((lambda () (interactive) (load-file user-init-file)) :wk "Reload emacs config")) (lm/leader-keys "i" '(:ignore t :wk "Insert") "i p" '(org-download-screenshot :wk "Insert screenshot (org)")) (lm/leader-keys "t" '(:ignore t :wk "Toggle") "t l" '(display-line-numbers-mode :wk "Toggle line numbers") "t i" '(org-toggle-inline-images :wk "Toggle inline images") "t t" '(visual-line-mode :wk "Toggle truncated lines")) (lm/leader-keys "s" '(:ignore t :wk "Shell") "s c" '(shell-command :wk "Run a shell command") "s d" '(sh-cd-here :wk "Move current shell to current dir") "s m" '(sh-mode :wk "Shell mode")) (lm/leader-keys "c" '(:ignore t :wk "Capitalize") "c w" '(capitalize-word :wk "Capitalize word") "c r" '(capitalize-region :wk "Capitalize region") "c c" '(upcase-char :wk "Upcase char") "c u" '(upcase-region :wk "Upcase region")) (lm/leader-keys "l" '(:ignore t :wk "Downcase") "l w" '(downcase-word :wk "Downcase word") "l u" '(downcase-region :wk "Downcase region")) ;; Evil window bindings (lm/leader-keys "w" '(:ignore t :wk "Window") "w w" '(evil-window-next :wk "Next window") "w h" '(evil-window-left :wk "Move cursor to window left") "w j" '(evil-window-down :wk "Move cursor to window below") "w k" '(evil-window-up :wk "Move cursor to window above") "w l" '(evil-window-right :wk "Move cursor to window right") "w s" '(evil-window-split :wk "Split window horizontally") "w v" '(evil-window-vsplit :wk "Split window vertically") "w H" '(evil-window-move-far-left :wk "Move split to left") "w J" '(evil-window-move-very-bottom :wk "Move split to bottom") "w K" '(evil-window-move-very-top :wk "Move split to top") "w L" '(evil-window-move-far-right :wk "Move split to right") "w >" '(evil-window-increase-width :wk "Increase window width") "w ." '(evil-window-increase-width :wk "Increase window width") "w <" '(evil-window-decrease-width :wk "Increase window width") "w ," '(evil-window-decrease-width :wk "Increase window width") "w c" '(evil-window-delete :wk "Close window") "w o" '(delete-other-windows :wk "Delete other windows") "w =" '(balance-windows :wk "Balance windows") "q k" '(kill-buffer-and-window :wk "Kill buf and window") "q q" '(save-buffers-kill-terminal :wk "Save bufs, kill term")) ;; (evil-global-set-key 'visual "K" (kbd ":m '<-2 RET gv '< gk")) (evil-global-set-key 'visual "K" 'drag-stuff-up) ;; (evil-global-set-key 'visual "J" (kbd ":m '>+1 RET gv '> gj")) (evil-global-set-key 'visual "J" 'drag-stuff-down) (lm/leader-keys "p" '(:ignore t :wk "Project") "p o" '(dashboard-open :wk "Return to dashboard") "p f" '(project-find-file :wk "Find project file")) ) #+end_src * ALL THE ICONS #+begin_src emacs-lisp (use-package all-the-icons :ensure t :diminish :if (display-graphic-p)) (use-package all-the-icons-dired :hook (dired-mode . (lambda () (all-the-icons-dired-mode t)))) #+end_src * AUTOSAVE #+begin_src emacs-lisp (setq backup-directory-alist `((".*" . "~/emacs/auto-saves"))) (setq auto-save-file-name-transforms `((".*" "~/emacs/auto-saves" t))) #+end_src * COMPANY #+begin_src emacs-lisp (use-package company :defer 2 :diminish :custom (company-begin-commands '(self-insert-command)) (company-idle-delay .1) (company-minimum-prefix-length 2) (company-show-numbers t) (company-tooltip-align-annotations 't) (global-company-mode t)) (use-package company-box :after company :diminish :hook (company-mode . company-box-mode)) #+end_src * DASHBOARD #+begin_src emacs-lisp (use-package dashboard :ensure t :diminish :init (setq initial-buffer-choice 'dashboard-open) (setq dashboard-set-heading-icons t) ;; (setq dashboard-set-navigator t) (setq dashboard-set-file-icons t) (setq dashboard-banner-logo-title "Welcome to Emacs!") (setq dashboard-startup-banner 'logo) ;; default logo (setq dashboard-center-content t) (setq dashboard-items '((recents . 5) (agenda . 5) (bookmarks . 3) (projects . 3))) :config (dashboard-setup-startup-hook)) #+end_src * DIMINISH This package implements hiding or abbreviation of the modeline displays (lighters) of minor-modes. With this package installed, you can add ':diminish' to any use-package block to hide that particular mode in the modeline. #+begin_src emacs-lisp (use-package diminish) #+end_src * DRAG-STUFF #+begin_src emacs-lisp (use-package drag-stuff :diminish :config (drag-stuff-global-mode 1)) #+end_src * FLYCHECK Install =luacheck= from your Linux distro's repositories for flycheck to work correctly with lua files. Install =python-pylint= for flycheck to work with python files. Haskell works with flycheck as long as =haskell-ghc= or =haskell-stack-ghc= is installed. For more information on language support for flycheck, [[https://www.flycheck.org/en/latest/languages.html][read this]]. #+begin_src emacs-lisp (use-package flycheck :ensure t :defer t :diminish :init (global-flycheck-mode)) #+end_src * FONTS Defining the various fonts emacs will use ** Setting The Font Face #+begin_src emacs-lisp (set-face-attribute 'default nil ;; try switch to Source Code Pro :font "FiraCodeNerdFontMono" :height 110 :weight 'medium) (set-face-attribute 'variable-pitch nil :font "FiraCodeNerdFontMono" :height 120 :weight 'medium) (set-face-attribute 'fixed-pitch nil :font "FiraCodeNerdFontMono" :height 110 :weight 'medium) ;; Makes commented text and keywords italics. ;; This is working in emacsclient but not emacs. ;; Your font must have an italic face available. (set-face-attribute 'font-lock-comment-face nil :slant 'italic) (set-face-attribute 'font-lock-keyword-face nil :slant 'italic) ;; This sets the default font on all graphical frames created after restarting Emacs. ;; Does the same thing as 'set-face-attribute default' above, but emacsclient fonts ;; are not right unless I also add this method of setting the default font. (add-to-list 'default-frame-alist '(font . "FiraCodeNerdFontMono-14")) ;; Uncomment the following line if line spacing needs adjusting. ;; (setq-default line-spacing 0.12) #+end_src ** Zoom In/Out Enable zoom in/out with C-=/- and also for C-scrl-up/down #+begin_src emacs-lisp (global-set-key (kbd "C-=") 'text-scale-increase) (global-set-key (kbd "C--") 'text-scale-decrease) (global-set-key (kbd "") 'text-scale-increase) (global-set-key (kbd "") 'text-scale-decrease) #+end_src * GNUPLOT #+begin_src emacs-lisp (use-package gnuplot-mode) ;; automatically open files ending with .gp or .gnuplot in gnuplot mode ;; (setq auto-mode-alist ;; (append '(("\\.\\(gp\\|gnuplot\\)$" . gnuplot-mode)) auto-mode-alist))) #+end_src * IMAGE DIR-ED #+begin_src emacs-lisp (use-package image-dired+) #+end_src * INDENTING/TABS #+begin_src emacs-lisp (setq-default indent-tabs-mode nil) (setq-default tab-width 4) (setq-default indent-line-function 'insert-tab) (setq-default c-default-style "linux" c-basic-offset 4) ;; if indent-tabs-mode is off, untabify before saving ;;(add-hook 'write-file-hooks ;; (lambda () (if (not indent-tabs-mode) ;; (untabify (point-min) (point-max))))) #+end_src * LIGATURES #+begin_src emacs-lisp ;; This assumes you've installed the package via MELPA. (use-package ligature :config ;; Enable the "www" ligature in every possible major mode (ligature-set-ligatures 't '("www")) ;; Enable traditional ligature support in eww-mode, if the ;; `variable-pitch' face supports it (ligature-set-ligatures 'eww-mode '("ff" "fi" "ffi")) ;; Enable all FiraMonoNerdFont and Fira Code ligatures in programming modes (ligature-set-ligatures 'prog-mode '(;; == === ==== => =| =>>=>=|=>==>> ==< =/=//=// =~ ;; =:= =!= ("=" (rx (+ (or ">" "<" "|" "/" "~" ":" "!" "=")))) ;; ;; ;;; (";" (rx (+ ";"))) ;; && &&& ("&" (rx (+ "&"))) ;; !! !!! !. !: !!. != !== !~ ("!" (rx (+ (or "=" "!" "\." ":" "~")))) ;; ?? ??? ?: ?= ?. ("?" (rx (or ":" "=" "\." (+ "?")))) ;; %% %%% ("%" (rx (+ "%"))) ;; |> ||> |||> ||||> |] |} || ||| |-> ||-|| ;; |->>-||-<<-| |- |== ||=|| ;; |==>>==<<==<=>==//==/=!==:===> ("|" (rx (+ (or ">" "<" "|" "/" ":" "!" "}" "\]" "-" "=" )))) ;; \\ \\\ \/ ("\\" (rx (or "/" (+ "\\")))) ;; ++ +++ ++++ +> ("+" (rx (or ">" (+ "+")))) ;; :: ::: :::: :> :< := :// ::= (":" (rx (or ">" "<" "=" "//" ":=" (+ ":")))) ;; // /// //// /\ /* /> /===:===!=//===>>==>==/ ("/" (rx (+ (or ">" "<" "|" "/" "\\" "\*" ":" "!" "=")))) ;; .. ... .... .= .- .? ..= ..< ("\." (rx (or "=" "-" "\?" "\.=" "\.<" (+ "\.")))) ;; -- --- ---- -~ -> ->> -| -|->-->>->--<<-| ("-" (rx (+ (or ">" "<" "|" "~" "-")))) ;; *> */ *) ** *** **** ("*" (rx (or ">" "/" ")" (+ "*")))) ;; www wwww ("w" (rx (+ "w"))) ;; <>