Share your Spacemacs tweaks

With the folks from Nextjournal we’ve been getting really excited about Spacemacs lately. There are a few Cursive users and one Atom user holding out, but the rest of us have all moved to Spacemacs. This includes old vim hands and people who had been using Emacs for years.

It’s super nice how polished and complete Spacemacs is, but still anything that is based on Emacs is meant to be tweaked. This thread is for sharing those tweaks.

The rules

  • one tweak per post
  • share up to 10 lines of emacs lisp code (we’re looking for tweaks, not for new packages)
  • explain what it does, how you use it, and why you like it
3 Likes

This one courtesy of @joannecheng: relative line numbers!

(add-hook 'find-file-hook #'linum-mode)
(add-hook 'linum-mode-hook #'linum-relative-on)
(unless (display-graphic-p)
  (setq linum-relative-format "%3s  "))

This way files will show line numbers relative to the position of the cursor, e.g. here I’m on line 32, so lines above and below 32 show how far away they are from 32.

This is useful because it lets you very quickly jump to a line, e.g. I can jump to the last line in the image with 4j.

The final command in the snippet is needed to make things look nice when running inside a terminal.

Navigate sexps with vim-like keys. Mnemonics:

  • L: like l except sexp based
  • H: like h except sexp based
  • U: up
  • R: return
  (evil-global-set-key 'normal "U" 'backward-up-list)
  (evil-global-set-key 'visual "U" 'backward-up-list)
  (evil-global-set-key 'normal "R" 'down-list)
  (evil-global-set-key 'visual "R" 'down-list)
  (evil-global-set-key 'normal "L" 'sp-forward-sexp)
  (evil-global-set-key 'visual "L" 'sp-forward-sexp)
  (evil-global-set-key 'normal "H" 'sp-backward-sexp)
  (evil-global-set-key 'visual "H" 'sp-backward-sexp)

I know it’s a weird mix of smartparens and built-in Emacs commands. I don’t like the SPC k transient state for navigation, though I can’t articulate why.

4 Likes

One more tweak. I never really understood how the system clipboard interacts with Vim’s y or p operations, never mind Emacs’s kill-ring. simpleclip simplifies things, by allowing you to copy/paste/cut using Cmd-C/V/X (Super on Linux), like most other editors. With simpclip, the kill ring isn’t by touched by operations involving the system clipboard — both clipboards are kept separate.

   dotspacemacs-additional-packages '(simpleclip)

 ; ... in dotspacemacs/user-config

  (require 'simpleclip)
  (simpleclip-mode 1)

(spacemacs/set-leader-keys "ocv" 'comment-region)

Assume the point is on a paren. v % will highlight the form you want to comment. Then in command mode you can use this binding (eg fd SPC ocv) to comment that form without needing to manually manage any enclosing forms.

2 Likes

Cool, this work really well with SPC v (expand-region)

Here’s a tweak I’d like to make, but I’m not sure what the right way is.

In lisp-mode (SPC k .) comman isn’t being used, I’d like to bind it to the major mode leader, as in normal mode, so that I can e.g. evaluate a form without having to switch modes.

Anyone know how you would do that? I guess it’s using evil-global-set-key as @pesterhazy demonstrated, but how do I figure out which keymap , is bound to? describe-key doesn’t really help since it’s a prefix key.

Does anyone have a shortcut which sends a (reset) expression to the repl.

I’m currently using integrant.repl and every time I make a change I have to switch to the REPL and type (reset) to reload the system. It would be nice if I had a keyboard shortcut to do that.

I don’t remember where I first saw this tip, but as a simple way to globally redefine keys, create a custom minor-mode with its own keymap.

For example, I like to have <esc> remapped to <ctrl-s> everywhere. I tried to do this before by picking out each keymap and adding the new binding, but even after something like 10 custom keymap bindings, there was always still more that were missing (there was always one of the company-mode maps I couldn’t seem to figure out).

This custom minor-mode hack fixed all of them in less lines, and is (or should be) guaranteed to work for whatever new keymaps any new layers bring along (and also makes sure that <ctrl-h> sends a backspace, as is right and proper):

  (defvar custom-keys-minor-mode-map
    (let ((map (make-sparse-keymap)))
      (define-key map (kbd "C-s") (kbd "<escape>"))
      (define-key map (kbd "C-h") (kbd "DEL"))
      map)
    "Minor mode for custom keymap.")

  (define-minor-mode custom-keys-minor-mode
    "A minor mode to allow for global keymap overrides."
    :init-value t
    :lighter nil)

  (custom-keys-minor-mode 1)

I think it’s SPC m s x (or the more succinct , s x)

, s x is for CIDER refresh.

I need a (reset) command for Integrant/Component.

You can hook into that, add a .dir-locals file at the root of your project, which looks like this

((nil . ((cider-refresh-before-fn . "user/suspend!")
         (cider-refresh-after-fn  . "user/resume!")
         )))

The exact stop/start or suspend/resume functions depend on your setup. If you’re using Component with reloaded.repl then use reloaded.repl/suspend and reloaded.repl/resume. For integrant you might have to define your own wrappers in user.clj.

3 Likes
((nil . ((cider-refresh-before-fn . "integrant.repl/suspend")
         (cider-refresh-after-fn  . "integrant.repl/resume"))))

Just playing around with Duct and found this in the template.