This is a repository to place my Emacs configuration, and is inteneded to be used only by myself :-)
Emacs 25 and above is required.
My Emacs setup has borrowed a lot from the following sources:
qjp-mode
is a minor mode and most of my own key bindings live in this minor mode. Turning offqjp-mode
basically falls back to the key bindings of vanilla Emacs.- I make sure
qjp-mode
’s keymap has the HIGHEST priority whenever I open a file. Thus, no worries about conflicting key bindings from third-party packages.
- I switched back to using
evil
again. But only used for text editting. - In insert state, I still use Emacs key bindings.
- I rarely touch key bindings starting with
C-x
or having the form ofC-c C-<letter>
. Those are stardard key bindings and default key bindings provided by third-party packages. For example,C-x C-f
forfind-file
andC-c C-c
inorg-mode
to evaluate a code block. - Most of the key bindings I add for my own defuns and third-party packages
lives in
C-c <letter>
. For example,C-c p
for allprojectile
key bindings, andC-c h
forhelm
key bindings.
- Take advantage of the leader key feature in
evil
and AVOIDCtrl
in non-insert state. But since my key bindings are organized in a very Emacsy way, i.e., still using standard key bindings likeC-x C-f
and usingC-c <letter>
for all custom key bindings, I hope using the leader key could be consistent with these key bindings used in insert state. - I like the idea of using
SPC
as the leader key, which is exactly whatSpacemacs
does, but I don’t want to REBIND all the key bindings likeSpacemacs
. For example, I don’t want to useSPC f f
forfind-file
.
Let’s bind SPC
to evil-execute-in-god-state
in normal state. Then in
normal state:
- Standard key binding:
C-x C-f
becomesSPC x f
- Mode-specific key binding:
C-c C-c
becomesSPC c c
- Custom key binding:
C-;
becomesSPC ;
- Custom key binding in
C-c
prefix:C-c p p
becomesSPC c SPC p p
Neat! (At least for the first three.) I don’t need to rebind any key bindings!
The last one isn’t that good. So I decide to roll my own god-mode
and
evil-god-state
: qjp-leader-mode
and evil-qjp-leader-state
. In
qjp-leader-mode
, which has almost identical code to god-mode
, while most
of keys are interpreted in the same way as god-mode
, some special keys
can be interpreted as C-c <letter>
. For example, make p
be such a
special key that is interpreted as C-c p
rather than C-p
, and now
SPC
should be bound to evil-execute-in-qjp-leader-state
instead of
evil-execute-in-god-state
, then for the previous key bindings:
C-x C-f
becomesSPC x f
C-c C-c
becomesSPC c c
C-;
becomesSPC ;
C-c p p
becomesSPC p p
(this is different now!)
The first three are the same, but the last one becomes much simpler. In
fact, after such a change, the leader key feature we have “looks” quite
similar to Spacemacs
, but actually they are different! Our key bindings
are very Emacsy and we don’t rebind the keys! When using the leader key
feature, we still think in the Emacs way, SPC x f
for C-x C-f
and SPC p
p
for C-c p p
, exactly the same thinking process when under the insert
state, where Emacs key bindings are used.
qjp-leader-mode
and evil-qjp-leader-state
are strictly only used to
emulate the leader key feature because intepreting keys like p
in such a
special way may not be what we want in some circumstances. The good news is
that qjp-leader-mode
’s keymap is NOT shared with god-mode
’s. So I can
still use god-mode
when it is more natural and convenient. For example, I
still use god-mode
in helm
sessions and for minibuffer navigation. In a
helm
session, activating god-mode
make it possible to use n
and p
to
move down and up, and z
to access the actions.
Here is a more complete overview of my current key mappings:
- In normal/visual state,
SPC
toevil-execute-in-qjp-leader-state
- In all states,
M-j
(it is really easy to reach) toevil-execute-in-qjp-leader-state
- In insert state, use Emacs key bindings
- In insert state, key chord
kk
toevil-execute-in-qjp-leader-state
, and key chordjj
toevil-normal-state
M-'
to emulateC-g
- In helm/minibuffer,
ESC
and key chordjj
togod-mode
When in insert state, use key chords to perform some small actions.
Key Chords | Action |
---|---|
xf | find file |
xs | save file |
bb | switch buffers |
These key chords are available globally.
Key Chords | Action |
j1 | C-x 1 |
j2 | C-x 2 |
j3 | C-x 3 |
- Using xcape to bind CapsLock to both
Ctrl
andEscape
- Using
xmodmap
to bind the<menu>
key to the right of theSpace
, and map<menu>
to beC-c
in Emacs, which makeC-c
accessible using only one key in all modes.
evil-embrace
evil-surround
evil-visualstar
evil-indent-plus
evil-args
evil-exchange
evil-nerd-commenter
I prefer using directories to structurally organize my settings.
There are three main directories under the .emacs.d
:
startup
: Global settings that should be loaded immediately after startup.modules
: Main part. Configuring all the built-in and ELPA packages.site-lisp
: Configurations for the packages not on ELPA.
Under each of the directory, there is a directory-init file named
qjp-*-init.el
. *
stands for the corresponding directory name. Each
directory-init file will be in charge of loading all the settings under its
directory. init.el
will load these three directory-init files in order:
init.el --> startup/qjp-startup-init.el --> modules/qjp-modules-init.el --> site-lisp/qjp-site-lisp-init.el
There are many files in different levels of the directory tree, so when I want
to modify the settings, I use helm-projectile
to quickly switch to a specific
file that I want to edit. As for the ELPA packages, I mainly use melpa to
install the latest version of the packages.
Other than some global settings, the two important parts of this module are the profiler and the settings for the package manager.
The profiler can measure the loading time for a specific Emacs Lisp module so that I can generate tables containing all the loading times in an Org-mode buffer. Currently on a SSD machine, Emacs takes less than 1.2s to finish the initialization process.
The package manager settings will keep tracking the packages currently installed
in the machine and store the installed package list into a file. When starting
the Emacs, install any packages that are not installed yet. Note this is not an
on-demand installation feature as provided in Emacs Prelude. All the packages
will be installed no matter whether I have explicitly use them in our settings
or not. I actually prefer this way because some packages actually need
zero-configuration(we have autoload
s!).
I put almost all the code for settings under this directory, and there are 8 submodules in it.
qjp-basic
: I put settings for UI and built-in packages here.qjp-defuns
: Some useful function definitions. Since there are different categories of such definitions, I split them into three files and put these files underdefuns
subdirectory.qjp-mode
: A minor mode which is mainly used to define my own key bindings. I rarely useglobal-set-key
and nearly all my customized keybindings live only when the minor mode is on.qjp-misc
: This is a very huge part. All the third-party packages installed from ELPA which are not for programming purpose, LaTeX or Org-mode should be configured here. If there are only a few lines of code of settings for a third-party package, then I put the code insideqjp-misc.el
. However, if the number of the lines of code is a little bit large, I prefer putting the code into a separate file undermisc
subdirectory.qjp-org
: There are actually several files underorg
subdirectory and each file has settings for a specific functionality of the Org-mode.qjp-tex
: Settings for AUCTeX.qjp-programming
: Each programming language has its own config file underprogramming
subdirectory and the general settings for programming mode are inqjp-programming-basic.el
.qjp-alias
: Nothing serious here. Just some short names for some commands that have no keybindings. I’m considering merging this into other parts.
This module has packages that are not hosted in any package archieves. These
packages are usually modified by myself and hosted in my own Git repos. Use
git-submodule
to manage them.
For old key remappings using Space
as both Space
and Ctrl
and without
Evil
, see this article. Now I’m using a combination of god-mode and evil-mode,
which requires much less key mapping tweak.