Skip to content

Use the w, e, b motions like a spider. Move by subwords and skip insignificant punctuation.

License

Notifications You must be signed in to change notification settings

filipgodlewski/nvim-spider

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

nvim-spider 🕷️🕸️

Use the w, e, b motions like a spider. Move by subwords and skip insignificant punctuation.

A lua implementation of CamelCaseMotion, with extra consideration of punctuation. Works in normal, visual, and operator-pending mode. Supports counts and dot-repeat.

Features

The w, e, b (and ge) motions work the same as the default ones by vim, except for two differences:

Subword Motion

The movements happen by subwords, meaning it stops at the sub-parts of a camelCase, SCREAMING_SNAKE_CASE, or kebab-case variable.

-- positions vim's `w` will move to
local myVariableName = FOO_BAR_BAZ
--    ^              ^ ^

-- positions spider's `w` will move to
local myVariableName = FOO_BAR_BAZ
--    ^ ^       ^    ^ ^   ^   ^

Skipping Insignificant Punctuation

A sequence of one or more punctuation characters is considered significant if it is surrounded by whitespace and does not include any non-punctuation characters.

foo == bar .. "baz"
--  ^      ^    significant punctuation

foo:find("a")
-- ^    ^  ^  insignificant punctuation

This speeds up the movement across the line by reducing the number of mostly unnecessary stops.

-- positions vim's `w` will move to
if foo:find("%d") and foo == bar then print("[foo] has" .. bar) end
-- ^  ^^   ^  ^^  ^   ^   ^  ^   ^    ^    ^  ^  ^ ^  ^ ^  ^  ^ ^  -> 21

-- positions spider's `w` will move to
if foo:find("%d") and foo == bar then print("[foo] has" .. bar) end
-- ^   ^      ^   ^   ^   ^  ^   ^    ^       ^    ^    ^  ^    ^  -> 14

If you prefer to use this plugin only for subword motion, you can disable this feature by setting skipInsignificantPunctuation = false in the .setup() call.

Note
This plugin ignores vim's iskeyword option.

Installation

-- packer
use { "chrisgrieser/nvim-spider" }

-- lazy.nvim
{
	"chrisgrieser/nvim-spider",
	keys = {
		{ -- example for lazy-loading and keymap
			"e",
			"<cmd>lua require('spider').motion('e')<CR>",
			mode = { "n", "o", "x" },
		},
	},
},

No keybindings are created by default. Below are the mappings to replace the default w, e, and b motions with this plugin's version of them.

vim.keymap.set(
	{ "n", "o", "x" },
	"w",
	"<cmd>lua require('spider').motion('w')<CR>",
	{ desc = "Spider-w" }
)
vim.keymap.set(
	{ "n", "o", "x" },
	"e",
	"<cmd>lua require('spider').motion('e')<CR>",
	{ desc = "Spider-e" }
)
vim.keymap.set(
	{ "n", "o", "x" },
	"b",
	"<cmd>lua require('spider').motion('b')<CR>",
	{ desc = "Spider-b" }
)

Note
For dot-repeat to work, you have to call the motions as Ex-commands. When calling function() require("spider").motion("w") end as third argument of the keymap, dot-repeatability will not work.

Configuration

The .setup() call is optional. Currently, its only option is to disable the skipping of insignificant punctuation:

-- default values
require("spider").setup {
	skipInsignificantPunctuation = true,
	subwordMovement = true,
}

You can also pass this configuration table to the motion function:

require("spider").motion("w", { skipInsignificantPunctuation = false })

Any options passed here will be used, and any options not passed will use the default configuration (from setup() or the default configuration).

Notes on Operator-pending Mode

In operator pending mode, vim's web motions are actually a bit inconsistent. For instance, cw will change to the end of a word instead of the start of the next word, like dw does. This is probably done for convenience in vi's early days before there were text objects. In my view, this is quite problematic since it makes people habitualize inconsistent motion behavior.

In this plugin, such small inconsistencies are therefore deliberately not implemented. Apart from the inconsistency, such a behavior can create unexpected results when used in subwords or near punctuation. If you absolutely want to, you can map cw to ce though. (Remember to add remap = true as option for the keymap.)

Subword Text Object

This plugin supports w, e, and b in operator-pending mode, but does not include a subword variant of iw. For a version of iw that considers camelCase, check out the subword text object of nvim-various-textobjs.

Credits

Thanks
To @vypxl and @ii14 for figuring out dot-repeatability.

About Me
In my day job, I am a sociologist studying the social mechanisms underlying the digital economy. For my PhD project, I investigate the governance of the app economy and how software ecosystems manage the tension between innovation and compatibility. If you are interested in this subject, feel free to get in touch.

Blog
I also occasionally blog about vim: Nano Tips for Vim

Profiles

Buy Me a Coffee at ko-fi.com

About

Use the w, e, b motions like a spider. Move by subwords and skip insignificant punctuation.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Lua 100.0%