SmartMotion.nvim Week 2 – Crafting Motions, Recipes, and Experimental Inference #48
FluxxField
announced in
Announcements
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Hello everyone!
This is going to be my first update/discussion here on Github. I am planning on trying to do updates every week or so as the plugin grows. Especially right now in these early stages of development
Due to popular demand, I’m going to dive into how you craft your own motions using SmartMotion.nvim. I’ll walk you through how a motion is built, how each part fits together, and how simple changes can radically alter behavior.
We’ve also got a ton of new features to cover:
modifiers
are now part of the motion pipelinemotion_state
has been expanded with new fields for controlling flow and behaviorpipeline_wrapper
is gone — replaced by a clean and powerful main loop🧱 Anatomy of a Motion
Every SmartMotion motion is made up of 5–6 parts:
Each of these is pluggable, so you can mix and match for powerful custom behavior.
🧪 A Simple Example: Jump to Word After Cursor
Let’s say we want to recreate
w
— jump to the start of the next word.Want to jump to words before the cursor? Just change the filter:
Want the hint label to appear at the end of each word? Just change the visualizer:
Don't want centered jumps?
Same motion, totally different UX — and no new code required.
🛠 Recreating Hop, Leap, and Sneak
Here’s where it gets exciting. You can build versions of other popular motion plugins:
Hop-style 2-character search
Sneak-style f/t motions
Flash-style live search
🧠 What is
motion_state
?motion_state
is the shared state object passed between modules. It holds key data for:Core Fields
Target Tracking
Hint Labeling
Label Logic
Selection Mode
Motion-Specific Fields
These vary based on the extractor/filter:
Use
motion_state
to pass state between parts of your motion — whether it’s how many characters to search, whether to show prefixes, or something custom to your plugin.🚪 Exit Types
Motions exit in different ways. SmartMotion supports the following:
✨ What Is a Target?
Targets are the core data unit of SmartMotion:
Every module works with these. In the future I plan to add more metadata like the motion that created this target. Allowing for powerful repeats and more with a SmartMotion history that is in the works!
🧩 Modifiers – Add Metadata, Don't Filter
Modifiers don’t change what targets exist — they just add info.
Example:
distance_metadata
addssort_weight
so the closest targets can be prioritized visually or logically.You can write your own modifier to add weights, context, types, etc.
🔁 Coroutines for Modules
All modules (collector, extractor, modifier, filter) are coroutines. Why?
But don’t worry — you can use the provided
module_wrapper
to abstract this away. Just write a simplerun()
function that yields targets or returns a string exit type.Below is an example of the
filter_visible
filter. It uses the module_wrapper under the hood. This way things are simple and you only need to write a simple function.But! What if you need to return more than one target from the data you get? Let's say you recived a line and want to return words from it? Module wrapper can handle this as well. Just a little more complicated. The example below recieves one line at a time and yield multiple words
🧱 Registering Your Own Modules
SmartMotion is built for plugin interop. Other plugins can register modules:
You can then build motions using your modules, or expose them to users.
🔮 Experimental: Inference
This is still very early — but the goal is:
Example: Press
d
, this triggers smart-motion. It waits for your next key press. Lets say itsw
. It checks to see if there is an extractor mapped tow
. There is! Its theword
extractor. Now SmartMotion has everything it needs to do what you were thinking.d
tells us the action, which isdelete
, andw
tells us the extractor which isword
.This means, with things like "l" for a line extractor,
f
/t
for a text_search extractor you only need to map SmartMotion to things liked
,y
, andc
and you magically havedt
,yf
,cl
,dw
and more! All with 3 mappingsWe’re just starting to prototype this, and feedback is welcome!
💬 Wrap-up
That’s it for Week 2!
If you’ve built a cool motion or have ideas for new modules, drop them in the comments! If you want to try inference, it’s opt-in — but available to test.
Thanks again for all the support and ideas. More to come in Week 3!
Beta Was this translation helpful? Give feedback.
All reactions