HD's GNU Emacs Config

Table of Contents

emacs-org.png

ABOUT THIS CONFIG

This is my personal GNU Emacs literate configuration. I will do my best to clarify what external dependencies are required for this emacs config. However, the external dependency list may not be complete, and I may have made other undocumented changes to my system. Therefor I would NOT recommend blindly copying this config. Instead, i would suggest reading though this config, and copying/reimplimenting only those sections which are reivant to your own personal emacs config.

External Dependencies

  • CMake: Needed for compiling some things
  • JetBrains Mono
  • Org-roam dependencies (if not already installed):
    1. dash
    2. f
    3. s
    4. org
    5. emacsql
    6. magit-selection

Inspiration

My personal emacs config has been inspired by many factors, and it would be to difficult to enumerate all such factors. Therefor, I will Instead list bellow what i have deemed to be the foundational influences to my personal emacs config.

IMPORTANT PROGRAMS TO LOAD FIRST

Elpacs Package Manager

SETUP Elpaca

  (defvar elpaca-installer-version 0.7)
  (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 :depth 1
                                :files (:defaults "elpaca-test.el" (: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 (apply #'call-process `("git" nil ,buffer t "clone"
                                                   ,@(when-let ((depth (plist-get order :depth)))
                                                       (list (format "--depth=%d" depth) "--no-single-branch"))
                                                   ,(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)))
              (progn (message "%s" (buffer-string)) (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 a package via the elpaca macro
;; See the "recipes" section of the manual for more details.

;; (elpaca example-package)

Use-package Support

Install use-package support

(elpaca elpaca-use-package

Enable use-package :ensure support for Elpaca.

(elpaca-use-package-mode)
(setq elpaca-use-package-by-default t))

Add More Repos

Adding extra repositories to emacs

(require 'package)
(setq package-archives '(("melpa" . "https://melpa.org/packages/") 
                         ("org" . "https://orgmode.org/elpa/") 
                         ("elpa" . "https://elpa.gnu.org/packages/")))
(package-initialize) 
(unless package-archive-contents 
  (package-refresh-contents))

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 the :wait recipe keyword to block until that package has been installed/configured For example: (use-package general :ensure (:wait t) :demand t)

(elpaca-wait)

Expands to: (elpaca evil (use-package evil :demand t))

Evil Mode

(use-package evil
  :init
  (setq evil-want-keybinding nil)
  (setq evil-want-integration t)
  (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)

        ;;Turns off elpaca-use-package-mode current declaration
        ;;Note this will cause the declaration to be interpreted immediately (not deferred).
        ;;Useful for configuring built-in emacs features.
        (use-package emacs :ensure nil :config (setq ring-bell-function #'ignore))

General Keybindings

SETUP

Enable the general package; required for "General Keybindings"

(use-package general
  :config
  (general-evil-setup)

GLOBAL LEADER KEY

Set SPC as the global leader key, and make the global leader key available in insert mode

;; setup 'SPC' as the global leader key
(general-create-definer hd/leader-keys
  :states '(normal visual emacs)
  :keymaps 'override
  :prefix "SPC" ;; set leader
  :gloabal-prefix "C-SPC") ;; access leader in insert mode

Buffers

(hd/leader-keys
  "b" '(:ignore t :wk "buffer")
  "b b" '(switch-to-buffer :wk "Switch buffer")
  "b k" '(kill-current-buffer :wk "Kill this buffer")
  "b i" '(ibuffer :wk "Ibuffer")
  "b n" '(next-buffer :wk "Next buffer")
  "b p" '(previous-buffer :wk "Previous buffer")
  "b r" '(revert-buffer :wk "Reload buffer")
  "b R" '(revert-buffer-quick :wk "Reload buffer WITHOUT conformation"))

Dired

(hd/leader-keys
  "d" '(:ignore t :wk "Dired")
  "d d" '(dired :wk "dired"))

Elfeed

(hd/leader-keys
  "r" '(:ignore t :wk "Elfeed")
  "r o" '(elfeed :wk "Elfeed")
  "r u" '(elfeed-update :wk "Elfeed Update")
  "r U" '(elfeed-update-feed :wk "Elfeed Update Feed")

Elfeed-tube commands

"r p" '(elfeed-tube-mpv :wk "Open feed in MPV"))

Eshell

(hd/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 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"))

Files

(hd/leader-keys
  "." '(find-file :wk "Find file")
  "f c" '((lambda () (interactive) (find-file "~/dotfiles/emacs/README.org")) :wk "Edit Emacs config")
  "f h" '((lambda () (interactive) (find-file "~/dotfiles/hypr/hyprland.org")) :wk "Edit Hyprland config")
  "f q" '(qrencode-export-buffer-to-file :wk "Export qrcode buffers to a file")
  "f r" '(counsel-recentf :wk "Find recent files")
  "f w" '((lambda () (interactive) (find-file "~/dotfiles/waybar/waybar.org")) :wk "Edit Waybar config")
"TAB TAB" '(comment-line :wk "Comment lines"))

Help

(hd/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 "~/.config/emacs/init.el")) :wk "Reload emacs config"))

Menus

  • Org Export Dispatch

    Create a key binding for a simple orgmode export menu, like what is used in DOOM Emacs.

    (hd/leader-keys
      "m e" '(org-export-dispatch :wk "Export dispatcher for orgmode."))
    

Open

(hd/leader-keys
  "o" '(:ignore t :wk "Open")
  "o s" '(org-side-tree :wk "Org Side-Tree")
  "o l" '(browse-url-xdg-open :wk "open a URL in the XDG default browser")
  "o b" '(browse-url-of-buffer :wk "open the current buffer in the XDG default browser")
  "o q" '(qrencode-url-at-point :wk "Generate a qrcode from UR under cursor"))

Toggles

(hd/leader-keys
  "t" '(:ignore t :wk "Toggle")
  "t i" '(org-toggle-inline-images :wk "Toggle Orgmode inline images")
  "t l" '(org-toggle-link-display :wk "Toggle Orgmode link display")
  "t L" '(display-line-numbers-mode :wk "Toggle line numbers")
  "t r" '(read-only-mode :wk "Toggle Read Only mode")
  "t t" '(visual-line-mode :wk "Toggle visual line mode")
  "t v" '(vterm-toggle :wk "Toggle vterm")
  "t m" '(treemacs :wk "Toggle treemacs")
  "t s" '(org-side-tree-toggle :wk "Toggle Org Side tree"))

Windows

(hd/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")
  ;; Window motions
  "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-up :wk "Buffer move right"))
)

ALL THE ICONS

This is an icon set that can be used with dashoard, dired, ibuffer and other Emacs programs.

(use-package all-the-icons
  :ensure t
  :if (display-graphic-p))

Dired support

(use-package all-the-icons-dired
  :hook (dired-mode . (lambda () (all-the-icons-dired-mode t))))

AUTO-COMPETE

Auto-Complete (a.k.a auto-complete.el, auto-complete-mode) is an extension that automates and advances the completion-system of GNU Emacs. It is superior to the old system. Features include:

  • Visual interface
  • Reduce overhead of completion by using a statistical method
  • Extensibility
(ac-config-default)

Compnay

use company for code competion

(use-package company
  :config
(global-company-mode 1))

BUFFER MOVE

Creating some functions to allow us to easily move windows (splits) around. The following block of code was taken from buffer-move.el found on EmacsWiki: https://www.emacswiki.org/emacs/buffer-move.el

(require 'windmove)

buf-move-up

Swap the current buffer and the buffer above the split. If there is no split, ie now window above the current one, an error is signaled.

;;;###autoload
(defun buf-move-up ()

Switches between the current buffer, and the buffer above the split, if possible.

(interactive)
(let* ((other-win (windmove-find-other-window 'up))
         (buf-this-buf (window-buffer (selected-window))))
  (if (null other-win)
      (error "No window above this one")

swap top with this one

(set-window-buffer (selected-window) (window-buffer other-win))

move this one to top

(set-window-buffer other-win buf-this-buf)
(select-window other-win))))

buf-move-down

Swap the current buffer and the buffer under the split. If there is no split, ie no window under the current one, an error is signaled.

;;;###autoload
(defun buf-move-down ()

Switches between the current buffer, and the buffer below the split, if possible.

(interactive)
(let* ((other-win (windmove-find-other-window 'down))
         (buf-this-buf (window-buffer (selected-window))))
  (if (or (null other-win) 
          (string-match "^ \\*Minibuf" (buffer-name (window-buffer other-win))))
      (error "No window under this one")

swap top with this one

(set-window-buffer (selected-window) (window-buffer other-win))

move this one to top

(set-window-buffer other-win buf-this-buf)
(select-window other-win))))

buf-move-left

Swap the current buffer and the buffer on the left of the split. If there is no split, ie no window on the left of the current one, an error is signaled.

;;;###autoload
(defun buf-move-left ()

Switches between the current buffer, and the buffer left of the split, if possible.

(interactive)
(let* ((other-win (windmove-find-other-window 'left))
         (buf-this-buf (window-buffer (selected-window))))
  (if (null other-win)
      (error "No left split")

swap top with this one

(set-window-buffer (selected-window) (window-buffer other-win))

move this one to top

(set-window-buffer other-win buf-this-buf)
(select-window other-win))))

buf-move-right

Swap the current buffer and the buffer on the right of the split. If there is no split, ie no window on the right of the current one, an error is signaled.

;;;###autoload
(defun buf-move-right ()

Switches between the current buffer, and the buffer right of the split, if possible.

(interactive)
(let* ((other-win (windmove-find-other-window 'right))
         (buf-this-buf (window-buffer (selected-window))))
  (if (null other-win)
      (error "No right split")

swap top with this one

(set-window-buffer (selected-window) (window-buffer other-win))

move this one to top

(set-window-buffer other-win buf-this-buf)
(select-window other-win))))

DOOM MODELINE

Enable Doom Modeline

(use-package doom-modeline
:ensure t
:init (doom-modeline-mode 1))

Emms

(use-package emms
  :config 
  (require 'emms-setup)
  (require 'emms-mpris)
  (emms-all)
  (emms-mpris-enable)
  :custom
  (emms-browser-covers #'emms-browser-cache-thumbnail-async)
  :bind
  (("C-c w m b" . emms-browser)
   ("C-c w m e" . emms)
   ("C-c w m p" . emms-play-playlist)
   ("<XF86AudioPrev>" . emms-previous)
   ("<XF86AudioNext>" . emms-next)
   ("<XF86AudioPlay>" . emms-pause)))

ELFEED

Elfeed

(use-package elfeed
  :defer t
  :ensure (:wait t)
  :commands (elfeed))

Elfeed-goodies

(package-install 'elfeed-goodies)
(require 'elfeed)
(require 'elfeed-goodies)

(elfeed-goodies/setup)

Elfeed-org

Load elfeed-org

(package-install 'elfeed-org)
(require 'elfeed-org)

Initialize elfeed-org This hooks up elfeed-org to read the configuration when elfeed is started with M-x elfeed

(elfeed-org)

Optionally specify a number of files containing elfeed configuration. If not set then the location below is used. Note: The customize interface is also supported.

(setq rmh-elfeed-org-files (list "~/.config/emacs/elfeed.org"))

Elfeed-tube

(use-package elfeed-tube
  :ensure t ;; or :straight t
  :after elfeed
  :demand t
  :config
  ;; (setq elfeed-tube-auto-save-p nil) ; default value
  ;; (setq elfeed-tube-auto-fetch-p t) ; default value
  (elfeed-tube-setup)

  :bind (:map elfeed-show-mode-map
              ("F" . elfeed-tube-fetch)
              ([remap save-buffer] . elfeed-tube-save)
              :map elfeed-search-mode-map
              ("F" . elfeed-tube-fetch)
              ([remap save-buffer] . elfeed-tube-save)))

Elfeed-tube-MPV

(use-package elfeed-tube-mpv
  :ensure t ;; or :straight t
  :bind (:map elfeed-show-mode-map
              ("C-c C-f" . elfeed-tube-mpv-follow-mode)
              ("C-c C-w" . elfeed-tube-mpv-where)))

FONTS

Defining the various fonts that emacs will use

Setting the font face

(set-face-attribute 'default nil
                    :font "JetBrains Mono"
                    :height 110
                    :weight 'medium)
(set-face-attribute 'variable-pitch nil
                    :font "DejaVu Sans"
                    :height 120
                    :weight 'medium)
(set-face-attribute 'fixed-pitch nil
                    :font "JetBrains Mono"
                    :height 110
                    :weight 'medium)
(set-face-attribute 'font-lock-comment-face nil
                    :slant 'italic)
(set-face-attribute 'font-lock-keyword-face nil
                    :slant 'italic)
(add-to-list 'default-frame-alist 
             '(font . "JetBrains Mono-11"))
(setq-default line-spacing 0.12)
(setq org-src-fontify-natively t)

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.

(global-set-key (kbd "C-=") 'text-scale-increase)
(global-set-key (kbd "C--") 'text-scale-decrease)
(global-set-key (kbd "C-<wheel-up>") 'text-scale-increase)
(global-set-key (kbd "C-<wheel-down>") 'text-scale-decrease)

GRAPHICAL USER INTERFACE TWEAKS

Let's make GNU Emacs look a little better.

Better List Bullets

credit: https://zzamboni.org/post/beautifying-org-mode-in-emacs/

(font-lock-add-keywords 'org-mode
                        '(("^ *\\([-]\\) "
                           (0 (prog1 () (compose-region (match-beginning 1) (match-end 1) "•"))))))

Disable Menubar, Toolbars and Scrollbars

(menu-bar-mode -1)
(tool-bar-mode -1)
(scroll-bar-mode -1)

Display Line Numbers and Truncated Lines

(global-display-line-numbers-mode 1)
(global-visual-line-mode 1)

(setq display-line-numbers-type 'relative)

Disable Line Numbers for Selected Modes

(dolist (mode '(term-mode-hook
                 vterm-mode-hook
                 shell-mode-hook
                treemacs-mode-hook
                 eshell-mode-hook
                 org-side-tree-mode-hook))
   (add-hook mode (lambda() (display-line-numbers-mode 0))))

Disable Symlink to Git directory popup dialog

(setq vc-follow-symlinks t)

IVY (COUNSEL)

  • Counsel, a collection of Ivy-enhanced versions of common Emacs commands.
(use-package counsel 
  :after ivy
  :config (counsel-mode))
  • Ivy, a generic completion framework for Emacs.
(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))
  :custom
  (setq ivy-use-virtual-buffers t)
  (setq ivy-count-format "(%d/%d) ")
  (setq enable-recursove-minibuffers t)
  :config
  (ivy-mode))
  • all-the-icons support for ivy-rich
(use-package all-the-icons-ivy-rich
  :ensure t
  :init (all-the-icons-ivy-rich-mode 1))
  • Ivy-rich allows us to add descriptions alongside the commands in M-x.
(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-ritch-switch-buffer-align-virtual-buffer t
   ivy-rich-path-style 'abbrev)
  :config
  (ivy-set-display-transformer 'ivy-switch-buffer
   'ivy-rich-switch-buffer-transformer)) 

Multiple Cursors

Initialize the multiple-cursors package, and define keybindings

(use-package multiple-cursors
  :bind (("C->"   . mc/mark-next-like-this)
         ("C-M->" . mc/mark-all-like-this-dwim)))

ORG MODE

Auto Tangle

A simple package to automate the process of tangling orgmode source code blocks to thier respective output files.

Install org-auto-tangle

(use-package org-auto-tangle
  ;;:load-path "site-lisp/org-auto-tangle/"    ;; this line is necessary only if you cloned the repo in your site-lisp directory 
  :defer t
  :hook (org-mode . org-auto-tangle-mode))

to enable org-auto-tangle in a buffer use the #+auto_tangle: t option flag.

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. So let's turn it OFF!

(electric-indent-mode -1)

Enable image scaling in orgmode

Enable modifying the scale of a linked image in an Orgmode document using #+ATTR_ORG:.

(setq org-image-actual-width nil)

Enable Table of Contents

(use-package toc-org
  :commands toc-org-enable
  :init (add-hook 'org-mode-hook 'toc-org-enable))

Enabling Org Bullets

Org-bullets gives us attractive bullets rather than asterisks.

(add-hook 'org-mode-hook 'org-indent-mode)
(use-package org-bullets)
(add-hook 'org-mode-hook (lambda () (org-bullets-mode 1)))

Bind <TAB> to org-cycle

bind the 'TAB' key to 'org-cycle'. This allows us to use the 'TAB' key in org-mode buffer (normal-mode) to fold/unfold org bullets.

credit: Emacs StackExchange

(evil-define-key 'normal evil-org-mode-map "<tab>" #'org-cycle)

Org-appear

The org-appear package provides the ability to toggle the visibility of hidden orgmode emphasis markers for easier edditing.

(use-package org-appear) 
(add-hook 'org-mode-hook 'org-appear-mode)

Org-inline-pdf

enble org-inline-pdf mode at emacs launch

;;  (use-package org-inline-pdf
;;    :ensure
;;    (:host github :repo "shg/org-inline-pdf" :branch "main" :files ("*.el" "out")))

org-mpv-notes

(use-package org-mpv-notes
  :ensure t
  :commands (org-mpv-notes-mode org-mpv-notes-open)
  :hook (org-mode . org-mpv-notes-setup-link))
(use-package mpv
  :pin melpa
  :ensure t)

Org-roam

Org-roam is a plain-text knowledge management system. It brings some of Roam's more powerful features into the Org-mode ecosystem.

(use-package org-roam 
  :ensure t
  :custom
  (org-roam-directory (file-truename "~/Documents/org/org-roam/"))
  :bind (("C-c n l" . org-roam-buffer-toggle)
         ("C-c n f" . org-roam-node-find)
         ("C-c n i" . org-roam-node-insert)
         ("C-c n d" . org-roam-dailies-capture-today)
         ("C-c n y" . org-roam-dailies-capture-yesterday)
         ("C-c n t" . org-roam-dailies-capture-tomorrow)
         ;; Org-roam UI binds
         ("C-c n u" . org-roam-ui-mode)
         ("C-c n g" . org-roam-ui-open))
  :config
  (org-roam-setup))
  • llama

    llama is a dependency of org-roam, and must have the repository manually specified.

    (use-package llama
      :ensure
      (:host github :repo "yasuhirokimura/llama" :branch "main" :files ("*.el" "out")))
    

Org-roam UI

a better interface for Org-roam Graphs.

(use-package org-roam-ui
  :ensure
    (:host github :repo "org-roam/org-roam-ui" :branch "main" :files ("*.el" "out"))
    :after org-roam
;;         normally we'd recommend hooking orui after org-roam, but since org-roam does not have
;;         a hookable mode anymore, you're advised to pick something yourself
;;         if you don't care about startup time, use

    :hook (after-init . org-roam-ui-mode)

    :config
    (setq org-roam-ui-sync-theme t
          org-roam-ui-follow t
          org-roam-ui-update-on-save t
          org-roam-ui-open-on-start t))

Source Code Block Tag Expansion

Org-tempo is not a seperate package but a module within org that can be enabled. Org-tempo allows for '<s' followed by TAB to expand to a beginsrc teg. Other expansions available include:

Typing the below + TAB Expands to …
<a #+BEGIN_EXPORT ascii … #+END_EXPORT
<c #+BEGIN_CENTER#+END_CENTER
<C #+BEGIN_COMMENT#+END_COMMENT
<e #+BEGIN_EXPAMPLE#+END_EXAMPLE
<E #+BEGIN_EXPORT#+END_EXPORT
<h #+BEGIN_EXPORT html … #+END_EXPORT
<l #+BEGIN_EXPORT latex … #+END_EXPORT
<q #+BEGIN_QUOTE#+END_QUOTE
<s #+BEGIN_SRC#+END_SRC
<v #+BEGIN_VERSE#+END_VERSE
(require 'org-tempo)

RAINBOW MODE

Display the actual color as a background for any hex color value (ex. #ffffff). The code block below enables rainbow-mode in all programming modes (prog-mode) as well as org-mode, which is why rainbow works in this document.

(use-package rainbow-mode
  :hook org-mode prog-mode)

SHELLS AND TERMINALS

CTRL-C Fix

Fix to allow the CTRL C key combination to be used to terminate a process in shell modes.

Vterm

;;(define-key vterm-mode-map (kbd "C-c") 'vterm-send-C-c)

Eshell

;;(define-key eshell-mode-map (kbd "C-c") 'eshell-interupt-process)

Eshell

Eshell is an Emacs 'shell' that is written in Elisp.

Make all eshell appear in a popup buffer. The elisp below is a combination of the bellow sources to create a popup buffer to my liking.

(setq display-buffer-alist '(("\\`\\*e?shell" display-buffer-in-side-window (side . bottom))))

eshell-syntax-highlighting – adds fish/zsh-like syntax highlighting.

(use-package eshell-syntax-highlighting
  :after esh-mode
  :config
  (eshell-syntax-highlighting-global-mode 1))

eshell-rc-script – your profile for eshell; like a bashrc for eshell. eshell-alias-file – set an alaises file for the eshell.

(setq eshell-rc-script (concat user-emacs-directory "eshell/profile")
      eshell-aliases-file (concat user-emacs-directory "eshell/aliases")
      eshell-history-size 5000
      eshell-buffer-maximum-lines 5000
      eshell-hist-ignoredups t
      eshell-scroll-to-bottom-on-input t
      eshell-destroy-buffer-when-process-dies t
      eshell-visual-commands'("bash" "fish" "htop" "ssh" "top" "zsh"))

Vterm

(use-package vterm
:config
(setq shell-file-name "/bin/bash"
      vterm-max-scrollback 5000))

Vterm-Toggle

vterm-toggle toggles between the vterm buffer and whatever buffer you are editing.

(use-package vterm-toggle
  :after vterm
  :config
  (setq vterm-toggle-fullscreen-p nil)
  (setq vterm-toggle-scope 'project)
  (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-at-bottom)
                 ;;(display-buffer-reuse-window display-buffer-in-direction)
                 ;;display-buffer-in-direction/direction/dedicated is added in emacs27
                 ;;(direction . bottom)
                 ;;(dedicated . t) ;dedicated is supported in emacs27
                 (reusable-frames . visible)
                 (window-height . 0.3))))

SUDO EDIT

sudo-edit gives us the ability to open files with sudo privileges or switch over to editing with sudo privileges if we intentionally opened a file without such privileges.

(use-package sudo-edit
  :config
    (hd/leader-keys
      "fu" '(sudo-edit-find-file :wk "Sudo find file")
      "fU" '(sudo-edit :wk "Sudo edit file")))

THEME

The first of the two lines below designates the directory where we will place all of our themes. The second line loads our chosen theme which is Sieze the night, a theme that i created with the help of the Emacs Theme Editor.

(add-to-list 'custom-theme-load-path "~/.config/emacs/themes/")

seize-the-night is my custom theme for Emacs. Currently [2024-12-08 Sun] it is still a work in progress because i need to add some polish, and fix up the colors to better match the Dracula theme.

;; (load-theme 'seize-the-night t)

Update: As of [2025-06-03 Tue] I have fully switched away from using my custo seize-the-night theme, and I have moved back to using Doom Dracula as my default theme. Some time in the future I may revisit this custom theme. For now though I will just leave this here for historical purposes.

Doom Themes

Until then i will use the Doom Dracula theme instead.

(use-package doom-themes
  :ensure t
  :config
  ;; Global settings (defaults)
  (setq doom-themes-enable-bold t    ; if nil, bold is universally disabled
        doom-themes-enable-italic t) ; if nil, italics is universally disabled
  (load-theme 'doom-dracula t)

  ;; Enable flashing mode-line on errors
  (doom-themes-visual-bell-config)
  ;; Enable custom neotree theme (all-the-icons must be installed!)
  (doom-themes-neotree-config)
  ;; or for treemacs users
  (setq doom-themes-treemacs-theme "doom-dracula") ; use "doom-colors" for less minimal icon theme
  (doom-themes-treemacs-config)
  ;; Corrects (and improves) org-mode's native fontification.
  (doom-themes-org-config))

Initial Buffer Choice & Options

Disable the built-in Emacs splash screen and set custom initial buffer

(setq inhibit-startup-screen 1)
(setq initial-buffer-choice "~/.config/emacs/startup.org")

Make initial buffer read-only and disable line numbers

(add-hook 'emacs-startup-hook 
          (lambda () 
            (read-only-mode 1)
            (display-line-numbers-mode -1)
          )
)

Visit scratch buffer from custom startpage

;;(switch-to-buffer "*scratch*")

WHICH-KEY

(use-package which-key
  :init
    (which-key-mode 1)
  :config
     (setq which-key-side-window-location 'bottom
             which-key-sort-order #'which-key-key-order-alpha
             which-key-sort-uppercase-first nil
             which-key-add-column-padding 1
             which-key-max-display-columns nil
             which-key-min-display-lines 6
             which-key-side-window-slot -10
             which-key-side-window-max-height 0.25
             which-key-idle-delay 0.3
             which-key-max-description-length 25
             which-key-allow-imprecise-window-fit 1
             which-key-separator " → "))

FOOTNOTES

Author: Henry Davies (HD)

Created: 2025-06-11 Wed 16:41

Validate