smart-motion.nvim icon indicating copy to clipboard operation
smart-motion.nvim copied to clipboard

Composable motion framework for Neovim. Build custom motions from modular parts, chain them seamlessly with flow state, and create your own navigation systems.

SmartMotion.nvim - Home-row powered smart motions for Neovim

   _____                      __  __  ___      __  _                          _
  / ___/____ ___  ____ ______/ /_/  |/  /___  / /_(_)___  ____    ____ _   __(_)___ ___
  \__ \/ __ `__ \/ __ `/ ___/ __/ /|_/ / __ \/ __/ / __ \/ __ \  / __ \ | / / / __ `__ \
 ___/ / / / / / / /_/ / /  / /_/ /  / / /_/ / /_/ / /_/ / / / / / / / / |/ / / / / / / /
/____/_/ /_/ /_/\__,_/_/   \__/__/  /_/\____/\__/_/\____/_/ /_(_)__/ /_/|___/_/_/ /_/ /_/

🚀 What is SmartMotion?

SmartMotion.nvim is a next-generation motion engine for Neovim, unifying the fragmented ecosystem of motion plugins with one modular, extensible system.

Think of it as a foundation that can replicate:

  • hop.nvim-style line jumps ✅
  • leap.nvim-style double-char targeting ✅
  • flash.nvim-style overlays ✅
  • Visual dt/ct motions with feedback ✅

With SmartMotion, you build exactly what you need - using composable modules, zero assumptions, and full control.

For deep dives into modules, flow state, action merging, or highlight customization, see the docs folder.

[!WARNING]

Early Stage Warning: This plugin is under active development. Breaking changes are expected as it matures.


demo gif


Configuration

SmartMotion comes with no default mappings -- everything is opt-in. Here's a quick-start example with presets and highlight customization:

return {
  "FluxxField/smart-motion.nvim",
  opts = {
    keys = "fjdksleirughtynm",
    highlight = {
      hint = { fg = "#FF2FD0" },
      two_char_hint = { fg = "#2FD0FF" },
      dim = "Comment",
    },
    presets = {
      words = true,
      search = true,
      delete = true,
    },
    flow_state_timeout_ms = 300,
    disable_dim_background = false,
    history_max_size = 20,
  },
}

To disable certain presets:

presets = {
  words = { "w", "b" }, -- disables "w" and "b" word motions
}

Default values:

M.defaults = {
  keys = "fjdksleirughtynm",
  highlight = {
    hint = "SmartMotionHint",
    hint_dim = "SmartMotionHintDim",
    two_char_hint = "SmartMotionTwoCharHint",
    two_char_hint_dim = "SmartMotionTwoCharHintDim",
    dim = "SmartMotionDim",
    search_prefix = "SmartMotionSearchPrefix",
    search_prefix_dim = "SmartMotionSearchPrefixDim",
  },
  presets = {},
  flow_state_timeout_ms = 300,
  disable_dim_background = false,
  history_max_size = 20,
}

[!NOTE] 📖 For a complete list of presets and highlight keys, see presets.md and advanced.md


🌊 Flow State: Smarter Navigation

SmartMotion introduces Flow State, enabling native-feeling chains of motion without repeated hinting.

Press w, see labels press w again quickly jump immediately. You're in flow.

Pressing another motion like b during flow seamlessly switches motion types.

[!NOTE] 📖 Learn more in the advanced usage guide


💡 Highlight Customization

Every part of the label system can be styled.

Whether you want high-contrast backgrounds, colors that match your theme, or to pull from existing highlight groups - it's all supported.

highlight = {
  hint = { fg = "#FF2FD0" },
  two_char_hint = { fg = "#2FD0FF" },
  dim = "Comment",
}

Supports both string references and highlight tables.

You can also use the toggle use_background_highlights to change between character and background hints

opts = {
  use_background_highlights = true,
}

[!NOTE] 📖 See full customization options in advanced.md → Highlight Customization


Modular System

Each motion is built from pluggable pieces:

  • Collectors (e.g., lines, buffers)
  • Extractors (e.g., words, chars)
  • Filters (e.g., visible only, directional)
  • Visualizers (e.g., hints, overlays)
  • Actions (e.g., jump, yank, delete, or merged)
  • Wrappers (e.g., live search or text input modes)

You can even inject targets manually or build entire pipelines from scratch.

[!NOTE] 📖 Read about custom wrappers, module contribution, and action merging in advanced.md


🎯 Presets

Presets let you quickly enable SmartMotion behaviors like word navigation, search, or delete:

presets = {
  words = true,
  search = true,
  delete = true,
}

[!NOTE] 📖 See all available presets and options in presets.md


🔬 What a Basic Motion Looks Like

w = {
  pipeline = {
    collector = "lines",
    extractor = "words",
    visualizer = "hint_start",
    filter = "default",
  },
  action = "jump",
  modes = { "n", "v" },
}

You can define your own motions with full control. Even combine actions like jump + yank with:

action = merge({ "jump", "yank" })

🙏 Acknowledgments

This plugin is only made possible by standing on the shoulders of giants. Inspiration and foundational ideas come from the incredible projects like:

The original concepts are all theirs - my hope is to bring their brilliant ideas together into one cohesive, extensible system.


📜 License

Licensed under GPL-3.0.


👤 Author

Built by FluxxField Business inquiries: [email protected]

[!IMPORTANT] ✨ Also builds premium websites: SLP Custom Built, Cornerstone Homes


For full documentation, visit the docs/ directory. Includes guides for:

  • Configuration
  • Preset Setup
  • Custom Motions
  • Advanced Usage Highly recommended!