-- mod-version:3 local core = require "core" local command = require "core.command" local DocView = require "core.docview" local function check_doc() local av = core.active_view return av:is(DocView) and #av.doc.selections > 4 end -- returns: -- * if the doc has selections -- * if the selections span multiple lines local function doc_get_selection_status(doc) local selections = false for _,line1,col1,line2,col2 in doc:get_selections() do if line1 ~= line2 then return true, true end if col1 ~= col2 then selections = true end end return selections, false end local function has_selections() if not check_doc() then return false end local selections, has_multilines = doc_get_selection_status(core.active_view.doc) -- we want this to be true if there are only single lines selections return selections and not has_multilines, core.active_view.doc end local function has_no_selections() if not check_doc() then return false end return not doc_get_selection_status(core.active_view.doc), core.active_view.doc end local function align(doc, right) local max_col = 0 local done = { } -- get alignment column for _,line1,col1,_,col2 in doc:get_selections(true) do -- only use the first caret in a line if not done[line1] then done[line1] = true max_col = math.max(max_col, right and col2 or col1) end end done = { } for idx,line1,col1,line2,col2 in doc:get_selections(true) do -- only align the first caret in a line if not done[line1] then done[line1] = true local diff = max_col - (right and col2 or col1) if diff > 0 then doc:insert(line1, col1, string.rep(" ", diff)) end doc:set_selections(idx, line1, col1 + diff, line2, col2 + diff, right) end end end command.add(has_no_selections, { ["doc:align-carets"] = align, }) command.add(has_selections, { ["doc:left-align-selections"] = align, ["doc:right-align-selections"] = function(doc) align(doc, true) end, })