diff options
| author | Raymaekers Luca <raymaekers.luca@gmail.com> | 2024-06-23 15:23:48 +0200 | 
|---|---|---|
| committer | Raymaekers Luca <raymaekers.luca@gmail.com> | 2024-06-23 15:23:48 +0200 | 
| commit | 1f7e952a75a870b0a4e9900964cae3729c216cc3 (patch) | |
| tree | 5f8b8d5704d05e59fc55922a64957caaf2f569c3 /config/essentials/vis | |
| parent | 8986d060f2f308ba768758ef9c3077f00f3d6b2a (diff) | |
checkpoint
Diffstat (limited to 'config/essentials/vis')
| -rw-r--r-- | config/essentials/vis/backup.lua | 48 | ||||
| -rw-r--r-- | config/essentials/vis/build.lua | 8 | ||||
| -rw-r--r-- | config/essentials/vis/commentary.lua | 441 | ||||
| -rw-r--r-- | config/essentials/vis/complete-line.lua | 171 | ||||
| -rw-r--r-- | config/essentials/vis/ctags.lua | 343 | ||||
| -rw-r--r-- | config/essentials/vis/cursors.lua | 6 | ||||
| -rw-r--r-- | config/essentials/vis/format.lua | 8 | ||||
| -rw-r--r-- | config/essentials/vis/fzf-mru.lua | 33 | ||||
| -rw-r--r-- | config/essentials/vis/fzf-open.lua | 9 | ||||
| -rw-r--r-- | config/essentials/vis/title.lua | 30 | ||||
| -rw-r--r-- | config/essentials/vis/vis-go.lua | 13 | ||||
| -rw-r--r-- | config/essentials/vis/visrc.lua | 1 | 
12 files changed, 740 insertions, 371 deletions
diff --git a/config/essentials/vis/backup.lua b/config/essentials/vis/backup.lua index f48895f..7c44c60 100644 --- a/config/essentials/vis/backup.lua +++ b/config/essentials/vis/backup.lua @@ -1,36 +1,48 @@ +--[[ +Based on https://github.com/roguh/vis-backup +Changes made: +- stylua +- file path +--]] +  local backup = {}  -- Return the backup path concatenated with the filename, replace / with % -backup.entire_path_with_double_percentage_signs = -    function(backup_dir, path) -        return backup_dir .. "/" .. string.gsub(path, "/", "%%") -    end +backup.entire_path_with_double_percentage_signs = function(backup_dir, path) +	return backup_dir .. "/" .. string.gsub(path, "/", "%%") +end  -- Return the backup path concatenated with the filename, replace / with %  -- and append the current time using time_format -backup.entire_path_with_double_percentage_signs_and_timestamp = function( -    backup_dir, path) -    return backup_dir .. "/" .. os.date(backup.time_format) .. -               string.gsub(path, "/", "%%") +backup.entire_path_with_double_percentage_signs_and_timestamp = function(backup_dir, path) +	return backup_dir .. "/" .. os.date(backup.time_format) .. string.gsub(path, "/", "%%")  end  -- Before saving the file, copy the current contents of the file to a backup file  vis.events.subscribe(vis.events.FILE_SAVE_PRE, function(file, path) -    if file.size > backup.byte_limit then return end +	if file.size > backup.byte_limit then +		return +	end -    -- E.g. when editing stdin as an interactive filter -    -- `vis -` -    if path == nil then return end +	-- E.g. when editing stdin as an interactive filter +	-- `vis -` +	if path == nil then +		return +	end -    local backup_path = backup.get_fname(backup.directory, path) +	local backup_path = backup.get_fname(backup.directory, path) -    local backup_file = io.open(backup_path, "w") -    local current_file = io.open(path) -    if backup_file == nil or current_file == nil then return end +	local backup_file = io.open(backup_path, "w") +	local current_file = io.open(path) +	if backup_file == nil or current_file == nil then +		return +	end -    for line in current_file:lines() do backup_file:write(line .. "\n") end +	for line in current_file:lines() do +		backup_file:write(line .. "\n") +	end -    backup_file:close() +	backup_file:close()  end)  -- Set defaults diff --git a/config/essentials/vis/build.lua b/config/essentials/vis/build.lua index 8a062cd..90dd905 100644 --- a/config/essentials/vis/build.lua +++ b/config/essentials/vis/build.lua @@ -1,3 +1,11 @@ +--[[ +Based on https://gitlab.com/muhq/vis-build +Changes made: +- stylua format +- print build messages on success +--]] + +  -- Copyright (c) 2024 Florian Fischer. All rights reserved.  --  -- vis-build is free software: you can redistribute it and/or modify it under diff --git a/config/essentials/vis/commentary.lua b/config/essentials/vis/commentary.lua index 26d06b5..742d2df 100644 --- a/config/essentials/vis/commentary.lua +++ b/config/essentials/vis/commentary.lua @@ -1,251 +1,284 @@ +--[[ +Based on https://github.com/lutobler/vis-commentary +Changes made: +- stylua +--]] +  --  -- 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 = '#' +	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('%?', '%%?')) +	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('%%', '%%%%') +	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) +	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)) +	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]) +	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) +	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 +	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 +	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() +	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 +	return function() +		local win = vis.win +		local lines = win.file.lines -        local comment = comment_string[win.syntax] -        if not comment then return end +		local comment = comment_string[win.syntax] +		if not comment then +			return +		end -        local prefix, suffix = comment:match('^([^|]+)|?([^|]*)$') -        if not prefix 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 +		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 +			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) +				block_comment(lines, a, b, prefix, suffix) -                sel:to(lnum, col) -- restore cursor position -            end -        end +				sel:to(lnum, col) -- restore cursor position +			end +		end -        win:draw() -        vis.mode = vis.modes.NORMAL -- go to normal mode -    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") +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 index 93728a3..98515a9 100644 --- a/config/essentials/vis/complete-line.lua +++ b/config/essentials/vis/complete-line.lua @@ -1,141 +1,56 @@ +--[[ +Based on https://repo.or.cz/vis-complete-line.git +Changes made: +- stylua +- removed <C-x><C-e>, <C-x><C-y> and related functions and variables +--]] +  -- 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 +	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 +	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  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 +	local function h(msg) +		return string.format("|@%s| %s", progname, msg) +	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") +	vis:map(vis.modes.INSERT, "<C-x><C-l>", line_complete, h("Complete the current line"))  end) diff --git a/config/essentials/vis/ctags.lua b/config/essentials/vis/ctags.lua new file mode 100644 index 0000000..40d4aef --- /dev/null +++ b/config/essentials/vis/ctags.lua @@ -0,0 +1,343 @@ +--[[ +Based on https://github.com/kupospelov/vis-ctags +Changes made: +- stylua +--]] + +require("vis") + +local positions = {} +local tags = { "tags" } +local ctags = { actions = {} } + +local function abs_path(prefix, path) +	if string.find(path, "^/") ~= nil then +		return path, path +	end + +	if string.find(path, "^./") ~= nil then +		path = path:sub(3) +	end + +	return prefix .. path, path +end + +local function is_directory(path) +	local dir = io.open(path .. "/", "r") +	if dir then +		dir:close() +		return true +	else +		return false +	end +end + +local function find_tags(path) +	for i = #path, 1, -1 do +		if path:sub(i, i) == "/" then +			local prefix = path:sub(1, i) +			for j = 1, #tags do +				local tagfile = tags[j] +				local filename +				if tagfile:sub(1, 1) == "/" then +					filename = tagfile +				else +					filename = prefix .. tagfile +				end +				if not is_directory(filename) then +					local file = io.open(filename, "r") + +					if file ~= nil then +						return file, prefix +					end +				end +			end +		end +	end +end + +local function bsearch(file, word) +	local buffer_size = 8096 +	local format = '\n(.-)\t(.-)\t(.-);"\t' + +	local from = 0 +	local to = file:seek("end") +	local startpos = nil + +	while from <= to do +		local mid = from + math.floor((to - from) / 2) +		file:seek("set", mid) + +		local content = file:read(buffer_size, "*line") +		if content ~= nil then +			local key, _, _ = string.match(content, format) +			if key == nil then +				break +			end + +			if key == word then +				startpos = mid +			end + +			if key >= word then +				to = mid - 1 +			else +				from = mid + 1 +			end +		else +			to = mid - 1 +		end +	end + +	if startpos ~= nil then +		file:seek("set", startpos) + +		local result = {} +		while true do +			local content = file:read(buffer_size, "*line") +			if content == nil then +				break +			end + +			for key, filename, excmd in string.gmatch(content, format) do +				if key == word then +					result[#result + 1] = { name = filename, excmd = excmd } +				else +					return result +				end +			end +		end + +		return result +	end +end + +local function get_query() +	local line = vis.win.selection.line +	local pos = vis.win.selection.col +	local str = vis.win.file.lines[line] + +	local from, to = 0, 0 +	while pos > to do +		from, to = str:find("[%a_]+[%a%d_]*", to + 1) +		if from == nil or from > pos then +			return nil +		end +	end + +	return string.sub(str, from, to) +end + +local function get_matches(word, path) +	local file, prefix = find_tags(path) + +	if file ~= nil then +		local results = bsearch(file, word) +		file:close() + +		if results ~= nil then +			local matches = {} +			for i = 1, #results do +				local result = results[i] +				local abspath, name = abs_path(prefix, result.name) +				local desc = string.format("%s%s", name, tonumber(result.excmd) and ":" .. result.excmd or "") + +				matches[#matches + 1] = { desc = desc, path = abspath, excmd = result.excmd } +			end + +			return matches +		end +	end +end + +local function get_match(word, path) +	local matches = get_matches(word, path) +	if matches ~= nil then +		for i = 1, #matches do +			if matches[i].path == path then +				return matches[i] +			end +		end + +		return matches[1] +	end +end + +local function escape(text) +	return text:gsub("[][)(}{|+?*.]", "\\%0") +		:gsub("%^", "\\^") +		:gsub("^/\\%^", "/^") +		:gsub("%$", "\\$") +		:gsub("\\%$/$", "$/") +		:gsub("\\\\%$%$/$", "\\$$") +end + +--[[ +- Can't test vis:command() as it will still return true if the edit command fails. +- Can't test File.modified as the edit command can succeed if the current file is +  modified but open in another window and this behavior is useful. +- Instead just check the path again after trying the edit command. +]] +local function goto_pos(pos, force) +	if pos.path ~= vis.win.file.path then +		vis:command(string.format(force and 'e! "%s"' or 'e "%s"', pos.path)) +		if pos.path ~= vis.win.file.path then +			return false +		end +	end +	if tonumber(pos.excmd) then +		vis.win.selection:to(pos.excmd, pos.col) +	else +		vis.win.selection:to(1, 1) +		vis:command(escape(pos.excmd)) +		vis.win.selection.pos = vis.win.selection.range.start +		vis.mode = vis.modes.NORMAL +	end +	return true +end + +local function goto_tag(path, excmd, force) +	local old = { +		path = vis.win.file.path, +		excmd = vis.win.selection.line, +		col = vis.win.selection.col, +	} + +	local last_search = vis.registers["/"] +	if goto_pos({ path = path, excmd = excmd, col = 1 }, force) then +		positions[#positions + 1] = old +		vis.registers["/"] = last_search +	end +end + +local function pop_pos(force) +	if #positions < 1 then +		return +	end +	if goto_pos(positions[#positions], force) then +		table.remove(positions, #positions) +	end +end + +local function win_path() +	if vis.win.file.path == nil then +		return os.getenv("PWD") .. "/" +	end +	return vis.win.file.path +end + +local function tag_cmd(tag, force) +	local match = get_match(tag, win_path()) +	if match == nil then +		vis:info(string.format("Tag not found: %s", tag)) +	else +		goto_tag(match.path, match.excmd, force) +	end +end + +local function gen_vis_menu(matches) +	local width = 0 +	for _, match in ipairs(matches) do +		width = math.max(width, match.desc:len()) +	end +	-- limit max width of desc field (filename) in menu +	width = math.min(width, 40) +	local fmt = "%" .. #tostring(#matches) .. "d %-" .. width .. "s %s" + +	local lines = {} +	for i, match in ipairs(matches) do +		local desc = match.desc +		if desc:len() > width then +			desc = "..." .. desc:sub(desc:len() - width + 4) +		end + +		-- work around bug displaying tabs in vis-menu and +		-- provide a clearer context +		local excmd = match.excmd:gsub("%s+", " ") +		excmd = excmd:gsub("^/^", "") +		excmd = excmd:gsub("$/$", "") +		table.insert(lines, fmt:format(i, desc, excmd)) +	end + +	-- limit vis-menu height to ~1/4 the window height +	-- +1 gives an empty line at bottom to signify +	-- that there are no more lines to scroll through +	local nlines = math.min(math.floor(vis.win.height / 4), #lines) +	if nlines == #lines then +		nlines = nlines + 1 +	end +	return "vis-menu -l " .. nlines .. " -p 'Choose tag:' << 'EOF'\n" .. table.concat(lines, "\n") .. "\n" .. "EOF" +end + +local function tselect_cmd(tag, force) +	local matches = get_matches(tag, win_path()) +	if matches == nil then +		vis:info(string.format("Tag not found: %s", tag)) +	else +		local status, output = vis:pipe(vis.win.file, { start = 0, finish = 0 }, gen_vis_menu(matches)) + +		if status ~= 0 then +			vis:info("Command failed") +			return +		end + +		local choice = tonumber(string.match(output, "%d+")) +		if choice == nil or choice < 1 or choice > #matches then +			vis:info("Invalid choice") +			return +		end +		goto_tag(matches[choice].path, matches[choice].excmd, force) +	end +end + +vis:command_register("tag", function(argv, force) +	if #argv == 1 then +		tag_cmd(argv[1], force) +	end +end) + +vis:command_register("tselect", function(argv, force) +	if #argv == 1 then +		tselect_cmd(argv[1], force) +	end +end) + +vis:command_register("pop", function(_, force) +	pop_pos(force) +end) + +vis:option_register("tags", "string", function(value) +	tags = {} +	for str in value:gmatch("([^%s]+)") do +		table.insert(tags, str) +	end +end, "Paths to search for tags (separated by spaces)") + +ctags.actions.tag = function() +	local query = get_query() +	local force = false +	if query ~= nil then +		tag_cmd(query, force) +	end +	return 0 +end + +ctags.actions.tselect = function() +	local query = get_query() +	local force = false +	if query ~= nil then +		tselect_cmd(query, force) +	end +	return 0 +end + +ctags.actions.pop = function() +	pop_pos() +	return 0 +end + +vis:map(vis.modes.NORMAL, "<C-]>", ctags.actions.tag) +vis:map(vis.modes.NORMAL, "g<C-]>", ctags.actions.tselect) +vis:map(vis.modes.NORMAL, "<C-t>", ctags.actions.pop) + +return ctags diff --git a/config/essentials/vis/cursors.lua b/config/essentials/vis/cursors.lua index 5b3d43b..01c1ede 100644 --- a/config/essentials/vis/cursors.lua +++ b/config/essentials/vis/cursors.lua @@ -1,3 +1,9 @@ +--[[ +Based on https://github.com/erf/vis-cursors +Changes made: +- stylua +--]] +  local M = {}  local cursors = {}  local files = {} diff --git a/config/essentials/vis/format.lua b/config/essentials/vis/format.lua index d35db04..67613a6 100644 --- a/config/essentials/vis/format.lua +++ b/config/essentials/vis/format.lua @@ -1,3 +1,11 @@ +--[[ +Based on https://github.com/milhnl/vis-format +Changes made: +- stylua +- restore position after format +- use local M to return the module +--]] +  local M = {}  M.check_same = true  M.wrapwidth = 90 diff --git a/config/essentials/vis/fzf-mru.lua b/config/essentials/vis/fzf-mru.lua index 6c2510d..455d083 100644 --- a/config/essentials/vis/fzf-mru.lua +++ b/config/essentials/vis/fzf-mru.lua @@ -1,12 +1,23 @@ -local module = {} -module.fzfmru_filepath = os.getenv("XDG_CACHE_HOME") .. "/vis-fzf-mru" -module.fzfmru_path = "fzf" -module.fzfmru_args = "--height=40%" -module.fzfmru_history = 20 +--[[ +Based on https://github.com/peaceant/vis-fzf-mru +Changes made: +- stylua +- renamed module to M +- renamed fzfmru to fzf +- height to 40% +- use XDG_CACHE_HOME +- ignore exit code 130 +--]] + +local M = {} +M.fzf_filepath = os.getenv("XDG_CACHE_HOME") .. "/vis-fzf-mru" +M.fzf_path = "fzf" +M.fzf_args = "--height=40%" +M.fzf_history = 20  local function read_mru()      local mru = {} -    local f = io.open(module.fzfmru_filepath) +    local f = io.open(M.fzf_filepath)      if f == nil then return end      for line in f:lines() do table.insert(mru, line) end      f:close() @@ -25,13 +36,13 @@ local function write_mru(win)      -- check duplicate      if file_path == mru[1] then return end -    local f = io.open(module.fzfmru_filepath, "w+") +    local f = io.open(M.fzf_filepath, "w+")      if f == nil then return end      table.insert(mru, 1, file_path)      for i, k in ipairs(mru) do -        if i > module.fzfmru_history then break end +        if i > M.fzf_history then break end          if i == 1 or k ~= file_path then              f:write(string.format("%s\n", k))          end @@ -43,8 +54,8 @@ end  vis.events.subscribe(vis.events.WIN_OPEN, write_mru)  vis:command_register("fzfmru", function(argv) -    local command = "cat " .. module.fzfmru_filepath .. " | " .. -                        module.fzfmru_path .. " " .. module.fzfmru_args .. " " .. +    local command = "cat " .. M.fzf_filepath .. " | " .. +                        M.fzf_path .. " " .. M.fzf_args .. " " ..                          table.concat(argv, " ")      local file = io.popen(command) @@ -72,4 +83,4 @@ vis:command_register("fzfmru", function(argv)      return true  end) -return module +return M diff --git a/config/essentials/vis/fzf-open.lua b/config/essentials/vis/fzf-open.lua index 1c9d1e6..ff4f694 100644 --- a/config/essentials/vis/fzf-open.lua +++ b/config/essentials/vis/fzf-open.lua @@ -1,3 +1,12 @@ +--[[ +Based on https://git.cepl.eu/cgit/vis/vis-fzf-open +Changes made: +- stylua +- height argument +- module renamed to M +- ignore exit code 130 +--]] +  -- Copyright (C) 2017  Guillaume Chérel  -- Copyright (C) 2023  Matěj Cepl  -- diff --git a/config/essentials/vis/title.lua b/config/essentials/vis/title.lua index d743b63..06a3964 100644 --- a/config/essentials/vis/title.lua +++ b/config/essentials/vis/title.lua @@ -1,16 +1,28 @@ -require('vis') +--[[ +Based on https://github.com/erf/vis-title +Changes made: +- stylua +--]] + +require("vis")  local function set_title(title) -    -- print() cannot be used here as it will mess up vis -    vis:command(string.format(":!printf '\\033]2;vis %s\\007'", title)) +	-- print() cannot be used here as it will mess up vis +	vis:command(string.format(":!printf '\\033]2;vis %s\\007'", title))  end -vis.events.subscribe(vis.events.INIT, function() print('\27[22;2t') end) +vis.events.subscribe(vis.events.INIT, function() +	print("\27[22;2t") +end) -vis.events.subscribe(vis.events.WIN_OPEN, -                     function(win) set_title(win.file.name or '[No Name]') end) +vis.events.subscribe(vis.events.WIN_OPEN, function(win) +	set_title(win.file.name or "[No Name]") +end) -vis.events.subscribe(vis.events.FILE_SAVE_POST, -                     function(file) set_title(file.name) end) +vis.events.subscribe(vis.events.FILE_SAVE_POST, function(file) +	set_title(file.name) +end) -vis.events.subscribe(vis.events.QUIT, function() print('\27[23;2t') end) +vis.events.subscribe(vis.events.QUIT, function() +	print("\27[23;2t") +end) diff --git a/config/essentials/vis/vis-go.lua b/config/essentials/vis/vis-go.lua index b0b383f..647e003 100644 --- a/config/essentials/vis/vis-go.lua +++ b/config/essentials/vis/vis-go.lua @@ -1,3 +1,12 @@ +--[[ +Based on https://gitlab.com/timoha/vis-go +Changes made: +- stylua format +- check if line, col in godef() +- no formatting because already handled by format.lua +- removed the goimports option +--]] +  local function jump_to(path, line, col)  	if path then  		vis:command(string.format("e %s", path)) @@ -44,7 +53,9 @@ local function godef()  		-- same file  		line, col = string.match(out, "([^:]+):([^:]+)")  	end -	jump_to(path, line, col) +	if line and col then +		jump_to(path, line, col) +	end  end  local function godef_back() diff --git a/config/essentials/vis/visrc.lua b/config/essentials/vis/visrc.lua index 2a6a706..93954ae 100644 --- a/config/essentials/vis/visrc.lua +++ b/config/essentials/vis/visrc.lua @@ -8,6 +8,7 @@ require("build")  -- use Trash directory instead, remove set_dir function  require("backup")  require("cursors") +require("ctags")  require("title")  require("commentary")  require("complete-line")  | 
