26 Commits

Author SHA1 Message Date
github-actions[bot]
335b3ad36d chore(master): release 0.9.1 2024-07-10 16:21:44 +03:00
9e628239ab docs: update docs lib version & regenerate 2024-07-10 16:18:54 +03:00
d7dd1c4dd7 fix: normal mode transforms 2024-07-10 16:18:54 +03:00
16069971e9 docs: update doc file 2024-07-10 16:18:54 +03:00
9c62c9cd9d refactor: move cache file to .cache dir 2024-07-10 16:18:54 +03:00
33eecfffab refactor: use plugin name 2024-05-07 01:00:38 +03:00
701d373e7a refactor: remove main.lua 2024-05-07 01:00:38 +03:00
1c8fa21578 refactor: file structure 2024-05-07 01:00:38 +03:00
github-actions[bot]
1c39528e7c chore(master): release 0.9.0 2024-05-05 23:06:45 +03:00
972a44cf1e doc: add command desc 2024-05-05 23:02:08 +03:00
ecd4d6bbbc fix: range commands 2024-05-05 23:02:08 +03:00
ea38606a28 fix: sorter init 2024-05-05 23:02:08 +03:00
3362c3c4f1 refactor: clean ups 2024-05-05 23:02:08 +03:00
a9d3ffc2de test: add tests 2024-05-05 23:02:08 +03:00
168552b425 fix: error on select 2024-05-05 23:02:08 +03:00
8e7fe74888 docs: update auto docs 2024-05-05 23:02:08 +03:00
4bbba5d1b3 docs: update readme 2024-05-05 23:02:08 +03:00
eaf84d857d fix: commands 2024-05-05 23:02:08 +03:00
0cb9c1e4ee docs: update readme 2024-05-05 23:02:08 +03:00
8de9125de1 refactor: make telescope dependency optional
lazy load the telescope popup, so that if it's disabled
it won't be attempted
2024-05-05 23:02:08 +03:00
bb177a3360 feat: non-telescope popup 2024-05-05 23:02:08 +03:00
67aef1de42 docs: update readme 2024-05-05 23:02:08 +03:00
github-actions[bot]
b44d58a533 chore(master): release 0.8.0 2024-05-04 11:36:27 +03:00
6863e0e9a6 feat: allow sorter selection in config 2024-05-04 11:33:43 +03:00
733f26fef6 fix: frequency sort 2024-05-04 11:33:43 +03:00
be9c119ee2 fix: user commands 2024-05-04 11:33:43 +03:00
23 changed files with 842 additions and 664 deletions

View File

