mirror of
https://github.com/chenasraf/text-transform.nvim.git
synced 2026-05-18 01:48:57 +00:00
Compare commits
26 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
335b3ad36d | ||
| 9e628239ab | |||
| d7dd1c4dd7 | |||
| 16069971e9 | |||
| 9c62c9cd9d | |||
| 33eecfffab | |||
| 701d373e7a | |||
| 1c8fa21578 | |||
|
|
1c39528e7c | ||
| 972a44cf1e | |||
| ecd4d6bbbc | |||
| ea38606a28 | |||
| 3362c3c4f1 | |||
| a9d3ffc2de | |||
| 168552b425 | |||
| 8e7fe74888 | |||
| 4bbba5d1b3 | |||
| eaf84d857d | |||
| 0cb9c1e4ee | |||
| 8de9125de1 | |||
| bb177a3360 | |||
| 67aef1de42 | |||
|
|
b44d58a533 | ||
| 6863e0e9a6 | |||
| 733f26fef6 | |||
| be9c119ee2 |
35
CHANGELOG.md
35
CHANGELOG.md
@@ -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
170
README.md
@@ -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
|
||||||
|
|||||||
13
doc/tags
13
doc/tags
@@ -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()*
|
|
||||||
|
|||||||
@@ -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:
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
|
||||||
67
lua/text-transform/popup/common.lua
Normal file
67
lua/text-transform/popup/common.lua
Normal 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
|
||||||
20
lua/text-transform/popup/init.lua
Normal file
20
lua/text-transform/popup/init.lua
Normal 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
|
||||||
30
lua/text-transform/popup/select.lua
Normal file
30
lua/text-transform/popup/select.lua
Normal 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
|
||||||
104
lua/text-transform/popup/telescope.lua
Normal file
104
lua/text-transform/popup/telescope.lua
Normal 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
|
||||||
@@ -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,
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
|
||||||
@@ -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()
|
||||||
|
|||||||
@@ -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
|
|
||||||
@@ -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
|
||||||
19
lua/text-transform/utils/init.lua
Normal file
19
lua/text-transform/utils/init.lua
Normal 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
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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
63
tests/test_popups.lua
Normal 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
|
||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user