Like a padawan growing into a Jedi, sharpen your Vim skills with gentle, contextual guidance. padawan.nvim never blocks or modifies your input — it observes and advises.
- Arrow key detection — Suggests
hjkl when arrow keys are used
- Repeat detection — Detects
hjkl/w/b spam and suggests smarter motions (w, f{char}, }, Ctrl+d, etc.)
- Insert mode hints — Catches patterns like
0i (use I), $a (use A), A<CR> (use o)
- Operator shortcuts — Detects verbose combos like
d$ (use D), xi (use s), dwi (use cw)
- Visual mode guidance — Suggests direct operator+motion instead of visual selection
- Ctrl-C warning — Suggests
<Esc> over <C-c> to preserve autocommands
- Search awareness — Detects
j/k after / search and suggests n/N
- Line boundary hints — Suggests
0/^/$ when repeating h/l near line edges
- Rate-limited messages — No spam, same suggestion won't repeat within a cooldown window
{
"otsukatsuka/padawan.nvim",
event = "VeryLazy",
opts = {},
}
packer.nvim
use {
"otsukatsuka/padawan.nvim",
config = function()
require("padawan").setup()
end,
}
All options are optional. Shown below are the defaults:
require("padawan").setup({
enabled = true, -- Enable/disable the plugin
repeat_threshold = 5, -- Number of consecutive presses before suggesting
message_style = "echo", -- "echo" (cmdline) or "notify" (nvim-notify compatible)
silent_modes = {}, -- Suppress messages in these modes, e.g. { "i" }
ignored_filetypes = { -- Skip detection in these filetypes
"TelescopePrompt", "lazy", "NvimTree", "neo-tree", "mason", "oil",
},
cooldown_ms = 1500, -- Reset repeat counter after this idle period (ms)
message_cooldown_ms = 3000, -- Minimum interval between same message (ms)
custom_messages = {}, -- Override built-in messages by ID (see below)
})
Override any built-in message by its ID:
require("padawan").setup({
custom_messages = {
arrow_left = "Use h!",
h_repeat = "Stop spamming h! Try w/b/f instead.",
},
})
Movement — Arrow Keys
| Detected |
Suggestion |
Message ID |
<Left> |
h |
arrow_left |
<Right> |
l |
arrow_right |
<Up> |
k |
arrow_up |
<Down> |
j |
arrow_down |
Movement — hjkl Repeat
Triggered when the same key is pressed consecutively beyond the threshold.
| Detected |
Suggestion |
Message ID |
h x N |
w b f t ^ 0 |
h_repeat |
l x N |
w e f t $ |
l_repeat |
j x N |
} Ctrl+d G / |
j_repeat |
k x N |
{ Ctrl+u gg ? |
k_repeat |
Movement — Line Boundary
When h/l repeat is detected near line edges:
| Detected |
Suggestion |
Message ID |
h near col 1 |
0 ^ |
h_near_start |
l near end |
$ |
l_near_end |
Movement — Word Repeat
| Detected |
Suggestion |
Message ID |
w x N |
f{char} t{char} |
w_repeat |
b x N |
F{char} T{char} |
b_repeat |
Insert Mode Patterns
| Detected |
Suggestion |
Message ID |
i then <Left> |
I a A o O |
i_left |
0i or ^i |
I |
line_start_insert |
$a |
A |
line_end_insert |
A<CR> |
o |
newline_below |
Search
| Detected |
Suggestion |
Message ID |
j/k after //? |
n N |
use_n_after_search |
Editing
| Detected |
Suggestion |
Message ID |
<C-c> |
<Esc> |
ctrl_c |
Editing — Operator Commands
| Detected |
Suggestion |
Message ID |
dd x N |
{count}dd (e.g. 3dd) |
dd_repeat |
yy x N |
{count}yy (e.g. 3yy) |
yy_repeat |
dw |
diw daw |
dw_suggest |
db |
diw daw |
db_suggest |
cw |
ciw caw |
cw_suggest |
cb |
ciw caw |
cb_suggest |
d$ |
D |
d_dollar_suggest |
c$ |
C |
c_dollar_suggest |
xi |
s |
xi_suggest |
dwi |
cw |
dw_insert_suggest |
dbi |
cb |
db_insert_suggest |
x x N |
dw diw d$ |
x_repeat |
X x N |
db diw |
shift_x_repeat |
s x N |
cw ciw cl |
s_repeat |
u x N |
{count}u :earlier |
u_repeat |
p x N |
{count}p |
p_repeat |
Visual Mode Patterns
| Detected |
Suggestion |
Message ID |
v + motion + d/y/c |
d{motion} y{motion} c{motion} |
visual_operator_suggest |
V + j/k + d/x |
{count}dd (e.g. 3dd) |
visual_line_delete |
V + j/k + y |
{count}yy (e.g. 3yy) |
visual_line_yank |
vu |
gu{motion} |
visual_case_lower_suggest |
vU |
gU{motion} |
visual_case_upper_suggest |
| Command |
Description |
:PadawanEnable |
Enable suggestions |
:PadawanDisable |
Disable suggestions |
:PadawanToggle |
Toggle suggestions |
padawan.nvim uses vim.on_key to observe keystrokes without intercepting them — zero interference with your keymaps or plugins, no input lag, works across Normal/Insert/Visual modes, and automatically skips macro playback and dot-repeat.
MIT