- [[#automatically-create-table-of-contents][Automatically Create Table of Contents]]
- [[#make-m-ret-not-add-blank-lines][Make M-RET Not Add Blank Lines]]
- [[#org-export-to-manpage-format][Org Export To Manpage Format]]
- [[#perspective][PERSPECTIVE]]
- [[#projectile][PROJECTILE]]
- [[#registers][REGISTERS]]
- [[#scrolling][SCROLLING]]
- [[#shells][SHELLS]]
- [[#eshell][Eshell]]
- [[#vterm][Vterm]]
- [[#splits-and-window-controls][SPLITS AND WINDOW CONTROLS]]
- [[#theme][THEME]]
- [[#which-key][WHICH KEY]]
- [[#writeroom-mode][WRITEROOM MODE]]
* IMPORTANT! 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".
* A FEW PROGRAMS TO LOAD FIRST
The order in which the various Emacs modules load is very important. So the very first code block is going to contain essential modules that many other modules will depend on later in this config.
** 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
** 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'.
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.
General.el allows us to set keybindings. As a longtime Doom Emacs user, I have grown accustomed to using SPC as the prefix key. General makes setting keybindings (especially with SPC) much easier. All of the keybindings we set later in the config depend on general being loaded.
#+begin_src emacs-lisp
(use-package general
:config
(general-evil-setup 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
* BUFFERS AND BOOKMARKS
#+begin_src emacs-lisp
(nvmap :prefix "SPC"
"b b" '(ibuffer :which-key "Ibuffer")
"b c" '(clone-indirect-buffer-other-window :which-key "Clone indirect buffer other window")
"b k" '(kill-current-buffer :which-key "Kill current buffer")
"Show the full path to the current file in the minibuffer."
(interactive)
(let ((file-name (buffer-file-name)))
(if file-name
(progn
(message file-name)
(kill-new file-name))
(error "Buffer not visiting a file"))))
#+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.
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.
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'
=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.
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.
:ensure nil) ;; tell use-package not to try to install org-tempo since it's already there.
#+end_src
** Source Code Block Syntax Highlighting
We want the same syntax highlighting in source blocks as in the native language files.
#+begin_src emacs-lisp
(setq org-src-fontify-natively t
org-src-tab-acts-natively t
org-confirm-babel-evaluate nil
org-edit-src-content-indentation 0)
#+end_src
** Automatically Create Table of Contents
Toc-org helps you to have an up-to-date table of contents in org files without exporting (useful useful for README files on GitHub). Use :TOC: to create the table.
The Perspective package provides multiple named workspaces (or "perspectives") in Emacs, similar to multiple desktops in window managers like Awesome and XMonad. Each perspective has its own buffer list and its own window layout. This makes it easy to work on many separate projects without getting lost in all the buffers. Switching to a perspective activates its window configuration, and when in a perspective, only its buffers are available.
#+begin_src emacs-lisp
(use-package perspective
:bind
("C-x C-b" . persp-list-buffers) ; or use a nicer switcher, see below
:config
(persp-mode))
#+end_src
* PROJECTILE
#+begin_src emacs-lisp
(use-package projectile
:config
(projectile-global-mode 1))
#+end_src
* REGISTERS
Emacs registers are compartments where you can save text, rectangles and positions for later use. Once you save text or a rectangle in a register, you can copy it into the buffer once or many times; once you save a position in a register, you can jump back to that position once or many times. The default GNU Emacs keybindings for these commands (with the exception of counsel-register) involves 'C-x r' followed by one or more other keys. I wanted to make this a little more user friendly, so I chose to replace the 'C-x r' part of the key chords with 'SPC r'.
(setq mouse-wheel-follow-mouse 't) ;; scroll window under mouse
#+end_src
* SHELLS
In my configs, all of my shells (bash, fish, zsh and the ESHELL) require my shell-color-scripts-git package to be installed. On Arch Linux, you can install it from the AUR. Otherwise, go to my shell-color-scripts repository on GitLab to get it.
** Eshell
Eshell is an Emacs 'shell' that is written in Elisp.
Vterm is a terminal emulator within Emacs. The 'shell-file-name' setting sets the shell to be used in M-x shell, M-x term, M-x ansi-term and M-x vterm. By default, the shell is set to 'fish' but could change it to 'bash' or 'zsh' if you prefer.