This configuration includes comprehensive editing enhancements for efficient code manipulation across multiple languages.
Autopairs
Intelligent bracket and quote pairing with language-specific rules:
{
"windwp/nvim-autopairs",
event = "InsertEnter",
dependencies = {
"nvim-treesitter/nvim-treesitter",
"saghen/blink.cmp",
},
}
Features
Treesitter-aware
Understands context to avoid pairing in strings/comments
Language-specific
Custom rules for Go, Rust, JavaScript, TypeScript, React
JSX support
Space padding for JSX expressions
Smart deletion
Delete both pairs with single backspace
Configuration
npairs.setup({
check_ts = true, -- Use treesitter for smarter pairing
ts_config = {
lua = { "string", "source" },
javascript = { "template_string" },
typescript = { "template_string" },
javascriptreact = { "template_string", "jsx_attribute" },
typescriptreact = { "template_string", "jsx_attribute" },
},
disable_filetype = { "TelescopePrompt", "vim", "lazy", "mason" },
enable_check_bracket_line = true,
enable_bracket_in_quote = true,
map_cr = true, -- Handle JSX Enter!
map_bs = true, -- Map backspace for pair deletion
})
Treesitter integration prevents autopairs from triggering inside strings, comments, and template literals.
JSX space padding
Automatically adds space padding in JSX braces:
Rule(" ", " ")
:with_pair(function(opts)
local pair = opts.line:sub(opts.col - 1, opts.col)
return vim.tbl_contains({
brackets[1][1] .. brackets[1][2],
brackets[2][1] .. brackets[2][2],
brackets[3][1] .. brackets[3][2],
}, pair)
end)
Example:
<div className={|}>
// Press space:
<div className={ | }>
Language-specific rules
npairs.add_rule(Rule("<", ">", { "rust" })
:with_pair(cond.before_regex("%a+:?:?$", 3)))
Handles lifetime annotations and turbofish:npairs.add_rule(Rule("{", "}", { "go" })
:with_pair(cond.not_after_regex("%s")))
Better struct literal handling:
User{|} works correctly
- Avoids issues with whitespace
Template string awareness prevents pairing inside:const str = `no pairing ${|} here`
Blink.cmp integration
local blink_ok, blink = pcall(require, "blink.cmp")
if blink_ok then
-- blink.cmp doesn't need explicit autopairs integration
-- autopairs' map_cr handles <CR> behavior automatically
end
Autopairs works seamlessly with Blink.cmp completion.
Automatic HTML/JSX tag closing and renaming:
{
"windwp/nvim-ts-autotag",
event = { "BufReadPost", "BufNewFile" },
opts = {
opts = {
enable_close = true, -- Auto close tags
enable_rename = true, -- Auto rename pairs
enable_close_on_slash = true, -- Auto close on trailing </
},
},
}
Features
Auto close
<div>|</div>
<!-- Type content, tag closes automatically -->
Auto rename
<div>content</div>
<!-- Change div to span, closing tag updates automatically -->
<span>content</span>
Self-closing
<Component /|
<!-- Type >, automatically becomes self-closing -->
<Component />
Supported languages
- HTML
- XML
- JavaScript (JSX)
- TypeScript (TSX)
- Vue
- Svelte
- PHP
Context-aware commenting with JSX support:
{
"numToStr/Comment.nvim",
lazy = false,
dependencies = { "JoosepAlviste/nvim-ts-context-commentstring" },
config = function()
require("Comment").setup({
pre_hook = require("ts_context_commentstring.integrations.comment_nvim").create_pre_hook(),
})
end,
}
Keybindings
| Key | Mode | Action | Description |
|---|
gcc | Normal | Toggle line | Comment/uncomment current line |
gbc | Normal | Toggle block | Block comment current line |
gc | Visual | Toggle lines | Comment/uncomment selection |
gb | Visual | Toggle block | Block comment selection |
{
"JoosepAlviste/nvim-ts-context-commentstring",
lazy = true,
opts = {
enable_autocmd = false, -- Handled by Comment.nvim pre_hook
},
}
Automatically uses correct comment syntax based on context:
function App() {
return (
<div>
{/* HTML comment in JSX */}
// JavaScript comment outside JSX
</div>
)
}
<template>
<!-- HTML comment -->
</template>
<script>
// JavaScript comment
</script>
<style>
/* CSS comment */
</style>
<!-- Markdown comment -->
```js
// JavaScript in code block
Context-commentstring uses Treesitter to determine the correct comment syntax for the current cursor position.
Vim-sleuth
Automatic indentation detection:
Automatically detects and sets:
shiftwidth - Indentation width
expandtab - Tabs vs spaces
tabstop - Tab display width
Vim-sleuth analyzes the file and other project files to detect the indentation style automatically.
CamelCase motion
Navigate and operate on CamelCase and snake_case words:
{
"bkad/CamelCaseMotion",
init = function()
vim.g.camelcasemotion_key = "<leader>"
end,
}
Keybindings
All motions are prefixed with <leader>:
| Key | Action | Description |
|---|
<leader>w | Next word | Jump to next CamelCase word part |
<leader>b | Previous word | Jump to previous CamelCase word part |
<leader>e | End of word | Jump to end of CamelCase word part |
<leader>ge | End backwards | Jump backwards to end of word part |
Example
const myVariableName = "value"
// ^ <leader>w -> ^ <leader>w -> ^ <leader>w -> ^
Text objects
| Operator | Target | Description |
|---|
i<leader>w | Inner word | CamelCase word part (inner) |
a<leader>w | Around word | CamelCase word part (outer) |
Examples:
di<leader>w - Delete CamelCase word part
ci<leader>w - Change CamelCase word part
vi<leader>w - Select CamelCase word part
Additional editing features
From mini.nvim
Surround
Add/delete/replace surrounding brackets, quotes, etc.
Split/join
Split/join code blocks intelligently (gS)
Operators
Additional operators for replace, exchange, sort
From Treesitter
Text objects
Code-aware text objects (af, if, ac, ic, etc.)
Parameter swap
Swap function parameters with <leader>a/<leader>A
Workflow examples
Rename HTML tag
Navigate CamelCase
<div class="container">
Content
</div>
- Change
div to section
- Closing tag updates automatically to
</section>
function processUserDataFromAPI() {
// ^ cursor here
- Press
<leader>w → jumps to User
- Press
<leader>w → jumps to Data
- Press
<leader>w → jumps to From
Completions
Blink.cmp integrates with autopairs for completion
Treesitter
Powers context detection for autopairs and comments
Mini.nvim
Additional editing operators and surround