@@ -1,5 +1,40 @@
# Changelog # Changelog
## [0.9.1](https://github.com/chenasraf/text-transform.nvim/compare/v0.9.0...v0.9.1) (2024-07-10)
### Bug Fixes
* normal mode transforms ([d7dd1c4](https://github.com/chenasraf/text-transform.nvim/commit/d7dd1c4dd7e4ccd2da1458e5fb9a6653ad4e5e17))
## [0.9.0](https://github.com/chenasraf/text-transform.nvim/compare/v0.8.0...v0.9.0) (2024-05-05)
### Features
* non-telescope popup ([bb177a3](https://github.com/chenasraf/text-transform.nvim/commit/bb177a3360372f3fd40c82da71a13f1db59d3d9e))
### Bug Fixes
* commands ([eaf84d8](https://github.com/chenasraf/text-transform.nvim/commit/eaf84d857d860828cbb5af96887a24c2ab99f8e8))
* error on select ([168552b](https://github.com/chenasraf/text-transform.nvim/commit/168552b4259672fe918b1f3baeed787548e8fd03))
* range commands ([ecd4d6b](https://github.com/chenasraf/text-transform.nvim/commit/ecd4d6bbbcd45231f2e8ea00961f076ff56dd1e7))
* sorter init ([ea38606](https://github.com/chenasraf/text-transform.nvim/commit/ea38606a28f2308a37b301ebb4c56e2bd584b459))
## [0.8.0](https://github.com/chenasraf/text-transform.nvim/compare/v0.7.0...v0.8.0) (2024-05-04)
### Features
* allow sorter selection in config ([6863e0e](https://github.com/chenasraf/text-transform.nvim/commit/6863e0e9a66b5592fbba2aea7a07760465844cf7))
### Bug Fixes
* frequency sort ([733f26f](https://github.com/chenasraf/text-transform.nvim/commit/733f26fef61b050ae8f62582e3f9c03268f8e835))
* user commands ([be9c119](https://github.com/chenasraf/text-transform.nvim/commit/be9c119ee23f1e93a5bd537c01f55e11d2607180))
## [0.7.0](https://github.com/chenasraf/text-transform.nvim/compare/v0.6.0...v0.7.0) (2024-05-03) ## [0.7.0](https://github.com/chenasraf/text-transform.nvim/compare/v0.6.0...v0.7.0) (2024-05-03)

170
README.md
View File

@@ -38,114 +38,51 @@ with `my_var` or vice versa? This plugin is for you!
## 🔽 Installation ## 🔽 Installation
<div> ### [Lazy](https://github.com/folke/lazy.nvim)
<table>
<thead>
<tr>
<th>
<img width="221" height="1"/>
Package manager
</th>
<th>
<img width="661" height="1"/>
Snippet
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
[folke/lazy.nvim](https://github.com/folke/lazy.nvim)
</td>
<td>
```lua ```lua
-- stable version
require("lazy").setup({ require("lazy").setup({
"chenasraf/text-transform.nvim", "chenasraf/text-transform.nvim",
-- stable version
version = "*", -- or: tag = "stable" version = "*", -- or: tag = "stable"
dependencies = { -- dev version
-- for Telescope popup -- branch = "develop",
'nvim-telescope/telescope.nvim', -- Optional - for Telescope popup
'nvim-lua/plenary.nvim', dependencies = { 'nvim-telescope/telescope.nvim', 'nvim-lua/plenary.nvim' }
},
})
-- dev version
require("lazy").setup({
"chenasraf/text-transform.nvim",
branch = "develop",
dependencies = {
-- for Telescope popup
'nvim-telescope/telescope.nvim',
'nvim-lua/plenary.nvim',
},
}) })
``` ```
</td> ### [Packer](https://github.com/wbthomason/packer.nvim)
</tr>
<tr>
<td>
[wbthomason/packer.nvim](https://github.com/wbthomason/packer.nvim)
</td>
<td>
```lua ```lua
-- stable version
use { "chenasraf/text-transform.nvim", use { "chenasraf/text-transform.nvim",
-- stable version
tag = "stable", tag = "stable",
requires = { -- dev version
-- for Telescope popup -- branch = "develop",
'nvim-telescope/telescope.nvim', -- Optional - for Telescope popup
'nvim-lua/plenary.nvim', requires = { 'nvim-telescope/telescope.nvim', 'nvim-lua/plenary.nvim' }
}
}
-- dev version
use { "chenasraf/text-transform.nvim",
branch = "develop",
requires = {
-- for Telescope popup
'nvim-telescope/telescope.nvim',
'nvim-lua/plenary.nvim',
}
} }
``` ```
</td> ### [Plug](https://github.com/junegunn/vim-plug)
</tr>
<tr>
<td>
[junegunn/vim-plug](https://github.com/junegunn/vim-plug)
</td>
<td>
```vim ```vim
-- Dependencies - for Telescope popup " Dependencies - optional for Telescope popup
Plug "nvim-telescope/telescope.nvim" Plug 'nvim-telescope/telescope.nvim'
Plug "nvim-lua/plenary.nvim" Plug 'nvim-lua/plenary.nvim'
-- stable version " stable version
Plug "chenasraf/text-transform.nvim", { Plug 'chenasraf/text-transform.nvim', { 'tag': 'stable' }
"tag": "stable", " dev version
} Plug 'chenasraf/text-transform.nvim', { 'branch': 'develop' }
-- dev version
Plug "chenasraf/text-transform.nvim", {
"branch": "develop",
}
``` ```
</td> If you decide not to use Telescope, you can ignore the dependencies. In that case, be sure to change
</tr> your config with `popup_type = 'select'` so that TextTransform never tries to load Telescope.
</tbody> It falls back to `vim.ui.select()` instead, which may or may not still be Telescope behind the
</table> scenes, or something else; depending on your setup.
</div>
## 🚀 Getting started ## 🚀 Getting started
@@ -177,16 +114,16 @@ rest to use the defaults.
```lua ```lua
require("text-transform").setup({ require("text-transform").setup({
-- Prints information about internals of the plugin. Very verbose, only useful for debugging. --- Prints information about internals of the plugin. Very verbose, only useful for debugging.
debug = false, debug = false,
-- Keymap configurations --- Keymap configurations
keymap = { keymap = {
-- Keymap to open the telescope popup. Set to `false` or `nil` to disable keymapping --- Keymap to open the telescope popup. Set to `false` or `nil` to disable keymapping
-- You can always customize your own keymapping manually. --- You can always customize your own keymapping manually.
telescope_popup = { telescope_popup = {
-- Opens the popup in normal mode --- Opens the popup in normal mode
["n"] = "<Leader>~", ["n"] = "<Leader>~",
-- Opens the popup in visual/visual block modes --- Opens the popup in visual/visual block modes
["v"] = "<Leader>~", ["v"] = "<Leader>~",
}, },
}, },
@@ -204,6 +141,14 @@ require("text-transform").setup({
snake_case = { enabled = true }, snake_case = { enabled = true },
title_case = { enabled = true }, title_case = { enabled = true },
}, },
--- Sort the replacers in the popup.
--- Possible values: 'frequency', 'name'
sort_by = "frequency",
--- The popup type to show.
--- Possible values: 'telescope', 'select'
popup_type = 'telescope'
}) })
``` ```
@@ -211,16 +156,18 @@ require("text-transform").setup({
The following commands are available for your use in your own mappings or for reference. The following commands are available for your use in your own mappings or for reference.
| Command | Description | | Command | Description |
| ---------------------------------- | ------------------------------------------------------------------------------------------------------ | | ---------------- | ---------------------------------------------------------------------------------------------------------------------- |
| `:TtTelescope` \| `:TextTransform` | Pops up a Telescope window with the available converters which will directly act on the selected text. | | `:TextTransform` | Pop up a either a Telescope window or a selection popup, depending on the `popup_type` config. |
| `:TtCamel` | Replaces selection with `camelCase`. | | `:TtTelescope` | Pop up a Telescope window with all the transformers, which will directly act on the selected text or highlighted word. |
| `:TtConst` | Replaces selection with `CONST_CASE`. | | `:TtSelect` | Pop up a selection popup with all the transformers, which will directly act on the selected text or highlighted word. |
| `:TtDot` | Replaces selection with `dot.case`. | | `:TtCamel` | Replace selection/word with `camelCase`. |
| `:TtKebab` | Replaces selection with `kebab-case`. | | `:TtSnake` | Replace selection/word with `snake_case`. |
| `:TtPascal` | Replaces selection with `PascalCase`. | | `:TtPascal` | Replace selection/word with `PascalCase`. |
| `:TtSnake` | Replaces selection with `snake_case`. | | `:TtConst` | Replace selection/word with `CONST_CASE`. |
| `:TtTitle` | Replaces selection with `Title Case`. | | `:TtDot` | Replace selection/word with `dot.case`. |
| `:TtKebab` | Replace selection/word with `kebab-case`. |
| `:TtTitle` | Replace selection/word with `Title Case`. |
## ⌨️⌨️ Keymaps ## ⌨️⌨️ Keymaps
@@ -250,17 +197,16 @@ You can also create custom mappings to specific case conversions or to the Teles
```lua ```lua
-- Trigger telescope popup -- Trigger telescope popup
local telescope = require('text-transform.telescope') vim.keymap.set("n", "<leader>~~", ":TtTelescope", { silent = true, desc = "Transform Text" })
vim.keymap.set("n", "<leader>~~", telescope.popup, { silent = true })
-- Trigger case converters directly -- Trigger case converters directly
vim.keymap.set({ "n", "v" }, "<leader>Ccc", ":TtCamel", { silent = true }) vim.keymap.set({ "n", "v" }, "<leader>Ccc", ":TtCamel", { silent = true, desc = "To camelCase" })
vim.keymap.set({ "n", "v" }, "<leader>Cco", ":TtConst", { silent = true }) vim.keymap.set({ "n", "v" }, "<leader>Csn", ":TtSnake", { silent = true, desc = "To snake_case" })
vim.keymap.set({ "n", "v" }, "<leader>Cdo", ":TtDot", { silent = true }) vim.keymap.set({ "n", "v" }, "<leader>Cpa", ":TtPascal", { silent = true, desc = "To PascalCase" })
vim.keymap.set({ "n", "v" }, "<leader>Cke", ":TtKebab", { silent = true }) vim.keymap.set({ "n", "v" }, "<leader>Cco", ":TtConst", { silent = true, desc = "To CONST_CASE" })
vim.keymap.set({ "n", "v" }, "<leader>Cpa", ":TtPascal", { silent = true }) vim.keymap.set({ "n", "v" }, "<leader>Cdo", ":TtDot", { silent = true, desc = "To dot.case" })
vim.keymap.set({ "n", "v" }, "<leader>Csn", ":TtSnake", { silent = true }) vim.keymap.set({ "n", "v" }, "<leader>Cke", ":TtKebab", { silent = true, desc = "To kebab-case" })
vim.keymap.set({ "n", "v" }, "<leader>Ctt", ":TtTitle", { silent = true }) vim.keymap.set({ "n", "v" }, "<leader>Ctt", ":TtTitle", { silent = true, desc = "To Title Case" })
``` ```
## 💁🏻 Contributing ## 💁🏻 Contributing

View File

@@ -1,14 +1,16 @@
TextTransform.enable() text-transform.txt /*TextTransform.enable()* TextTransform.config text-transform.txt /*TextTransform.config*
TextTransform.get_visual_selection_details() text-transform.txt /*TextTransform.get_visual_selection_details()* TextTransform.get_visual_selection_details() text-transform.txt /*TextTransform.get_visual_selection_details()*
TextTransform.init_commands() text-transform.txt /*TextTransform.init_commands()* TextTransform.merge() text-transform.txt /*TextTransform.merge()*
TextTransform.options text-transform.txt /*TextTransform.options*
TextTransform.popup() text-transform.txt /*TextTransform.popup()*
TextTransform.replace_columns() text-transform.txt /*TextTransform.replace_columns()* TextTransform.replace_columns() text-transform.txt /*TextTransform.replace_columns()*
TextTransform.replace_range() text-transform.txt /*TextTransform.replace_range()*
TextTransform.replace_selection() text-transform.txt /*TextTransform.replace_selection()* TextTransform.replace_selection() text-transform.txt /*TextTransform.replace_selection()*
TextTransform.replace_word() text-transform.txt /*TextTransform.replace_word()* TextTransform.replace_word() text-transform.txt /*TextTransform.replace_word()*
TextTransform.restore_positions() text-transform.txt /*TextTransform.restore_positions()* TextTransform.restore_positions() text-transform.txt /*TextTransform.restore_positions()*
TextTransform.save_positions() text-transform.txt /*TextTransform.save_positions()* TextTransform.save_positions() text-transform.txt /*TextTransform.save_positions()*
TextTransform.select_popup() text-transform.txt /*TextTransform.select_popup()*
TextTransform.setup() text-transform.txt /*TextTransform.setup()* TextTransform.setup() text-transform.txt /*TextTransform.setup()*
TextTransform.show_popup() text-transform.txt /*TextTransform.show_popup()*
TextTransform.telescope_popup() text-transform.txt /*TextTransform.telescope_popup()*
TextTransform.to_camel_case() text-transform.txt /*TextTransform.to_camel_case()* TextTransform.to_camel_case() text-transform.txt /*TextTransform.to_camel_case()*
TextTransform.to_const_case() text-transform.txt /*TextTransform.to_const_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_dot_case() text-transform.txt /*TextTransform.to_dot_case()*
@@ -17,8 +19,5 @@ TextTransform.to_pascal_case() text-transform.txt /*TextTransform.to_pascal_case
TextTransform.to_snake_case() text-transform.txt /*TextTransform.to_snake_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_title_case() text-transform.txt /*TextTransform.to_title_case()*
TextTransform.to_words() text-transform.txt /*TextTransform.to_words()* 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()* TextTransform.transform_words() text-transform.txt /*TextTransform.transform_words()*
find_word_boundaries() text-transform.txt /*find_word_boundaries()* find_word_boundaries() text-transform.txt /*find_word_boundaries()*
utils.dump() text-transform.txt /*utils.dump()*
utils.merge() text-transform.txt /*utils.merge()*

View File

@@ -1,30 +1,22 @@
============================================================================== ==============================================================================
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
*TextTransform.init_commands()* *TextTransform.config*
`TextTransform.init_commands`() `TextTransform.config`
Initializes user commands
@private
==============================================================================
------------------------------------------------------------------------------
*TextTransform.options*
`TextTransform.options`
Your plugin configuration with its default values. Your plugin configuration with its default values.
Default values: Default values:
> >lua
TextTransform.options = { TextTransform.config = {
-- Prints information about internals of the plugin. Very verbose, only useful for debugging. --- Prints information about internals of the plugin. Very verbose, only useful for debugging.
debug = false, debug = false,
-- Keymap configurations --- Keymap configurations
keymap = { keymap = {
-- Keymap to open the telescope popup. Set to `false` or `nil` to disable keymapping --- Keymap to open the telescope popup. Set to `false` or `nil` to disable keymapping
-- You can always customize your own keymapping manually. --- You can always customize your own keymapping manually.
telescope_popup = { telescope_popup = {
-- Opens the popup in normal mode --- Opens the popup in normal mode
["n"] = "<Leader>~", ["n"] = "<Leader>~",
-- Opens the popup in visual/visual block modes --- Opens the popup in visual/visual block modes
["v"] = "<Leader>~", ["v"] = "<Leader>~",
}, },
}, },
@@ -42,26 +34,17 @@ Default values:
snake_case = { enabled = true }, snake_case = { enabled = true },
title_case = { enabled = true }, title_case = { enabled = true },
}, },
--- Sort the replacers in the popup.
--- Possible values: 'frequency', 'name'
sort_by = "frequency",
--- The popup type to show.
--- Possible values: 'telescope', 'select'
popup_type = "telescope",
} }
local function init()
local o = TextTransform.options
D.log("config", "Initializing TextTransform with %s", utils.dump(o))
commands.init_commands()
if o.keymap.telescope_popup then
local keys = o.keymap.telescope_popup
if keys.n then
vim.keymap.set("n", keys.n, telescope.popup, { silent = true })
end
if keys.v then
vim.keymap.set("v", keys.v, telescope.popup, { silent = true })
end
end
end
< <
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
*TextTransform.setup()* *TextTransform.setup()*
`TextTransform.setup`({options}) `TextTransform.setup`({options})
@@ -79,9 +62,24 @@ Usage ~
*find_word_boundaries()* *find_word_boundaries()*
`find_word_boundaries`({line}, {start_col}) `find_word_boundaries`({line}, {start_col})
Finds the boundaries of the surrounding word around `start_col` within `line`. Finds the boundaries of the surrounding word around `start_col` within `line`.
@param line number Parameters ~
@param start_col number {line} `(number)`
@return number start_col, number end_col {start_col} `(number)`
Return ~
`(number)` start_col, number end_col
------------------------------------------------------------------------------
*TextTransform.replace_range()*
`TextTransform.replace_range`({start_line}, {start_col}, {end_line}, {end_col}, {transform_name})
Replace the range between the given positions with the given transform.
Acts on the lines between the given positions, replacing the text between the given columns.
Parameters ~
{start_line} `(number)` The starting line
{start_col} `(number)` The starting column
{end_line} `(number)` The ending line
{end_col} `(number)` The ending column
{transform_name} `(string)` The transformer name
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
*TextTransform.replace_word()* *TextTransform.replace_word()*
@@ -90,8 +88,9 @@ Replace the word under the cursor with the given transform.
If `position` is provided, replace the word under the given position. If `position` is provided, replace the word under the given position.
Otherwise, attempts to find the word under the cursor. Otherwise, attempts to find the word under the cursor.
@param transform_name string The transformer name Parameters ~
@param position table|nil A table containing the position of the word to replace {transform_name} `(string)` The transformer name
{position} `(table|nil)` A table containing the position of the word to replace
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
*TextTransform.replace_columns()* *TextTransform.replace_columns()*
@@ -99,6 +98,9 @@ Otherwise, attempts to find the word under the cursor.
Replaces each column in visual block mode 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. Assumes that the each selection is 1 character and operates on the whole word under each cursor.
Parameters ~
{transform_name} `(string)` The transformer name
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
*TextTransform.replace_selection()* *TextTransform.replace_selection()*
`TextTransform.replace_selection`({transform_name}) `TextTransform.replace_selection`({transform_name})
@@ -106,7 +108,8 @@ Replaces a selection with the given transform. This function attempts to infer t
type based on the cursor positiono and visual selections, and passes information to relevant type based on the cursor positiono and visual selections, and passes information to relevant
range replacement functions. range replacement functions.
@param transform_name string The transformer name Parameters ~
{transform_name} `(string)` The transformer name
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
*TextTransform.get_visual_selection_details()* *TextTransform.get_visual_selection_details()*
@@ -119,35 +122,134 @@ the full information around the selection logic.
============================================================================== ==============================================================================
------------------------------------------------------------------------------
*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()*
`TextTransform.save_positions`() `TextTransform.save_positions`()
Save the current cursor position, mode, and visual selection ranges Save the current cursor position, mode, and visual selection ranges
@private
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
*TextTransform.restore_positions()* *TextTransform.restore_positions()*
`TextTransform.restore_positions`({state}) `TextTransform.restore_positions`({positions})
Restore the cursor position, mode, and visual selection ranges saved using `save_position()`, Restore the cursor position, mode, and visual selection ranges saved using `save_position()`,
or a given modified state, if passed as the first argument or a given modified state, if passed as the first argument
============================================================================== ==============================================================================
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
*TextTransform.popup()* *TextTransform.to_words()*
`TextTransform.popup`() `TextTransform.to_words`({string})
Splits a string into words.
Parameters ~
{string} `(string)`
Return ~
`(table)`
------------------------------------------------------------------------------
*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.
Parameters ~
{words} `(string|table)` string or table of strings
{with_word_cb} `(function)` (word: string, index: number, words: table) -> string
{separator} `(string|nil)` (optional)
Return ~
`(string)`
------------------------------------------------------------------------------
*TextTransform.to_camel_case()*
`TextTransform.to_camel_case`({string})
Transforms a string into camelCase.
Parameters ~
{string} `(string)`
Return ~
`(string)`
------------------------------------------------------------------------------
*TextTransform.to_snake_case()*
`TextTransform.to_snake_case`({string})
Transfroms a string into snake_case.
Parameters ~
{string} `(any)`
Return ~
`(string)`
------------------------------------------------------------------------------
*TextTransform.to_pascal_case()*
`TextTransform.to_pascal_case`({string})
Transforms a string into PascalCase.
Parameters ~
{string} `(string)`
Return ~
`(string)`
------------------------------------------------------------------------------
*TextTransform.to_title_case()*
`TextTransform.to_title_case`({string})
Transforms a string into Title Case.
Parameters ~
{string} `(string)`
Return ~
`(string)`
------------------------------------------------------------------------------
*TextTransform.to_kebab_case()*
`TextTransform.to_kebab_case`({string})
Transforms a string into kebab-case.
Parameters ~
{string} `(string)`
Return ~
`(string)`
------------------------------------------------------------------------------
*TextTransform.to_dot_case()*
`TextTransform.to_dot_case`({string})
Transforms a string into dot.case.
Parameters ~
{string} `(string)`
Return ~
`(string)`
------------------------------------------------------------------------------
*TextTransform.to_const_case()*
`TextTransform.to_const_case`({string})
Transforms a string into CONSTANT_CASE.
Parameters ~
{string} `(string)`
Return ~
`(string)`
==============================================================================
------------------------------------------------------------------------------
*TextTransform.show_popup()*
`TextTransform.show_popup`()
Pops up a selection 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.select_popup()*
`TextTransform.select_popup`()
Pops up a selection 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.telescope_popup()*
`TextTransform.telescope_popup`()
Pops up a telescope menu, containing the available case transformers. 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 When a transformer is selected, the cursor position/range/columns will be used to replace the
words around the cursor or inside the selection. words around the cursor or inside the selection.
@@ -158,93 +260,18 @@ made.
============================================================================== ==============================================================================
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
*TextTransform.to_words()* *TextTransform.merge()*
`TextTransform.to_words`({string}) `TextTransform.merge`({t1}, {t2})
Splits a string into words.
@param string string
@return table
------------------------------------------------------------------------------
*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.
@param words string|table string or table of strings
@param with_word_cb function (word: string, index: number, words: table) -> string
@param separator string|nil (optional)
@return string
------------------------------------------------------------------------------
*TextTransform.to_camel_case()*
`TextTransform.to_camel_case`({string})
Transforms a string into camelCase.
@param string string
@return string
------------------------------------------------------------------------------
*TextTransform.to_snake_case()*
`TextTransform.to_snake_case`({string})
Transfroms a string into snake_case.
@param string any
@return string
------------------------------------------------------------------------------
*TextTransform.to_pascal_case()*
`TextTransform.to_pascal_case`({string})
Transforms a string into PascalCase.
@param string string
@return string
------------------------------------------------------------------------------
*TextTransform.to_title_case()*
`TextTransform.to_title_case`({string})
Transforms a string into Title Case.
@param string string
@return string
------------------------------------------------------------------------------
*TextTransform.to_kebab_case()*
`TextTransform.to_kebab_case`({string})
Transforms a string into kebab-case.
@param string string
@return string
------------------------------------------------------------------------------
*TextTransform.to_dot_case()*
`TextTransform.to_dot_case`({string})
Transforms a string into dot.case.
@param string string
@return string
------------------------------------------------------------------------------
*TextTransform.to_const_case()*
`TextTransform.to_const_case`({string})
Transforms a string into CONSTANT_CASE.
@param string string
@return string
==============================================================================
------------------------------------------------------------------------------
*utils.merge()*
`utils.merge`({t1}, {t2})
Merges two tables into one. Same as `vim.tbl_extend("keep", t1, t2)`. Merges two tables into one. Same as `vim.tbl_extend("keep", t1, t2)`.
Mutates the first table. Mutates the first table.
TODO accept multiple tables to merge TODO accept multiple tables to merge
@param t1 table Parameters ~
@param t2 table {t1} `(table)`
@return table {t2} `(table)`
Return ~
------------------------------------------------------------------------------ `(table)`
*utils.dump()*
`utils.dump`({obj})
Dumps the object into a string.
@param obj any
@return string
vim:tw=78:ts=8:noet:ft=help:norl: vim:tw=78:ts=8:noet:ft=help:norl:

View File

@@ -1,9 +1,12 @@
local D = require("text-transform.utils.debug")
local util = require("text-transform.utils")
local state = require("text-transform.state")
local replacers = require("text-transform.replacers") local replacers = require("text-transform.replacers")
local telescope = require("text-transform.telescope") local popup = require("text-transform.popup")
local common = require("text-transform.popup.common")
local TextTransform = {} local TextTransform = {}
--- Initializes user commands
--- @private
function TextTransform.init_commands() function TextTransform.init_commands()
local map = { local map = {
TtCamel = "camel_case", TtCamel = "camel_case",
@@ -15,14 +18,54 @@ function TextTransform.init_commands()
TtTitle = "title_case", TtTitle = "title_case",
} }
for cmd, transformer_name in pairs(map) do local cmdopts = { range = true, force = true }
vim.api.nvim_create_user_command(cmd, function() local opts = function(desc)
replacers.replace_selection(transformer_name) return util.merge(cmdopts, { desc = desc })
end, {})
end end
vim.api.nvim_create_user_command("TtTelescope", telescope.popup, {}) for cmd, transformer_name in pairs(map) do
vim.api.nvim_create_user_command("TextTransform", telescope.popup, {}) local item
for _, t in ipairs(common.items) do
if t.value == transformer_name then
item = t.label
break
end
end
vim.api.nvim_create_user_command(cmd, function()
state.save_positions()
replacers.replace_selection(transformer_name)
vim.schedule(function()
state.restore_positions()
end)
end, opts("Change to " .. item))
end
-- specific popups
vim.api.nvim_create_user_command("TtTelescope", function()
local telescope = require("text-transform.popup.telescope")
telescope.telescope_popup()
end, opts("Change Case with Telescope"))
vim.api.nvim_create_user_command("TtSelect", function()
local select = require("text-transform.popup.select")
select.select_popup()
end, opts("Change Case with Select"))
-- auto popup by config
vim.api.nvim_create_user_command("TextTransform", popup.show_popup, opts("Change Case"))
end
function TextTransform.init_keymaps()
local keymaps = _G.TextTransform.config.keymap
D.log("init_keymaps", "Initializing keymaps, config %s", vim.inspect(_G.TextTransform))
if keymaps.telescope_popup then
local keys = keymaps.telescope_popup
if keys.n then
vim.keymap.set("n", keys.n, popup.show_popup, { silent = true, desc = "Change Case" })
end
if keys.v then
vim.keymap.set("v", keys.v, popup.show_popup, { silent = true, desc = "Change Case" })
end
end
end end
return TextTransform return TextTransform

View File

@@ -1,24 +1,38 @@
local telescope = require("text-transform.telescope")
local commands = require("text-transform.commands") local commands = require("text-transform.commands")
local D = require("text-transform.util.debug") local D = require("text-transform.utils.debug")
local utils = require("text-transform.util") local utils = require("text-transform.utils")
local TextTransform = {} local TextTransform = {}
local function ensure_config()
-- when the config is not set to the global object, we set it
if _G.TextTransform.config == nil then
_G.TextTransform.config = TextTransform.config
end
end
local function init()
ensure_config()
local o = TextTransform.config
D.log("config", "Initializing TextTransform with %s", vim.inspect(o))
commands.init_commands()
commands.init_keymaps()
end
--- Your plugin configuration with its default values. --- Your plugin configuration with its default values.
--- ---
--- Default values: --- Default values:
---@eval return MiniDoc.afterlines_to_code(MiniDoc.current.eval_section) ---@eval return MiniDoc.afterlines_to_code(MiniDoc.current.eval_section)
TextTransform.options = { TextTransform.config = {
-- Prints information about internals of the plugin. Very verbose, only useful for debugging. --- Prints information about internals of the plugin. Very verbose, only useful for debugging.
debug = false, debug = false,
-- Keymap configurations --- Keymap configurations
keymap = { keymap = {
-- Keymap to open the telescope popup. Set to `false` or `nil` to disable keymapping --- Keymap to open the telescope popup. Set to `false` or `nil` to disable keymapping
-- You can always customize your own keymapping manually. --- You can always customize your own keymapping manually.
telescope_popup = { telescope_popup = {
-- Opens the popup in normal mode --- Opens the popup in normal mode
["n"] = "<Leader>~", ["n"] = "<Leader>~",
-- Opens the popup in visual/visual block modes --- Opens the popup in visual/visual block modes
["v"] = "<Leader>~", ["v"] = "<Leader>~",
}, },
}, },
@@ -36,24 +50,16 @@ TextTransform.options = {
snake_case = { enabled = true }, snake_case = { enabled = true },
title_case = { enabled = true }, title_case = { enabled = true },
}, },
--- Sort the replacers in the popup.
--- Possible values: 'frequency', 'name'
sort_by = "frequency",
--- The popup type to show.
--- Possible values: 'telescope', 'select'
popup_type = "telescope",
} }
local function init()
local o = TextTransform.options
D.log("config", "Initializing TextTransform with %s", utils.dump(o))
commands.init_commands()
if o.keymap.telescope_popup then
local keys = o.keymap.telescope_popup
if keys.n then
vim.keymap.set("n", keys.n, telescope.popup, { silent = true })
end
if keys.v then
vim.keymap.set("v", keys.v, telescope.popup, { silent = true })
end
end
end
--- Define your text-transform setup. --- Define your text-transform setup.
--- ---
---@param options table Module config table. See |TextTransform.options|. ---@param options table Module config table. See |TextTransform.options|.
@@ -62,7 +68,7 @@ end
function TextTransform.setup(options) function TextTransform.setup(options)
options = options or {} options = options or {}
TextTransform.options = utils.merge(TextTransform.options, options) TextTransform.config = utils.merge(TextTransform.config, options)
if vim.api.nvim_get_vvar("vim_did_enter") == 0 then if vim.api.nvim_get_vvar("vim_did_enter") == 0 then
vim.defer_fn(function() vim.defer_fn(function()
@@ -72,7 +78,7 @@ function TextTransform.setup(options)
init() init()
end end
return TextTransform.options return TextTransform.config
end end
return TextTransform return TextTransform

View File

@@ -1,5 +1,8 @@
local M = require("text-transform.main") local utils = require("text-transform.utils")
local utils = require("text-transform.util") local tt = require("text-transform.transformers")
local replacers = require("text-transform.replacers")
local state = require("text-transform.state")
local popup = require("text-transform.popup")
local TextTransform = {} local TextTransform = {}
@@ -7,6 +10,14 @@ function TextTransform.setup(opts)
_G.TextTransform.config = require("text-transform.config").setup(opts) _G.TextTransform.config = require("text-transform.config").setup(opts)
end end
_G.TextTransform = utils.merge(M, TextTransform) local function merge(table)
TextTransform = utils.merge(TextTransform, table)
end
merge(tt)
merge(replacers)
merge(state)
merge(popup)
_G.TextTransform = TextTransform
return _G.TextTransform return _G.TextTransform

View File

@@ -1,18 +0,0 @@
local utils = require("text-transform.util")
local tt = require("text-transform.transformers")
local replacers = require("text-transform.replacers")
local state = require("text-transform.state")
local telescope = require("text-transform.telescope")
local TextTransform = {}
local function merge(table)
TextTransform = utils.merge(TextTransform, table)
end
merge(tt)
merge(replacers)
merge(state)
merge(telescope)
return TextTransform

View File

@@ -0,0 +1,67 @@
local D = require("text-transform.utils.debug")
local state = require("text-transform.state")
local replacers = require("text-transform.replacers")
local popup_common = {}
popup_common.items = {
{ label = "camelCase", value = "camel_case" },
{ label = "snake_case", value = "snake_case" },
{ label = "PascalCase", value = "pascal_case" },
{ label = "kebab-case", value = "kebab_case" },
{ label = "dot.case", value = "dot_case" },
{ label = "Title Case", value = "title_case" },
{ label = "CONST_CASE", value = "const_case" },
}
popup_common.default_frequency = {
camel_case = 1,
snake_case = 1,
pascal_case = 1,
kebab_case = 1,
dot_case = 1,
title_case = 1,
const_case = 1,
}
local cache_dir = vim.fn.stdpath("cache")
local frequency_file = cache_dir .. "/text-transform-frequency.json"
local frequency
function popup_common.load_frequency()
if frequency then
return frequency
end
if vim.fn.filereadable(frequency_file) == 0 then
frequency = popup_common.default_frequency
vim.fn.writefile({ vim.fn.json_encode(frequency) }, frequency_file)
else
frequency = vim.fn.json_decode(vim.fn.readfile(frequency_file))
end
D.log("telescope", "frequency loaded: %s", vim.inspect(frequency))
return frequency
end
function popup_common.inc_frequency(name)
frequency[name] = (frequency[name] or 0) + 1
D.log("telescope", "new frequency: %s %d", name, frequency[name])
vim.fn.writefile({ vim.fn.json_encode(frequency) }, frequency_file)
end
function popup_common.entry_maker(entry)
return {
value = entry.value,
display = entry.label,
ordinal = entry.label,
frequency = frequency[entry.value] or 1,
}
end
function popup_common.select(selection)
vim.schedule(function()
replacers.replace_selection(selection.value)
state.restore_positions()
end)
end
return popup_common

View File

@@ -0,0 +1,20 @@
local TextTransform = {}
--- Pops up a selection 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.
function TextTransform.show_popup()
local config = _G.TextTransform.config
if config.popup_type == "telescope" then
local telescope = require("text-transform.popup.telescope")
telescope.telescope_popup()
else
local select = require("text-transform.popup.select")
select.select_popup()
end
end
return TextTransform

View File

@@ -0,0 +1,30 @@
local common = require("text-transform.popup.common")
local state = require("text-transform.state")
local TextTransform = {}
--- Pops up a selection 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.
function TextTransform.select_popup()
common.load_frequency()
state.save_positions()
vim.ui.select(common.items, {
prompt = "Change Case",
format_item = function(item)
return item.label
end,
}, function(choice)
if not choice then
return
end
local item = common.entry_maker(choice)
common.select(item)
end)
end
return TextTransform

View File

@@ -0,0 +1,104 @@
local common = require("text-transform.popup.common")
local D = require("text-transform.utils.debug")
local state = require("text-transform.state")
local pickers = require("telescope.pickers")
local finders = require("telescope.finders")
local telescope_conf = require("telescope.config").values
local actions = require("telescope.actions")
local action_state = require("telescope.actions.state")
local dropdown = require("telescope.themes").get_dropdown({})
local Sorter = require("telescope.sorters").Sorter
local TextTransform = {}
local frequency_sorter = Sorter:new({
---@diagnostic disable-next-line: unused-local
scoring_function = function(self, prompt, line)
local generic_sorter = telescope_conf.generic_sorter()
generic_sorter:init()
local entry
for _, item in ipairs(common.items) do
if item.label == line then
entry = common.entry_maker(item)
break
end
end
D.log("frequency_sorter", "entry %s", vim.inspect(entry))
D.log("frequency_sorter", "prompt %s line %s", prompt, line)
-- Basic filtering based on prompt matching, non-matching items score below 0 to exclude them
local basic_score = (generic_sorter:scoring_function(prompt, line) or 1)
D.log("frequency_sorter", "%s basic_score: %s", entry.value, basic_score)
if basic_score < 0 then
return basic_score
end
-- D.log("frequency_sorter", "entry: %s", vim.inspect(entry))
-- D.log("frequency_sorter", "prompt: %s", prompt)
-- Calculate score based on frequency, higher frequency should have lower score
local freq_score = (entry.frequency or 1) * 10
D.log("frequency_sorter", "freq_score: %s", freq_score)
local final_score = 999999999 - freq_score + basic_score
D.log("frequency_sorter", "%s final_score: %s", line, final_score)
-- Combine scores, with frequency having the primary influence if present
return final_score
end,
})
local generic_sorter = telescope_conf.generic_sorter()
local sorter_map = {
frequency = frequency_sorter,
name = generic_sorter,
}
--- 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.
function TextTransform.telescope_popup()
state.save_positions()
local filtered = {}
local config = _G.TextTransform.config
local sorter = sorter_map[config.sort_by] or generic_sorter
if config.sort_by == "frequency" then
common.load_frequency()
end
for _, item in ipairs(common.items) do
if config.replacers[item.value] and not config.replacers[item.value].enabled then
goto continue
end
table.insert(filtered, item)
::continue::
end
local picker = pickers.new(dropdown, {
prompt_title = "Change Case",
finder = finders.new_table({
results = common.items,
entry_maker = common.entry_maker,
}),
sorter = sorter,
attach_mappings = function(prompt_bufnr)
actions.select_default:replace(function()
local selection = action_state.get_selected_entry()
common.inc_frequency(selection.value)
actions.close(prompt_bufnr)
common.select(selection)
end)
return true
end,
})
vim.schedule(function()
picker:find()
end)
end
return TextTransform

View File

@@ -1,14 +1,13 @@
local D = require("text-transform.util.debug") local D = require("text-transform.utils.debug")
local state = require("text-transform.state") local S = require("text-transform.state")
local utils = require("text-transform.util")
local t = require("text-transform.transformers") local t = require("text-transform.transformers")
local TextTransform = {} local TextTransform = {}
--- Finds the boundaries of the surrounding word around `start_col` within `line`. --- Finds the boundaries of the surrounding word around `start_col` within `line`.
--- @param line number ---@param line number
--- @param start_col number ---@param start_col number
--- @return number start_col, number end_col ---@return number start_col, number end_col
local function find_word_boundaries(line, start_col) local function find_word_boundaries(line, start_col)
local line_text = vim.fn.getline(line) local line_text = vim.fn.getline(line)
-- dashes, underscores, and periods are considered part of a word -- dashes, underscores, and periods are considered part of a word
@@ -19,16 +18,28 @@ local function find_word_boundaries(line, start_col)
local word_end_col = vim.fn.match(line_text:sub(word_start_col), non_word_pat) local word_end_col = vim.fn.match(line_text:sub(word_start_col), non_word_pat)
+ word_start_col + word_start_col
- 1 - 1
D.log("replacers", "Found word boundaries: %s", vim.inspect({ word_start_col, word_end_col })) D.log(
D.log("replacers", "Word text: %s", line_text:sub(word_start_col, word_end_col)) "find_word_boundaries",
D.log("replacers", "Line text: %s", line_text) "Found word boundaries: %s",
vim.inspect({ word_start_col, word_end_col })
)
D.log("find_word_boundaries", "Word text: %s", line_text:sub(word_start_col, word_end_col))
D.log("find_word_boundaries", "Line text: %s", line_text)
return word_start_col, word_end_col return word_start_col, word_end_col
end end
--- Replace the range between the given positions with the given transform.
--- Acts on the lines between the given positions, replacing the text between the given columns.
---
---@param start_line number The starting line
---@param start_col number The starting column
---@param end_line number The ending line
---@param end_col number The ending column
---@param transform_name string The transformer name
function TextTransform.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) D.log("replace_range", "Replacing range with %s", transform_name)
local transform = t["to_" .. transform_name] local transform = t["to_" .. transform_name]
local lines = vim.fn.getline(start_line, end_line) --- @type any local lines = vim.fn.getline(start_line, end_line) ---@type any
local transformed = {} local transformed = {}
if #lines == 1 then if #lines == 1 then
local line = lines[1] local line = lines[1]
@@ -55,10 +66,10 @@ end
--- If `position` is provided, replace the word under the given position. --- If `position` is provided, replace the word under the given position.
--- Otherwise, attempts to find the word under the cursor. --- Otherwise, attempts to find the word under the cursor.
--- ---
--- @param transform_name string The transformer name ---@param transform_name string The transformer name
--- @param position table|nil A table containing the position of the word to replace ---@param position table|nil A table containing the position of the word to replace
function TextTransform.replace_word(transform_name, position) function TextTransform.replace_word(transform_name, position)
D.log("replacers", "Replacing word with %s", transform_name) D.log("replace_word", "Replacing word with %s", transform_name)
local word, line, col, start_col, end_col local word, line, col, start_col, end_col
if not position then if not position then
word = vim.fn.expand("<cword>") word = vim.fn.expand("<cword>")
@@ -67,11 +78,11 @@ function TextTransform.replace_word(transform_name, position)
start_col, end_col = find_word_boundaries(line, col) start_col, end_col = find_word_boundaries(line, col)
word = vim.fn.getline(line):sub(start_col, end_col) word = vim.fn.getline(line):sub(start_col, end_col)
end end
D.log("replacers", "Found word %s", word) D.log("replace_word", "Found word %s", word)
D.log("replacers", "Using transformer %s", transform_name) D.log("replace_word", "Using transformer %s", transform_name)
local transformer = t["to_" .. transform_name] local transformer = t["to_" .. transform_name]
local transformed = transformer(word) local transformed = transformer(word)
D.log("replacers", "New value %s", transformed) D.log("replace_word", "New value %s", transformed)
if not position then if not position then
vim.cmd("normal ciw" .. transformed) vim.cmd("normal ciw" .. transformed)
else else
@@ -81,9 +92,11 @@ end
--- Replaces each column in visual block mode 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. --- Assumes that the each selection is 1 character and operates on the whole word under each cursor.
---
---@param transform_name string The transformer name
function TextTransform.replace_columns(transform_name) function TextTransform.replace_columns(transform_name)
local selections = TextTransform.get_visual_selection_details() local selections = TextTransform.get_visual_selection_details()
D.log("replacers", "Replacing columns with %s", transform_name) D.log("replace_columns", "Replacing columns with %s", transform_name)
for _, sel in ipairs(selections) do for _, sel in ipairs(selections) do
TextTransform.replace_word(transform_name, { 0, sel.start_line, sel.start_col, 0 }) TextTransform.replace_word(transform_name, { 0, sel.start_line, sel.start_col, 0 })
end end
@@ -93,22 +106,24 @@ end
--- type based on the cursor positiono and visual selections, and passes information to relevant --- type based on the cursor positiono and visual selections, and passes information to relevant
--- range replacement functions. --- range replacement functions.
--- ---
--- @param transform_name string The transformer name ---@param transform_name string The transformer name
function TextTransform.replace_selection(transform_name) function TextTransform.replace_selection(transform_name)
D.log("replacers", "Replacing selection with %s", transform_name) D.log("replace_selection", "Replacing selection with %s", transform_name)
-- determine if cursor is a 1-width column across multiple lines or a normal selection -- 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 start_line, start_col, end_line, end_col = unpack(vim.fn.getpos("'<"))
local selections = TextTransform.get_visual_selection_details() local selections = TextTransform.get_visual_selection_details()
D.log("replacers", "Selections: %s", utils.dump(selections)) D.log("replace_selection", "Selections: %s", vim.inspect(selections))
local is_multiline = #selections > 1 local is_multiline = #selections > 1
local is_column = is_multiline and selections[1].start_col == selections[#selections].end_col local is_column = is_multiline and selections[1].start_col == selections[#selections].end_col
local is_single_cursor = not is_multiline local is_single_cursor = not is_multiline
and not is_column and not is_column
and selections
and selections[1]
and selections[1].start_col == selections[1].end_col and selections[1].start_col == selections[1].end_col
D.log( D.log(
"replacers", "replace_selection",
"is_multiline: %s, is_column: %s, is_word: %s", "is_multiline: %s, is_column: %s, is_word: %s",
is_multiline, is_multiline,
is_column, is_column,
@@ -138,16 +153,32 @@ end
--- This allows to treat all ranges equally and allows to work on each selection without knowing --- This allows to treat all ranges equally and allows to work on each selection without knowing
--- the full information around the selection logic. --- the full information around the selection logic.
function TextTransform.get_visual_selection_details() function TextTransform.get_visual_selection_details()
if not S.state.positions.pos then
D.log("get_visual_selection_details", "No positions saved")
return {}
end
D.log( D.log(
"replacers", "get_visual_selection_details",
"Getting visual selection details - mode: %s, is_visual: %s, is_block: %s", "Getting visual selection details - mode: %s, is_visual: %s, is_block: %s",
state.positions.mode, S.state.mode,
utils.is_visual_mode(), S.is_visual_mode(),
utils.is_block_visual_mode() S.is_block_visual_mode()
) )
-- Get the start and end positions of the selection
local start_pos = S.state.positions.visual_start
local end_pos = S.state.positions.visual_end
local start_line, start_col = start_pos[2], start_pos[3]
local end_line, end_col = end_pos[2], end_pos[3]
-- Check if currently in visual mode; if not, return the cursor position -- Check if currently in visual mode; if not, return the cursor position
if not utils.is_visual_mode() and not utils.is_block_visual_mode() then if
local pos = state.positions.pos not S.is_visual_mode()
and not S.is_block_visual_mode()
and not S.has_range(start_pos, end_pos)
then
D.log("get_visual_selection_details", "Returning single cursor position: " .. vim.inspect(S))
local pos = S.state.positions.pos
return { return {
{ {
start_line = pos[2], start_line = pos[2],
@@ -158,12 +189,6 @@ function TextTransform.get_visual_selection_details()
} }
end end
-- Get the start and end positions of the selection
local start_pos = state.positions.visual_start
local end_pos = state.positions.visual_end
local start_line, start_col = start_pos[2], start_pos[3]
local end_line, end_col = end_pos[2], end_pos[3]
-- Swap if selection is made upwards or backwards -- Swap if selection is made upwards or backwards
if start_line > end_line or (start_line == end_line and start_col > end_col) then if start_line > end_line or (start_line == end_line and start_col > end_col) then
start_line, end_line = end_line, start_line start_line, end_line = end_line, start_line
@@ -171,7 +196,7 @@ function TextTransform.get_visual_selection_details()
end end
-- If it's block visual mode, return table for each row -- If it's block visual mode, return table for each row
if utils.is_block_visual_mode() then if S.is_block_visual_mode() or S.has_range(start_pos, end_pos) then
local block_selection = {} local block_selection = {}
for line = start_line, end_line do for line = start_line, end_line do
if start_col == end_col then if start_col == end_col then
@@ -185,9 +210,15 @@ function TextTransform.get_visual_selection_details()
end_col = start_col, end_col = start_col,
}) })
end end
D.log(
"get_visual_selection_details",
"Returning block selection: %s",
vim.inspect(block_selection)
)
return block_selection return block_selection
else else
-- Normal visual mode, return single table entry -- Normal visual mode, return single table entry
D.log("get_visual_selection_details", "Returning normal selection")
return { return {
{ {
start_line = start_line, start_line = start_line,

View File

@@ -1,59 +1,16 @@
local D = require("text-transform.util.debug") local D = require("text-transform.utils.debug")
local function ensure_config()
-- when the config is not set to the global object, we set it
if _G.TextTransform.config == nil then
_G.TextTransform.config = require("text-transform.config").options
end
end
-- methods -- methods
local TextTransform = { local TextTransform = {
-- Boolean determining if the plugin is enabled or not. -- The current state of the plugin
enabled = false, state = {
-- A table containing cursor position and visual selection details, -- A table containing cursor position and visual selection details,
-- saved using `save_position()` and can be restored using `restore_positions()` -- saved using `save_position()` and can be restored using `restore_positions()`
positions = nil, --@type {buf: number, mode: string, pos: table, visual_start: table, visual_end: table}
positions = {},
},
} }
--- Toggle the plugin by calling the `enable`/`disable` methods respectively.
--- @private
function TextTransform.toggle()
if TextTransform.enabled then
return TextTransform.disable()
end
return TextTransform.enable()
end
--- Enables the plugin
--- @private
function TextTransform.enable()
ensure_config()
if TextTransform.enabled then
return TextTransform
end
TextTransform.enabled = true
return TextTransform
end
---Disables the plugin and reset the internal state.
---@private
function TextTransform.disable()
ensure_config()
if not TextTransform.enabled then
return TextTransform
end
-- reset the state
TextTransform.enabled = false
TextTransform.positions = nil
return TextTransform
end
local function get_mode_type(mode) local function get_mode_type(mode)
-- classify mode as either visual, line, block or normal -- classify mode as either visual, line, block or normal
local mode_map = { local mode_map = {
@@ -64,42 +21,67 @@ local function get_mode_type(mode)
return mode_map[mode] or "normal" return mode_map[mode] or "normal"
end end
function TextTransform.has_range(visual_start, visual_end)
return visual_start and visual_end and visual_start[2] ~= visual_end[2]
end
local function capture_part(start_sel, end_sel, return_type)
local l, sel
if return_type == "start" then
l = math.min(start_sel[2], end_sel[2])
sel = start_sel
else
l = math.max(start_sel[2], end_sel[2])
sel = end_sel
end
return { sel[1], l, sel[3], sel[4] }
end
function TextTransform.is_block_visual_mode()
return TextTransform.state.positions.mode == "block"
-- return vim.fn.mode() == "V" or vim.fn.mode() == "\22"
end
function TextTransform.is_visual_mode()
return TextTransform.state.positions.mode == "visual"
-- return vim.fn.mode() == 'v'
end
--- Save the current cursor position, mode, and visual selection ranges --- Save the current cursor position, mode, and visual selection ranges
--- @private
function TextTransform.save_positions() function TextTransform.save_positions()
local buf = vim.api.nvim_get_current_buf() local buf = vim.api.nvim_get_current_buf()
local mode_info = vim.api.nvim_get_mode() local mode_info = vim.api.nvim_get_mode()
local mode = get_mode_type(mode_info.mode) local mode = get_mode_type(mode_info.mode)
local pos = vim.fn.getcurpos() local pos = vim.fn.getcurpos()
-- leave mode -- leave mode, required to get the positions - they only register on mode leave
-- in case of visual mode
local esc = vim.api.nvim_replace_termcodes("<esc>", true, false, true) local esc = vim.api.nvim_replace_termcodes("<esc>", true, false, true)
vim.api.nvim_feedkeys(esc, "x", true) vim.api.nvim_feedkeys(esc, "x", true)
local visual_start = vim.fn.getpos("'<") local visual_start = vim.fn.getpos("'<")
local visual_end = vim.fn.getpos("'>") local visual_end = vim.fn.getpos("'>")
D.log("popup_menu", "Saved mode %s, cursor %s", mode, vim.inspect(pos)) D.log("save_positions", "Saved mode %s, cursor %s", mode, vim.inspect(pos))
if mode == "visual" or mode == "line" or mode == "block" then if mode == "visual" or mode == "line" or mode == "block" then
if mode == "block" then -- for block visual mode if TextTransform.has_range(visual_start, visual_end) then -- for ranges
D.log("popup_menu", "Visual mode is block, %s", vim.inspect({ visual_start, visual_end })) D.log(
"save_positions",
"Visual range, mode is %s, %s",
mode,
vim.inspect({ visual_start, visual_end })
)
-- Adjust the positions to correctly capture the entire block -- Adjust the positions to correctly capture the entire block
visual_start = { visual_start = capture_part(visual_start, visual_end, "start")
visual_start[1], visual_end = capture_part(visual_start, visual_end, "end")
math.min(visual_start[2], visual_end[2]),
visual_start[3],
visual_start[4],
}
visual_end =
{ visual_end[1], math.max(visual_start[2], visual_end[2]), visual_end[3], visual_end[4] }
end end
D.log( D.log(
"popup_menu", "state",
"Saved visual mode %s, cursor %s", "Saved visual mode %s, cursor %s",
mode, mode,
vim.inspect({ visual_start, visual_end }) vim.inspect({ visual_start, visual_end })
) )
end end
local state = { local positions = {
buf = buf, buf = buf,
mode = mode, mode = mode,
pos = pos, pos = pos,
@@ -107,32 +89,38 @@ function TextTransform.save_positions()
visual_end = visual_end, visual_end = visual_end,
} }
D.log("popup_menu", "State: %s", vim.inspect(state)) D.log("save_positions", "State: %s", vim.inspect(positions))
TextTransform.positions = state TextTransform.state.positions = positions
return state return positions
end end
--- Restore the cursor position, mode, and visual selection ranges saved using `save_position()`, --- Restore the cursor position, mode, and visual selection ranges saved using `save_position()`,
--- or a given modified state, if passed as the first argument --- or a given modified state, if passed as the first argument
function TextTransform.restore_positions(state) function TextTransform.restore_positions(positions)
state = state or TextTransform.positions positions = positions or TextTransform.state.positions
vim.api.nvim_set_current_buf(state.buf) vim.api.nvim_set_current_buf(positions.buf)
vim.fn.setpos(".", state.pos) vim.fn.setpos(".", positions.pos)
D.log("popup_menu", "Restored mode %s, cursor %s", state.mode, vim.inspect(state.pos)) D.log(
"restore_positions",
"Restored mode %s, cursor %s",
positions.mode,
vim.inspect(positions.pos)
)
-- Attempt to restore visual mode accurately -- Attempt to restore visual mode accurately
if if
(state.mode == "visual" or state.mode == "block") (positions.mode == "visual" or positions.mode == "block")
and state.visual_start and positions.visual_start
and state.visual_end and positions.visual_end
then then
vim.fn.setpos("'<", state.visual_start) vim.fn.setpos("'<", positions.visual_start)
vim.fn.setpos("'>", state.visual_end) vim.fn.setpos("'>", positions.visual_end)
local command = "normal! gv" local command = "normal! gv"
vim.cmd(command) vim.cmd(command)
D.log("popup_menu", [[Restored visual mode %s using "%s"]], state.mode, command) D.log("restore_positions", [[Restored visual mode %s using "%s"]], positions.mode, command)
end end
TextTransform.positions = nil
TextTransform.state.positions = {}
end end
return TextTransform return TextTransform

View File

@@ -1,153 +0,0 @@
local D = require("text-transform.util.debug")
local state = require("text-transform.state")
local replacers = require("text-transform.replacers")
local pickers = require("telescope.pickers")
local finders = require("telescope.finders")
local telescope_conf = require("telescope.config").values
local actions = require("telescope.actions")
local action_state = require("telescope.actions.state")
local dropdown = require("telescope.themes").get_dropdown({})
local Sorter = require("telescope.sorters").Sorter
local generic_sorter = telescope_conf.generic_sorter()
local TextTransform = {}
local items = {
{ label = "camelCase", value = "camel_case" },
{ label = "snake_case", value = "snake_case" },
{ label = "PascalCase", value = "pascal_case" },
{ label = "kebab-case", value = "kebab_case" },
{ label = "dot.case", value = "dot_case" },
{ label = "Title Case", value = "title_case" },
{ label = "CONST_CASE", value = "const_case" },
}
local default_frequency = {
camel_case = 1,
snake_case = 1,
pascal_case = 1,
kebab_case = 1,
dot_case = 1,
title_case = 1,
const_case = 1,
}
local frequency_file = vim.fn.stdpath("config") .. "/text-transform-frequency.json"
local frequency
local function load_frequency()
if frequency then
return frequency
end
if vim.fn.filereadable(frequency_file) == 0 then
frequency = default_frequency
vim.fn.writefile({ vim.fn.json_encode(frequency) }, frequency_file)
else
frequency = vim.fn.json_decode(vim.fn.readfile(frequency_file))
end
D.log("telescope", "frequency loaded: %s", vim.inspect(frequency))
return frequency
end
local function inc_frequency(name)
frequency[name] = (frequency[name] or 0) + 1
D.log("telescope", "new frequency: %s %d", name, frequency[name])
vim.fn.writefile({ vim.fn.json_encode(frequency) }, frequency_file)
end
local function entry_maker(entry)
return {
value = entry.value,
display = entry.label,
ordinal = entry.label,
frequency = frequency[entry.value] or 1,
}
end
local frequency_sorter = Sorter:new({
---@diagnostic disable-next-line: unused-local
scoring_function = function(self, prompt, line)
local entry
for _, item in ipairs(items) do
if item.label == line then
entry = entry_maker(item)
break
end
end
-- Basic filtering based on prompt matching, non-matching items score below 0 to exclude them
local basic_score = generic_sorter:score(prompt, entry) or 0
-- D.log("telescope", "basic_score: %s", basic_score)
if basic_score < 0 then
return basic_score
end
-- D.log("telescope", "entry: %s", vim.inspect(entry))
-- D.log("telescope", "prompt: %s", prompt)
-- Calculate score based on frequency, higher frequency should have lower score
local freq_score = (entry.frequency or 1) -- Multiply by -1 because we want higher frequency to have lower score
-- D.log("telescope", "freq_score: %s", freq_score)
D.log("telescope", "%s final_score: %s", line, 99999999 - freq_score * 100 + basic_score)
-- Combine scores, with frequency having the primary influence if present
return 99999999 - freq_score * 100 + basic_score -- Division to ensure frequency has a higher weight
end,
})
---@diagnostic disable-next-line: unused-local
-- for _i, k in pairs(default_ordered_keys) do
-- local v = map[k]
-- vim.cmd("amenu TransformsWord." .. k .. " :lua TextTransform.replace_word('" .. v .. "')<CR>")
-- vim.cmd(
-- "amenu TransformsSelection." .. k .. " :lua TextTransform.replace_columns('" .. v .. "')<CR>"
-- )
-- 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.
function TextTransform.popup()
state.save_positions()
load_frequency()
local filtered = {}
print(vim.inspect(_G.TextTransform.config))
local config = _G.TextTransform.config
for _, item in ipairs(items) do
if not config.replacers[item.value] or not config.replacers[item.value].enabled then
goto continue
end
table.insert(filtered, item)
::continue::
end
local picker = pickers.new(dropdown, {
prompt_title = "Change Case",
finder = finders.new_table({
results = items,
entry_maker = entry_maker,
}),
sorter = frequency_sorter,
attach_mappings = function(prompt_bufnr)
actions.select_default:replace(function()
local selection = action_state.get_selected_entry()
inc_frequency(selection.value)
actions.close(prompt_bufnr)
vim.schedule(function()
replacers.replace_selection(selection.value)
state.restore_positions()
end)
end)
return true
end,
})
vim.schedule(function()
picker:find()
end)
end
return TextTransform

View File

@@ -1,13 +1,13 @@
local D = require("text-transform.util.debug") local D = require("text-transform.utils.debug")
local utils = require("text-transform.util") -- local utils = require("text-transform.utils")
local TextTransform = {} local TextTransform = {}
TextTransform.WORD_BOUNDRY = "[%_%-%s%.]" TextTransform.WORD_BOUNDRY = "[%_%-%s%.]"
--- Splits a string into words. --- Splits a string into words.
--- @param string string ---@param string string
--- @return table ---@return table
function TextTransform.to_words(string) function TextTransform.to_words(string)
local words = {} local words = {}
local word = "" local word = ""
@@ -47,12 +47,12 @@ function TextTransform.to_words(string)
-- Append current character to the current word -- Append current character to the current word
word = word .. char word = word .. char
end end
D.log("transformers", "i %d char %s word %s words %s", i, char, word, utils.dump(words)) -- D.log("to_words", "i %d char %s word %s words %s", i, char, word, utils.dump(words))
end end
if word ~= "" then if word ~= "" then
table.insert(words, word:lower()) table.insert(words, word:lower())
end end
D.log("transformers", "words %s", vim.inspect(words)) D.log("to_words", "words %s", vim.inspect(words))
return words return words
end end
@@ -60,10 +60,10 @@ end
--- The callback is called with the word, the index, and the table of words. --- The callback is called with the word, the index, and the table of words.
--- The separator is added between each word. --- The separator is added between each word.
--- ---
--- @param words string|table string or table of strings ---@param words string|table string or table of strings
--- @param with_word_cb function (word: string, index: number, words: table) -> string ---@param with_word_cb function (word: string, index: number, words: table) -> string
--- @param separator string|nil (optional) ---@param separator string|nil (optional)
--- @return string ---@return string
function TextTransform.transform_words(words, with_word_cb, separator) function TextTransform.transform_words(words, with_word_cb, separator)
if type(words) ~= "table" then if type(words) ~= "table" then
words = TextTransform.to_words(words) words = TextTransform.to_words(words)
@@ -75,14 +75,14 @@ function TextTransform.transform_words(words, with_word_cb, separator)
new_word = separator .. new_word new_word = separator .. new_word
end end
out = out .. new_word out = out .. new_word
D.log("transformers", "word %s (%d) new_word %s out %s", word, i, new_word, out) D.log("transform_words", "word %s (%d) new_word %s out %s", word, i, new_word, out)
end end
return out return out
end end
--- Transforms a string into camelCase. --- Transforms a string into camelCase.
--- @param string string ---@param string string
--- @return string ---@return string
function TextTransform.to_camel_case(string) function TextTransform.to_camel_case(string)
return TextTransform.transform_words(string, function(word, i) return TextTransform.transform_words(string, function(word, i)
if i == 1 then if i == 1 then
@@ -93,8 +93,8 @@ function TextTransform.to_camel_case(string)
end end
--- Transfroms a string into snake_case. --- Transfroms a string into snake_case.
--- @param string any ---@param string any
--- @return string ---@return string
function TextTransform.to_snake_case(string) function TextTransform.to_snake_case(string)
return TextTransform.transform_words(string, function(word, i) return TextTransform.transform_words(string, function(word, i)
if i == 1 then if i == 1 then
@@ -105,16 +105,16 @@ function TextTransform.to_snake_case(string)
end end
--- Transforms a string into PascalCase. --- Transforms a string into PascalCase.
--- @param string string ---@param string string
--- @return string ---@return string
function TextTransform.to_pascal_case(string) function TextTransform.to_pascal_case(string)
local cc = TextTransform.to_camel_case(string) local cc = TextTransform.to_camel_case(string)
return cc:sub(1, 1):upper() .. cc:sub(2) return cc:sub(1, 1):upper() .. cc:sub(2)
end end
--- Transforms a string into Title Case. --- Transforms a string into Title Case.
--- @param string string ---@param string string
--- @return string ---@return string
function TextTransform.to_title_case(string) function TextTransform.to_title_case(string)
return TextTransform.transform_words(string, function(word) return TextTransform.transform_words(string, function(word)
return word:sub(1, 1):upper() .. word:sub(2):lower() return word:sub(1, 1):upper() .. word:sub(2):lower()
@@ -122,8 +122,8 @@ function TextTransform.to_title_case(string)
end end
--- Transforms a string into kebab-case. --- Transforms a string into kebab-case.
--- @param string string ---@param string string
--- @return string ---@return string
function TextTransform.to_kebab_case(string) function TextTransform.to_kebab_case(string)
return TextTransform.transform_words(string, function(word) return TextTransform.transform_words(string, function(word)
return word:lower() return word:lower()
@@ -131,8 +131,8 @@ function TextTransform.to_kebab_case(string)
end end
--- Transforms a string into dot.case. --- Transforms a string into dot.case.
--- @param string string ---@param string string
--- @return string ---@return string
function TextTransform.to_dot_case(string) function TextTransform.to_dot_case(string)
return TextTransform.transform_words(string, function(word) return TextTransform.transform_words(string, function(word)
return word:lower() return word:lower()
@@ -140,8 +140,8 @@ function TextTransform.to_dot_case(string)
end end
--- Transforms a string into CONSTANT_CASE. --- Transforms a string into CONSTANT_CASE.
--- @param string string ---@param string string
--- @return string ---@return string
function TextTransform.to_const_case(string) function TextTransform.to_const_case(string)
return TextTransform.transform_words(string, function(word) return TextTransform.transform_words(string, function(word)
return word:upper() return word:upper()

View File

@@ -1,33 +0,0 @@
local state = require("text-transform.state")
local utils = {}
--- Merges two tables into one. Same as `vim.tbl_extend("keep", t1, t2)`.
--- Mutates the first table.
---
--- TODO accept multiple tables to merge
---
--- @param t1 table
--- @param t2 table
--- @return table
function utils.merge(t1, t2)
return vim.tbl_extend("force", t1, t2)
end
--- Dumps the object into a string.
--- @param obj any
--- @return string
function utils.dump(obj)
return vim.inspect(obj)
end
function utils.is_block_visual_mode()
return state.positions.mode == "block"
-- return vim.fn.mode() == "V" or vim.fn.mode() == "\22"
end
function utils.is_visual_mode()
return state.positions.mode == "visual"
-- return vim.fn.mode() == 'v'
end
return utils

View File

@@ -6,12 +6,6 @@ local function is_debug()
and _G.TextTransform.config.debug and _G.TextTransform.config.debug
end end
---prints only if debug is true.
---
---@param scope string: the scope from where this function is called.
---@param str string: the formatted string.
---@param ... any: the arguments of the formatted string.
---@private
function D.log(scope, str, ...) function D.log(scope, str, ...)
if not is_debug() then if not is_debug() then
return return
@@ -26,20 +20,15 @@ function D.log(scope, str, ...)
print( print(
string.format( string.format(
"[text-transform:%s %s in %s] > %s", "%s [text-transform:%s in %s] > %s",
os.date("%H:%M:%S"), os.date("%H:%M:%S"),
line,
scope, scope,
line,
string.format(str, ...) string.format(str, ...)
) )
) )
end end
---prints the table if debug is true.
---
---@param table table: the table to print.
---@param indent number?: the default indent value, starts at 0.
---@private
function D.tprint(table, indent) function D.tprint(table, indent)
if not is_debug() then if not is_debug() then
return return

View File

@@ -0,0 +1,19 @@
local TextTransform = {}
--- Merges two tables into one. Same as `vim.tbl_extend("keep", t1, t2)`.
--- Mutates the first table.
---
--- TODO accept multiple tables to merge
---
---@param t1 table
---@param t2 table
---@return table
function TextTransform.merge(t1, t2)
return vim.tbl_extend("force", t1, t2)
end
function TextTransform.has_range(visual_start, visual_end)
return visual_start and visual_end and visual_start[2] ~= visual_end[2]
end
return TextTransform

View File

@@ -1,3 +1,4 @@
local MiniTest = require("mini.test")
-- partially imported from https://github.com/echasnovski/mini.nvim -- partially imported from https://github.com/echasnovski/mini.nvim
local Helpers = {} local Helpers = {}
@@ -162,4 +163,9 @@ Helpers.new_child_neovim = function()
return child return child
end end
function Helpers.init_plugin(child, config)
config = config or ""
child.lua([[require('text-transform').setup(]] .. config .. [[)]])
end
return Helpers return Helpers

View File

@@ -32,11 +32,6 @@ T["setup()"]["sets exposed methods and default options value"] = function()
-- global object that holds your plugin information -- global object that holds your plugin information
eq_type_global(child, "_G.TextTransform", "table") 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 -- config
eq_type_global(child, "_G.TextTransform.config", "table") eq_type_global(child, "_G.TextTransform.config", "table")
@@ -55,14 +50,17 @@ T["setup()"]["sets exposed methods and default options value"] = function()
end end
T["setup()"]["overrides default values"] = function() T["setup()"]["overrides default values"] = function()
child.lua([[require('text-transform').setup({ helpers.init_plugin(
child,
[[{
-- write all the options with a value different than the default ones -- write all the options with a value different than the default ones
debug = true, debug = true,
keymap = { keymap = {
["v"] = "<leader>c", ["v"] = "<leader>c",
["n"] = "<leader>c", ["n"] = "<leader>c",
}, },
})]]) }]]
)
-- assert the value, and the type -- assert the value, and the type
eq_type_config(child, "debug", "boolean") eq_type_config(child, "debug", "boolean")

63
tests/test_popups.lua Normal file
View File

@@ -0,0 +1,63 @@
local helpers = dofile("tests/helpers.lua")
local MiniTest = require("mini.test")
-- 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["popups"] = MiniTest.new_set()
T["popups"]["exposes show_popup"] = function()
helpers.init_plugin(child)
eq_type_global(child, "_G.TextTransform", "table")
eq_type_global(child, "_G.TextTransform.show_popup", "function")
eq_type_global(child, "_G.TextTransform.telescope_popup", "nil")
end
T["popups"]["telescope exposes telescope_popup"] = function()
helpers.init_plugin(child)
eq_type_global(child, "_G.TextTransform", "table")
eq_type_global(child, "_G.TextTransform.telescope_popup", "nil")
child.lua([[Telescope = require('text-transform.popup.telescope')]])
eq_type_global(child, "Telescope.telescope_popup", "function")
end
T["popups"]["select exposes select_popup"] = function()
helpers.init_plugin(child)
eq_type_global(child, "_G.TextTransform", "table")
eq_type_global(child, "_G.TextTransform.select_popup", "nil")
child.lua([[Select = require('text-transform.popup.select')]])
eq_type_global(child, "Select.select_popup", "function")
end
return T

View File

@@ -24,7 +24,7 @@ local T = MiniTest.new_set({
}) })
local function test_string(child, str) local function test_string(child, str)
child.lua([[require('text-transform').setup()]]) helpers.init_plugin(child)
child.lua([[result = require('text-transform').to_words("]] .. str .. [[")]]) child.lua([[result = require('text-transform').to_words("]] .. str .. [[")]])
end end