diff options
Diffstat (limited to 'config/essentials/vis/commentary.lua')
-rw-r--r-- | config/essentials/vis/commentary.lua | 251 |
1 files changed, 251 insertions, 0 deletions
diff --git a/config/essentials/vis/commentary.lua b/config/essentials/vis/commentary.lua new file mode 100644 index 0000000..26d06b5 --- /dev/null +++ b/config/essentials/vis/commentary.lua @@ -0,0 +1,251 @@ +-- +-- vis-commentary +-- +local comment_string = { + actionscript = '//', + ada = '--', + ansi_c = '/*|*/', + antlr = '//', + apdl = '!', + apl = '#', + applescript = '--', + asp = '\'', + autoit = ';', + awk = '#', + b_lang = '//', + bash = '#', + batch = ':', + bibtex = '%', + boo = '#', + chuck = '//', + cmake = '#', + coffeescript = '#', + context = '%', + cpp = '//', + crystal = '#', + csharp = '//', + css = '/*|*/', + cuda = '//', + dart = '//', + desktop = '#', + django = '{#|#}', + dmd = '//', + dockerfile = '#', + dot = '//', + eiffel = '--', + elixir = '#', + erlang = '%', + faust = '//', + fennel = ';;', + fish = '#', + forth = '|\\', + fortran = '!', + fsharp = '//', + gap = '#', + gettext = '#', + gherkin = '#', + glsl = '//', + gnuplot = '#', + go = '//', + groovy = '//', + gtkrc = '#', + haskell = '--', + html = '<!--|-->', + icon = '#', + idl = '//', + inform = '!', + ini = '#', + Io = '#', + java = '//', + javascript = '//', + json = '/*|*/', + jsp = '//', + latex = '%', + ledger = '#', + less = '//', + lilypond = '%', + lisp = ';', + logtalk = '%', + lua = '--', + makefile = '#', + markdown = '<!--|-->', + matlab = '#', + moonscript = '--', + myrddin = '//', + nemerle = '//', + nsis = '#', + objective_c = '//', + pascal = '//', + perl = '#', + php = '//', + pico8 = '//', + pike = '//', + pkgbuild = '#', + prolog = '%', + props = '#', + protobuf = '//', + ps = '%', + pure = '//', + python = '#', + rails = '#', + rc = '#', + rebol = ';', + rest = '.. ', + rexx = '--', + rhtml = '<!--|-->', + rstats = '#', + ruby = '#', + rust = '//', + sass = '//', + scala = '//', + scheme = ';', + smalltalk = '"|"', + sml = '(*)', + snobol4 = '#', + sql = '#', + tcl = '#', + tex = '%', + text = '', + toml = '#', + vala = '//', + vb = '\'', + vbscript = '\'', + verilog = '//', + vhdl = '--', + wsf = '<!--|-->', + xml = '<!--|-->', + yaml = '#', + zig = '//', + nim = '#', + julia = '#', + rpmspec = '#' +} + +-- escape all magic characters with a '%' +local function esc(str) + if not str then return "" end + return (str:gsub('%%', '%%%%'):gsub('^%^', '%%^'):gsub('%$$', '%%$'):gsub( + '%(', '%%('):gsub('%)', '%%)'):gsub('%.', '%%.') + :gsub('%[', '%%['):gsub('%]', '%%]'):gsub('%*', '%%*') + :gsub('%+', '%%+'):gsub('%-', '%%-'):gsub('%?', '%%?')) +end + +-- escape '%' +local function pesc(str) + if not str then return "" end + return str:gsub('%%', '%%%%') +end + +local function rtrim(s) + local n = #s + while n > 0 and s:find("^%s", n) do n = n - 1 end + return s:sub(1, n) +end + +local function comment_line(lines, lnum, prefix, suffix) + if suffix ~= "" then suffix = " " .. suffix end + lines[lnum] = string.gsub(lines[lnum], "(%s*)(.*)", + "%1" .. pesc(prefix) .. " %2" .. pesc(suffix)) +end + +local function uncomment_line(lines, lnum, prefix, suffix) + local match_str = "^(%s*)" .. esc(prefix) .. "%s?(.*)" .. esc(suffix) + local m = table.pack(lines[lnum]:match(match_str)) + lines[lnum] = m[1] .. rtrim(m[2]) +end + +local function is_comment(line, prefix) + return (line:match("^%s*(.+)"):sub(0, #prefix) == prefix) +end + +local function toggle_line_comment(lines, lnum, prefix, suffix) + if not lines or not lines[lnum] then return end + if not lines[lnum]:match("^%s*(.+)") then return end -- ignore empty lines + if is_comment(lines[lnum], prefix) then + uncomment_line(lines, lnum, prefix, suffix) + else + comment_line(lines, lnum, prefix, suffix) + end +end + +-- if one line inside the block is not a comment, comment the block. +-- only uncomment, if every single line is comment. +local function block_comment(lines, a, b, prefix, suffix) + local uncomment = true + for i = a, b do + if lines[i]:match("^%s*(.+)") and not is_comment(lines[i], prefix) then + uncomment = false + end + end + + if uncomment then + for i = a, b do + if lines[i]:match("^%s*(.+)") then + uncomment_line(lines, i, prefix, suffix) + end + end + else + for i = a, b do + if lines[i]:match("^%s*(.+)") then + comment_line(lines, i, prefix, suffix) + end + end + end +end + +vis:map(vis.modes.NORMAL, "gcc", function() + local win = vis.win + local lines = win.file.lines + local comment = comment_string[win.syntax] + if not comment then return end + local prefix, suffix = comment:match('^([^|]+)|?([^|]*)$') + if not prefix then return end + + for sel in win:selections_iterator() do + local lnum = sel.line + local col = sel.col + + toggle_line_comment(lines, lnum, prefix, suffix) + sel:to(lnum, col) -- restore cursor position + end + + win:draw() +end, "Toggle comment on a the current line") + +local function visual_f(i) + return function() + local win = vis.win + local lines = win.file.lines + + local comment = comment_string[win.syntax] + if not comment then return end + + local prefix, suffix = comment:match('^([^|]+)|?([^|]*)$') + if not prefix then return end + + for sel in win:selections_iterator() do + local r = sel.range + local lnum = sel.line -- line number of cursor + local col = sel.col -- column of cursor + + if sel.anchored and r then + sel.pos = r.start + local a = sel.line + sel.pos = r.finish + local b = sel.line - i + + block_comment(lines, a, b, prefix, suffix) + + sel:to(lnum, col) -- restore cursor position + end + end + + win:draw() + vis.mode = vis.modes.NORMAL -- go to normal mode + end +end + +vis:map(vis.modes.VISUAL_LINE, "gc", visual_f(1), + "Toggle comment on the selected lines") +vis:map(vis.modes.VISUAL, "gc", visual_f(0), + "Toggle comment on the selected lines") |