#+TITLE: DT's GNU Emacs Config #+AUTHOR: Derek Taylor (DT) #+DESCRIPTION: DT's personal Emacs config. #+STARTUP: showeverything #+OPTIONS: toc:2 * TABLE OF CONTENTS :toc: - [[#important-programs-to-load-first][IMPORTANT PROGRAMS TO LOAD FIRST]] - [[#adding-the-scripts-directory-to-path][Adding the scripts directory to path]] - [[#sourcing-the-scripts][Sourcing the scripts]] - [[#all-the-icons][ALL THE ICONS]] - [[#backup-files][BACKUP FILES]] - [[#company][COMPANY]] - [[#dashboard][DASHBOARD]] - [[#diminish][DIMINISH]] - [[#dired][DIRED]] - [[#evil][EVIL]] - [[#flycheck][FLYCHECK]] - [[#fonts][FONTS]] - [[#setting-the-font-face][Setting the Font Face]] - [[#zooming-inout][Zooming In/Out]] - [[#general-keybindings][GENERAL KEYBINDINGS]] - [[#graphical-user-interface-tweaks][GRAPHICAL USER INTERFACE 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]] - [[#modeline][MODELINE]] - [[#neotree][NEOTREE]] - [[#org-mode][ORG MODE]] - [[#enabling-table-of-contents][Enabling Table of Contents]] - [[#enabling-org-bullets][Enabling Org Bullets]] - [[#disable-electric-indent][Disable Electric Indent]] - [[#diminish-org-indent-mode][Diminish Org Indent Mode]] - [[#org-level-headers][Org Level Headers]] - [[#source-code-block-tag-expansion][Source Code Block Tag Expansion]] - [[#projectile][PROJECTILE]] - [[#rainbow-mode][RAINBOW MODE]] - [[#shells-and-terminals][SHELLS AND TERMINALS]] - [[#eshell][Eshell]] - [[#vterm][Vterm]] - [[#vterm-toggle][Vterm-Toggle]] - [[#sudo-edit][SUDO EDIT]] - [[#theme][THEME]] - [[#transparency][TRANSPARENCY]] - [[#which-key][WHICH-KEY]] * IMPORTANT PROGRAMS TO LOAD FIRST To keep this =config.org= a reasonable length, I have moved a lot of code to individual scripts that will be sourced by this config. These scripts are found in "~/.config/emacs/scripts" and do not contain any code that most people are likely to need to edit. ** Adding the scripts directory to path #+begin_src emacs-lisp (add-to-list 'load-path "~/.config/emacs/scripts/") #+end_src ** Sourcing the scripts #+begin_src emacs-lisp (require 'elpaca-setup) ;; The Elpaca Package Manager (require 'buffer-move) ;; Buffer-move for better window management (require 'app-launchers) ;; Use emacs as a run launcher like dmenu (experimental) #+end_src * ALL THE ICONS This is an icon set that can be used with dashboard, dired, ibuffer and other Emacs programs. #+begin_src emacs-lisp (use-package all-the-icons :ensure t :if (display-graphic-p)) (use-package all-the-icons-dired :hook (dired-mode . (lambda () (all-the-icons-dired-mode t)))) #+end_src * BACKUP FILES By default, Emacs creates automatic backups of files in their original directories, such "file.el" and the backup "file.el~". This leads to a lot of clutter, so let's tell Emacs to put all backups that it creates in the =TRASH= directory. #+begin_src emacs-lisp (setq backup-directory-alist '((".*" . "~/.Trash"))) #+end_src * COMPANY [[https://company-mode.github.io/][Company]] is a text completion framework for Emacs. The name stands for "complete anything". Completion will start automatically after you type a few letters. Use M-n and M-p to select, to complete or to complete the common part. #+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 Emacs Dashboard is an extensible startup screen showing you recent files, bookmarks, agenda items and an Emacs banner. #+begin_src emacs-lisp (use-package dashboard :ensure t :init (setq initial-buffer-choice 'dashboard-open) (setq dashboard-set-heading-icons t) (setq dashboard-set-file-icons t) (setq dashboard-banner-logo-title "Emacs Is More Than A Text Editor!") ;;(setq dashboard-startup-banner 'logo) ;; use standard emacs logo as banner (setq dashboard-startup-banner "/home/dt/.config/emacs/images/dtmacs-logo.png") ;; use custom image as banner (setq dashboard-center-content nil) ;; set to 't' for centered content (setq dashboard-items '((recents . 5) (agenda . 5 ) (bookmarks . 3) (projects . 3) (registers . 3))) :custom (dashboard-modify-heading-icons '((recents . "file-text") (bookmarks . "book"))) :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 * DIRED #+begin_src emacs-lisp (use-package dired-open :config (setq dired-open-extensions '(("gif" . "sxiv") ("jpg" . "sxiv") ("png" . "sxiv") ("mkv" . "mpv") ("mp4" . "mpv")))) (use-package peep-dired :after dired :hook (evil-normalize-keymaps . peep-dired-hook) :config (evil-define-key 'normal dired-mode-map (kbd "h") 'dired-up-directory) (evil-define-key 'normal dired-mode-map (kbd "l") 'dired-open-file) ; use dired-find-file instead if not using dired-open package (evil-define-key 'normal peep-dired-mode-map (kbd "j") 'peep-dired-next-file) (evil-define-key 'normal peep-dired-mode-map (kbd "k") 'peep-dired-prev-file) ) #+end_src * EVIL [[https://github.com/emacs-evil/evil][Evil]] is an extensible vi/vim layer for Emacs. Because...let's face it. The Vim keybindings are just plain better. #+begin_src emacs-lisp ;; Expands to: (elpaca evil (use-package evil :demand t)) (use-package evil :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-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)) (use-package evil-tutor) #+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 that Emacs will use. ** Setting the Font Face #+begin_src emacs-lisp (set-face-attribute 'default nil :font "JetBrains Mono" :height 110 :weight 'medium) (set-face-attribute 'variable-pitch nil :font "Ubuntu" :height 120 :weight 'medium) (set-face-attribute 'fixed-pitch nil :font "JetBrains Mono" :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 . "JetBrains Mono-11")) ;; Uncomment the following line if line spacing needs adjusting. (setq-default line-spacing 0.12) #+end_src ** Zooming In/Out You can use the bindings CTRL plus =/- for zooming in/out. You can also use CTRL plus the mouse wheel for zooming in/out. #+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 * GENERAL KEYBINDINGS #+begin_src emacs-lisp (use-package general :config (general-evil-setup) ;; set up 'SPC' as the global leader key (general-create-definer dt/leader-keys :states '(normal insert visual emacs) :keymaps 'override :prefix "SPC" ;; set leader :global-prefix "M-SPC") ;; access leader in insert mode (dt/leader-keys "SPC" '(counsel-M-x :wk "Counsel M-x") "." '(find-file :wk "Find file") "f c" '((lambda () (interactive) (find-file "~/.config/emacs/config.org")) :wk "Edit emacs config") "f r" '(counsel-recentf :wk "Find recent files") "TAB TAB" '(comment-line :wk "Comment lines")) (dt/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")) (dt/leader-keys "d" '(:ignore t :wk "Dired") "d d" '(dired :wk "Open dired") "d j" '(dired-jump :wk "Dired jump to current") "d n" '(neotree-dir :wk "Open directory in neotree") "d p" '(peep-dired :wk "Peep-dired")) (dt/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 and elisp expression") "e h" '(counsel-esh-history :which-key "Eshell history") "e l" '(eval-last-sexp :wk "Evaluate elisp expression before point") "e r" '(eval-region :wk "Evaluate elisp in region") "e s" '(eshell :which-key "Eshell")) (dt/leader-keys "h" '(:ignore t :wk "Help") "h b" '(describe-bindings :wk "Describe bindings") "h f" '(describe-function :wk "Describe function") "h t" '(load-theme :wk "Load theme") "h v" '(describe-variable :wk "Describe variable") "h r r" '((lambda () (interactive) (load-file "~/.config/emacs/init.el") (ignore (elpaca-process-queues))) :wk "Reload emacs config")) (dt/leader-keys "m" '(:ignore t :wk "Org") "m a" '(org-agenda :wk "Org agenda") "m e" '(org-export-dispatch :wk "Org export dispatch") "m i" '(org-toggle-item :wk "Org toggle item") "m t" '(org-todo :wk "Org todo") "m B" '(org-babel-tangle :wk "Org babel tangle") "m T" '(org-todo-list :wk "Org todo list")) (dt/leader-keys "m b" '(:ignore t :wk "Tables") "m b -" '(org-table-insert-hline :wk "Insert hline in table")) (dt/leader-keys "m d" '(:ignore t :wk "Date/deadline") "m d t" '(org-time-stamp :wk "Org time stamp")) (dt/leader-keys "p" '(projectile-command-map :wk "Projectile")) (dt/leader-keys "t" '(:ignore t :wk "Toggle") "t e" '(eshell-toggle :wk "Toggle eshell") "t l" '(display-line-numbers-mode :wk "Toggle line numbers") "t n" '(neotree-toggle :wk "Toggle neotree file viewer") "t t" '(visual-line-mode :wk "Toggle truncated lines") "t v" '(vterm-toggle :wk "Toggle vterm")) (dt/leader-keys "w" '(:ignore t :wk "Windows") ;; Window splits "w c" '(evil-window-delete :wk "Close window") "w n" '(evil-window-new :wk "New window") "w s" '(evil-window-split :wk "Horizontal split window") "w v" '(evil-window-vsplit :wk "Vertical split window") ;; Window motions "w h" '(evil-window-left :wk "Window left") "w j" '(evil-window-down :wk "Window down") "w k" '(evil-window-up :wk "Window up") "w l" '(evil-window-right :wk "Window right") "w w" '(evil-window-next :wk "Goto next window") ;; Move Windows "w H" '(buf-move-left :wk "Buffer move left") "w J" '(buf-move-down :wk "Buffer move down") "w K" '(buf-move-up :wk "Buffer move up") "w L" '(buf-move-right :wk "Buffer move right")) ) #+end_src * GRAPHICAL USER INTERFACE TWEAKS Let's make GNU Emacs look a little better. ** Disable Menubar, Toolbars and Scrollbars #+begin_src emacs-lisp (menu-bar-mode -1) (tool-bar-mode -1) (scroll-bar-mode -1) #+end_src ** Display Line Numbers and Truncated Lines #+begin_src emacs-lisp (global-display-line-numbers-mode 1) (global-visual-line-mode t) #+end_src * IVY (COUNSEL) + Ivy, a generic completion mechanism for Emacs. + Counsel, a collection of Ivy-enhanced versions of common Emacs commands. + Ivy-rich allows us to add descriptions alongside the commands in M-x. #+begin_src emacs-lisp (use-package counsel :after ivy :diminish :config (counsel-mode)) (use-package ivy :bind ;; ivy-resume resumes the last Ivy-based completion. (("C-c C-r" . ivy-resume) ("C-x B" . ivy-switch-buffer-other-window)) :diminish :custom (setq ivy-use-virtual-buffers t) (setq ivy-count-format "(%d/%d) ") (setq enable-recursive-minibuffers t) :config (ivy-mode)) (use-package all-the-icons-ivy-rich :ensure t :init (all-the-icons-ivy-rich-mode 1)) (use-package ivy-rich :after ivy :ensure t :init (ivy-rich-mode 1) ;; this gets us descriptions in M-x. :custom (ivy-virtual-abbreviate 'full ivy-rich-switch-buffer-align-virtual-buffer t ivy-rich-path-style 'abbrev) :config (ivy-set-display-transformer 'ivy-switch-buffer 'ivy-rich-switch-buffer-transformer)) #+end_src * LANGUAGE SUPPORT Emacs has built-in programming language modes for Lisp, Scheme, DSSSL, Ada, ASM, AWK, C, C++, Fortran, Icon, IDL (CORBA), IDLWAVE, Java, Javascript, M4, Makefiles, Metafont, Modula2, Object Pascal, Objective-C, Octave, Pascal, Perl, Pike, PostScript, Prolog, Python, Ruby, Simula, SQL, Tcl, Verilog, and VHDL. Other languages will require you to install additional modes. #+begin_src emacs-lisp (use-package haskell-mode) (use-package lua-mode) #+end_src * MODELINE The modeline is the bottom status bar that appears in Emacs windows. For more information on what is available to configure in the Doom modeline, check out: https://github.com/seagle0128/doom-modeline #+begin_src emacs-lisp (use-package doom-modeline :ensure t :init (doom-modeline-mode 1) :config (setq doom-modeline-height 30 ;; sets modeline height doom-modeline-bar-width 5 ;; sets right bar width doom-modeline-persp-name t ;; adds perspective name to modeline doom-modeline-persp-icon t)) ;; adds folder icon next to persp name #+end_src * NEOTREE Neotree is a file tree viewer. When you open neotree, it jumps to the current file thanks to neo-smart-open. The neo-window-fixed-size setting makes the neotree width be adjustable. NeoTree provides following themes: classic, ascii, arrow, icons, and nerd. Theme can be configed by setting "two" themes for neo-theme: one for the GUI and one for the terminal. I like to use 'SPC t' for 'toggle' keybindings, so I have used 'SPC t n' for toggle-neotree. | COMMAND | DESCRIPTION | KEYBINDING | |----------------+---------------------------+------------| | neotree-toggle | /Toggle neotree/ | SPC t n | | neotree- dir | /Open directory in neotree/ | SPC d n | #+BEGIN_SRC emacs-lisp (use-package neotree :config (setq neo-smart-open t neo-show-hidden-files t neo-window-width 55 neo-window-fixed-size nil inhibit-compacting-font-caches t projectile-switch-project-action 'neotree-projectile-action) ;; truncate long file names in neotree (add-hook 'neo-after-create-hook #'(lambda (_) (with-current-buffer (get-buffer neo-buffer-name) (setq truncate-lines t) (setq word-wrap nil) (make-local-variable 'auto-hscroll-mode) (setq auto-hscroll-mode nil))))) #+end_src * ORG MODE ** Enabling Table of Contents #+begin_src emacs-lisp (use-package toc-org :commands toc-org-enable :init (add-hook 'org-mode-hook 'toc-org-enable)) #+end_src ** Enabling Org Bullets Org-bullets gives us attractive bullets rather than asterisks. #+begin_src emacs-lisp (add-hook 'org-mode-hook 'org-indent-mode) (use-package org-bullets) (add-hook 'org-mode-hook (lambda () (org-bullets-mode 1))) #+end_src ** Disable Electric Indent Org mode source blocks have some really weird and annoying default indentation behavior. I think this has to do with electric-indent-mode, which is turned on by default in Emacs, and the fact that Org defaults to indenting 2 spaces in source blocks. So let's turn it all of that OFF! #+begin_src emacs-lisp (electric-indent-mode -1) (setq org-edit-src-content-indentation 0) #+end_src ** Diminish Org Indent Mode Removes "Ind" from showing in the modeline. #+begin_src emacs-lisp (eval-after-load 'org-indent '(diminish 'org-indent-mode)) #+end_src ** Org Level Headers #+begin_src emacs-lisp (custom-set-faces '(org-level-1 ((t (:inherit outline-1 :height 1.7)))) '(org-level-2 ((t (:inherit outline-2 :height 1.6)))) '(org-level-3 ((t (:inherit outline-3 :height 1.5)))) '(org-level-4 ((t (:inherit outline-4 :height 1.4)))) '(org-level-5 ((t (:inherit outline-5 :height 1.3)))) '(org-level-6 ((t (:inherit outline-5 :height 1.2)))) '(org-level-7 ((t (:inherit outline-5 :height 1.1))))) #+end_src ** Source Code Block Tag Expansion Org-tempo is not a separate package but a module within org that can be enabled. Org-tempo allows for '