My Emacs configuration. It rocks.
There are many ways to install Emacs. I use homebrew.
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.
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,swiperandcounsel. When active,ivy-modecompletes the selection process by narrowing available choices while previewing in the minibuffer. Alternative packages are helm and ido. I likeivythe most. - counsel-projectile - Projectile has native support for ivy.
counsel-projectileprovides further integration by taking advantage ofivy'ssupport 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.
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.
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 ffor the functioncounsel-describe-function, which overrides the defaultdescribe-functionwhich will show the documentation for a specific Emacs or package function.C-h vfor the functioncounsel-describe-variable, which overrides the defaultdescribe-variablewhich will show the documentation for a specific Emacs or package variable.C-h kfor the functioncounsel-describe-keywhich will prompt you for a key combination, then will show you the documentation of the function for that combination.C-h wfor the functionwhere-iswhich will show you keybindings for a given function.
It's often useful to work with multiple windows. These are the official docs. I tend to only use these commands:
C-x 2forsplit-window-belowto split horizontally.C-x 3forsplit-window-rightto split vertically.C-x 1fordelete-other-windowsto close all other windows.C-x 0fordelete-windowto close the current window.
I have also setup C-; as a custom binding for prev-window for quickly jumping between windows.
M->bound toend-of-bufferto move to end of buffer.M-<bound tobeginning-of-bufferto move to start of buffer.C-x C-cbound tosave-buffers-kill-terminalto save and quit Emacs.C-a C-SPCwithC-norC-pto mark lines up and down.C-x hto select entire buffer thenM-x write-fileto save as a new file.M-x revert-bufferto revert the buffer to it's last save.M-pto move the line up. See stu-bindings.el. Not bound in markdown-mode.M-nto move the line down. See stu-bindings.el. Not bound in markdown-mode.C-;bound toprev-windowto jump to the previous window.C-.to comment a line.M-jbound toprevious-bufferto show the previous buffer in the window.M-kbound tonext-bufferto show the next buffer in the window.
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
C-sbound toswiper-isearchto search in the current buffer.M-xbound tocounsel-M-xwhich overridesM-xand is used to search all functions.C-x C-fbound tocounsel-find-filefor finding files.M-ybound tocounsel-yank-popwhich will show a minibuffer list of your recent kills that can be yankedC-x bbound toivy-switch-bufferto select a buffer to swith to.C-c vbound toivy-push-viewto name the current view and push it to the view listC-c Vbound toivy-pop-viewwhich will let you choose a previously pushed view.C-c sbound tocounsel-agwhich will search for a string in a root directory.C-c C-rbound toivy-resumewhich will resume the last completion session. This is nice.
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 pbound tocounsel-projectile-switch-projectto switch between known projects.C-c p fbound tocounsel-projectile-find-fileto find a project file.C-c p gbound tocounsel-projectile-find-file-dwimto find a project file using completion based on context.C-c p dbound tocounsel-projectile-find-dirto find a project directory.C-c p bbound tocounsel-projectile-switch-to-bufferto switch to a project buffer.C-c p s sbound tocounsel-projectile-agto search the project files usingag. Very useful.
The docs are ok, worth reading once. I find the built-in command list better.
C-c C-hbound toTDBshow all the markdown commands.C-c C-sis the styling prefix.bfor bold,ifor italic etc. Check the menu in the minubuffer for more options.C-c C-lbound tomarkdown-insert-linkto insert a link.C-c C-ibound tomarkdown-insert-imageto insert an image.C-c C-tis the header prefix. 1, 2, 3, etc for the different headers.
There are many more commands. Read the docs.
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 (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-inwhich start an nREPL using your projects configuration and will inject the necessary middleware.cider-connect-cljwhich 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 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.