summaryrefslogtreecommitdiff
path: root/config/essentials/vis
diff options
context:
space:
mode:
authorRaymaekers Luca <raymaekers.luca@gmail.com>2024-06-20 23:46:00 +0200
committerRaymaekers Luca <raymaekers.luca@gmail.com>2024-06-20 23:46:00 +0200
commita0f45aece21a6280633023ec84f60eb0d5e0849a (patch)
tree3d8d0e8294e84606ffea97e524be1cb94cdf8cb4 /config/essentials/vis
parent2f8816e47e0797083a667d5cf7e778940dd1f789 (diff)
checkpoint
Diffstat (limited to 'config/essentials/vis')
-rw-r--r--config/essentials/vis/Makefile2
-rw-r--r--config/essentials/vis/commentary.lua251
-rw-r--r--config/essentials/vis/complete-line.lua141
-rw-r--r--config/essentials/vis/cursors.lua12
-rw-r--r--config/essentials/vis/format.lua131
-rw-r--r--config/essentials/vis/visrc.lua108
6 files changed, 593 insertions, 52 deletions
diff --git a/config/essentials/vis/Makefile b/config/essentials/vis/Makefile
index be230e3..1599b58 100644
--- a/config/essentials/vis/Makefile
+++ b/config/essentials/vis/Makefile
@@ -2,7 +2,7 @@
LUA_FILES := $(shell find . -name "*.lua")
-all: check format
+all: format check
check:
luacheck --no-color --globals=vis -- $(LUA_FILES)
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")
diff --git a/config/essentials/vis/complete-line.lua b/config/essentials/vis/complete-line.lua
new file mode 100644
index 0000000..93728a3
--- /dev/null
+++ b/config/essentials/vis/complete-line.lua
@@ -0,0 +1,141 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+-- © 2020 Georgi Kirilov
+local progname = ...
+
+local lpeg = require("lpeg")
+local R, C, Cmt = lpeg.R, lpeg.C, lpeg.Cmt
+
+-- copied from vis.h
+local VIS_MOVE_NOP = 64
+
+local cont = R("\128\191")
+
+local charpattern = R("\0\127") + R("\194\223") * cont + R("\224\239") * cont *
+ cont + R("\240\244") * cont * cont * cont
+
+local function concat_keys(tbl)
+ local keys = {}
+ for k in pairs(tbl) do table.insert(keys, k) end
+ return table.concat(keys, "\n"), #keys
+end
+
+local function line_complete()
+ local file = vis.win.file
+ local sel = vis.win.selection
+ local cur_line = file.lines[sel.line]
+ local indent_patt = "^[ \t\v\f]+"
+ local prefix = cur_line:sub(1, sel.col - 1):gsub(indent_patt, "")
+ local candidates = {}
+ for l in file:lines_iterator() do
+ local unindented = l:gsub(indent_patt, "")
+ local start, finish = unindented:find(prefix, 1, true)
+ if start == 1 and finish < #unindented then
+ candidates[unindented] = true
+ end
+ end
+ local candidates_str, n = concat_keys(candidates)
+ if n < 2 then
+ if n == 1 then vis:insert(candidates_str:sub(#prefix + 1)) end
+ return
+ end
+ -- XXX: with too many candidates this command will become longer that the shell can handle:
+ local command = string.format("vis-menu -l %d <<'EOF'\n%s\nEOF\n",
+ math.min(n, math.ceil(vis.win.height / 2)),
+ candidates_str)
+ local status, output = vis:pipe(nil, nil, command)
+ if n > 0 and status == 0 then
+ vis:insert(output:sub(#prefix + 1):gsub("\n$", ""))
+ end
+end
+
+local function selection_by_pos(pos)
+ for s in vis.win:selections_iterator() do
+ if s.pos == pos then return s end
+ end
+end
+
+local function charwidth(cells_so_far, char)
+ if char == "\t" then
+ local tw = vis.tabwidth or 8
+ local trail = cells_so_far % tw
+ return tw - trail
+ else
+ return 1
+ end
+end
+
+local function virtcol(line, col)
+ local ncells = 0
+ local nchars = 0
+ local function upto(_, _, char)
+ if nchars < col - 1 then
+ ncells = ncells + charwidth(ncells, char)
+ nchars = nchars + 1
+ return true
+ end
+ end
+ (Cmt(C(charpattern), upto) ^ 0):match(line)
+ return ncells + 1
+end
+
+local function neighbor(lines, ln, col, direction)
+ local line = ln + direction > 0 and lines[ln + direction]
+ if not line then return end
+ local column = virtcol(lines[ln], col)
+ local ncells = 0
+ local function upto(_, _, char)
+ ncells = ncells + charwidth(ncells, char)
+ return ncells < column
+ end
+ return
+ (Cmt(C(charpattern), upto) ^ (-column + 1) / 0 * C(charpattern)):match(
+ line)
+end
+
+local function dup_neighbor(direction)
+ return function(file, _, pos)
+ local sel = selection_by_pos(pos)
+ local char = neighbor(file.lines, sel.line, sel.col, direction)
+ if not char then return pos end
+ file:insert(pos, char)
+ return pos + #char
+ end
+end
+
+local function dup_neighbor_feedkeys(direction)
+ local sel = vis.win.selection
+ local file = vis.win.file
+ local char = neighbor(file.lines, sel.line, sel.col, direction)
+ if not char then return end
+ vis:feedkeys(char)
+end
+
+local function operator(handler)
+ local id = vis:operator_register(handler)
+ return id >= 0 and function()
+ vis:operator(id)
+ vis:motion(VIS_MOVE_NOP)
+ end
+end
+
+vis.events.subscribe(vis.events.INIT, function()
+ local function h(msg) return string.format("|@%s| %s", progname, msg) end
+
+ local function column_complete(direction)
+ local binding = operator(dup_neighbor(direction))
+ return function()
+ if #vis.win.selections == 1 then
+ dup_neighbor_feedkeys(direction)
+ else
+ return binding()
+ end
+ end
+ end
+
+ vis:map(vis.modes.INSERT, "<C-y>", column_complete(-1),
+ h "Insert the character which is above the cursor")
+ vis:map(vis.modes.INSERT, "<C-e>", column_complete(1),
+ h "Insert the character which is below the cursor")
+ vis:map(vis.modes.INSERT, "<C-x><C-l>", line_complete,
+ h "Complete the current line")
+end)
diff --git a/config/essentials/vis/cursors.lua b/config/essentials/vis/cursors.lua
index 37165b6..5b3d43b 100644
--- a/config/essentials/vis/cursors.lua
+++ b/config/essentials/vis/cursors.lua
@@ -6,7 +6,7 @@ local files = {}
M.maxsize = 1000
-- get the default system cache directory
-local get_default_cache_path = function()
+local function get_default_cache_path()
local HOME = os.getenv('HOME')
local XDG_CACHE_HOME = os.getenv('XDG_CACHE_HOME')
local BASE = XDG_CACHE_HOME or HOME
@@ -16,7 +16,7 @@ end
-- default save path
M.path = get_default_cache_path()
-local read_files = function()
+local function read_files()
-- read file
local file = io.open(M.path)
@@ -36,10 +36,10 @@ local read_files = function()
end
-- read cursors from file on init
-local on_init = function() read_files() end
+local function on_init() read_files() end
-- apply cursor pos on win open
-local on_win_open = function(win)
+local function on_win_open(win)
if win.file == nil or win.file.path == nil then return end
@@ -58,7 +58,7 @@ local on_win_open = function(win)
end
-- set cursor pos on close
-local on_win_close = function(win)
+local function on_win_close(win)
if win.file == nil or win.file.path == nil then return end
@@ -81,7 +81,7 @@ local on_win_close = function(win)
end
-- write cursors to file on quit
-local on_quit = function()
+local function on_quit()
local file = io.open(M.path, 'w+')
if file == nil then return end
diff --git a/config/essentials/vis/format.lua b/config/essentials/vis/format.lua
new file mode 100644
index 0000000..15488dd
--- /dev/null
+++ b/config/essentials/vis/format.lua
@@ -0,0 +1,131 @@
+local global_options = {check_same = true}
+
+local function stdio_formatter(cmd, options)
+ local function apply(win, range, pos)
+ local size = win.file.size
+ local all = {start = 0, finish = size}
+ if range == nil then range = all end
+ local command = type(cmd) == 'function' and cmd(win, range, pos) or cmd
+ local check_same = (options and options.check_same ~= nil) and
+ options.check_same or global_options.check_same
+ local check = check_same == true or
+ (type(check_same) == 'number' and check_same >= size)
+ local status, out, err = vis:pipe(win.file, all, command)
+ if status ~= 0 then
+ vis:message(err)
+ elseif out == nil or out == '' then
+ vis:info('No output from formatter')
+ elseif not check or win.file:content(all) ~= out then
+ local start, finish = range.start, range.finish
+ win.file:delete(range)
+ win.file:insert(start,
+ out:sub(start + 1, finish + (out:len() - size)))
+ end
+ return pos
+ end
+ return {
+ apply = apply,
+ options = options or {ranged = type(cmd) == 'function'}
+ }
+end
+
+local function with_filename(win, option)
+ if win.file.path then
+ return option .. "'" .. win.file.path:gsub("'", "\\'") .. "'"
+ else
+ return ''
+ end
+end
+
+local formatters = {}
+formatters = {
+ bash = stdio_formatter(function(win)
+ return 'shfmt ' .. with_filename(win, '--filename ') .. ' -'
+ end),
+ csharp = stdio_formatter('dotnet csharpier'),
+ go = stdio_formatter('gofmt'),
+ lua = {
+ pick = function(win)
+ local _, out = vis:pipe(win.file,
+ {start = 0, finish = win.file.size},
+ 'test -e .lua-format && echo luaformatter || echo stylua')
+ return formatters[out:gsub('\n$', '')]
+ end
+ },
+ luaformatter = stdio_formatter('lua-format'),
+ markdown = stdio_formatter(function(win)
+ if win.options and win.options.colorcolumn ~= 0 then
+ return 'prettier --parser markdown --prose-wrap always ' ..
+ ('--print-width ' .. (win.options.colorcolumn - 1) .. ' ') ..
+ with_filename(win, '--stdin-filepath ')
+ else
+ return 'prettier --parser markdown ' ..
+ with_filename(win, '--stdin-filepath ')
+ end
+ end, {ranged = false}),
+ powershell = stdio_formatter([[
+ "$( (command -v powershell.exe || command -v pwsh) 2>/dev/null )" -c '
+ Invoke-Formatter -ScriptDefinition `
+ ([IO.StreamReader]::new([Console]::OpenStandardInput()).ReadToEnd())
+ ' | sed -e :a -e '/^[\r\n]*$/{$d;N;};/\n$/ba'
+ ]]),
+ rust = stdio_formatter('rustfmt'),
+ stylua = stdio_formatter(function(win, range)
+ if range and (range.start ~= 0 or range.finish ~= win.file.size) then
+ return
+ 'stylua -s --range-start ' .. range.start .. ' --range-end ' ..
+ range.finish .. with_filename(win, ' --stdin-filepath ') ..
+ ' -'
+ else
+ return 'stylua -s ' .. with_filename(win, '--stdin-filepath ') ..
+ ' -'
+ end
+ end),
+ text = stdio_formatter(function(win)
+ if win.options and win.options.colorcolumn ~= 0 then
+ return 'fmt -w ' .. (win.options.colorcolumn - 1)
+ else
+ return 'fmt'
+ end
+ end, {ranged = false})
+}
+
+local function getwinforfile(file)
+ for win in vis:windows() do
+ if win and win.file and win.file.path == file.path then
+ return win
+ end
+ end
+end
+
+local function apply(file_or_keys, range, pos)
+ local win =
+ type(file_or_keys) ~= 'string' and getwinforfile(file_or_keys) or
+ vis.win
+ local ret = type(file_or_keys) ~= 'string' and function() return pos end or
+ function() return 0 end
+ pos = pos or win.selection.pos
+ local formatter = formatters[win.syntax]
+ if formatter and formatter.pick then formatter = formatter.pick(win) end
+ if formatter == nil then
+ vis:info('No formatter for ' .. win.syntax)
+ return ret()
+ end
+ if range ~= nil and not formatter.options.ranged and range.start ~= 0 and
+ range.finish ~= win.file.size then
+ vis:info('Formatter for ' .. win.syntax .. ' does not support ranges')
+ return ret()
+ end
+ pos = formatter.apply(win, range, pos) or pos
+ vis:insert('') -- redraw and friends don't work
+ win.selection.pos = pos
+ return ret()
+end
+
+return {
+ formatters = formatters,
+ options = global_options,
+ apply = apply,
+ stdio_formatter = stdio_formatter,
+ with_filename = with_filename
+}
diff --git a/config/essentials/vis/visrc.lua b/config/essentials/vis/visrc.lua
index 3a9ff1d..60162bc 100644
--- a/config/essentials/vis/visrc.lua
+++ b/config/essentials/vis/visrc.lua
@@ -1,71 +1,83 @@
------------------------------------
--- LIBRARIES
------------------------------------
-require('vis')
+require("vis")
-- plugins
require("build")
require("backup")
require("cursors")
require("title")
+require("commentary")
+require("complete-line")
+local format = require("format")
-vis:command_register("make", function() vis:communicate() end, "make")
+-- todo:
+-- c-scope
+-- c-tags
------------------------------------
---- FUNCTIONS
+--- VARIABLES
------------------------------------
-local map_cmd = function(mode, map, command, help)
- vis:map(mode, map, function() vis:command(command) end, help)
-end
-
-local map_cmd_restore = function(mode, map, command, help)
- vis:map(mode, map, function()
- if (mode == vis.modes.INSERT) then vis:feedkeys("<Escape>") end
+local m = vis.modes
- vis:feedkeys("m")
- vis:command(command)
- vis:feedkeys("M")
+------------------------------------
+--- FUNCTIONS
+------------------------------------
- if (mode == vis.modes.INSERT) then vis:feedkeys("i") end
- end, help)
+local function map_cmd(mode, map, command, help)
+ vis:map(mode, map, function()
+ vis:command(command)
+ end, help)
end
-local map_keys = function(mode, map, keys, help)
- vis:map(mode, map, function() vis:feedkeys(keys) end, help)
+-- TOOD: use window selection to restore position
+local function wrap_restore(f, ...)
+ local pos = vis.win.selection.pos
+ f(...)
+ vis.win.selection.pos = pos
end
-------------------------------------
---- VARIABLES
-------------------------------------
-
-local m = vis.modes
+local function map_keys(mode, map, keys, help)
+ vis:map(mode, map, function()
+ vis:feedkeys(keys)
+ end, help)
+end
------------------------------------
--- COMMANDS
-----------------------------------
-vis:command_register("Q", function() vis:command("qa!") end, "Quit all")
-vis:command_register("delws",
- function() vis:command("x/[ \t]+$|^[ \t]+$/d") end,
- "Remove trailing whitespace")
+vis:command_register("make", function()
+ vis:command("!make && head -n 1")
+end, "make")
+vis:command_register("Q", function()
+ vis:command("qa!")
+end, "Quit all")
+vis:command_register("delws", function()
+ vis:command("x/[ \t]+$|^[ \t]+$/d")
+end, "Remove trailing whitespace")
-------------------------------------
--- MAPPINGS
-------------------------------------
-map_cmd_restore(m.NORMAL, " r", "e $vis_filepath", "Reload active file")
+vis:map(m.NORMAL, " r", function()
+ wrap_restore(vis.command, vis, "e $vis_filepath")
+end, "Reload active file")
+
+vis:map(m.NORMAL, "=", format.apply, "Format active file")
map_cmd(m.NORMAL, " c", "e ~/.config/vis/visrc.lua", "Edit config file")
map_cmd(m.NORMAL, " q", "q!", "Quit (force)")
map_cmd(m.NORMAL, " s", "!doas vis $vis_filepath", "Edit as superuser")
map_cmd(m.NORMAL, " w", "w", "Write")
-map_cmd(m.NORMAL, " x", "!chmod u+x $vis_filepath",
- "Make active file executable")
+map_cmd(m.NORMAL, " x", "!chmod u+x $vis_filepath", "Make active file executable")
vis:map(m.NORMAL, " eh", function()
- vis:command("!lowdown $vis_filepath > ${vis_filepath%.md}.html")
- vis:info("exported.")
+ vis:command("!lowdown $vis_filepath > ${vis_filepath%.md}.html")
+ vis:info("exported.")
end, "Export markdown to html")
map_keys(m.NORMAL, " nl", ":<seq -f '%0.0f. ' 1 ", "Insert numbered list")
@@ -77,20 +89,26 @@ map_keys(m.NORMAL, " nl", ":<seq -f '%0.0f. ' 1 ", "Insert numbered list")
------------------------------------
vis.events.subscribe(vis.events.INIT, function()
- vis.options.ignorecase = true
- vis.options.autoindent = true
- vis.options.shell = "/bin/sh"
- local theme = "nord"
- vis:command("set theme " .. theme)
+ vis.options.ignorecase = true
+ vis.options.autoindent = true
+ vis.options.shell = "/bin/sh"
+ local theme = "nord"
+ vis:command("set theme " .. theme)
end)
-vis.events.subscribe(vis.events.WIN_OPEN,
- function(win) -- luacheck: no unused args
- win.options.relativenumbers = true
-
- if win.syntax == "bash" then
- map_keys(m.NORMAL, " v",
- "V:x/^(\\s*)(.+)$/ c/\\1>\\&2 printf '\\2: %s\\\\n' \"$\\2\"/<Enter><Escape>",
- "Print variable")
- end
+vis.events.subscribe(vis.events.WIN_OPEN, function(win) -- luacheck: no unused args
+ win.options.relativenumbers = true
+
+ if win.syntax == "bash" then
+ map_keys(
+ m.NORMAL,
+ " v",
+ "V:x/^(\\s*)(.+)$/ c/\\1>\\&2 printf '\\2: %s\\\\n' \"$\\2\"/<Enter><Escape>",
+ "Print variable"
+ )
+ end
+
+ vis:command_register("pipe", function()
+ vis:pipe(win.file, nil, "sed 's/.*/- &/'")
+ end, "pipe test")
end)