mirror of
https://github.com/chenasraf/text-transform.nvim.git
synced 2026-05-18 01:48:57 +00:00
@@ -18,7 +18,13 @@ Transform the current word or selection between multiple case types. Need to eas
|
||||
with my_var or vice versa? This plugin is for you!
|
||||
|
||||
- Works on current word in **Normal Mode**
|
||||
- Will replace the current word selectable by <kbd>cw</kbd>
|
||||
- Works on selection in **Visual Mode**
|
||||
- Will replace only inside the selection
|
||||
- Works on column selections in **Visual Block Mode**
|
||||
- Will detect if the block is a single column or multiple columns
|
||||
- If it's a single column, will replace the word under each cursor
|
||||
- If it's a selection with length, will replace only inside the selection range
|
||||
|
||||
| Transformation | Example Inputs | Output |
|
||||
| -------------- | --------------------------- | -------- |
|
||||
|
||||
2
doc/tags
2
doc/tags
@@ -7,7 +7,7 @@ TextTransform.options text-transform.txt /*TextTransform.options*
|
||||
TextTransform.pascal_case() text-transform.txt /*TextTransform.pascal_case()*
|
||||
TextTransform.replace_at() text-transform.txt /*TextTransform.replace_at()*
|
||||
TextTransform.replace_columns() text-transform.txt /*TextTransform.replace_columns()*
|
||||
TextTransform.replace_selection() text-transform.txt /*TextTransform.replace_selection()*
|
||||
TextTransform.replace_cursor_range() text-transform.txt /*TextTransform.replace_cursor_range()*
|
||||
TextTransform.replace_word() text-transform.txt /*TextTransform.replace_word()*
|
||||
TextTransform.setup() text-transform.txt /*TextTransform.setup()*
|
||||
TextTransform.snake_case() text-transform.txt /*TextTransform.snake_case()*
|
||||
|
||||
@@ -78,11 +78,6 @@ Transforms a string into CONSTANT_CASE.
|
||||
`TextTransform.replace_at`({start_line}, {start_col}, {end_line}, {end_col}, {transform})
|
||||
Replaces the text at the given position with the given transform.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
*TextTransform.replace_selection()*
|
||||
`TextTransform.replace_selection`({transform})
|
||||
Replaces the current visual selection with the given transform.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
*TextTransform.replace_word()*
|
||||
`TextTransform.replace_word`({transform})
|
||||
@@ -91,7 +86,13 @@ Replaces the current word with the given transform.
|
||||
------------------------------------------------------------------------------
|
||||
*TextTransform.replace_columns()*
|
||||
`TextTransform.replace_columns`({transform})
|
||||
Replaces each column selection with the given transform.
|
||||
Replaces each column in visual block mode selection with the given transform.
|
||||
Assumes that the each selection is 1 character and operates on the whole word under each cursor.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
*TextTransform.replace_cursor_range()*
|
||||
`TextTransform.replace_cursor_range`({line}, {start_col}, {end_col}, {transform})
|
||||
Replaces each cursor selection range with the given transform.
|
||||
|
||||
|
||||
vim:tw=78:ts=8:noet:ft=help:norl:
|
||||
@@ -65,11 +65,7 @@ function TextTransform._setup()
|
||||
local v = map[k]
|
||||
vim.cmd("amenu TransformsWord." .. k .. " :lua TextTransform.replace_word('" .. v .. "')<CR>")
|
||||
vim.cmd(
|
||||
"amenu TransformsSelection."
|
||||
.. k
|
||||
.. " :lua TextTransform.replace_selection('"
|
||||
.. v
|
||||
.. "')<CR>"
|
||||
"amenu TransformsSelection." .. k .. " :lua TextTransform.replace_columns('" .. v .. "')<CR>"
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@ end
|
||||
TextTransform.into_words = M.into_words
|
||||
TextTransform.replace_word = M.replace_word
|
||||
TextTransform.replace_selection = M.replace_selection
|
||||
TextTransform.replace_columns = M.replace_columns
|
||||
|
||||
TextTransform.camel_case = M.camel_case
|
||||
TextTransform.snake_case = M.snake_case
|
||||
|
||||
@@ -54,27 +54,31 @@ function TextTransform.into_words(str)
|
||||
local previous_is_split_token = false
|
||||
for i = 1, #str do
|
||||
local char = str:sub(i, i)
|
||||
local is_upper = char:match("%u")
|
||||
local is_num = char:match("%d")
|
||||
local is_separator = char:match("[%_%-%s%.]")
|
||||
local is_split_token = is_upper or is_num
|
||||
-- split on uppercase letters or numbers
|
||||
if char:match("%u") or char:match("%d") and not previous_is_split_token then
|
||||
if is_split_token and not previous_is_split_token then
|
||||
if word ~= "" then
|
||||
table.insert(words, word)
|
||||
table.insert(words, word:lower())
|
||||
end
|
||||
previous_is_split_token = true
|
||||
word = char
|
||||
-- split on underscores, hyphens, and spaces
|
||||
elseif char:match("[%_%-%s%.]") then
|
||||
elseif is_separator then
|
||||
if word ~= "" then
|
||||
table.insert(words, word)
|
||||
table.insert(words, word:lower())
|
||||
previous_is_split_token = false
|
||||
end
|
||||
word = ""
|
||||
else
|
||||
word = word .. char
|
||||
previous_is_split_token = char:match("%u") or char:match("%d")
|
||||
previous_is_split_token = is_split_token
|
||||
end
|
||||
end
|
||||
if word ~= "" then
|
||||
table.insert(words, word)
|
||||
table.insert(words, word:lower())
|
||||
previous_is_split_token = false
|
||||
end
|
||||
return words
|
||||
@@ -201,19 +205,6 @@ function TextTransform.replace_at(start_line, start_col, end_line, end_col, tran
|
||||
end
|
||||
end
|
||||
|
||||
--- Replaces the current visual selection with the given transform.
|
||||
function TextTransform.replace_selection(transform)
|
||||
-- get the current visual selection, and transform the line, only replacing the selected text itself
|
||||
local _, start_line, start_col = unpack(vim.fn.getpos("'<"))
|
||||
local _, end_line, end_col = unpack(vim.fn.getpos("'>"))
|
||||
|
||||
-- transform all included lines
|
||||
TextTransform.replace_at(start_line, start_col, end_line, end_col, transform)
|
||||
|
||||
-- move the cursor to the end of the transformed text
|
||||
vim.fn.cursor(end_line, end_col)
|
||||
end
|
||||
|
||||
--- Replaces the current word with the given transform.
|
||||
function TextTransform.replace_word(transform)
|
||||
local word = vim.fn.expand("<cword>")
|
||||
@@ -221,24 +212,40 @@ function TextTransform.replace_word(transform)
|
||||
vim.cmd("normal ciw" .. transformed)
|
||||
end
|
||||
|
||||
--- Replaces each column selection with the given transform.
|
||||
--- Replaces each column in visual block mode selection with the given transform.
|
||||
--- Assumes that the each selection is 1 character and operates on the whole word under each cursor.
|
||||
function TextTransform.replace_columns(transform)
|
||||
-- get each cursor position and apply to each cursor's word
|
||||
local cursors = vim.fn.getpos("'<")
|
||||
-- get all the multiple cursor positions
|
||||
local _, start_line, start_col = unpack(vim.fn.getpos("'<"))
|
||||
local _, end_line = unpack(vim.fn.getpos("'>"))
|
||||
|
||||
for _, cursor in ipairs(cursors) do
|
||||
-- unpack the cursor values
|
||||
local start_line, start_col, end_line, end_col = unpack(cursor)
|
||||
local line = vim.fn.getline(start_line)
|
||||
D.tprint({ start_line, start_col, end_line })
|
||||
|
||||
if start_col == end_col then
|
||||
-- if the cursor is one length, get the word under the cursor
|
||||
local word = line:match("%w+", start_col)
|
||||
TextTransform.replace_at(start_line, start_col, start_line, start_col + #word, transform)
|
||||
else
|
||||
-- otherwise, get the word between the cursors
|
||||
TextTransform.replace_at(start_line, start_col, end_line, end_col, transform)
|
||||
end
|
||||
-- for each cursor start_col, find the word under the cursor and transform it
|
||||
for line_num = start_line, end_line do
|
||||
-- get the line of this cursor
|
||||
local line = vim.fn.getline(line_num)
|
||||
-- match the surrounding word using start_col
|
||||
local word = line:match("[%w%_%-]+", start_col)
|
||||
-- replace the word with the transformed word
|
||||
TextTransform.replace_cursor_range(line_num, start_col, start_col + #word - 1, transform)
|
||||
end
|
||||
end
|
||||
|
||||
--- Replaces each cursor selection range with the given transform.
|
||||
function TextTransform.replace_cursor_range(line, start_col, end_col, transform)
|
||||
return TextTransform.replace_at(line, start_col, line, end_col, transform)
|
||||
end
|
||||
|
||||
function TextTransform.replace_selection(transform)
|
||||
-- determine if cursor is a 1-length column or a normal selection
|
||||
local is_column = vim.fn.getpos("'<")[2] == vim.fn.getpos("'>")[2]
|
||||
|
||||
if is_column then
|
||||
TextTransform.replace_columns(transform)
|
||||
else
|
||||
local _, start_line, start_col, end_col = unpack(vim.fn.getpos("'<"))
|
||||
TextTransform.replace_cursor_range(start_line, start_col, end_col, transform)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
78
tests/test_config.lua
Normal file
78
tests/test_config.lua
Normal file
@@ -0,0 +1,78 @@
|
||||
local helpers = dofile("tests/helpers.lua")
|
||||
|
||||
-- See https://github.com/echasnovski/mini.nvim/blob/main/lua/mini/test.lua for more documentation
|
||||
|
||||
local child = helpers.new_child_neovim()
|
||||
local eq_global, eq_config, eq_state =
|
||||
helpers.expect.global_equality, helpers.expect.config_equality, helpers.expect.state_equality
|
||||
local eq_type_global, eq_type_config, eq_type_state =
|
||||
helpers.expect.global_type_equality,
|
||||
helpers.expect.config_type_equality,
|
||||
helpers.expect.state_type_equality
|
||||
|
||||
local T = MiniTest.new_set({
|
||||
hooks = {
|
||||
-- This will be executed before every (even nested) case
|
||||
pre_case = function()
|
||||
-- Restart child process with custom 'init.lua' script
|
||||
child.restart({ "-u", "scripts/minimal_init.lua" })
|
||||
end,
|
||||
-- This will be executed one after all tests from this set are finished
|
||||
post_once = child.stop,
|
||||
},
|
||||
})
|
||||
|
||||
-- Tests related to the `setup` method.
|
||||
T["setup()"] = MiniTest.new_set()
|
||||
|
||||
T["setup()"]["sets exposed methods and default options value"] = function()
|
||||
child.lua([[require('text-transform').setup()]])
|
||||
|
||||
-- global object that holds your plugin information
|
||||
eq_type_global(child, "_G.TextTransform", "table")
|
||||
|
||||
-- public methods
|
||||
eq_type_global(child, "_G.TextTransform.toggle", "function")
|
||||
eq_type_global(child, "_G.TextTransform.disable", "function")
|
||||
eq_type_global(child, "_G.TextTransform.enable", "function")
|
||||
|
||||
-- config
|
||||
eq_type_global(child, "_G.TextTransform.config", "table")
|
||||
|
||||
-- assert the value, and the type
|
||||
eq_type_config(child, "debug", "boolean")
|
||||
eq_config(child, "debug", false)
|
||||
|
||||
eq_type_config(child, "keymap", "table")
|
||||
|
||||
eq_type_config(child, "keymap.v", "string")
|
||||
eq_config(child, "keymap.v", "<Leader>~")
|
||||
|
||||
eq_type_config(child, "keymap.n", "string")
|
||||
eq_config(child, "keymap.n", "<Leader>~")
|
||||
end
|
||||
|
||||
T["setup()"]["overrides default values"] = function()
|
||||
child.lua([[require('text-transform').setup({
|
||||
-- write all the options with a value different than the default ones
|
||||
debug = true,
|
||||
keymap = {
|
||||
["v"] = "<leader>c",
|
||||
["n"] = "<leader>c",
|
||||
},
|
||||
})]])
|
||||
|
||||
-- assert the value, and the type
|
||||
eq_type_config(child, "debug", "boolean")
|
||||
eq_config(child, "debug", true)
|
||||
|
||||
eq_type_config(child, "keymap", "table")
|
||||
|
||||
eq_type_config(child, "keymap.v", "string")
|
||||
eq_config(child, "keymap.v", "<leader>c")
|
||||
|
||||
eq_type_config(child, "keymap.n", "string")
|
||||
eq_config(child, "keymap.n", "<leader>c")
|
||||
end
|
||||
|
||||
return T
|
||||
68
tests/test_into_words.lua
Normal file
68
tests/test_into_words.lua
Normal file
@@ -0,0 +1,68 @@
|
||||
local helpers = dofile("tests/helpers.lua")
|
||||
|
||||
-- See https://github.com/echasnovski/mini.nvim/blob/main/lua/mini/test.lua for more documentation
|
||||
|
||||
local child = helpers.new_child_neovim()
|
||||
local eq_global, eq_config, eq_state =
|
||||
helpers.expect.global_equality, helpers.expect.config_equality, helpers.expect.state_equality
|
||||
local eq_type_global, eq_type_config, eq_type_state =
|
||||
helpers.expect.global_type_equality,
|
||||
helpers.expect.config_type_equality,
|
||||
helpers.expect.state_type_equality
|
||||
|
||||
local T = MiniTest.new_set({
|
||||
hooks = {
|
||||
-- This will be executed before every (even nested) case
|
||||
pre_case = function()
|
||||
-- Restart child process with custom 'init.lua' script
|
||||
child.restart({ "-u", "scripts/minimal_init.lua" })
|
||||
end,
|
||||
-- This will be executed one after all tests from this set are finished
|
||||
post_once = child.stop,
|
||||
},
|
||||
})
|
||||
|
||||
T["into_words()"] = MiniTest.new_set()
|
||||
|
||||
T["into_words()"]["should split two words with spaces"] = function()
|
||||
child.lua([[require('text-transform').setup()]])
|
||||
child.lua([[result = require('text-transform').into_words("hello world")]])
|
||||
eq_type_global(child, "result", "table")
|
||||
eq_global(child, "result[1]", "hello")
|
||||
eq_global(child, "result[2]", "world")
|
||||
end
|
||||
|
||||
T["into_words()"]["should split two words with no spaces"] = function()
|
||||
child.lua([[require('text-transform').setup()]])
|
||||
child.lua([[result = require('text-transform').into_words("helloWorld")]])
|
||||
eq_type_global(child, "result", "table")
|
||||
eq_global(child, "result[1]", "hello")
|
||||
eq_global(child, "result[2]", "world")
|
||||
end
|
||||
|
||||
T["into_words()"]["should split two words with dots"] = function()
|
||||
child.lua([[require('text-transform').setup()]])
|
||||
child.lua([[result = require('text-transform').into_words("hello.world")]])
|
||||
eq_type_global(child, "result", "table")
|
||||
eq_global(child, "result[1]", "hello")
|
||||
eq_global(child, "result[2]", "world")
|
||||
end
|
||||
|
||||
T["into_words()"]["should split two words with a number inside"] = function()
|
||||
child.lua([[require('text-transform').setup()]])
|
||||
child.lua([[result = require('text-transform').into_words("helloWorld123")]])
|
||||
eq_type_global(child, "result", "table")
|
||||
eq_global(child, "result[1]", "hello")
|
||||
eq_global(child, "result[2]", "world")
|
||||
eq_global(child, "result[3]", "123")
|
||||
end
|
||||
|
||||
T["into_words()"]["should split two words and ignore trailing/leading spaces"] = function()
|
||||
child.lua([[require('text-transform').setup()]])
|
||||
child.lua([[result = require('text-transform').into_words(" hello world ")]])
|
||||
eq_type_global(child, "result", "table")
|
||||
eq_global(child, "result[1]", "hello")
|
||||
eq_global(child, "result[2]", "world")
|
||||
end
|
||||
|
||||
return T
|
||||
@@ -22,59 +22,6 @@ local T = MiniTest.new_set({
|
||||
},
|
||||
})
|
||||
|
||||
-- Tests related to the `setup` method.
|
||||
T["setup()"] = MiniTest.new_set()
|
||||
|
||||
T["setup()"]["sets exposed methods and default options value"] = function()
|
||||
child.lua([[require('text-transform').setup()]])
|
||||
|
||||
-- global object that holds your plugin information
|
||||
eq_type_global(child, "_G.TextTransform", "table")
|
||||
|
||||
-- public methods
|
||||
eq_type_global(child, "_G.TextTransform.toggle", "function")
|
||||
eq_type_global(child, "_G.TextTransform.disable", "function")
|
||||
eq_type_global(child, "_G.TextTransform.enable", "function")
|
||||
|
||||
-- config
|
||||
eq_type_global(child, "_G.TextTransform.config", "table")
|
||||
|
||||
-- assert the value, and the type
|
||||
eq_config(child, "debug", false)
|
||||
eq_type_config(child, "debug", "boolean")
|
||||
|
||||
eq_type_config(child, "keymap", "table")
|
||||
|
||||
eq_config(child, "keymap.v", "<Leader>~")
|
||||
eq_type_config(child, "keymap.v", "string")
|
||||
|
||||
eq_config(child, "keymap.n", "<Leader>~")
|
||||
eq_type_config(child, "keymap.n", "string")
|
||||
end
|
||||
|
||||
T["setup()"]["overrides default values"] = function()
|
||||
child.lua([[require('text-transform').setup({
|
||||
-- write all the options with a value different than the default ones
|
||||
debug = true,
|
||||
keymap = {
|
||||
["v"] = "<leader>c",
|
||||
["n"] = "<leader>c",
|
||||
},
|
||||
})]])
|
||||
|
||||
-- assert the value, and the type
|
||||
eq_type_config(child, "debug", "boolean")
|
||||
eq_config(child, "debug", true)
|
||||
|
||||
eq_type_config(child, "keymap", "table")
|
||||
|
||||
eq_config(child, "keymap.v", "<leader>c")
|
||||
eq_type_config(child, "keymap.v", "string")
|
||||
|
||||
eq_config(child, "keymap.n", "<leader>c")
|
||||
eq_type_config(child, "keymap.n", "string")
|
||||
end
|
||||
|
||||
local function make_transform_test(fn_name, input, expected)
|
||||
return function()
|
||||
child.lua([[require('text-transform').setup()]])
|
||||
@@ -83,33 +30,6 @@ local function make_transform_test(fn_name, input, expected)
|
||||
end
|
||||
end
|
||||
|
||||
T["into_words()"] = MiniTest.new_set()
|
||||
|
||||
T["into_words()"]["should split two words with spaces"] = function()
|
||||
child.lua([[require('text-transform').setup()]])
|
||||
child.lua([[result = require('text-transform').into_words("helloWorld")]])
|
||||
eq_type_global(child, "result", "table")
|
||||
eq_global(child, "result[1]", "hello")
|
||||
eq_global(child, "result[2]", "World")
|
||||
end
|
||||
|
||||
T["into_words()"]["should split two words with dots"] = function()
|
||||
child.lua([[require('text-transform').setup()]])
|
||||
child.lua([[result = require('text-transform').into_words("hello.world")]])
|
||||
eq_type_global(child, "result", "table")
|
||||
eq_global(child, "result[1]", "hello")
|
||||
eq_global(child, "result[2]", "world")
|
||||
end
|
||||
|
||||
T["into_words()"]["should split two words with a number inside"] = function()
|
||||
child.lua([[require('text-transform').setup()]])
|
||||
child.lua([[result = require('text-transform').into_words("helloWorld123")]])
|
||||
eq_type_global(child, "result", "table")
|
||||
eq_global(child, "result[1]", "hello")
|
||||
eq_global(child, "result[2]", "World")
|
||||
eq_global(child, "result[3]", "123")
|
||||
end
|
||||
|
||||
local map = {
|
||||
["camel_case"] = {
|
||||
{ "hello_world", "helloWorld" },
|
||||
@@ -118,6 +38,7 @@ local map = {
|
||||
{ "hello.world", "helloWorld" },
|
||||
{ "hello", "hello" },
|
||||
{ "helloWorld123", "helloWorld123" },
|
||||
{ "HELLO_WORLD", "helloWorld" },
|
||||
},
|
||||
["snake_case"] = {
|
||||
{ "helloWorld", "hello_world" },
|
||||
@@ -126,6 +47,7 @@ local map = {
|
||||
{ "hello.world", "hello_world" },
|
||||
{ "hello", "hello" },
|
||||
{ "helloWorld123", "hello_world_123" },
|
||||
{ "HELLO_WORLD", "hello_world" },
|
||||
},
|
||||
["pascal_case"] = {
|
||||
{ "hello_world", "HelloWorld" },
|
||||
@@ -134,6 +56,7 @@ local map = {
|
||||
{ "hello.world", "HelloWorld" },
|
||||
{ "hello", "Hello" },
|
||||
{ "helloWorld123", "HelloWorld123" },
|
||||
{ "HELLO_WORLD", "HelloWorld" },
|
||||
},
|
||||
["kebab_case"] = {
|
||||
{ "helloWorld", "hello-world" },
|
||||
@@ -142,6 +65,7 @@ local map = {
|
||||
{ "hello.world", "hello-world" },
|
||||
{ "hello", "hello" },
|
||||
{ "helloWorld123", "hello-world-123" },
|
||||
{ "HELLO_WORLD", "hello-world" },
|
||||
},
|
||||
["dot_case"] = {
|
||||
{ "helloWorld", "hello.world" },
|
||||
@@ -150,6 +74,7 @@ local map = {
|
||||
{ "hello.world", "hello.world" },
|
||||
{ "hello", "hello" },
|
||||
{ "helloWorld123", "hello.world.123" },
|
||||
{ "HELLO_WORLD", "hello.world" },
|
||||
},
|
||||
["const_case"] = {
|
||||
{ "helloWorld", "HELLO_WORLD" },
|
||||
@@ -158,6 +83,7 @@ local map = {
|
||||
{ "hello.world", "HELLO_WORLD" },
|
||||
{ "hello", "HELLO" },
|
||||
{ "helloWorld123", "HELLO_WORLD_123" },
|
||||
{ "HELLO_WORLD", "HELLO_WORLD" },
|
||||
},
|
||||
["title_case"] = {
|
||||
{ "helloWorld", "Hello World" },
|
||||
@@ -166,6 +92,7 @@ local map = {
|
||||
{ "hello.world", "Hello World" },
|
||||
{ "hello", "Hello" },
|
||||
{ "helloWorld123", "Hello World 123" },
|
||||
{ "HELLO_WORLD", "Hello World" },
|
||||
},
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user