Skip to content

ashok-khanna/ParEvil

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

46 Commits
 
 
 
 
 
 
 
 

Repository files navigation

ParEvil

An experimental set of keybindings to integrate ParEdit into Evil Mode. The general concept IMO is good (a separate 'Paredit State'), the keybindings however are personal preference and I am constantly tweaking them myself. No perfect solution, but see what works best for you and customise to your hearts content :-)

Last Updated: 8 October 2021

ParEdit1 is one of the oldest and most famous structural editing tools for the Lisp-family of languages, and one that I felt most comfortable with (whether it be its classic design or simply muscle memory). It is perfectly viable for use in Evil Mode, particularly with the assistance of Evil Paredit2 to avoid accidental breakage of parentheses parity.

However, key sequences without modifiers feel much more natural in VIM / Evil Mode, and my aim has been to find a set of keybindings that will allow for a more natural integration of ParEdit with Evil Mode. Indeed, whilst there are many other excellent packages which aim to do this (see Lispy3, Lispyville4, Smartparens5, Evil Cleverparens6, Symex7, and more8), it wouldn't be Emacs if we didn't reinvent the wheel and end up writing our own keybinds.

Thus, herein, is my current approach to structural editing within Evil Mode. You can download and load parevil.el into your Emacs configuration and feel free to send through any comments & suggestions.

;; Add the below to your .emacs to use ParEvil and then evaluate it
;; Don't forget to save your .emacs!

(load "/path-to-parevil/parevil.el)

ParEvil Summary

Modifying the standard bindings of VIM would be a foolish endeavour, and we will not do so as a starting principle. Rather, we create a new mode (Paredit State) as follows, which we can toggle from and to Normal Mode by pressing spacebar. Note that we only bind spacebar within Normal mode for lisp-related major modes, so you are free to bind spacebar to something else for other major modes. As a starting point, our new mode inherits all of the keybindings from Normal mode. We then introduce the following bindings specific for common ParEdit commands. Any ParEdit command not listed below can be accessed by its default keybinding.

Key Function in Paredit State Key Function in Paredit State
f paredit-forward sp paredit-backward-slurp-sexp
b paredit-backward sb paredit-forward-slurp-sexp
n paredit-forward-down { paredit-backward-barf-sexp
w paredit-backward-up } paredit-forward-barf-sexp
q beginning-of-defun gr paredit-raise-sexp
gn paredit-forward-up gl paredit-splice-sexp
gp paredit-backward-down gw paredit-wrap-round
gh paredit-recenter-on-sexp ge indent-region
t transpose-sexps T transpose-sexps -1
p Custom Paste se mark-sexp (i.e. select sexp)
sd Custom Sexp Cut sy Custom Sexp Copy
gs Custom Multi Cut gy Custom Multi Copy

Note that the some of the above commands accept numeric prefix arguments. For example, we can move 4 sexps forward with 4f.

Note on Uncommon Features

One command not found directly in ParEdit is transpose-sexps9 which we add with the following. The trick to transposing is to have your cursor right after an sexp that you wish to transpose with the one before or after it.

;; Accepts numeric prefix argument

(define-key evil-paredit-state-map "t" 'transpose-sexps)

;; For convenience, a reverse transpose can be achieved with T:

(define-key evil-paredit-state-map "T" (lambda () (interactive) (transpose-sexps -1)))

We also added the following new functions to cut / copy all expressions within a group (from point onwards). These hopefully should work okay, but let me know any unintended behaviour.

;; Cut all remaining expressions in a group

(define-key evil-normal-state-map "gs"
  (lambda ()
    (interactive)
    (let ((starting-point (point))
	  (ending-point nil))
      (save-excursion
	(paredit-backward-up)
	(evil-jump-item)
	(setq ending-point (point)))
      (kill-region starting-point ending-point))))

;; Copy all remaining expressions in a group

(define-key evil-normal-state-map "gy"
  (lambda ()
    (interactive)
    (let ((starting-point (point))
	  (ending-point nil))
      (save-excursion
     	(paredit-backward-up)
	(evil-jump-item)
	(setq ending-point (point)))
      (kill-ring-save starting-point ending-point))))

Footnotes

  1. Main Website: http://mumble.net/~campbell/emacs/paredit.el. Quick Reference: http://mumble.net/~campbell/emacs/paredit.html

  2. GitHub Repo: https://github.com/roman/evil-paredit

  3. GitHub Repo: https://github.com/abo-abo/lispy

  4. GitHub Repo: https://github.com/noctuid/lispyville

  5. GitHub Repo: https://github.com/Fuco1/smartparens

  6. GitHub Repo: https://github.com/luxbock/evil-cleverparens

  7. GitHub Repo: https://github.com/countvajhula/symex.el

  8. Let me know if you have a package you want to list here

  9. Reference: https://www.gnu.org/software/emacs/manual/html_node/emacs/Expressions.html

About

An experimental set of keybindings to integrate ParEdit into Evil Mode

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published