diff --git a/lua/substitute.lua b/lua/substitute.lua index f73b360..5b44ebe 100644 --- a/lua/substitute.lua +++ b/lua/substitute.lua @@ -26,6 +26,7 @@ function substitute.operator(options) options = options or {} substitute.state.register = options.register or vim.v.register substitute.state.count = options.count or (vim.v.count > 0 and vim.v.count or 1) + substitute.state.wrappers = options.wrappers or nil if config.options.preserve_cursor_position then substitute.state.curpos = vim.api.nvim_win_get_cursor(0) end @@ -40,19 +41,25 @@ function substitute.operator_callback(vmode) local substitued_text = utils.text(0, marks.start, marks.finish, vmode) - local regcontents = vim.fn.getreg(substitute.state.register) - local regtype = vim.fn.getregtype(substitute.state.register) - local replacement = vim.split(regcontents:rep(substitute.state.count):gsub("\n$", ""), "\n") + local doSubstitution = function(state, _) + local regcontents = vim.fn.getreg(state.register) + local regtype = vim.fn.getregtype(state.register) + local replacement = vim.split(regcontents:rep(substitute.state.count):gsub("\n$", ""), "\n") - local subs_marks = utils.substitute_text(0, marks.start, marks.finish, vmode, replacement, regtype) + local subs_marks = utils.substitute_text(0, marks.start, marks.finish, vmode, replacement, regtype) - vim.api.nvim_buf_set_mark(0, "[", subs_marks[1].start.row, subs_marks[1].start.col, {}) - vim.api.nvim_buf_set_mark(0, "]", subs_marks[#subs_marks].finish.row, subs_marks[#subs_marks].finish.col - 1, {}) + vim.api.nvim_buf_set_mark(0, "[", subs_marks[1].start.row, subs_marks[1].start.col, {}) + vim.api.nvim_buf_set_mark(0, "]", subs_marks[#subs_marks].finish.row, subs_marks[#subs_marks].finish.col - 1, {}) - if config.options.highlight_substituted_text.enabled then - substitute.highlight_substituted_text(subs_marks) + if config.options.highlight_substituted_text.enabled then + substitute.highlight_substituted_text(subs_marks) + end end + local wrapper = substitute.state.wrappers or doSubstitution + + wrapper(substitute.state, doSubstitution) + if config.options.yank_substituted_text then vim.fn.setreg(utils.get_default_register(), table.concat(substitued_text, "\n"), utils.get_register_type(vmode)) end @@ -78,6 +85,7 @@ function substitute.line(options) motion = count .. "_", count = 1, register = options.register or vim.v.register, + wrappers = options.wrappers or nil, }) end @@ -87,6 +95,7 @@ function substitute.eol(options) motion = "$", register = options.register or vim.v.register, count = options.count or (vim.v.count > 0 and vim.v.count or 1), + wrappers = options.wrappers or nil, }) end @@ -94,6 +103,8 @@ function substitute.visual(options) options = options or {} substitute.state.register = options.register or vim.v.register substitute.state.count = options.count or (vim.v.count > 0 and vim.v.count or 1) + substitute.state.wrappers = options.wrappers or nil + vim.o.operatorfunc = "v:lua.require'substitute'.operator_callback" vim.api.nvim_feedkeys("g@`<", "ni", false) end diff --git a/lua/substitute/utils.lua b/lua/substitute/utils.lua index 56898d6..a69496d 100644 --- a/lua/substitute/utils.lua +++ b/lua/substitute/utils.lua @@ -23,6 +23,7 @@ end function utils.substitute_text(bufnr, start, finish, regtype, replacement, replacement_regtype) regtype = utils.get_register_type(regtype) + replacement_regtype = utils.get_register_type(replacement_regtype) if "l" == regtype then vim.api.nvim_buf_set_lines(bufnr, start.row - 1, finish.row, false, replacement) @@ -97,6 +98,13 @@ function utils.substitute_text(bufnr, start, finish, regtype, replacement, repla vim.api.nvim_buf_set_text(bufnr, start.row - 1, start.col, start.row - 1, start.col, replacement) else local current_row_len = vim.fn.getline(finish.row):len() + print(vim.inspect(replacement)) + if replacement_regtype == "l" then + table.insert(replacement, 1, "") + table.insert(replacement, "") + end + print(vim.inspect(replacement)) + vim.api.nvim_buf_set_text( bufnr, start.row - 1, diff --git a/lua/substitute/wrappers.lua b/lua/substitute/wrappers.lua new file mode 100644 index 0000000..c330154 --- /dev/null +++ b/lua/substitute/wrappers.lua @@ -0,0 +1,117 @@ +local wrappers = {} + +function wrappers.linewise(next) + return function(state, callback) + local body = vim.fn.getreg(state.register) + local type = vim.fn.getregtype(state.register) + + vim.fn.setreg(state.register, body, "l") + + if nil == next then + callback(state) + else + next(state, callback) + end + + vim.fn.setreg(state.register, body, type) + end +end + +function wrappers.charwise(next) + return function(state, callback) + local body = vim.fn.getreg(state.register) + local type = vim.fn.getregtype(state.register) + + local reformated_body = body:gsub("\n$", "") + vim.fn.setreg(state.register, reformated_body, "c") + + if nil == next then + callback(state) + else + next(state, callback) + end + + vim.fn.setreg(state.register, body, type) + end +end + +function wrappers.blockwise(next) + return function(state, callback) + local body = vim.fn.getreg(state.register) + local type = vim.fn.getregtype(state.register) + + vim.fn.setreg(state.register, body, "b") + + if nil == next then + callback(state) + else + next(state, callback) + end + + vim.fn.setreg(state.register, body, type) + end +end + +function wrappers.trim(next) + return function(state, callback) + local body = vim.fn.getreg(state.register) + + local reformated_body = body:gsub("^%s*", ""):gsub("%s*$", "") + vim.fn.setreg(state.register, reformated_body, vim.fn.getregtype(state.register)) + + if nil == next then + callback(state) + else + next(state, callback) + end + + vim.fn.setreg(state.register, body, vim.fn.getregtype(state.register)) + end +end + +function wrappers.join(next) + return function(state, callback) + local body = vim.fn.getreg(state.register) + + local reformated_body = body:gsub("%s*\r?\n%s*", " ") + vim.fn.setreg(state.register, reformated_body, vim.fn.getregtype(state.register)) + + if nil == next then + callback(state) + else + next(state, callback) + end + + vim.fn.setreg(state.register, body, vim.fn.getregtype(state.register)) + end +end + +function wrappers.change(change, next) + return function(state, callback) + if nil == next then + callback(state) + else + next(state, callback) + end + + local cursor_pos = vim.api.nvim_win_get_cursor(0) + vim.cmd(string.format("silent '[,']normal! %s", change)) + vim.api.nvim_win_set_cursor(0, cursor_pos) + end +end + +function wrappers.build(chain) + local wrapper = nil + + for index = #chain, 1, -1 do + if vim.tbl_contains({ "==", ">>", "<<" }, chain[index]) then + wrapper = wrappers.change(chain[index], wrapper) + else + wrapper = wrappers[chain[index]](wrapper) + end + end + + return wrapper +end + +return wrappers