summaryrefslogtreecommitdiff
path: root/config/essentials/vis/commentary.lua
diff options
context:
space:
mode:
authorRaymaekers Luca <raymaekers.luca@gmail.com>2024-06-22 02:05:44 +0200
committerRaymaekers Luca <raymaekers.luca@gmail.com>2024-06-22 02:05:44 +0200
commit36d2972c60ec86b873fa496d1f5ea95cf748cf49 (patch)
treea6d6750fa17c2964cd241afa8e963cac6106b390 /config/essentials/vis/commentary.lua
parent4914b43f642e2772a140a8f9b1f26b4e555ed88b (diff)
parent32256e087aaf7744348a5ba33e802d5c8d9d97dd (diff)
Merge branch 'main' of db:dotfiles
Diffstat (limited to 'config/essentials/vis/commentary.lua')
-rw-r--r--config/essentials/vis/commentary.lua251
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")