Home

Awesome

leap-spooky.nvim 👻

Spooky is a Leap extension that allows for remote operations on Vim's native text objects: that is, it exposes atomic bundles of (virtual or actual) leaping motions and text object selections.

showcase

AFAIK, the basic idea first appeared in vim-seek, one of vim-sneak's predecessors. (The feature is coincidentally called "leaping motions" there, no kidding.)

It's not just the number of keystrokes that matter here, but the potentially more intuitive workflow achieved through these higher abstractions, that are nevertheless obvious extensions of Vim's grammar. As usual, the aim is to sharpen the saw; there are no big list of new commands to learn, except for two affixes that can be added to all existing text objects. carb[leap] ("change around remote block [marked by leap motion]") in no time will be just as natural as targets.vim's canb ("change around next block").

Usage

Leap is automatically invoked once the text object is specified; after e.g. yarw, start typing the 2-character search pattern, and select the target as you would usually do. The difference is that instead of jumping there, the word will be yanked.

What are some fun things you can do with this?

Status

WIP - everything is experimental at the moment.

Requirements

Setup

setup creates all the necessary mappings - you can call it without arguments, if the defaults are okay:

require('leap-spooky').setup {
  -- Additional text objects, to be merged with the default ones.
  -- E.g.: {'iq', 'aq'}
  extra_text_objects = nil,
  -- Mappings will be generated corresponding to all native text objects,
  -- like: (ir|ar|iR|aR|im|am|iM|aM){obj}.
  -- Special line objects will also be added, by repeating the affixes.
  -- E.g. `yrr<leap>` and `ymm<leap>` will yank a line in the current
  -- window.
  affixes = {
    -- The cursor moves to the targeted object, and stays there.
    magnetic = { window = 'm', cross_window = 'M' },
    -- The operation is executed seemingly remotely (the cursor boomerangs
    -- back afterwards).
    remote = { window = 'r', cross_window = 'R' },
  },
  -- Defines text objects like `riw`, `raw`, etc., instead of
  -- targets.vim-style `irw`, `arw`. (Note: prefix is forced if a custom
  -- text object does not start with "a" or "i".)
  prefix = false,
  -- The yanked text will automatically be pasted at the cursor position
  -- if the unnamed register is in use.
  paste_on_remote_yank = false,
}

Customisation

Note: This is absolutely not stable API, just a current snapshot for people who would like to experiment.

spooky_action returns a one-argument function that can be used as leap's action parameter. That is, you have to call it when used in a mapping.

The signature looks like: spooky_action(select_cmd, {opts})

Example:

require('leap').leap {
  target_windows = { vim.fn.win_getid() }
  action = require('leap-spooky').spooky_action(
    function () return "viw" end,
    { keeppos = true, on_exit = (vim.v.operator == 'y') and 'p', },
  ),
}

You can also check the source code for ideas, or if something is unclear.

Planned features