Skip to content

Commit

Permalink
feat!(textobj): add support for around indentation
Browse files Browse the repository at this point in the history
This commit expects the opts table to provide a table for the ai and ii
text object settings. This will break if you have a previous version,
which used to accept a string.

Ref #2
  • Loading branch information
arsham committed Jul 15, 2022
1 parent 8cefd2d commit 034a3e7
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 14 deletions.
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Jumping along the indents (`[i`, `]i`):

![jumping](https://user-images.githubusercontent.com/428611/148661970-0aad20f2-61ce-4347-8971-6147556a1603.gif)

Text object (`dii`, `yii`, `vii`, etc.):
Text object (`dii`, `cai`, `yii`, `vai`, etc.):

![textobj](https://user-images.githubusercontent.com/428611/148661973-2d3cccad-715f-4f1e-a277-feb2e85396a9.gif)

Expand Down Expand Up @@ -65,7 +65,10 @@ Here is the default settings:
up = "[i",
down = "]i",
},
textobj = "ii",
textobj = {
ii = "ii",
ai = "ai",
},
}
```

Expand Down
54 changes: 42 additions & 12 deletions lua/indent-tools/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -96,12 +96,15 @@ end

---Selects all lines with equal or higher indents to the current line in line
-- visual mode. It ignores any empty lines.
local function in_indent() --{{{
-- @param around boolean? if true it will include empty lines around the
-- indentation.
local function in_indent(around) --{{{
local cur_line = vim.api.nvim_win_get_cursor(0)[1]
local cur_indent = vim.fn.indent(cur_line)
local total_lines = vim.api.nvim_buf_line_count(0)

local first_line = cur_line
local first_non_empty_line = cur_line
for i = cur_line, 0, -1 do
if cur_indent == 0 and #vim.fn.getline(i) == 0 then
-- If we are at column zero, we will stop at an empty line.
Expand All @@ -112,11 +115,13 @@ local function in_indent() --{{{
if indent < cur_indent then
break
end
first_non_empty_line = i
end
first_line = i
end

local last_line = cur_line
local last_non_empty_line = cur_line
for i = cur_line, total_lines, 1 do
if cur_indent == 0 and #vim.fn.getline(i) == 0 then
break
Expand All @@ -126,21 +131,54 @@ local function in_indent() --{{{
if indent < cur_indent then
break
end
last_non_empty_line = i
end
last_line = i
end

if not around then
first_line = first_non_empty_line
last_line = last_non_empty_line
end
local sequence = string.format("%dgg0o%dgg$V", first_line, last_line)
quick.normal("xt", sequence)
end
--}}}

local defaults = { --{{{
normal = { up = "[i", down = "]i" },
textobj = "ii",
textobj = { ii = "ii", ai = "ai" },
}
--}}}

local function setup_textobj(opts)
vim.validate({
opts = { opts, "table" },
ii = { opts.ii, { "string", "nil", "boolean" } },
ai = { opts.ai, { "string", "nil", "boolean" } },
})

if opts.ii then
local o = { silent = true, desc = "in indentation block" }
vim.keymap.set("v", opts.ii, function()
in_indent(false)
end, o)
vim.keymap.set("o", opts.ii, function()
quick.normal("x", "v" .. opts.ii)
end, o)
end

if opts.ai then
local o = { silent = true, desc = "around indentation block" }
vim.keymap.set("v", opts.ai, function()
in_indent(true)
end, o)
vim.keymap.set("o", opts.ai, function()
quick.normal("x", "v" .. opts.ai)
end, o)
end
end

return {
config = function(opts) --{{{
opts = vim.tbl_deep_extend("force", defaults, opts)
Expand All @@ -149,7 +187,7 @@ return {
normal = { opts.normal, { "table", "nil", "boolean" } },
normal_up = { opts.normal.up, { "string", "nil", "boolean" } },
normal_down = { opts.normal.down, { "string", "nil", "boolean" } },
textobj = { opts.textobj, { "string", "nil", "boolean" } },
textobj = { opts.textobj, { "table", "nil", "boolean" } },
})

if opts then
Expand All @@ -168,15 +206,7 @@ return {
end

if opts.textobj then
vim.keymap.set(
"v",
opts.textobj,
in_indent,
{ silent = true, desc = "in indentation block" }
)
vim.keymap.set("o", opts.textobj, function()
quick.normal("x", "v" .. opts.textobj)
end, { desc = "in indentation block" })
setup_textobj(opts.textobj)
end
end
end,
Expand Down

0 comments on commit 034a3e7

Please sign in to comment.