Skip to content

Latest commit

 

History

5 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Code Toolkit

A collection of editing helpers:

  • toggle the case style of a word/selection,
  • expand or collapse a multiline expression,
  • highlight TODO/FIXME-style tags in comments,
  • auto-close and auto-rename matching HTML/JSX-style tags,
  • auto-close bracket/quote pairs, with wrapping, endwise, and cmp support.

Installation

-- lazy.nvim
{ "alexsobolenko/code-toolkit.nvim" }
-- packer.nvim
use "alexsobolenko/code-toolkit.nvim"
" vim-plug
Plug 'alexsobolenko/code-toolkit.nvim'
# native packages (Neovim 0.5+)
git clone https://github.com/alexsobolenko/code-toolkit.nvim \
  ~/.local/share/nvim/site/pack/plugins/start/code-toolkit.nvim

No setup() call is required — the plugin registers its commands automatically.

Features

Toggle case

Converts the word under the cursor (Normal mode) or the current selection (Visual mode) to one of:

id example
camel fooBarBaz
pascal FooBarBaz
snake foo_bar_baz
constant FOO_BAR_BAZ
kebab foo-bar-baz
dot foo.bar.baz
path foo/bar/baz
title Foo Bar Baz
sentence Foo bar baz
lower foobarbaz
upper FOOBARBAZ
lowerFirst fooBarBaz
upperFirst FooBarBaz
swap fOObARbAZ

A single-line selection is converted as one merged string; a multi-line selection converts each line independently.

Usage:

:CodeToolkitToggleCase snake   " apply directly
:CodeToolkitToggleCase         " open a picker (shows a live preview per option)

This plugin sets no keymaps of its own — bind whatever you like in your config, in both Normal and Visual mode:

local code_toolkit = require("code-toolkit")
vim.keymap.set({ "n", "x" }, "<leader>cc", function()
  code_toolkit.toggle_case()
end)
vim.keymap.set({ "n", "x" }, "<leader>cs", function()
  code_toolkit.toggle_case("snake")
end)

-- OR --

vim.keymap.set({ "n", "x" }, "<leader>cc", "<cmd>CodeToolkitToggleCase<cr>")
vim.keymap.set({ "n", "x" }, "<leader>cs", "<cmd>CodeToolkitToggleCase snake<cr>")

Toggle multiline expression

Puts the cursor inside a () / [] / {} expression — function call/params, array literal, object literal — and expands a single-line expression into one item per line (with a trailing comma where the language supports it), or collapses a multi-line one back onto a single line.

It tells apart:

  • a call/array/parameter list from control-flow parens (if (...), for (...), switch (...), etc.) — those are left alone
  • foo[0] index access from an array literal
  • an object literal {a: 1} from a code block { ... }
  • PHP's array(...) as an array

For a function declaration, toggling also moves the opening { between the same line as the closing ) and its own next line, matching whichever direction the params are going (K&R when exploded, Allman when collapsed).

Collapsing refuses (with a warning) if any item spans multiple lines or contains a line comment.

Usage:

:CodeToolkitToggleMultilineExpression
vim.keymap.set("n", "<leader>cm", function()
  code_toolkit.toggle_multiline_expression()
end)

-- OR --

vim.keymap.set("n", "<leader>cm", "<cmd>CodeToolkitToggleMultilineExpression<cr>")

Comment highlight

Highlights TODO, FIXME, BUG, HACK, WARN, WARNING, NOTE, PERF and XXX when they appear inside a comment — never inside a string or in ordinary code. Enabled automatically, no command or keymap needed.

The whole comment on the tag's line is highlighted, not just the bare word — a // TODO: fix this trailing comment is highlighted from // to end of line, and a tag inside a /* ... */ block is highlighted from the tag through to wherever the comment actually ends on that line (stopping at */ if it closes there, otherwise running to end of line).

It uses treesitter to tell comments apart from strings/code when a buffer's treesitter highlighter is active, and falls back to legacy :syntax otherwise.

To customize the tag list or colors:

require("code-toolkit").setup({
  comment_highlight = {
    tags = {
      { tag = "TODO", fg = "#1e90ff", bold = true },
      { tag = "FIXME", fg = "#ff5555", bold = true },
      -- fg / bg / bold / italic / underline / strikethrough per tag
    },
  },
})

Autotag

Closes and renames matching tags in html, xml, vue, php, javascript, javascriptreact, typescript and typescriptreact buffers. Enabled automatically, no command or keymap needed.

  • Typing the closing > of an opening tag inserts the matching closing tag and leaves the cursor between them. Void HTML elements (br, img, input, ...) and self-closing tags (<Foo />) are left alone.
  • Renaming either side of a tag pair (in Insert or Normal mode) updates the other side to match, once the edit is applied.

To customize the filetype list, tag skip list, or disable either half of the feature:

require("code-toolkit").setup({
  autotag = {
    filetypes = { "html", "javascriptreact", "typescriptreact", "vue", "php", "javascript", "typescript", "xml" },
    enable_close = true,
    enable_rename = true,
    skip_tags = { "br", "img", "input", "hr", "meta", "link" },
  },
})

Autopairs

Auto-closes (), [], {}, "", '' and `` as you type, in every filetype unless excluded. Enabled automatically, no command or keymap needed for the typing behavior itself.

  • Typing an opening character inserts its matching close and puts the cursor between them; typing the close character again just moves past it instead of inserting a duplicate. A pair isn't added when the next character is a word character, when a stray unmatched closer already follows on the line, or when the cursor is inside an existing string or comment (via treesitter, or legacy :syntax as a fallback).
  • <CR> between a freshly-typed empty pair splits it onto three lines with the middle line indented one level; <BS> between an empty pair deletes both characters at once.
  • In lua, sh/bash and ruby buffers, <CR> after an opening construct (function (), if ... then, for ... do, def, class, case ... in, etc.) also inserts the matching end/fi/done/esac on the next line, unless the line is already a complete one-liner or the closer is already present below.
  • Pairing is skipped while recording or executing a macro, and never triggers in Visual block mode or Replace mode.

Two actions aren't automatic and have no default keymap — bind them yourself:

require("code-toolkit").setup({
  autopairs = {
    disable_filetypes = { "TelescopePrompt" },
    disable_in_macro = true,
    endwise = {
      enabled = true,
      filetypes = { "lua", "sh", "bash", "ruby" },
    },
  },
})

vim.keymap.set({ "n", "x" }, "<M-e>", "<cmd>CodeToolkitFastWrap<cr>")
vim.keymap.set("n", "<leader>cp", "<cmd>CodeToolkitToggleAutopairs<cr>")

:CodeToolkitFastWrap wraps the word under the cursor (Normal mode) or the current selection (Visual mode) in a pair you pick from a picker. :CodeToolkitToggleAutopairs turns the whole feature on/off.

For nvim-cmp to add () after confirming a function/method completion, wire the plugin's hook into your own cmp config:

local cmp = require("cmp")
cmp.event:on("confirm_done", require("code-toolkit.autopairs").cmp_on_confirm_done())

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages