#+TITLE: DT's GNU Emacs Config #+AUTHOR: Derek Taylor (DT) #+DESCRIPTION: DT's personal Emacs config. #+STARTUP: showeverything #+EXPORT_FILE_NAME: /home/dt/Org/html/config.html #+SETUPFILE: https://fniessen.github.io/org-html-themes/org/theme-readtheorg.setup #+OPTIONS: num:nil ^:{} * TABLE OF CONTENTS :TOC: - [[#about-this-config][ABOUT THIS CONFIG]] - [[#package-management][PACKAGE MANAGEMENT]] - [[#setup-packageel-to-work-with-melpa][Setup package.el to work with MELPA]] - [[#installing-use-package][Installing use-package]] - [[#all-the-icons][ALL THE ICONS]] - [[#general-keybindings][GENERAL KEYBINDINGS]] - [[#dashboard][DASHBOARD]] - [[#configuring-dashboard][Configuring Dashboard]] - [[#dashboard-in-emacsclient][Dashboard in Emacsclient]] - [[#evil-mode][EVIL MODE]] - [[#finding-files][FINDING FILES]] - [[#dired][DIRED]] - [[#keybindings-to-open-dired][Keybindings To Open Dired]] - [[#keybindings-within-dired][Keybindings Within Dired]] - [[#keybindings-for-peep-dired-mode][Keybindings For Peep-Dired-Mode]] - [[#fonts][FONTS]] - [[#setting-the-font-face][Setting The Font Face]] - [[#zooming-in-and-out][Zooming In and Out]] - [[#graphical-user-interface-tweaks][GRAPHICAL USER INTERFACE TWEAKS]] - [[#disable-menu-toolbars-and-scrollbars][Disable Menu, Toolbars and Scrollbars]] - [[#display-line-numbers-and-truncated-lines][Display Line Numbers and Truncated Lines]] - [[#change-modeline-to-dooms-modeline][Change Modeline To Doom's Modeline]] - [[#ivy-counselswiper][IVY (COUNSEL/SWIPER)]] - [[#installing-ivy-and-basic-setup][Installing Ivy And Basic Setup]] - [[#making-m-x-great-again][Making M-x Great Again!]] - [[#ivy-posframe][Ivy-posframe]] - [[#language-support][LANGUAGE SUPPORT]] - [[#magit][MAGIT]] - [[#org-mode][ORG MODE]] - [[#defining-a-few-things][Defining A Few Things]] - [[#enabling-org-bullets][Enabling Org Bullets]] - [[#org-link-abbreviations][Org Link Abbreviations]] - [[#org-todo-keywords][Org Todo Keywords]] - [[#source-code-block-tag-expansion][Source Code Block Tag Expansion]] - [[#source-code-block-syntax-highlighting][Source Code Block Syntax Highlighting]] - [[#automatically-create-table-of-contents][Automatically Create Table of Contents]] - [[#projectile][PROJECTILE]] - [[#scrolling][SCROLLING]] - [[#shells][SHELLS]] - [[#eshell][Eshell]] - [[#vterm][Vterm]] - [[#theme][THEME]] - [[#which-key][WHICH KEY]] * PUT THIS IN YOUR INIT.EL I don't want to use init.el to config Emacs. I want to use an org file to config Emacs because I like literate configs with lots of comments. The following code block should be your init.el. This tells init.el to use the source code blocks from this file (config.org). #+begin_example (org-babel-load-file (expand-file-name "config.org" user-emacs-directory)) #+end_example * ABOUT THIS CONFIG This is my personal Emacs config. I patterned my config to mimic Doom Emacs, which is a distribution of Emacs that uses the "evil" keybindings (Vim keybindings) and includes a number of nice extensions and a bit of configuration out of the box. I am maintaining this config not just for myself, but also for those that want to explore some of what is possible with Emacs. I will add a lot of examples of plugins and settings, some of them I may not even use personally. I do this because many people following me on YouTube and Odysee look at my configs as "documentation". * PACKAGE MANAGEMENT ** Setup package.el to work with MELPA #+begin_src emacs-lisp (require 'package) (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/")) (package-refresh-contents) (package-initialize) #+end_src ** Installing use-package Install use-package and enable ':ensure t' globally. The ':ensure' keyword causes the package(s) within use-package statements to be installed automatically if not already present on your system. To avoid having to add ':ensure t' to every use-package statement in this config, I set 'use-package-always-ensure'. #+begin_src emacs-lisp (unless (package-installed-p 'use-package) (package-install 'use-package)) (setq use-package-always-ensure t) #+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) #+end_src * GENERAL KEYBINDINGS General.el allows us to set keybindings. As a longtime Doom Emacs user, I have grown accustomed to using SPC as the prefix key. It certainly is easier on the hands than constantly using CTRL for a prefix. #+begin_src emacs-lisp (use-package general :config (general-evil-setup t)) (nvmap :prefix "SPC" "SPC" '(counsel-M-x :which-key "M-x") "." '(find-file :which-key "Find file") ;; Buffers "b b" '(ibuffer :which-key "Ibuffer") "b k" '(kill-current-buffer :which-key "Kill current buffer") "b n" '(next-buffer :which-key "Next buffer") "b p" '(previous-buffer :which-key "Previous buffer") "b B" '(ibuffer-list-buffers :which-key "Ibuffer list buffers") "b K" '(kill-buffer :which-key "Kill buffer") ;; Eshell "e h" '(counsel-esh-history :which-key "Eshell history") "e s" '(eshell :which-key "Eshell") "f r" '(counsel-recentf :which-key "Recent files") "h r r" '((lambda () (interactive) (load-file "~/.emacs.d/init.el")) :which-key "Reload emacs config") "t t" '(toggle-truncate-lines :which-key "Toggle truncate lines") ;; Window splits "w c" '(evil-window-delete :which-key "Close window") "w n" '(evil-window-new :which-key "New window") "w s" '(evil-window-split :which-key "Horizontal split window") "w v" '(evil-window-vsplit :which-key "Vertical split window") ;; Window motions "w h" '(evil-window-left :which-key "Window left") "w j" '(evil-window-down :which-key "Window down") "w k" '(evil-window-up :which-key "Window up") "w l" '(evil-window-right :which-key "Window right") "w w" '(evil-window-next :which-key "Goto next window")) #+end_src * DASHBOARD Emacs Dashboard is an extensible startup screen showing you recent files, bookmarks, agenda items and an Emacs banner. ** Configuring Dashboard #+begin_src emacs-lisp (use-package dashboard :init ;; tweak dashboard config before loading it (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/.emacs.d/emacs-dash.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))) :config (dashboard-setup-startup-hook) (dashboard-modify-heading-icons '((recents . "file-text") (bookmarks . "book")))) #+end_src ** Dashboard in Emacsclient This setting ensures that emacsclient always opens on *dashboard* rather than *scratch*. #+begin_src emacs-lisp (setq initial-buffer-choice (lambda () (get-buffer "*dashboard*"))) #+end_src * EVIL MODE Evil is an extensible 'vi' layer for Emacs. It emulates the main features of Vim, and provides facilities for writing custom extensions. Evil Collection is also installed since it adds 'evil' bindings to parts of Emacs that the standard Evil package does not cover, such as: calenda, help-mode adn ibuffer. #+begin_src emacs-lisp (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 (evil-collection-init)) #+end_src * FINDING FILES Though 'recentf' is one way to find recent files although I prefer using 'counsel-recentf'. #+begin_src emacs-lisp (use-package recentf :config (recentf-mode)) #+end_src * DIRED Dired is the file manager within Emacs. Below, I setup keybindings for image previews (peep-dired). I've chosen the format of 'SPC d' plus 'key'. ** Keybindings To Open Dired | COMMAND | DESCRIPTION | KEYBINDING | |------------+------------------------------------+------------| | dired | /Open dired file manager/ | SPC d d | | dired-jump | /Jump to current directory in dired/ | SPC d j | ** Keybindings Within Dired | COMMAND | DESCRIPTION | KEYBINDING | |--------------------+---------------------------------------------+------------| | dired-view-file | /View file in dired/ | SPC d v | | dired-up-directory | /Go up in directory tree/ | h | | dired-find-file | /Go down in directory tree (or open if file)/ | l | ** Keybindings For Peep-Dired-Mode | COMMAND | DESCRIPTION | KEYBINDING | |----------------------+------------------------------------------+------------| | peep-dired | /Toggle image previews within dired/ | SPC d p | | peep-dired-next-file | /Move to next file in peep-dired-mode/ | j | | peep-dired-prev-file | /Move to previous file in peep-dired-mode/ | k | #+begin_src emacs-lisp (use-package all-the-icons-dired) (use-package dired-open) (use-package peep-dired) (nvmap :prefix "SPC" "d d" '(dired :which-key "Open dired") "d j" '(dired-jump :which-key "Dired jump to current")) (with-eval-after-load 'dired (define-key dired-mode-map (kbd "M-p") 'peep-dired) (evil-define-key'(normal visual) dired-mode-map (kbd "h") 'dired-up-directory) (evil-define-key'(normal visual) dired-mode-map (kbd "l") 'dired-open-file)) ; use dired-find-file instead if not using dired-open package (evil-define-key'(normal visual) dired-mode-map (kbd "j") 'peep-dired-next-file) (evil-define-key'(normal visual) dired-mode-map (kbd "k") 'peep-dired-prev-file) ;; Get file icons in dired (add-hook 'dired-mode-hook 'all-the-icons-dired-mode) ;; With dired-open plugin, you can launch external programs for certain extensions ;; For example, I set all .png files to open in 'sxiv' and all .mp4 files to open in 'mpv' (setq dired-open-extensions '(("gif" . "sxiv") ("jpg" . "sxiv") ("png" . "sxiv") ("mkv" . "mpv") ("mp4" . "mpv"))) #+end_src * FONTS Defining our fonts. Right now I'm using Source Code Pro (SauceCodePro) from the nerd-fonts repository. Installed from the AUR, it does =NOT= include all variations of the font (such as italics). You can download the italics Source Code Pro font from the nerd-fonts GitHub though. ** Setting The Font Face #+begin_src emacs-lisp (set-face-attribute 'default nil :font "Source Code Pro" :height 110 :weight 'medium) (set-face-attribute 'variable-pitch nil :font "Ubuntu Nerd Font" :height 120 :weight 'medium) (set-face-attribute 'fixed-pitch nil :font "Source Code Pro" :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) ;; Uncomment the following line if line spacing needs adjusting. (setq-default line-spacing 0.12) ;; Needed if using emacsclient. Otherwise, your fonts will be smaller than expected. (add-to-list 'default-frame-alist '(font . "Source Code Pro-11")) ;; changes certain keywords to symbols, such as lamda! (setq global-prettify-symbols-mode t) #+end_src ** Zooming In and 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 ;; zoom in/out like we do everywhere else. (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 * GRAPHICAL USER INTERFACE TWEAKS Let's make GNU Emacs look a little better. ** Disable Menu, 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 ** Change Modeline To Doom's Modeline #+begin_src emacs-lisp (use-package doom-modeline) (doom-modeline-mode 1) #+end_src * IVY (COUNSEL/SWIPER) Ivy, counsel and swiper are a generic completion mechanism for Emacs. Ivy-rich allows us to add descriptions alongside the commands in M-x. ** Installing Ivy And Basic Setup #+begin_src emacs-lisp (use-package counsel :after ivy :config (counsel-mode)) (use-package ivy :defer 0.1 :diminish :bind (("C-c C-r" . ivy-resume) ("C-x B" . ivy-switch-buffer-other-window)) :custom (setq ivy-count-format "(%d/%d) ") (setq ivy-use-virtual-buffers t) (setq enable-recursive-minibuffers t) :config (ivy-mode)) (use-package ivy-rich :after ivy :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) (ivy-rich-mode 1)) ;; this gets us descriptions in M-x. (use-package swiper :after ivy :bind (("C-s" . swiper) ("C-r" . swiper))) #+end_src ** Making M-x Great Again! The following line removes the annoying '^' in things like counsel-M-x and other ivy/counsel prompts. The default '^' string means that if you type something immediately after this string only completion candidates that begin with what you typed are shown. Most of the time, I'm searching for a command without knowing what it begins with though. #+begin_src emacs-lisp (setq ivy-initial-inputs-alist nil) #+end_src Smex is a package the makes M-x remember our history. Now M-x will show our last used commands first. #+begin_src emacs-lisp (use-package smex) (smex-initialize) #+end_src ** Ivy-posframe Ivy-posframe is an ivy extension, which lets ivy use posframe to show its candidate menu. Some of the settings below involve: + ivy-posframe-display-functions-alist -- sets the display position for specific programs + ivy-posframe-height-alist -- sets the height of the list displayed for specific programs Available functions (positions) for 'ivy-posframe-display-functions-alist' + ivy-posframe-display-at-frame-center + ivy-posframe-display-at-window-center + ivy-posframe-display-at-frame-bottom-left + ivy-posframe-display-at-window-bottom-left + ivy-posframe-display-at-frame-bottom-window-center + ivy-posframe-display-at-point + ivy-posframe-display-at-frame-top-center =NOTE:= If the setting for 'ivy-posframe-display' is set to 'nil' (false), anything that is set to 'ivy-display-function-fallback' will just default to their normal position in Doom Emacs (usually a bottom split). However, if this is set to 't' (true), then the fallback position will be centered in the window. #+begin_src emacs-lisp (use-package ivy-posframe :init (setq ivy-posframe-display-functions-alist '((swiper . ivy-posframe-display-at-point) (complete-symbol . ivy-posframe-display-at-point) (counsel-M-x . ivy-display-function-fallback) (counsel-esh-history . ivy-posframe-display-at-window-center) (counsel-describe-function . ivy-display-function-fallback) (counsel-describe-variable . ivy-display-function-fallback) (counsel-find-file . ivy-display-function-fallback) (counsel-recentf . ivy-display-function-fallback) (counsel-register . ivy-posframe-display-at-frame-bottom-window-center) (dmenu . ivy-posframe-display-at-frame-top-center) (nil . ivy-posframe-display)) ivy-posframe-height-alist '((swiper . 20) (dmenu . 20) (t . 10))) :config (ivy-posframe-mode 1)) ; 1 enables posframe-mode, 0 disables it. #+end_src * LANGUAGE SUPPORT Adding packages for programming langauges, so we can have nice things like syntax highlighting. #+begin_src emacs-lisp (use-package haskell-mode) #+end_src * MAGIT A git client for Emacs. Often cited as a killer feature for Emacs. #+begin_src emacs-lisp (use-package magit) (use-package magit-todos :config (magit-todos-mode)) #+end_src * ORG MODE Org Mode is THE killer feature within Emacs. But it does need some tweaking. ** Defining A Few Things #+begin_src emacs-lisp (add-hook 'org-mode-hook 'org-indent-mode) (setq org-directory "~/Org/" org-agenda-files '("~/Org/agenda.org") org-default-notes-file (expand-file-name "notes.org" org-directory) org-ellipsis " ▼ " org-log-done 'time org-journal-dir "~/Org/journal/" org-journal-date-format "%B %d, %Y (%A) " org-journal-file-format "%Y-%m-%d.org" org-hide-emphasis-markers t) (setq org-src-preserve-indentation nil org-src-tab-acts-natively t org-edit-src-content-indentation 0) #+end_src ** Enabling Org Bullets Org-bullets gives us attractive bullets rather asterisks. #+begin_src emacs-lisp (use-package org-bullets) (add-hook 'org-mode-hook (lambda () (org-bullets-mode 1))) #+end_src ** Org Link Abbreviations This allows for the use of abbreviations that will get expanded out into a lengthy URL. #+begin_src emacs-lisp ;; An example of how this works. ;; [[arch-wiki:Name_of_Page][Description]] (setq org-link-abbrev-alist ; This overwrites the default Doom org-link-abbrev-list '(("google" . "http://www.google.com/search?q=") ("arch-wiki" . "https://wiki.archlinux.org/index.php/") ("ddg" . "https://duckduckgo.com/?q=") ("wiki" . "https://en.wikipedia.org/wiki/"))) #+end_src ** Org Todo Keywords This lets us create the various TODO tags that we can use in Org. #+begin_src emacs-lisp (setq org-todo-keywords ; This overwrites the default Doom org-todo-keywords '((sequence "TODO(t)" ; A task that is ready to be tackled "BLOG(b)" ; Blog writing assignments "GYM(g)" ; Things to accomplish at the gym "PROJ(p)" ; A project that contains other tasks "VIDEO(v)" ; Video assignments "WAIT(w)" ; Something is holding up this task "|" ; The pipe necessary to separate "active" states and "inactive" states "DONE(d)" ; Task has been completed "CANCELLED(c)" ))) ; Task has been cancelled #+end_src ** Source Code Block Tag Expansion Org-tempo is a package that allows for '