Skip to content

cute-jumper/.emacs.d

Repository files navigation

My Emacs Configuration

This is a repository to place my Emacs configuration, and is inteneded to be used only by myself :-)

Emacs 25 and above is required.

References

My Emacs setup has borrowed a lot from the following sources:

The Key Bindings Mechanism (In case anyone’s interested)

Separate Most of the Customized Key Bindings: qjp-mode

  • qjp-mode is a minor mode and most of my own key bindings live in this minor mode. Turning off qjp-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.

Key Bindings Overview

  • 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 of C-c C-<letter>. Those are stardard key bindings and default key bindings provided by third-party packages. For example, C-x C-f for find-file and C-c C-c in org-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 all projectile key bindings, and C-c h for helm key bindings.

Key Bindings Improved with Leader Key: qjp-leader-mode

Motivation

  • Take advantage of the leader key feature in evil and AVOID Ctrl in non-insert state. But since my key bindings are organized in a very Emacsy way, i.e., still using standard key bindings like C-x C-f and using C-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 what Spacemacs does, but I don’t want to REBIND all the key bindings like Spacemacs. For example, I don’t want to use SPC f f for find-file.

god-mode and evil-god-state to the rescue

Let’s bind SPC to evil-execute-in-god-state in normal state. Then in normal state:

  • Standard key binding: C-x C-f becomes SPC x f
  • Mode-specific key binding: C-c C-c becomes SPC c c
  • Custom key binding: C-; becomes SPC ;
  • Custom key binding in C-c prefix: C-c p p becomes SPC c SPC p p

Neat! (At least for the first three.) I don’t need to rebind any key bindings!

Improvement: qjp-leader-mode and evil-qjp-leader-state

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 becomes SPC x f
  • C-c C-c becomes SPC c c
  • C-; becomes SPC ;
  • C-c p p becomes SPC 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.

Used with god-mode at the same time

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.

Summary of Key Bindings

Here is a more complete overview of my current key mappings:

  • In normal/visual state, SPC to evil-execute-in-qjp-leader-state
  • In all states, M-j (it is really easy to reach) to evil-execute-in-qjp-leader-state
  • In insert state, use Emacs key bindings
  • In insert state, key chord kk to evil-execute-in-qjp-leader-state, and key chord jj to evil-normal-state
  • M-' to emulate C-g
  • In helm/minibuffer, ESC and key chord jj to god-mode

When in insert state, use key chords to perform some small actions.

Key ChordsAction
xffind file
xssave file
bbswitch buffers

These key chords are available globally.

Key ChordsAction
j1C-x 1
j2C-x 2
j3C-x 3

Optional Key Tweaks

  • Using xcape to bind CapsLock to both Ctrl and Escape
  • Using xmodmap to bind the <menu> key to the right of the Space, and map <menu> to be C-c in Emacs, which make C-c accessible using only one key in all modes.

Plugins for Evil

  • evil-embrace
  • evil-surround
  • evil-visualstar
  • evil-indent-plus
  • evil-args
  • evil-exchange
  • evil-nerd-commenter

Structure

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.

Startup

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!).

Modules

I put almost all the code for settings under this directory, and there are 8 submodules in it.

  1. qjp-basic: I put settings for UI and built-in packages here.
  2. qjp-defuns: Some useful function definitions. Since there are different categories of such definitions, I split them into three files and put these files under defuns subdirectory.
  3. qjp-mode: A minor mode which is mainly used to define my own key bindings. I rarely use global-set-key and nearly all my customized keybindings live only when the minor mode is on.
  4. 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 inside qjp-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 under misc subdirectory.
  5. qjp-org: There are actually several files under org subdirectory and each file has settings for a specific functionality of the Org-mode.
  6. qjp-tex: Settings for AUCTeX.
  7. qjp-programming: Each programming language has its own config file under programming subdirectory and the general settings for programming mode are in qjp-programming-basic.el.
  8. qjp-alias: Nothing serious here. Just some short names for some commands that have no keybindings. I’m considering merging this into other parts.

Site-lisp

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.

Old Key Bindings without Evil

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.

About

Emacs config with an Evil editor

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published