Emacs
My Emacs configuration. It rocks.
Installation
There are many ways to install Emacs. I use homebrew.
Configuration
Emacs config is loaded from ~/.emacs.d
The entrypoint to Emacs config is the Emacs Initialization File init.el
.
In my init.el
I load all my libraries from each of the ~/.emacs.d/customizations/stu-*
files.
Emacs configuration is simply a collection of functions and variables.
If you want to understand what's going on, read through the init.el
and then each of the customizations/stu-*.el
files. It's easy to understand if you can read Clojure.
Packages Stu Loves:
There are thousands of great Emacs packages. These are the few that I use. I'll try and keep this list up to date as best I can.
- projectile - a library for managing projects.
- ivy - Made up of three packages -
ivy
,swiper
andcounsel
. When active,ivy-mode
completes the selection process by narrowing available choices while previewing in the minibuffer. Alternative packages are helm and ido. I likeivy
the most. - counsel-projectile - Projectile has native support for ivy.
counsel-projectile
provides further integration by taking advantage ofivy's
support for selecting from a list of actions and applying the action without leaving the session. - company-mode - A text completion framework for completion at point, meaning completion in ordinary buffers.
- clojure-mode - An Emacs major mode that provides font-lock (syntax highlighting), indentation, navigation and refactoring support for the Clojure(Script) programming language. There is a section dedicated to it below.
- CIDER - CIDER extends Emacs with support for interactive programming in Clojure. There is a section dedicated to it below.
- clj-refactor - clj-refactor provides powerful refactoring functionality for Clojure projects. It complements the refactoring functionality you'd find in clojure-mode and CIDER. There is a section dedicated to it below.
- magit - The very best way to work with
git
. I love this package. - markdown-mode - A major mode for editing markdown files. So good.
- crux - crux bundles many useful interactive commands to enhance your overall Emacs experience.
- doom-themes - amazing collection of themes. I'm currenctly using doom-vibrant.
I also use these small packages for various things:
- ag - An Emacs frontend to The Silver Searcher. I use it for global search in a project (counsel-projectile-ag). It's insanely fast.
- avy - for jumping to visible text using a char based decision tree.
- aggressive-indent-mode - Always keep your code indented.
- idle-highlight-mode - Simple symbol highlighting.
- exec-path-from-shell - Library to ensure environment variables inside Emacs look the same as in the user's shell.
- paredit - Necessary for doing any kind of work with lisps. I set it to be used in clojure mode and in the REPL.
- rainbow-delimiters - Highlight delimeters
() {} []
according to their depth. - super-save - auto save buffers when certain things happen (like switching between buffers). Replaces the standard
auto-save-mode
. - focus - Dim surrounding text. I'm experimenting with this. I like it so far.
- zprint-mode - I use zprint for pretty printing Clojure code. This package allows me to pretty print with zprint with the buffer.
- doom-modeline - A fancy, fast modeline designed for minimalism.
Fonts:
- JetBrains Mono - I'm currently using this. Arguably the best font for programming.
- FiraCode - Another excellent font.
Both these fonts provide ligatures if that's your thing.
Some pointers to get up to speed quickly
Control Keys
When you see M-<key>
it means to press the Meta key. On my Mac Meta is the ⌥ key.
When you see C-<key>
it means to press the Ctrl key.
When you see s-<key>
it means to press the Super key. On my Mac Super is the ⌘ key.
Help
Emacs has a build in manual C-h C-h
for the function help-for-help
, but I don't find it that useful.
These keybindings are more useful:
C-h f
for the functioncounsel-describe-function
, which overrides the defaultdescribe-function
which will show the documentation for a specific Emacs or package function.C-h v
for the functioncounsel-describe-variable
, which overrides the defaultdescribe-variable
which will show the documentation for a specific Emacs or package variable.C-h k
for the functioncounsel-describe-key
which will prompt you for a key combination, then will show you the documentation of the function for that combination.C-h w
for the functionwhere-is
which will show you keybindings for a given function.
Windows
It's often useful to work with multiple windows. These are the official docs. I tend to only use these commands:
C-x 2
forsplit-window-below
to split horizontally.C-x 3
forsplit-window-right
to split vertically.C-x 1
fordelete-other-windows
to close all other windows.C-x 0
fordelete-window
to close the current window.
I have also setup C-;
as a custom binding for prev-window
for quickly jumping between windows.
Keybindings I use all the time
Emacs
M->
bound toend-of-buffer
to move to end of buffer.M-<
bound tobeginning-of-buffer
to move to start of buffer.C-x C-c
bound tosave-buffers-kill-terminal
to save and quit Emacs.C-a C-SPC
withC-n
orC-p
to mark lines up and down.C-x h
to select entire buffer thenM-x write-file
to save as a new file.M-x revert-buffer
to revert the buffer to it's last save.M-p
to move the line up. See stu-bindings.el. Not bound in markdown-mode.M-n
to move the line down. See stu-bindings.el. Not bound in markdown-mode.C-;
bound toprev-window
to jump to the previous window.C-.
to comment a line.M-j
bound toprevious-buffer
to show the previous buffer in the window.M-k
bound tonext-buffer
to show the next buffer in the window.
Avy
Avy is used for jumping around the visible screen.
C-'
bound to avy-goto-char-timer
which will start avy. Use the character prompts to narrow down your selection.
You can also use prefix commands to do things.
As an example, to kill this line (with this X) you would type the combination C-'
then K
then whatever keys avy is prompting your selection of the X.
These are the other prefix commands:
<space>
- mark to chark
: kill stayK
: kill whole liney
: yankw
: copyW
: copy whole lineY
: yank whole linet
: teleportT
: teleport whole linenn
Ivy
C-s
bound toswiper-isearch
to search in the current buffer.M-x
bound tocounsel-M-x
which overridesM-x
and is used to search all functions.C-x C-f
bound tocounsel-find-file
for finding files.M-y
bound tocounsel-yank-pop
which will show a minibuffer list of your recent kills that can be yankedC-x b
bound toivy-switch-buffer
to select a buffer to swith to.C-c v
bound toivy-push-view
to name the current view and push it to the view listC-c V
bound toivy-pop-view
which will let you choose a previously pushed view.C-c s
bound tocounsel-ag
which will search for a string in a root directory.C-c C-r
bound toivy-resume
which will resume the last completion session. This is nice.
Projectile
Projectile manages projects. The manual is good so read it.
Projectile and Counsel play nicely through the counsel-projectile
package, which basically overloads all the default projectile functions.
Each of these options has further options. If you want to see those options use M-o
after you have triggered any of these:
C-c p p
bound tocounsel-projectile-switch-project
to switch between known projects.C-c p f
bound tocounsel-projectile-find-file
to find a project file.C-c p g
bound tocounsel-projectile-find-file-dwim
to find a project file using completion based on context.C-c p d
bound tocounsel-projectile-find-dir
to find a project directory.C-c p b
bound tocounsel-projectile-switch-to-buffer
to switch to a project buffer.C-c p s s
bound tocounsel-projectile-ag
to search the project files usingag
. Very useful.
Markdown
The docs are ok, worth reading once. I find the built-in command list better.
C-c C-h
bound toTDB
show all the markdown commands.C-c C-s
is the styling prefix.b
for bold,i
for italic etc. Check the menu in the minubuffer for more options.C-c C-l
bound tomarkdown-insert-link
to insert a link.C-c C-i
bound tomarkdown-insert-image
to insert an image.C-c C-t
is the header prefix. 1, 2, 3, etc for the different headers.
There are many more commands. Read the docs.
Clojure
clojure-mode
Pretty much everything is configurable. To see a list of available configuration options do M-x customize-group RET clojure
.
clojure-mode
can handle indentation and alignment. I'm using zprint for pretty printing and formatting so I don't worry too much about this configuration.
clojure-mode
also provides refactoring support. The docs prvide examples.
It's worth checking out the related packages section of the docs.
CIDER
CIDER (Clojure(Script) Interactive Development Environment that Rocks!)
The main reason for doing Clojure develoment on Emacs.
CIDER provides alot of great features. The main feature is being able to connect and interact with a running nREPL.
There are many ways to interact with a REPL in CIDER. The two main ones are:
cider-jack-in
which start an nREPL using your projects configuration and will inject the necessary middleware.cider-connect-clj
which will connect to an existing nREPL server. The middle must be already configured.
The instructions for setting up the middleware is here.
CIDER has many configuration options.
You can configure project specific configuration.
If you are running your nREPL in a Docker container, add this to your project .dir-locals.el
to map the directories correctly for CIDER. If you don't do this you will not be able to find symbol definitions and move around easily.
((nil
(cider-path-translations . (("/root/.m2" . "/Users/stuartrexking/.m2")
("/root/code/" . "/Users/stuartrexking/Workspace/shopdeft/deft"))))
(clojure-mode
;; a list of connection endpoints, each endpoint is a list
(cider-known-endpoints . (("deft" "localhost" "7888")))))
Checkout all the things you can do with CIDER once you are connected.
clj-refactor
clj-refactor
provides powerful refactoring functionality for Clojure projects.
The important thing to understand is how the middleware is configured and enables clj-refactor
.
To use clj-refactor
you must be connected to a REPL.
My clj-refactor
keybinding is C-c C-,
See the wiki for a list of refactorings.