Emacs - Beginner Configuration

Overview
In my previous article I documented a very brief tutorial of Emacs Lisp. In this article let’s continue to create an Emacs configuration for beginner.
Introduction
Emacs is more than just a text/code editor (LSP, DAP). It is an extensible computing environment which can be used as email client (mu4e), window manager (exwm), editing remote files (tramp) and much more. With org-mode, you can use Emacs for keeping notes, maintaining to-do lists, planning projects, authoring documents, computational notebooks, literate programming (Babel) and more.
Unlike VSCode which is easy to get started, Emacs requires customization using elisp in order to be useful and effective for use. There are distributions like Spacemacs or Doom Emacs which make it easy to get started using Emacs. However I suggest you start by understanding some basics of Emacs Lisp, and try to configure your own Emacs dotfiles. Without understanding the basics you are going to encounter issues when you want to customize Emacs further.
With the fundamentals, you can then decide if you want to develop your own dotfiles or use Emacs distributions like Spacemacs or Doom Emacs.
The Basics
Emacs Screen

Above is a screenshot of Emacs out of the box
Frame
is highlighted in RED rectangle.Menu bar
is highlighted in BLUE rectangle.Tool bar
is highlighted in GREEN rectangle.Window
is highlighted in MAGENTA rectangle.- On the left of the window highlighted in BROWN is the window
fringe
. Mode line
is highlighted in YELLOW rectangle.Echo area
is highlighted in BLACK rectangle (at the bottom of the screen).
Emacs Initialization File
When Emacs is started, it normally tries to load a Lisp program from an initialization file, or init file for short. Traditionally, file ~/.emacs
is used as the init file, although Emacs also looks at ~/.emacs.el
, ~/.emacs.d/init.el
, ~/.config/emacs/init.el
, or other locations. You can also specify the XDC_CONFIG_HOME for your own location. In my case I keep my configuration in ~/.config/emacs/init.el
.
Dotfiles Structure
Similiar to Emacs Bootstrap, I am going to split the configuration into different elisp files under the elisp
folder and load them from init.el
(add-to-list 'load-path (concat user-emacs-directory "elisp"))(require 'base)(require 'theme)....

Base Configuration
Let’s get started with the base
configuration by creating a file called base.el
under the elisp
folder.
- For better viewing, I set the default font size to be 160.
- I defined a variable for the custom file, and load the custom file when Emacs starts. This is required to prevent Emacs from writing any customizations to my
init.el.
- Add and refresh MELPA (Milkypostman’s Emacs Lisp Package Archive) using package.el to enable installation of MELPA packages.
- Install use-package if it is not installed. I am going to use it to isolate package installation and configuration.
- I specify make-backup-files to be false. A backup file is a copy of the old contents of a file you are editing.
- For line numbers display, I set it to
relative
. - I set use-package-always-ensure to true so that use-package automatically install the package if not present.
- global-auto-revert-mode is set to true to automatically reload the file if it gets updated by another program.
- global-display-line-numbers-mode displays line numbers for all buffers.
- show-paren-mode allows me to see matching parentheses. A great help for checking Lisp syntax.
- I load the custom-file if it has been created by Emacs.
- Add a hook to remove trailing white spaces before saving the file.
You can further customize the base configurations as you like, e.g. you may want to skip the startup up screen, remove the tool bar, menu bar, scroll bar, etc.
Theme
The default Emacs theme is boring. Let’s add a theme to it.
- Create a file called
theme.el
underelisp
folder. - Use
use-package
to install thespacemacs-theme
. Defer loading is set to true (other package causes it to load).:init
keyword is used to execute code before a package is loaded.
(use-package spacemacs-theme
:defer t
:init
(load-theme 'spacemacs-dark t))(provide 'theme)
In init.el
I load the theme after the base configuration.
;; elisp files
(add-to-list 'load-path (concat user-emacs-directory "elisp"));; Base configuration
(require 'base);; Theme
(require 'theme)
Start Emacs and I can see the theme loaded now.

Evil Mode
I prefer Vim modal editing so let’s install evil-mode.
- Create a file called
vim.el
underelisp
folder.
(use-package evil
:init
(setq evil-vsplit-window-right t)
(setq evil-split-window-below t)
(setq evil-want-C-u-scroll t)
(setq evil-want-C-i-jump nil)
:config
(evil-mode 1))(provide 'vim)
Load this file in init.el
;; elisp files
(add-to-list 'load-path (concat user-emacs-directory "elisp"));; Base configuration
(require 'base);; Theme
(require 'theme);; Evil mode
(require 'vim)
You can switch between Vim and Emacs mode using C-z
.
Completion
Let’s install a completion framework using ivy, counsel and company.
Create a file called completion.el
under elisp
folder
ivy, counsel
Add the following lines to completion.el
.
(use-package ivy
:bind
("C-x s" . swiper)
("C-x C-r" . ivy-resume)
:config
(ivy-mode 1)
(setq ivy-use-virtual-buffers nil)
(define-key read-expression-map (kbd "C-r") 'counsel-expression-history))(use-package counsel
:bind
("M-x" . counsel-M-x)
("C-x C-m" . counsel-M-x)
("C-x C-f" . counsel-find-file)
("C-x c k" . counsel-yank-pop))
Press M-x
and I can see it is using counsel now.

There are many more counsel functions that you can use. You can further define the key mappings to use counsel functions.
company
Let’s add a text completion framework using company.
Add the following lines to completion.el
(use-package company
:config
(add-hook 'after-init-hook 'global-company-mode))
Start Emacs and I can see the completion menu as I type.

Which-Key
Emacs simply has too many key mappings. Let’s install which-key to help.
Add the following lines to completion.el
(use-package which-key
:defer 0
:diminish which-key-mode
:config
(which-key-mode)
(setq which-key-idle-delay 1))
Now in Emacs whenever you press a key combination, it will show available key mappings for you. E.g. when I press C-x

Project Interaction
Let’s install projectile to make it easier to manage projects.
Create a file called workspace.el
under elisp
folder.
(use-package projectile
:diminish projectile-mode
:config
(setq projectile-completion-system 'ivy)
(projectile-global-mode)
:bind-keymap
("C-c p" . projectile-command-map)
:init
(setq projectile-project-search-path '("~/workspace/development/"))
(setq projectile-switch-project-action #'projectile-dired))(use-package counsel-projectile
:after projectile
:bind
("C-SPC" . counsel-projectile-switch-project)
:config
(counsel-projectile-mode))(provide 'workspace)
I configured the folder to search for projects. Start Emacs and now I can easily switch between projects.
I configured all the projectile commands to start with C-c p
.

To switch projects, type Control-Space (C-SPC)
.

Startup Screen
The startup screen is boring. Let’s change it using dashboard.
Create a file called splash.el
under elisp
folder.
;; Dependencies
(use-package page-break-lines)
(use-package all-the-icons)(use-package dashboard
:config
(setq show-week-agenda-p t)
(setq dashboard-items '((recents . 15) (agenda . 5)))
(setq dashboard-set-heading-icons t)
(setq dashboard-set-file-icons t)
(setq dashboard-startup-banner 3)
(dashboard-setup-startup-hook)
)(provide 'splash)
Start Emacs and the dashboard should be shown.

Magit
Let’s install version control using Magit.
Create a file called vcs.el
under elisp
folder.
(use-package magit
:config
(setq magit-completing-read-function 'ivy-completing-read)
:bind
;; Magic
("C-x g s" . magit-status)
("C-x g x" . magit-checkout)
("C-x g c" . magit-commit)
("C-x g p" . magit-push)
("C-x g u" . magit-pull)
("C-x g e" . magit-ediff-resolve)
("C-x g r" . magit-rebase-interactive))(use-package magit-popup)(provide 'vcs)
Start Emacs and press C-x g s
to see the Git status.

Summary
We have now a very simple Emacs configuration as shown below. In coming articles we shall see how to add in LSP, DAP and also make it more user friendly just like Spacemacs or Doom Emacs.
The dotfiles I used can be found at this repository.
Check out this article on how I configure LSP and DAP for Emacs based on this configuration.