Skip to content

Minor mode to integrate Lispy and Evil

Notifications You must be signed in to change notification settings

ethan-leba/yaelispy

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Table of Contents

YAE-Lispy is Yet-Another-Evil Lispy variant that aims to make Lispy familiar and intuitive to the Vim user while retaining the full power of Lispy's structural editing capabilities.

YAE-Lispy differs from it's peers (see lispyville and sp3ctum/evil-lispy) in the following goals:

1. Vimify Lispy as much as possible.

YAE-Lispy leverages the Vimmer's muscle memory and minimizes the need to learn/use Emacs binding with lispy, and thus provides a complete overhaul of Lispy's keybindings. The keybindings are closely aligned to Vim's Visual state, while differing where sensible. In addition to rebinding keys to more familiar positions, YAE-Lispy includes some primitive operators to the keymapping that vanilla Lispy intended to be accessed via. the Emacs bindings.

2. Make Lispy the primary state.

In contrast to other evil-flavored lispy variants, which provide support for a hybrid Lispy/Normal state approach, dipping into the featureset of Lispy while remaining in the comfort of Normal state. YAE-Lispy opts for a different approach, intending for users to primarily use Lispy state while allowing for transient forays into Normal state.

The key n will drop the user into Normal state, and will be sent back to Lispy state under the following conditions:

  1. An edit is made to the buffer in normal mode.
  2. Insert mode is exited.

The main intended usecase is to modify single symbols. The YAE-Lisper can perform a quick operation on a symbol, and get dropped right back into the Lispy state on completion.

3. Make insertion vs. structure editing explicit.

YAE-Lispy uses the Vimmer's familiar Insert state instead of implicitly dispatching based on point location, as vanilla Lispy and evil-lispy does. One large benefit to this is that the SPC key is now freed to operate as a leader key. (*cough* doom/spacemacs *cough*) Insert mode is entered with i (unsurprisingly).

4. No knowledge of vanilla Lispy required.

Lispy is an incredibly powerful tool, but along with it's power comes great complexity -- the following sections serve to give a short and sweet overview of Lispy's capabilities from the context of YAE-Lispy's modifications that users with no experience with Lispy/Paredit/Structural Editing can hit the ground running with.

A quick recap on structural editing for the uninitiated

While most text editors operate on a character level, in Lispy state we operate via the tree structure of the program itself, which conveniently maps to the sexp structure.

For example, consider the venerable append function.

(defun append (x y)
  (cond
   ((not x) y)
   (t (cons (car x) (append (cdr x) y)))))

Here is the same function represented as a tree, where s marks a node on the tree.

   ┌─────┬───s───┬────────────┐
   │     │       │            │
   │     │     ┌─s─┐    ┌─────s─────────────┐
   ▼     ▼     │   │    ▼     │             │
defun append   │   │   cond   │             │
               │   │          │     ┌───────s────────────────┐
               ▼   ▼          │     ▼       │                │
               x   y          │    cons     │                │
                          ┌───s───┐     ┌───s───┐      ┌─────s─────┐
                          │       │     │       │      │     │     │
                          │       ▼     ▼       ▼      ▼     │     ▼
                          │       y    car      x    append  │     y
                       ┌──s──┐                           ┌───s───┐
                       │     │                           │       │
                       │     │                           │       │
                       ▼     ▼                           ▼       ▼
                      not    x                          cdr      x

We can see that leaves correspond to symbols, while the nodes correspond to lists.

Terminology

  • Parent: The node above the current.
  • Sibling:

Keybindings

First off, here are the keybindings in YAE-Lispy that map very closely to Vim's bindings.

key description demonstration
h move to the previous list.
k move to the previous list inside the current, if it exists.
j move to the next list at the current level.
f move to the next list.
d delete the current list (and then jump to the next list).
c delete the current list (and then enter insert mode).
p paste before the current list.
y yank the list at point.
u undo.
i enter insert mode.
a enter insert mode.

FOO

key command
h lispy-backward

