diff --git a/README.md b/README.md index 02c0d9f..e3922be 100644 --- a/README.md +++ b/README.md @@ -43,13 +43,16 @@ require('toggle').setup({ ### Keymap example ```lua -vim.keymap.set('n', 't', require('toggle').toggle, { desc = 'Toggle word' }) +-- v for visual mode, if needed +vim.keymap.set({ 'n', 'v' }, 't', require('toggle').toggle, { desc = 'Toggle word' }) ``` ## How it works -1. Gets the **word** under the cursor and checks for a mapping → replaces with `ciw` +1. Gets the **word** under the cursor and checks for a mapping → replaces with `ciw` / `ciW` 2. Falls back to the single **character** under the cursor → replaces with `r` +3. Also works for visual mode, in such case selection is being checked +4. Also checks if end of word matches anything in mappings and toggles it Mappings are circular: for a group like `{ 'public', 'protected', 'private' }`, each value cycles to the next, and the last wraps to the first. diff --git a/lua/toggle/defaults.lua b/lua/toggle/defaults.lua index eee4e1e..3ca35fe 100644 --- a/lua/toggle/defaults.lua +++ b/lua/toggle/defaults.lua @@ -11,6 +11,7 @@ return { -- short words { 'or', 'and' }, { 'on', 'off' }, + { 'in', 'out' }, { 'up', 'down' }, { 'get', 'set' }, { 'yes', 'no' }, diff --git a/lua/toggle/init.lua b/lua/toggle/init.lua index d801d9a..1b637d3 100644 --- a/lua/toggle/init.lua +++ b/lua/toggle/init.lua @@ -37,10 +37,11 @@ end function M.toggle() local replacers = { + replacer.__visual_mode_replacer, replacer.__get_cWORD_replacer, replacer.__get_cword_replacer, replacer.__get_end_of_word_replacer, - replacer.__character_replacer, + replacer.__get_character_replacer, } local current_cursor_position = vim.fn.getcurpos() diff --git a/lua/toggle/replacer.lua b/lua/toggle/replacer.lua index 7b03b79..f3cce87 100644 --- a/lua/toggle/replacer.lua +++ b/lua/toggle/replacer.lua @@ -66,4 +66,29 @@ M.__get_end_of_word_replacer = function() } end +M.__visual_mode_replacer = function() + local function is_visual_mode() + local mode = vim.api.nvim_get_mode().mode + return (mode == 'v') or (mode == 'V') + end + + local selected_text = '' + if is_visual_mode() then + local vstart = vim.fn.getpos('.') + local vend = vim.fn.getpos('v') + local lines = vim.fn.getregion(vstart, vend) + selected_text = lines[1] + end + + return { + can_handle = function() + return is_visual_mode() and mapping.__has_mapping(selected_text) + end, + + replace = function() + vim.api.nvim_command('norm! c' .. mapping.__get_mapping(selected_text)) + end, + } +end + return M diff --git a/test/test_files/test_1.txt b/test/test_files/test_1.txt index 50b2a23..230d2d3 100644 --- a/test/test_files/test_1.txt +++ b/test/test_files/test_1.txt @@ -2,3 +2,5 @@ false false, < goto_prev +thisisalongwordwithprotectedanotherwordinside +kaboomza diff --git a/test/toggle_spec.lua b/test/toggle_spec.lua index ba1a413..c230cd9 100644 --- a/test/toggle_spec.lua +++ b/test/toggle_spec.lua @@ -50,4 +50,23 @@ describe('toggle', function() assert(vim.fn.expand('') == 'goto_prev') end) end) + + it('toggle - no match', function() + open_file_at('test/test_files/test_1.txt', 6, 1, function() + toggle.toggle() + assert(vim.fn.expand('') == 'kaboomza') + toggle.toggle() + assert(vim.fn.expand('') == 'kaboomza') + end) + end) + + -- TODO + it('toggle - visual mode', function() + open_file_at('test/test_files/test_1.txt', 4, 5, function() + toggle.toggle() + assert(vim.fn.expand('') == 'goto_next') + toggle.toggle() + assert(vim.fn.expand('') == 'goto_prev') + end) + end) end)