diff --git a/README.md b/README.md index 9fccaf3..4a93e31 100644 --- a/README.md +++ b/README.md @@ -22,27 +22,27 @@ This includes lazy-loading on keymaps. If you install like this, you can ignore keys = { { "ai", - "lua require'treesitter_indent_object.textobj'.select_indent_outer()", + function() require'treesitter_indent_object.textobj'.select_indent_outer() end, mode = {"x", "o"}, desc = "Select context-aware indent (outer)", }, { "aI", - "lua require'treesitter_indent_object.textobj'.select_indent_outer(true)", + function() require'treesitter_indent_object.textobj'.select_indent_outer(true) end, mode = {"x", "o"}, desc = "Select context-aware indent (outer, line-wise)", }, { "ii", - "lua require'treesitter_indent_object.textobj'.select_indent_inner()", + function() require'treesitter_indent_object.textobj'.select_indent_inner() end, mode = {"x", "o"}, desc = "Select context-aware indent (inner, partial range)", }, { "iI", - "lua require'treesitter_indent_object.textobj'.select_indent_inner(true)", + function() require'treesitter_indent_object.textobj'.select_indent_inner(true, 'V') end, mode = {"x", "o"}, - desc = "Select context-aware indent (inner, entire range)", + desc = "Select context-aware indent (inner, entire range) in line-wise visual mode", }, }, }, @@ -50,7 +50,7 @@ This includes lazy-loading on keymaps. If you install like this, you can ignore
Click to see instructions for packer and vim-plug - + #### Example with Packer [wbthomason/packer.nvim](https://github.com/wbthomason/packer.nvim) @@ -94,7 +94,7 @@ require("indent_blankline").setup { require("treesitter_indent_object").setup() ``` -Key bindings are not configured by default. +Key bindings are not configured by default. Here are some examples. ```vim @@ -107,22 +107,22 @@ omap aI lua require'treesitter_indent_object.textobj'.select_indent_outer(t " vii to select inner block (only if block, only else block, etc.) xmap ii lua require'treesitter_indent_object.textobj'.select_indent_inner() omap ii lua require'treesitter_indent_object.textobj'.select_indent_inner() -" viI to select entire inner range (including if, else, etc.) -xmap iI lua require'treesitter_indent_object.textobj'.select_indent_inner(true) -omap iI lua require'treesitter_indent_object.textobj'.select_indent_inner(true) +" viI to select entire inner range (including if, else, etc.) in line-wise visual mode +xmap iI lua require'treesitter_indent_object.textobj'.select_indent_inner(true, 'V') +omap iI lua require'treesitter_indent_object.textobj'.select_indent_inner(true, 'V') ``` -Lua equivalent: +Lua equivalent: ```lua -- select context-aware indent -vim.keymap.set({"x", "o"}, "ai", "lua require'treesitter_indent_object.textobj'.select_indent_outer()") +vim.keymap.set({"x", "o"}, "ai", function() require'treesitter_indent_object.textobj'.select_indent_outer() end) -- ensure selecting entire line (or just use Vai) -vim.keymap.set({"x", "o"}, "aI", "lua require'treesitter_indent_object.textobj'.select_indent_outer(true)") +vim.keymap.set({"x", "o"}, "aI", function() require'treesitter_indent_object.textobj'.select_indent_outer(true) end) -- select inner block (only if block, only else block, etc.) -vim.keymap.set({"x", "o"}, "ii", "lua require'treesitter_indent_object.textobj'.select_indent_inner()") --- select entire inner range (including if, else, etc.) -vim.keymap.set({"x", "o"}, "iI", "lua require'treesitter_indent_object.textobj'.select_indent_inner(true)") +vim.keymap.set({"x", "o"}, "ii", function() require'treesitter_indent_object.textobj'.select_indent_inner() end) +-- select entire inner range (including if, else, etc.) in line-wise visual mode +vim.keymap.set({"x", "o"}, "iI", function() require'treesitter_indent_object.textobj'.select_indent_inner(true, 'V') end) ```
diff --git a/lua/treesitter_indent_object/textobj.lua b/lua/treesitter_indent_object/textobj.lua index 53dad6a..0df157b 100644 --- a/lua/treesitter_indent_object/textobj.lua +++ b/lua/treesitter_indent_object/textobj.lua @@ -13,15 +13,28 @@ local ts_indent_status, ts_indent = pcall(require, "nvim-treesitter.indent") local M = {} -local enter_visual_mode = function() +local enter_visual_mode = function(force_mode) -- enter visual mode if normal or operator-pending (no) mode -- Why? According to https://learnvimscriptthehardway.stevelosh.com/chapters/15.html -- If your operator-pending mapping ends with some text visually selected, Vim will operate on that text. -- Otherwise, Vim will operate on the text between the original cursor position and the new position. local mode = vim.api.nvim_get_mode() - --print(mode.mode, mode.blocking) - if mode.mode == 'no' or mode.mode == 'n' then - vim.cmd("normal! v") + + -- If set to 'V', try to force line-wise visual mode + if force_mode == 'V' then + if mode.mode == 'no' or mode.mode == 'n' or mode.mode == 'v' then + vim.cmd("normal! V") + end + -- If set to 'v', try to force char-wise visual mode + elseif force_mode == 'v' then + if mode.mode == 'no' or mode.mode == 'n' or mode.mode == 'V' then + vim.cmd("normal! v") + end + -- If not specified, respect the current visual mode + else + if mode.mode == 'no' or mode.mode == 'n' then + vim.cmd("normal! v") + end end end @@ -39,18 +52,18 @@ local update_selection = function (node, entire_line) end end -M.select_indent_outer = function(entire_line) +M.select_indent_outer = function(entire_line, force_mode) entire_line = entire_line or false -- We have to remember that end_col is end-exclusive local context_status, context_node, context_pattern = utils.get_current_context(vim.g.treesitter_indent_object_context_patterns, vim.g.treesitter_indent_object_use_treesitter_scope) if not context_status then return false end - enter_visual_mode() + enter_visual_mode(force_mode) update_selection(context_node, entire_line) end -M.select_indent_inner = function(select_all) +M.select_indent_inner = function(select_all, force_mode) select_all = select_all or false local use_ts_indent = ts_query_status and ts_indent_status and ts_query.has_indents(vim.bo.filetype) local indent_fn = nil @@ -192,7 +205,7 @@ M.select_indent_inner = function(select_all) -- end end - enter_visual_mode() + enter_visual_mode(force_mode) vim.api.nvim_win_set_cursor(0, {indented_row_start, 0}) vim.cmd("normal! ^o") vim.api.nvim_win_set_cursor(0, {indented_row_end, 0})