docs: add doc strings

This commit is contained in:
2024-04-30 13:57:09 +03:00
parent a669a998f4
commit 758d90b88f
9 changed files with 243 additions and 116 deletions

View File

@@ -24,7 +24,7 @@ with my_var or vice versa? This plugin is for you!
- 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
- If it's a selection with length, will replace only inside the selection ranges
| Transformation | Example Inputs | Output |
| -------------- | --------------------------- | -------- |
@@ -123,11 +123,13 @@ To get started, [install](#-installation) the plugin via your favorite package m
## ⚙️ Configuration
<details>
<summary>Click to unfold the full list of options with their default values</summary>
> **Note**: The options are also available in Neovim by calling `:h TextTransform.options`
The following are the default options when none are configured by the user.
To merge any new config into the default, you can override only the keys you need, and leave the
rest to use the defaults.
```lua
require("text-transform").setup({
-- Prints useful logs about what event are triggered, and reasons actions are executed.
@@ -142,8 +144,6 @@ require("text-transform").setup({
})
```
</details>
## 📝 Commands
Use the following as example, you can mix &amp; match the different replacement functions with the

View File

@@ -1,14 +1,24 @@
config.options text-transform.txt /*config.options*
config.setup() text-transform.txt /*config.setup()*
fn.replace_columns() text-transform.txt /*fn.replace_columns()*
transformers.to_camel_case() text-transform.txt /*transformers.to_camel_case()*
transformers.to_const_case() text-transform.txt /*transformers.to_const_case()*
transformers.to_dot_case() text-transform.txt /*transformers.to_dot_case()*
transformers.to_kebab_case() text-transform.txt /*transformers.to_kebab_case()*
transformers.to_pascal_case() text-transform.txt /*transformers.to_pascal_case()*
transformers.to_snake_case() text-transform.txt /*transformers.to_snake_case()*
transformers.to_title_case() text-transform.txt /*transformers.to_title_case()*
transformers.to_words() text-transform.txt /*transformers.to_words()*
transformers.transform_words() text-transform.txt /*transformers.transform_words()*
TextTransform.enable() text-transform.txt /*TextTransform.enable()*
TextTransform.get_visual_selection_details() text-transform.txt /*TextTransform.get_visual_selection_details()*
TextTransform.options text-transform.txt /*TextTransform.options*
TextTransform.replace_columns() text-transform.txt /*TextTransform.replace_columns()*
TextTransform.replace_selection() text-transform.txt /*TextTransform.replace_selection()*
TextTransform.replace_word() text-transform.txt /*TextTransform.replace_word()*
TextTransform.restore_positions() text-transform.txt /*TextTransform.restore_positions()*
TextTransform.save_positions() text-transform.txt /*TextTransform.save_positions()*
TextTransform.setup() text-transform.txt /*TextTransform.setup()*
TextTransform.setup() text-transform.txt /*TextTransform.setup()*
TextTransform.to_camel_case() text-transform.txt /*TextTransform.to_camel_case()*
TextTransform.to_const_case() text-transform.txt /*TextTransform.to_const_case()*
TextTransform.to_dot_case() text-transform.txt /*TextTransform.to_dot_case()*
TextTransform.to_kebab_case() text-transform.txt /*TextTransform.to_kebab_case()*
TextTransform.to_pascal_case() text-transform.txt /*TextTransform.to_pascal_case()*
TextTransform.to_snake_case() text-transform.txt /*TextTransform.to_snake_case()*
TextTransform.to_title_case() text-transform.txt /*TextTransform.to_title_case()*
TextTransform.to_words() text-transform.txt /*TextTransform.to_words()*
TextTransform.toggle() text-transform.txt /*TextTransform.toggle()*
TextTransform.transform_words() text-transform.txt /*TextTransform.transform_words()*
find_word_boundaries() text-transform.txt /*find_word_boundaries()*
popup_menu() text-transform.txt /*popup_menu()*
utils.dump() text-transform.txt /*utils.dump()*
utils.merge() text-transform.txt /*utils.merge()*

View File

@@ -1,12 +1,19 @@
==============================================================================
------------------------------------------------------------------------------
*config.options*
`config.options`
*TextTransform.setup()*
`TextTransform.setup`({opts})
Setup TextTransform options and merge them with user provided ones.
==============================================================================
------------------------------------------------------------------------------
*TextTransform.options*
`TextTransform.options`
Your plugin configuration with its default values.
Default values:
>
config.options = {
TextTransform.options = {
-- Prints useful logs about what event are triggered, and reasons actions are executed.
debug = false,
-- Keymap to trigger the transform.
@@ -19,7 +26,7 @@ Default values:
}
local function init()
local o = config.options
local o = TextTransform.options
D.log("config", "Initializing TextTransform with %s", utils.dump(o))
vim.keymap.set("n", o.keymap.n, telescope_popup, { silent = true })
@@ -29,8 +36,8 @@ Default values:
<
------------------------------------------------------------------------------
*config.setup()*
`config.setup`({options})
*TextTransform.setup()*
`TextTransform.setup`({options})
Define your text-transform setup.
Parameters ~
@@ -42,23 +49,97 @@ Usage ~
==============================================================================
------------------------------------------------------------------------------
*fn.replace_columns()*
`fn.replace_columns`({transform_name})
*find_word_boundaries()*
`find_word_boundaries`({line}, {start_col})
Finds the boundaries of the surrounding word around `start_col` within `line`.
@param line number
@param start_col number
@return number start_col, number end_col
------------------------------------------------------------------------------
*TextTransform.replace_word()*
`TextTransform.replace_word`({transform_name}, {position})
Replace the word under the cursor with the given transform.
If `position` is provided, replace the word under the given position.
Otherwise, attempts to find the word under the cursor.
@param transform_name string The transformer name
@param position table|nil A table containing the position of the word to replace
------------------------------------------------------------------------------
*TextTransform.replace_columns()*
`TextTransform.replace_columns`({transform_name})
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_selection()*
`TextTransform.replace_selection`({transform_name})
Replaces a selection with the given transform. This function attempts to infer the replacement
type based on the cursor positiono and visual selections, and passes information to relevant
range replacement functions.
@param transform_name string The transformer name
------------------------------------------------------------------------------
*TextTransform.get_visual_selection_details()*
`TextTransform.get_visual_selection_details`()
Takes the saved positions and translates them into individual visual ranges, regardless of how
the original selection was performed.
This allows to treat all ranges equally and allows to work on each selection without knowing
the full information around the selection logic.
==============================================================================
------------------------------------------------------------------------------
*transformers.to_words()*
`transformers.to_words`({string})
*TextTransform.toggle()*
`TextTransform.toggle`()
Toggle the plugin by calling the `enable`/`disable` methods respectively.
@private
------------------------------------------------------------------------------
*TextTransform.enable()*
`TextTransform.enable`()
Enables the plugin
@private
------------------------------------------------------------------------------
*TextTransform.save_positions()*
`TextTransform.save_positions`()
Save the current cursor position, mode, and visual selection ranges
@private
------------------------------------------------------------------------------
*TextTransform.restore_positions()*
`TextTransform.restore_positions`({state})
Restore the cursor position, mode, and visual selection ranges saved using `save_position()`,
or a given modified state, if passed as the first argument
==============================================================================
------------------------------------------------------------------------------
*popup_menu()*
`popup_menu`()
Pops up a telescope menu, containing the available case transformers.
When a transformer is selected, the cursor position/range/columns will be used to replace the
words around the cursor or inside the selection.
The cursor positions/ranges are saved before opening the menu and restored once a selection is
made.
==============================================================================
------------------------------------------------------------------------------
*TextTransform.to_words()*
`TextTransform.to_words`({string})
Splits a string into words.
@param string string
@return table
------------------------------------------------------------------------------
*transformers.transform_words()*
`transformers.transform_words`({words}, {with_word_cb}, {separator})
*TextTransform.transform_words()*
`TextTransform.transform_words`({words}, {with_word_cb}, {separator})
Transforms a table of strings into a string using a callback and separator.
The callback is called with the word, the index, and the table of words.
The separator is added between each word.
@@ -69,50 +150,50 @@ The separator is added between each word.
@return string
------------------------------------------------------------------------------
*transformers.to_camel_case()*
`transformers.to_camel_case`({string})
*TextTransform.to_camel_case()*
`TextTransform.to_camel_case`({string})
Transforms a string into camelCase.
@param string string
@return string
------------------------------------------------------------------------------
*transformers.to_snake_case()*
`transformers.to_snake_case`({string})
*TextTransform.to_snake_case()*
`TextTransform.to_snake_case`({string})
Transfroms a string into snake_case.
@param string any
@return string
------------------------------------------------------------------------------
*transformers.to_pascal_case()*
`transformers.to_pascal_case`({string})
*TextTransform.to_pascal_case()*
`TextTransform.to_pascal_case`({string})
Transforms a string into PascalCase.
@param string string
@return string
------------------------------------------------------------------------------
*transformers.to_title_case()*
`transformers.to_title_case`({string})
*TextTransform.to_title_case()*
`TextTransform.to_title_case`({string})
Transforms a string into Title Case.
@param string string
@return string
------------------------------------------------------------------------------
*transformers.to_kebab_case()*
`transformers.to_kebab_case`({string})
*TextTransform.to_kebab_case()*
`TextTransform.to_kebab_case`({string})
Transforms a string into kebab-case.
@param string string
@return string
------------------------------------------------------------------------------
*transformers.to_dot_case()*
`transformers.to_dot_case`({string})
*TextTransform.to_dot_case()*
`TextTransform.to_dot_case`({string})
Transforms a string into dot.case.
@param string string
@return string
------------------------------------------------------------------------------
*transformers.to_const_case()*
`transformers.to_const_case`({string})
*TextTransform.to_const_case()*
`TextTransform.to_const_case`({string})
Transforms a string into CONSTANT_CASE.
@param string string
@return string

View File

@@ -1,13 +1,13 @@
local telescope_popup = require("text-transform.telescope")
local D = require("text-transform.util.debug")
local utils = require("text-transform.util")
local config = {}
local TextTransform = {}
--- Your plugin configuration with its default values.
---
--- Default values:
---@eval return MiniDoc.afterlines_to_code(MiniDoc.current.eval_section)
config.options = {
TextTransform.options = {
-- Prints useful logs about what event are triggered, and reasons actions are executed.
debug = false,
-- Keymap to trigger the transform.
@@ -20,7 +20,7 @@ config.options = {
}
local function init()
local o = config.options
local o = TextTransform.options
D.log("config", "Initializing TextTransform with %s", utils.dump(o))
vim.keymap.set("n", o.keymap.n, telescope_popup, { silent = true })
@@ -32,10 +32,10 @@ end
---@param options table Module config table. See |TextTransform.options|.
---
---@usage `require("text-transform").setup()` (add `{}` with your |TextTransform.options| table)
function config.setup(options)
function TextTransform.setup(options)
options = options or {}
config.options = utils.merge(config.options, options)
TextTransform.options = utils.merge(TextTransform.options, options)
if vim.api.nvim_get_vvar("vim_did_enter") == 0 then
vim.defer_fn(function()
@@ -45,7 +45,7 @@ function config.setup(options)
init()
end
return config.options
return TextTransform.options
end
return config
return TextTransform

View File

@@ -1,7 +1,7 @@
local D = require("text-transform.util.debug")
local TextTransform = require("text-transform.main")
-- setup TextTransform options and merge them with user provided ones.
--- Setup TextTransform options and merge them with user provided ones.
function TextTransform.setup(opts)
_G.TextTransform.config = require("text-transform.config").setup(opts)
end

View File

@@ -3,13 +3,18 @@ local state = require("text-transform.state")
local utils = require("text-transform.util")
local t = require("text-transform.transformers")
local fn = {}
local TextTransform = {}
--- Finds the boundaries of the surrounding word around `start_col` within `line`.
--- @param line number
--- @param start_col number
--- @return number start_col, number end_col
local function find_word_boundaries(line, start_col)
local line_text = vim.fn.getline(line)
-- dashes, underscores, and periods are considered part of a word
local word_pat = "[A-Za-z0-9_.\\-]"
local non_word_pat = "[^A-Za-z0-9_.\\-]"
-- TODO handle searching backwards
local word_start_col = vim.fn.match(line_text:sub(start_col), word_pat) + start_col
local word_end_col = vim.fn.match(line_text:sub(word_start_col), non_word_pat)
+ word_start_col
@@ -20,7 +25,7 @@ local function find_word_boundaries(line, start_col)
return word_start_col, word_end_col
end
function fn.replace_range(start_line, start_col, end_line, end_col, transform_name)
function TextTransform.replace_range(start_line, start_col, end_line, end_col, transform_name)
D.log("replacers", "Replacing range with %s", transform_name)
local transform = t["to_" .. transform_name]
local lines = vim.fn.getline(start_line, end_line) --- @type any
@@ -46,7 +51,13 @@ function fn.replace_range(start_line, start_col, end_line, end_col, transform_na
vim.fn.setline(start_line, transformed)
end
function fn.replace_word(transform_name, position)
--- Replace the word under the cursor with the given transform.
--- If `position` is provided, replace the word under the given position.
--- Otherwise, attempts to find the word under the cursor.
---
--- @param transform_name string The transformer name
--- @param position table|nil A table containing the position of the word to replace
function TextTransform.replace_word(transform_name, position)
D.log("replacers", "Replacing word with %s", transform_name)
local word, line, col, start_col, end_col
if not position then
@@ -64,27 +75,30 @@ function fn.replace_word(transform_name, position)
if not position then
vim.cmd("normal ciw" .. transformed)
else
fn.replace_range(line, start_col, line, end_col, transform_name)
TextTransform.replace_range(line, start_col, line, end_col, transform_name)
end
end
--- 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 fn.replace_columns(transform_name)
local selections = fn.get_visual_selection_details()
function TextTransform.replace_columns(transform_name)
local selections = TextTransform.get_visual_selection_details()
D.log("replacers", "Replacing columns with %s", transform_name)
for _, sel in ipairs(selections) do
fn.replace_word(transform_name, { 0, sel.start_line, sel.start_col, 0 })
-- TODO replace with replace_word? if so, need to find how to get the word under a given position
-- fn.replace_range(sel.start_line, sel.start_col, sel.end_line, sel.end_col, transform_name)
TextTransform.replace_word(transform_name, { 0, sel.start_line, sel.start_col, 0 })
end
end
function fn.replace_selection(transform_name)
--- Replaces a selection with the given transform. This function attempts to infer the replacement
--- type based on the cursor positiono and visual selections, and passes information to relevant
--- range replacement functions.
---
--- @param transform_name string The transformer name
function TextTransform.replace_selection(transform_name)
D.log("replacers", "Replacing selection with %s", transform_name)
-- determine if cursor is a 1-width column across multiple lines or a normal selection
-- local start_line, start_col, end_line, end_col = unpack(vim.fn.getpos("'<"))
local selections = fn.get_visual_selection_details()
local selections = TextTransform.get_visual_selection_details()
D.log("replacers", "Selections: %s", utils.dump(selections))
local is_multiline = #selections > 1
@@ -102,17 +116,28 @@ function fn.replace_selection(transform_name)
)
if is_single_cursor then
fn.replace_word(transform_name)
TextTransform.replace_word(transform_name)
elseif is_column then
fn.replace_columns(transform_name)
TextTransform.replace_columns(transform_name)
else
for _, sel in pairs(selections) do
fn.replace_range(sel.start_line, sel.start_col, sel.end_line, sel.end_col, transform_name)
TextTransform.replace_range(
sel.start_line,
sel.start_col,
sel.end_line,
sel.end_col,
transform_name
)
end
end
end
function fn.get_visual_selection_details()
--- Takes the saved positions and translates them into individual visual ranges, regardless of how
--- the original selection was performed.
---
--- This allows to treat all ranges equally and allows to work on each selection without knowing
--- the full information around the selection logic.
function TextTransform.get_visual_selection_details()
D.log(
"replacers",
"Getting visual selection details - mode: %s, is_visual: %s, is_block: %s",
@@ -174,4 +199,4 @@ function fn.get_visual_selection_details()
end
end
return fn
return TextTransform

View File

@@ -8,48 +8,50 @@ local function ensure_config()
end
-- methods
local State = {
local TextTransform = {
-- Boolean determining if the plugin is enabled or not.
enabled = false,
-- A table containing cursor position and visual selection details,
-- saved using `save_position()` and can be restored using `restore_positions()`
positions = nil,
}
---Toggle the plugin by calling the `enable`/`disable` methods respectively.
---@private
function State.toggle()
if State.enabled then
return State.disable()
--- Toggle the plugin by calling the `enable`/`disable` methods respectively.
--- @private
function TextTransform.toggle()
if TextTransform.enabled then
return TextTransform.disable()
end
return State.enable()
return TextTransform.enable()
end
---Initializes the plugin.
---@private
function State.enable()
--- Enables the plugin
--- @private
function TextTransform.enable()
ensure_config()
if State.enabled then
return State
if TextTransform.enabled then
return TextTransform
end
State.enabled = true
return State
TextTransform.enabled = true
return TextTransform
end
---Disables the plugin and reset the internal state.
---@private
function State.disable()
function TextTransform.disable()
ensure_config()
if not State.enabled then
return State
if not TextTransform.enabled then
return TextTransform
end
-- reset the state
State.enabled = false
State.positions = nil
return State
TextTransform.enabled = false
TextTransform.positions = nil
return TextTransform
end
local function get_mode_type(mode)
@@ -62,7 +64,9 @@ local function get_mode_type(mode)
return mode_map[mode] or "normal"
end
function State.save_positions()
--- Save the current cursor position, mode, and visual selection ranges
--- @private
function TextTransform.save_positions()
local buf = vim.api.nvim_get_current_buf()
local mode_info = vim.api.nvim_get_mode()
local mode = get_mode_type(mode_info.mode)
@@ -104,12 +108,14 @@ function State.save_positions()
}
D.log("popup_menu", "State: %s", vim.inspect(state))
State.positions = state
TextTransform.positions = state
return state
end
function State.restore_positions(state)
state = state or State.positions
--- Restore the cursor position, mode, and visual selection ranges saved using `save_position()`,
--- or a given modified state, if passed as the first argument
function TextTransform.restore_positions(state)
state = state or TextTransform.positions
vim.api.nvim_set_current_buf(state.buf)
vim.fn.setpos(".", state.pos)
D.log("popup_menu", "Restored mode %s, cursor %s", state.mode, vim.inspect(state.pos))
@@ -126,7 +132,7 @@ function State.restore_positions(state)
vim.cmd(command)
D.log("popup_menu", [[Restored visual mode %s using "%s"]], state.mode, command)
end
State.positions = nil
TextTransform.positions = nil
end
return State
return TextTransform

View File

@@ -1,6 +1,5 @@
local TextTransform = require("text-transform.main")
local state = require("text-transform.state")
local D = require("text-transform.util.debug")
local pickers = require("telescope.pickers")
local finders = require("telescope.finders")
@@ -28,6 +27,12 @@ local items = {
-- )
-- end
--- Pops up a telescope menu, containing the available case transformers.
--- When a transformer is selected, the cursor position/range/columns will be used to replace the
--- words around the cursor or inside the selection.
---
--- The cursor positions/ranges are saved before opening the menu and restored once a selection is
--- made.
local popup_menu = function()
state.save_positions()

View File

@@ -1,21 +1,21 @@
local D = require("text-transform.util.debug")
local utils = require("text-transform.util")
local transformers = {}
local TextTransform = {}
transformers.WORD_BOUNDRY = "[%_%-%s%.]"
TextTransform.WORD_BOUNDRY = "[%_%-%s%.]"
--- Splits a string into words.
--- @param string string
--- @return table
function transformers.to_words(string)
function TextTransform.to_words(string)
local words = {}
local word = ""
local last_is_upper = false
local last_is_digit = false
for i = 1, #string do
local char = string:sub(i, i)
if char:match(transformers.WORD_BOUNDRY) then
if char:match(TextTransform.WORD_BOUNDRY) then
if word ~= "" then
table.insert(words, word:lower())
end
@@ -64,9 +64,9 @@ end
--- @param with_word_cb function (word: string, index: number, words: table) -> string
--- @param separator string|nil (optional)
--- @return string
function transformers.transform_words(words, with_word_cb, separator)
function TextTransform.transform_words(words, with_word_cb, separator)
if type(words) ~= "table" then
words = transformers.to_words(words)
words = TextTransform.to_words(words)
end
local out = ""
for i, word in ipairs(words) do
@@ -83,8 +83,8 @@ end
--- Transforms a string into camelCase.
--- @param string string
--- @return string
function transformers.to_camel_case(string)
return transformers.transform_words(string, function(word, i)
function TextTransform.to_camel_case(string)
return TextTransform.transform_words(string, function(word, i)
if i == 1 then
return word:lower()
end
@@ -95,8 +95,8 @@ end
--- Transfroms a string into snake_case.
--- @param string any
--- @return string
function transformers.to_snake_case(string)
return transformers.transform_words(string, function(word, i)
function TextTransform.to_snake_case(string)
return TextTransform.transform_words(string, function(word, i)
if i == 1 then
return word:lower()
end
@@ -107,16 +107,16 @@ end
--- Transforms a string into PascalCase.
--- @param string string
--- @return string
function transformers.to_pascal_case(string)
local cc = transformers.to_camel_case(string)
function TextTransform.to_pascal_case(string)
local cc = TextTransform.to_camel_case(string)
return cc:sub(1, 1):upper() .. cc:sub(2)
end
--- Transforms a string into Title Case.
--- @param string string
--- @return string
function transformers.to_title_case(string)
return transformers.transform_words(string, function(word)
function TextTransform.to_title_case(string)
return TextTransform.transform_words(string, function(word)
return word:sub(1, 1):upper() .. word:sub(2):lower()
end, " ")
end
@@ -124,8 +124,8 @@ end
--- Transforms a string into kebab-case.
--- @param string string
--- @return string
function transformers.to_kebab_case(string)
return transformers.transform_words(string, function(word)
function TextTransform.to_kebab_case(string)
return TextTransform.transform_words(string, function(word)
return word:lower()
end, "-")
end
@@ -133,8 +133,8 @@ end
--- Transforms a string into dot.case.
--- @param string string
--- @return string
function transformers.to_dot_case(string)
return transformers.transform_words(string, function(word)
function TextTransform.to_dot_case(string)
return TextTransform.transform_words(string, function(word)
return word:lower()
end, ".")
end
@@ -142,10 +142,10 @@ end
--- Transforms a string into CONSTANT_CASE.
--- @param string string
--- @return string
function transformers.to_const_case(string)
return transformers.transform_words(string, function(word)
function TextTransform.to_const_case(string)
return TextTransform.transform_words(string, function(word)
return word:upper()
end, "_")
end
return transformers
return TextTransform