vis-config

lua scripts to configure vis editor

git clone https://9o.is/git/vis-config.git

commit 99424e699d72060fc298d36a4a23a0538b27d360
parent 2ff10d1c88daad3d0b36660fb3be569a1b527688
Author: Jul <jul@9o.is>
Date:   Wed, 25 Feb 2026 19:53:09 +0800

save multiple ctag files including system libs

Diffstat:
Mlib/ctags.lua | 105+++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------
Mvisrc.lua | 41+++++++++++++++++++++++++++--------------
2 files changed, 100 insertions(+), 46 deletions(-)

diff --git a/lib/ctags.lua b/lib/ctags.lua @@ -1,16 +1,22 @@ local M = { - file = './tags', + file = '.tags', + path = '.', flags = '-R', } -local function generate_tags(win) - if not win.ctags then - vis:info('ctags not enabled') +local function generate_tags(win, file) + local tags = win.tags[file] + + if not tags then return end - local fd = io.popen(string.format('ctags %s -n -f %s', M.flags, M.file)) - fd:close() + local fd = io.popen(string.format('ctags %s -n -f %s %s', tags.flags, file, tags.path)) + local success, msg = fd:close() + + if not success then + vis:info(string.format('Error: %s', msg)) + end end local tagstack = {} @@ -22,6 +28,11 @@ vis:option_register('ctags', 'bool', function(value, toggle) win.ctags = toggle and not win.ctags or value if win.ctags then + if not win.tags then + win.tags = {} + M.add(win, M.file) + end + win:map(vis.modes.NORMAL, '<C-t>', function() vis:command('tag-back') end) @@ -35,50 +46,64 @@ vis:option_register('ctags', 'bool', function(value, toggle) local tag = win.file:content(win.selection.range) vis:command('tag ' .. tag) end) - - local f = io.open(M.file, 'r') - if not f then - generate_tags(win) - else - f:close() - end end return true end, 'Enables ctags') -vis:option_register('ctags-autosave', 'bool', function(value, toggle) - if not vis.win then return false end - vis.win.ctags_autosave = toggle and not vis.win.ctags_autosave or value - return true -end, 'Enables ctags autosaving') +vis:command_register('tag-generate', function(argv, _, win) + local file = argv[1] + + if not win.ctags then + vis:info('tag: disabled') + return + end + + if not win.tags then + vis:info('tag-generate: tags not configured') + return + end + + if file and not win.tags[file] then + vis:info('tag-generate: tags file not configured') + return + end -vis:command_register('tag-generate', function(_, _, win) - generate_tags(win) + for f in pairs(win.tags) do + if not file or (file and file == f) then + generate_tags(win, f) + end + end end, 'Generate ctags file') vis:command_register('tag', function(argv, _, win) + local tag = argv[1] + if not win.ctags then - vis:info('ctags not enabled') + vis:info('tag: disabled') return end - local tag = argv[1] + if not win.tags then + vis:info('tag: tags not configured') + return + end if not tag or tag == '' then vis:info('tag: missing argument') return false end - local file = io.popen(string.format('readtags -t %s - %s', M.file, tag)) - local line = file:read() - local success, msg, status = file:close() - - if not success then - vis:info(string.format('tag failed: [status %s] %s', status, msg)) - return false + local files = '' + for file in pairs(win.tags) do + files = files .. ' ' .. file end + local fd = io.popen(string.format( + "sh -c 'cat %s 2>/dev/null | grep -v \'^!_\' | readtags -t - - %s'", files, tag)) + local line = fd:read() + fd:close() + if not line or line == '' then vis:info('tag: nothing found') return false @@ -89,7 +114,7 @@ vis:command_register('tag', function(argv, _, win) line = win.selection.line, col = win.selection.col, } - + local file, lineno = line:match('^[^%s]+%s+([^%s]+)%s+(%d+)') if not vis:command(string.format('e %s', file)) then @@ -119,7 +144,23 @@ vis:command_register('tag-back', function() end, 'Go back in tag stack') vis.events.subscribe(vis.events.FILE_SAVE_POST, function() - if vis.win.ctags and vis.win.ctags_autosave then - generate_tags(vis.win) + if not vis.win.ctags then + return + end + + for file, prefs in pairs(vis.win.tags) do + if prefs.autosave then + generate_tags(vis.win, file) + end end end) + +M.add = function(win, file, prefs) + if not prefs then prefs = {} end + if not prefs.path then prefs.path = M.path end + if not prefs.file then prefs.file = M.file end + if not prefs.flags then prefs.flags = M.flags end + win.tags[file] = prefs +end + +return M diff --git a/visrc.lua b/visrc.lua @@ -4,12 +4,13 @@ require('plugins/surround') require('plugins/modelines') require('lib/window-manager') require('lib/status') -require('lib/ctags') require('lib/session') require('lib/router') require('lib/search') require('lib/utils') +local ctags = require('lib/ctags') + local lspc = require('plugins/vis-lspc') lspc.enabled = true lspc.autostart = false @@ -83,20 +84,32 @@ end) settings = { c = function(win) - if not start_lspc(lspc, 'clangd') then - vis:command('set ctags on') - vis:command('set ctags-autosave on') - - mapwin(win, {m.NORMAL, m.VISUAL}, 'K', function() - local sec = vis.count - local name = content(vis.win) - vis.count = nil - - if runq(string.format('whatis %s %s', sec and '-s '..sec or '', name)) then - vis:command(string.format('terminal man %s %s', sec or '', name)) - end - end, 'Man') + if start_lspc(lspc, 'clangd') then + return end + + vis:command('set ctags on') + + ctags.add(win, '.tags', { + path = '.', + flags = '-R --extras=+q-F --fields=+SzK --languages=c,c++', + autosave = true, + }) + + ctags.add(win, '.tags.system', { + path = '/usr/include', + flags = '-R --extras=+q-F --fields=+SzK --languages=c,c++', + }) + + mapwin(win, {m.NORMAL, m.VISUAL}, 'K', function() + local sec = vis.count + local name = content(vis.win) + vis.count = nil + + if runq(string.format('whatis %s %s', sec and '-s '..sec or '', name)) then + vis:command(string.format('terminal man %s %s', sec or '', name)) + end + end, 'Man') end, }