State of SmartMotion! The Big Update #131
Pinned
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.
State of SmartMotion - The Big Update
Hey everyone! It's been a while since the last update (the engine refactor back in July), and a lot has happened. This post covers everything that's been added, improved, and redesigned since then. SmartMotion has grown from a label-jumping plugin into a full motion framework, and I'm really excited to share where things stand.
If you're new here, check out the Quick Start to get up and running, or Why SmartMotion? for how it compares to flash, leap, hop, and others.
Motion-Based Inference
This is the single biggest change and the one that defines SmartMotion now.
Instead of registering explicit keymaps for every operator+motion combo (
dw,yw,cw,dj,yj,cj...), SmartMotion now uses inference. You enable one operator preset (likedelete) and it automatically composes with any composable motion.How it works:
d- SmartMotion waits for a motion keyw- SmartMotion looks up thewmotion, borrows its extractor/filter/collector11 composable motions (
w,b,e,j,k,s,S,f,F,t,T) x 5 operators (d,y,c,p,P) = 55+ compositions with zero explicit mappings.Unknown motion keys fall through to native Vim, so
d$,d0,dGall still work exactly as expected.Double-Tap Line Actions
dd,yy,ccare detected automatically. Double-tapping the operator key triggers the line variant of that action.Quick Action (Repeat Motion Key)
Press the motion key again to select the target under your cursor.
dww= delete word under cursor. Works for any single-char composable motion:yww,cww,djj, etc.Multi-Character Motion Resolution
SmartMotion handles ambiguous multi-char sequences intelligently.
dfcould be "delete + find-char" or "delete + function-name (fn)". It polls input with a timeout (respectsvim.o.timeoutlen) and resolves based on what you type next.df+ pause = find-char.dfntyped quickly = function name.Treesitter Text Objects
SmartMotion now provides pipeline-powered treesitter text objects that work with any Vim operator:
af/ifac/icaa/iafnThese work in visual and operator-pending mode, so
daf,caa,yic,gqaf,=if,>acall just work. No special registration needed. The inference system handlesdafby readinga(not composable), falling through to Vim's operator-pending mode, which triggers theaftext object.aaincludes trailing separators (commas),iadoesn't.ifandictrim{/}delimiters, giving you just the body content.f/F/t/T Motions +
;/,RepeatFull replacements for Vim's built-in character motions:
f/F- 2-character find (inclusive), with labels on all matchest/T- 2-character till (exclusive), cursor stops before/after target;- Repeat last char motion in same direction,- Repeat last char motion in reverse directionAll line-constrained by default.
;and,show labels on matches for quick re-selection. Character state persists across the session.Search Enhancements
Live Search (
s)Type to search, labels appear incrementally on matches. No need to finish typing, just hit a label at any time. Multi-window support. Label conflict avoidance ensures labels don't collide with characters you might type next.
Fuzzy Search (
S)FZY-based fuzzy matching with scoring: consecutive matches, word boundaries, and camelCase transitions all score higher. Respects
ignorecase/smartcase. Results sorted by score.Native Search Enhancement (
/,?)Vim's built-in
/and?now show SmartMotion labels on matches as you type. Toggle with<C-s>. When you press Enter, labels remain and you can jump to any match instantly.Operator-Pending Mode
All composable motions now work in operator-pending mode. This means native Vim operators compose with SmartMotion:
gqw- format to word target=]]- auto-indent to next function>j- indent to line targetgUw- uppercase to word targetExclusive motion semantics are handled correctly.
dwstops before the target (like native Vim), whiledeincludes the end of the word.Multi-Window Jumping
Search (
s,S), treesitter navigation (]],[[,]c,[c,]b,[b), diagnostics, git hunks, quickfix entries, and marks all search across all visible windows. Current window gets label priority. Disabled automatically in operator-pending mode since operators shouldn't cross window boundaries.New Collectors
Git Hunks (
]g/[g)Jump to git changed regions. Uses gitsigns.nvim API when available, falls back to
git diff. Hunk metadata includes type (add/delete/change).Quickfix & Location List (
]q/[q/]l/[l)Jump to quickfix or location list entries with labels. Multi-window support.
Marks (
g'/gm)g'shows labels on all buffer marks for quick jumping.gmuses dual selection to set a mark at any visible target.Scope / Block Navigation (
]b/[b)Treesitter-powered jump to control flow boundaries like
if,while,for,try,switch, closures, and more.Treesitter Power Features
Treesitter Search (
R)Search for text, then select the surrounding treesitter node. Works in normal, visual, and operator-pending modes. In operator-pending mode, the operator applies to the full node range. Great for "delete the function containing this text" workflows.
Treesitter Incremental Select (
gS)Start at the smallest named treesitter node at your cursor. Press
;to expand to parent node,,to shrink to child. Shows the node type and position ([3/7]) as you navigate the tree. Enter confirms the selection.Argument Swap (
saa)Select two arguments in a function call and they swap positions. Uses a dual-selection picker and treesitter to understand argument boundaries.
History System
History Browser (
g.)A floating window showing your motion history, organized by frecency (frequency x recency). Features:
/to filter by text, filename, or motion keyd/y/cthen a label to delete/yank/change at that target remotelyj/kto browse, contextual help bar at the bottomPins (
gp)Toggle a pin at your cursor position. Max 9 numbered pins plus 26 global (A-Z) pins. Jump directly with
g1-g9orgA-gZ. Set pins at specific slots withgp1-gp9orgPA-gPZ.Frecency & Persistence
History entries are scored by
visit_count x time_decay. Recent, frequently-visited targets bubble to the top. Everything saves to disk and merges intelligently across sessions.Multi-Cursor Operations
Multi-Delete (
gmd)Toggle-based selection. Press labels to mark targets (highlighted in green), press Enter to delete them all. Targets are processed in reverse order for safe sequential deletion.
Multi-Yank (
gmy)Same toggle interface. Enter yanks all selected targets, newline-separated, into the
"register.Visual Range Select (
gs)Dual-selection picker for creating visual selections. Pick a start target, then an end target, and SmartMotion enters visual mode spanning the range. Works across visible windows.
Quickfix & Telescope Integration
Populate quickfix or open Telescope with SmartMotion targets:
gQf/gTfgQd/gTdgQe/gTegQg/gTgFlow State
After selecting a target, if you press another motion key within 300ms (configurable), SmartMotion instantly jumps with no labels. Chain motions naturally:
wthenjthenbthenw, all flowing without relabeling.Remote Operations
Delete or yank without moving your cursor:
rdwrdlrywrylSelection Keys
Configurable keys for target selection beyond labels:
<CR>selects the first (topmost) target (default)<C-j>/<C-k>for next / previous target<M-h>toggles hint position (start vs end of target)By the Numbers
What's Next
SmartMotion has come a long way from the "very alpha" days. The architecture is stable, the inference system makes composition feel natural, and the treesitter integration goes deeper than any other motion plugin I know of.
A few things on the horizon:
If you've been using SmartMotion, I'd love to hear what's working, what's not, and what you want to see next. Drop a comment below or open a discussion!
All reactions