Reversible commands

A lot of Lispy commands come in pairs - one reverses the other:

key command key command
j lispy-down k lispy-up
s lispy-move-down w lispy-move-up
> lispy-slurp < lispy-barf
c lispy-clone C-d or DEL
C lispy-convolute C reverses itself
d lispy-different d reverses itself
M-j lispy-split + lispy-join
O lispy-oneline M lispy-multiline
S lispy-stringify C-u " lispy-quotes
; lispy-comment C-u ; lispy-comment
xi lispy-to-ifs xc lispy-to-cond
x> lispy-toggle-thread-last x> reverses itself

Keys that modify whitespace

These commands handle whitespace in addition to inserting the expected thing.

key command
SPC lispy-space
: lispy-colon
^ lispy-hat
C-m lispy-newline-and-indent

Command chaining

Most special commands will leave the point special after they're done. This allows to chain them as well as apply them continuously by holding the key. Some useful hold-able keys are jkf<>cws;. Not so useful, but fun is /: start it from |( position and hold until all your Lisp code is turned into Python :).

Navigating with avy-related commands

key command
q lispy-ace-paren
Q lispy-ace-char
a lispy-ace-symbol
H lispy-ace-symbol-replace
- lispy-ace-subword

q - lispy-ace-paren jumps to a "(" character within current top-level form (e.g. defun). It's much faster than typing in the avy binding + selecting "(", and there's less candidates, since they're limited to the current top-level form.

a - lispy-ace-symbol will let you select which symbol to mark within current form. This can be followed up with e.g. eval, describe, follow, raise etc. Or you can simply m to deactivate the mark and edit from there.

- - lispy-ace-subword is a niche command for a neat combo. Start with:

(buffer-substring-no-properties
 (region-beginning)|)

Type c, -, b and C-d to get:

(buffer-substring-no-properties
 (region-beginning)
 (region-|))

Fill end to finish the statement.

Operating on regions

Sometimes the expression that you want to operate on isn't bounded by parens. In that case you can mark it with a region and operate on that.

Ways to activate region

While in special:

  • Mark a sexp with m - lispy-mark-list
  • Mark a symbol within sexp a - lispy-ace-symbol.

While not in special:

  • C-SPC - set-mark-command
  • mark a symbol at point with M-m - lispy-mark-symbol
  • mark containing expression (list or string or comment) with C-M-, - lispy-mark

Move region around

The arrow keys j/k will move the region up/down within the current list. The actual code will not be changed.

Switch to the other side of the region

Use d - lispy-different to switch between different sides of the region. The side is important since the grow/shrink operations apply to current side of the region.

Grow/shrink region

Use a combination of:

  • > - lispy-slurp - extend by one sexp from the current side. Use digit argument to extend by several sexps.
  • < - lispy-barf - shrink by one sexp from the current side. Use digit argument to shrink by several sexps.

The other two arrow keys will mark the parent list of the current region:

  • h - lispy-left - mark the parent list with the point on the left
  • l - lispy-right - mark the parent list with the point on the right

To do the reverse of the previous operation, i.e. to mark the first child of marked list, use i - lispy-tab.

Commands that operate on region

  • m - lispy-mark-list - deactivate region
  • c - lispy-clone - clone region and keep it active
  • s - lispy-move-down - move region one sexp down
  • w - lispy-move-up - move region one sexp up
  • u - lispy-undo - deactivate region and undo
  • t - lispy-teleport - move region inside the sexp you select with lispy-ace-paren
  • C - lispy-convolute - exchange the order of application of two sexps that contain region
  • n - lispy-new-copy - copy region as kill without deactivating the mark
  • P - lispy-paste - replace region with current kill

YAE-Lispy specific commands

yae-lispy-insert

Post command behavior

  1. Jump to closest left paren
  2. Enter insert mode
  3. Enter insert mode if point is not special

About

Minor mode to integrate Lispy and Evil

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Languages

  • Emacs Lisp 94.9%
  • Shell 5.1%