Skip to content

Commit

Permalink
fix: range commands
Browse files Browse the repository at this point in the history
  • Loading branch information
chenasraf committed May 5, 2024
1 parent b03e51c commit be4147b
Show file tree
Hide file tree
Showing 8 changed files with 117 additions and 78 deletions.
8 changes: 4 additions & 4 deletions doc/tags
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
TextTransform.config text-transform.txt /*TextTransform.config*
TextTransform.enable() text-transform.txt /*TextTransform.enable()*
TextTransform.get_visual_selection_details() text-transform.txt /*TextTransform.get_visual_selection_details()*
TextTransform.init_commands() text-transform.txt /*TextTransform.init_commands()*
TextTransform.replace_columns() text-transform.txt /*TextTransform.replace_columns()*
TextTransform.replace_selection() text-transform.txt /*TextTransform.replace_selection()*
TextTransform.replace_word() text-transform.txt /*TextTransform.replace_word()*
TextTransform.restore_positions() text-transform.txt /*TextTransform.restore_positions()*
TextTransform.save_positions() text-transform.txt /*TextTransform.save_positions()*
TextTransform.setup() text-transform.txt /*TextTransform.setup()*
TextTransform.to_camel_case() text-transform.txt /*TextTransform.to_camel_case()*
TextTransform.to_const_case() text-transform.txt /*TextTransform.to_const_case()*
Expand All @@ -16,10 +13,13 @@ TextTransform.to_pascal_case() text-transform.txt /*TextTransform.to_pascal_case
TextTransform.to_snake_case() text-transform.txt /*TextTransform.to_snake_case()*
TextTransform.to_title_case() text-transform.txt /*TextTransform.to_title_case()*
TextTransform.to_words() text-transform.txt /*TextTransform.to_words()*
TextTransform.toggle() text-transform.txt /*TextTransform.toggle()*
TextTransform.transform_words() text-transform.txt /*TextTransform.transform_words()*
find_word_boundaries() text-transform.txt /*find_word_boundaries()*
init() text-transform.txt /*init()*
state.enable() text-transform.txt /*state.enable()*
state.restore_positions() text-transform.txt /*state.restore_positions()*
state.save_positions() text-transform.txt /*state.save_positions()*
state.toggle() text-transform.txt /*state.toggle()*
telescope.telescope_popup() text-transform.txt /*telescope.telescope_popup()*
utils.dump() text-transform.txt /*utils.dump()*
utils.merge() text-transform.txt /*utils.merge()*
16 changes: 8 additions & 8 deletions doc/text-transform.txt
Original file line number Diff line number Diff line change
Expand Up @@ -117,26 +117,26 @@ the full information around the selection logic.

==============================================================================
------------------------------------------------------------------------------
*TextTransform.toggle()*
`TextTransform.toggle`()
*state.toggle()*
`state.toggle`()
Toggle the plugin by calling the `enable`/`disable` methods respectively.
@private

------------------------------------------------------------------------------
*TextTransform.enable()*
`TextTransform.enable`()
*state.enable()*
`state.enable`()
Enables the plugin
@private

------------------------------------------------------------------------------
*TextTransform.save_positions()*
`TextTransform.save_positions`()
*state.save_positions()*
`state.save_positions`()
Save the current cursor position, mode, and visual selection ranges
@private

------------------------------------------------------------------------------
*TextTransform.restore_positions()*
`TextTransform.restore_positions`({state})
*state.restore_positions()*
`state.restore_positions`({new_state})
Restore the cursor position, mode, and visual selection ranges saved using `save_position()`,
or a given modified state, if passed as the first argument

Expand Down
9 changes: 6 additions & 3 deletions lua/text-transform/commands.lua
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
-- local D = require("text-transform.util.debug")
local state = require("text-transform.state")
local replacers = require("text-transform.replacers")
local popup = require("text-transform.popup")
Expand All @@ -16,22 +17,24 @@ function TextTransform.init_commands()
TtTitle = "title_case",
}

local cmdopts = { range = true, force = true }

for cmd, transformer_name in pairs(map) do
vim.api.nvim_create_user_command(cmd, function()
state.save_positions()
replacers.replace_selection(transformer_name)
end, {})
end, cmdopts)
end

-- specific popups
vim.api.nvim_create_user_command("TtTelescope", function()
local telescope = require("text-transform.telescope")
telescope.telescope_popup()
end, {})
end, cmdopts)
vim.api.nvim_create_user_command("TtSelect", function()
local select = require("text-transform.select")
select.select_popup()
end, {})
end, cmdopts)

-- auto popup by config
vim.api.nvim_create_user_command("TextTransform", popup.show_popup, {})
Expand Down
62 changes: 40 additions & 22 deletions lua/text-transform/replacers.lua
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,18 @@ local function find_word_boundaries(line, start_col)
local word_end_col = vim.fn.match(line_text:sub(word_start_col), non_word_pat)
+ word_start_col
- 1
D.log("replacers", "Found word boundaries: %s", vim.inspect({ word_start_col, word_end_col }))
D.log("replacers", "Word text: %s", line_text:sub(word_start_col, word_end_col))
D.log("replacers", "Line text: %s", line_text)
D.log(
"find_word_boundaries",
"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
end

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 lines = vim.fn.getline(start_line, end_line) --- @type any
local transformed = {}
Expand Down Expand Up @@ -58,7 +62,7 @@ end
--- @param transform_name string The transformer name
--- @param position table|nil A table containing the position of the word to replace
function TextTransform.replace_word(transform_name, position)
D.log("replacers", "Replacing word with %s", transform_name)
D.log("replace_word", "Replacing word with %s", transform_name)
local word, line, col, start_col, end_col
if not position then
word = vim.fn.expand("<cword>")
Expand All @@ -67,11 +71,11 @@ function TextTransform.replace_word(transform_name, position)
start_col, end_col = find_word_boundaries(line, col)
word = vim.fn.getline(line):sub(start_col, end_col)
end
D.log("replacers", "Found word %s", word)
D.log("replacers", "Using transformer %s", transform_name)
D.log("replace_word", "Found word %s", word)
D.log("replace_word", "Using transformer %s", transform_name)
local transformer = t["to_" .. transform_name]
local transformed = transformer(word)
D.log("replacers", "New value %s", transformed)
D.log("replace_word", "New value %s", transformed)
if not position then
vim.cmd("normal ciw" .. transformed)
else
Expand All @@ -83,7 +87,7 @@ end
--- Assumes that the each selection is 1 character and operates on the whole word under each cursor.
function TextTransform.replace_columns(transform_name)
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
TextTransform.replace_word(transform_name, { 0, sel.start_line, sel.start_col, 0 })
end
Expand All @@ -95,20 +99,22 @@ end
---
--- @param transform_name string The transformer 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
-- local start_line, start_col, end_line, end_col = unpack(vim.fn.getpos("'<"))
local selections = TextTransform.get_visual_selection_details()

D.log("replacers", "Selections: %s", utils.dump(selections))
D.log("replace_selection", "Selections: %s", utils.dump(selections))
local is_multiline = #selections > 1
local is_column = is_multiline and selections[1].start_col == selections[#selections].end_col
local is_single_cursor = not is_multiline
and not is_column
and selections
and selections[1]
and selections[1].start_col == selections[1].end_col

D.log(
"replacers",
"replace_selection",
"is_multiline: %s, is_column: %s, is_word: %s",
is_multiline,
is_column,
Expand Down Expand Up @@ -139,19 +145,31 @@ end
--- the full information around the selection logic.
function TextTransform.get_visual_selection_details()
if not state.positions then
D.log("replacers", "No positions saved")
D.log("get_visual_selection_details", "No positions saved")
return {}
end
D.log(
"replacers",
"get_visual_selection_details",
"Getting visual selection details - mode: %s, is_visual: %s, is_block: %s",
state.positions.mode,
utils.is_visual_mode(),
utils.is_block_visual_mode()
)

-- 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]

-- 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
not utils.is_visual_mode()
and not utils.is_block_visual_mode()
and not state.has_range(start_pos, end_pos)
then
local pos = state.positions.pos
D.log("get_visual_selection_details", "Returning single cursor position")
return {
{
start_line = pos[2],
Expand All @@ -162,20 +180,14 @@ function TextTransform.get_visual_selection_details()
}
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
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_col, end_col = end_col, start_col
end

-- If it's block visual mode, return table for each row
if utils.is_block_visual_mode() then
if utils.is_block_visual_mode() or state.has_range(start_pos, end_pos) then
local block_selection = {}
for line = start_line, end_line do
if start_col == end_col then
Expand All @@ -189,9 +201,15 @@ function TextTransform.get_visual_selection_details()
end_col = start_col,
})
end
D.log(
"get_visual_selection_details",
"Returning block selection: %s",
utils.dump(block_selection)
)
return block_selection
else
-- Normal visual mode, return single table entry
D.log("get_visual_selection_details", "Returning normal selection")
return {
{
start_line = start_line,
Expand Down
Loading

0 comments on commit be4147b

Please sign in to comment.