From ebec63e48c428fc2f6cd3208cd9dbe4d55f938b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Pankowski?= Date: Fri, 5 Sep 2025 23:50:08 +0200 Subject: [PATCH] add vis config --- .gitignore | 1 + shell/.config/shellconfig/aliases.sh | 8 ++ vis/.config/vis/lexers/templ.lua | 71 ++++++++++ vis/.config/vis/visrc.lua | 204 +++++++++++++++++++++++++++ 4 files changed, 284 insertions(+) create mode 100644 vis/.config/vis/lexers/templ.lua create mode 100644 vis/.config/vis/visrc.lua diff --git a/.gitignore b/.gitignore index 98dfacf..06ca986 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ lupan-wm/target __pycache__ /dwm /st +/vis/.config/vis/plugins/ diff --git a/shell/.config/shellconfig/aliases.sh b/shell/.config/shellconfig/aliases.sh index 582aaf0..4154552 100644 --- a/shell/.config/shellconfig/aliases.sh +++ b/shell/.config/shellconfig/aliases.sh @@ -14,3 +14,11 @@ fi alias nocaps='setxkbmap pl -option ctrl:nocaps' alias fixdp='xrandr --output DP-0 --right-of DP-2' + +vf() { + if [ -z "$1" ]; then + vis $(fzf) + else + vis $(fzf -q $1) + fi +} diff --git a/vis/.config/vis/lexers/templ.lua b/vis/.config/vis/lexers/templ.lua new file mode 100644 index 0000000..649a85a --- /dev/null +++ b/vis/.config/vis/lexers/templ.lua @@ -0,0 +1,71 @@ +-- Copyright 2006-2025 Mitchell. See LICENSE. +-- Go LPeg lexer. + +local lexer = lexer +local P, S = lpeg.P, lpeg.S + +local lex = lexer.new(...) + +-- Keywords. +lex:add_rule('keyword', lex:tag(lexer.KEYWORD, lex:word_match(lexer.KEYWORD))) + +-- Constants. +lex:add_rule('constant', lex:tag(lexer.CONSTANT_BUILTIN, lex:word_match(lexer.CONSTANT_BUILTIN))) + +-- Types. +lex:add_rule('type', lex:tag(lexer.TYPE, lex:word_match(lexer.TYPE))) + +-- Functions. +local builtin_func = -lpeg.B('.') * + lex:tag(lexer.FUNCTION_BUILTIN, lex:word_match(lexer.FUNCTION_BUILTIN)) +local func = lex:tag(lexer.FUNCTION, lexer.word) +local method = lpeg.B('.') * lex:tag(lexer.FUNCTION_METHOD, lexer.word) +lex:add_rule('function', (builtin_func + method + func) * #(lexer.space^0 * '(')) + +-- Identifiers. +lex:add_rule('identifier', lex:tag(lexer.IDENTIFIER, lexer.word)) + +-- Strings. +local sq_str = lexer.range("'", true) +local dq_str = lexer.range('"', true) +local raw_str = lexer.range('`', false, false) +lex:add_rule('string', lex:tag(lexer.STRING, sq_str + dq_str + raw_str)) + +-- Comments. +local line_comment = lexer.to_eol('//') +local block_comment = lexer.range('/*', '*/') +lex:add_rule('comment', lex:tag(lexer.COMMENT, line_comment + block_comment)) + +-- Numbers. +lex:add_rule('number', lex:tag(lexer.NUMBER, lexer.number * P('i')^-1)) + +-- Operators. +lex:add_rule('operator', lex:tag(lexer.OPERATOR, S('+-*/%&|^<>=!~:;.,()[]{}@'))) + +-- Fold points. +lex:add_fold_point(lexer.OPERATOR, '{', '}') +lex:add_fold_point(lexer.COMMENT, '/*', '*/') + +-- Word lists. +lex:set_word_list(lexer.KEYWORD, { + 'break', 'case', 'chan', 'const', 'continue', 'default', 'defer', 'else', 'fallthrough', 'for', + 'func', 'go', 'goto', 'if', 'import', 'interface', 'map', 'package', 'range', 'return', 'select', + 'struct', 'switch', 'type', 'var', 'templ' +}) + +lex:set_word_list(lexer.CONSTANT_BUILTIN, 'true false iota nil') + +lex:set_word_list(lexer.TYPE, { + 'any', 'bool', 'byte', 'comparable', 'complex64', 'complex128', 'error', 'float32', 'float64', + 'int', 'int8', 'int16', 'int32', 'int64', 'rune', 'string', 'uint', 'uint8', 'uint16', 'uint32', + 'uint64', 'uintptr' +}) + +lex:set_word_list(lexer.FUNCTION_BUILTIN, { + 'append', 'cap', 'close', 'complex', 'copy', 'delete', 'imag', 'len', 'make', 'new', 'panic', + 'print', 'println', 'real', 'recover' +}) + +lexer.property['scintillua.comment'] = '//' + +return lex diff --git a/vis/.config/vis/visrc.lua b/vis/.config/vis/visrc.lua new file mode 100644 index 0000000..8d073d5 --- /dev/null +++ b/vis/.config/vis/visrc.lua @@ -0,0 +1,204 @@ +require('vis') + +local plug = (function() + if not pcall(require, 'plugins/vis-plug') then + os.execute('git clone --quiet https://github.com/erf/vis-plug ' .. + (os.getenv('XDG_CONFIG_HOME') or os.getenv('HOME') .. '/.config') + .. '/vis/plugins/vis-plug') + end + return require('plugins/vis-plug') +end)() + +plug = require('plugins/vis-plug') + +local plugins = { + { + 'scaramacai/vis-themes', + theme = true, + file = 'almostnord', + -- file = 'strange-morning', + }, + { 'https://gitlab.com/muhq/vis-lspc', alias = 'lspc' }, + { 'lutobler/vis-commentary' }, + { 'https://repo.or.cz/vis-surround.git' }, + { 'peaceant/vis-fzf-mru', file = 'fzf-mru', alias = 'fzfmru' }, + { 'https://gitlab.com/muhq/vis-build' }, + { 'erf/vis-cursors' }, +} + +plug.init(plugins, true) + +vis.ftdetect.filetypes.templ = { + ext = { "%.templ$" }, +} + +plug.plugins.lspc.message_level = 2 + +plug.plugins.lspc.ls_map.templ = { + name = 'templ-lsp', + cmd = 'templ lsp', +} + +plug.plugins.fzfmru.fzfmru_history = 60 + +local function open_file(file, cmd) + vis:command((cmd or 'o') .. ' ' .. file) +end + +local function nil_or_tonumber(s) + return s and tonumber(s) +end + +local function open_file_pos(line, open_cmd) + local iter = string.gmatch(line, '[^:]+') + local file = iter() + local line_num = nil_or_tonumber(iter()) + local col = nil_or_tonumber(iter()) or 1 + open_file(file, open_cmd) + if line_num ~= nil then + vis.win.selection:to(line_num, col) + end +end + +local function open_file_current_line(open_cmd) + local line = vis.win.file.lines[vis.win.selection.line] + vis:info(line) + open_file_pos(line) +end + +local function escape_and_quoted(s) + return "'" .. s:gsub("'", "\\'") .. "'" +end + +local function search(cmd) + if cmd:match('^fzf ') and vis.register ~= '"' then + local reg = string.gsub(vis.registers[vis.register][1], '%z', '') + if reg ~= '' then + cmd = cmd .. ' --query=' .. escape_and_quoted(reg) + end + end + local code, out, err = vis:pipe(cmd, true) + if code == 0 then + open_file_pos(out, 'e') + elseif err ~= nil then + vis:info(err) + elseif code ~= 0 then + vis:info('Program exit code ' .. code) + end +end + +local file_slots = {} + +local function set_file_slot(num) + local file = vis.win.file.path + if file ~= nil then + file_slots[num] = file + vis:info('File slot [' .. num .. '] updated') + else + vis:info('Window has no file') + end +end + +local function open_file_slot(num, open_cmd) + local file = file_slots[num] + if file == nil then + vis:info('File slot [' .. num .. '] empty') + elseif file == vis.win.file.path then + vis:info('File slot [' .. num .. '] is the same file, no file change') + else + vis:info('File slot [' .. num .. '] open') + open_file(file, open_cmd) + end +end + +local function fzf_reload(cmd) + local prompt = escape_and_quoted('1. ' .. cmd:match('^%w*') .. '> ') + if not cmd:match('{q}') then + cmd = cmd .. ' {q}' + end + return 'fzf --ansi --bind "start:reload:' .. cmd .. '" --bind "change:reload:' .. cmd .. ' || true"' .. + ' --prompt ' .. prompt .. + ' --bind "alt-enter:unbind(change,alt-enter)+change-prompt(2. fzf> )+enable-search+clear-query"' +end + +local ripgrep = 'rg --column --line-number --color=always --smart-case' + +vis.events.subscribe(vis.events.INIT, function() + vis:command('set autoindent') + + vis:command_register('search', function(argv, force, win, selection, range) + search(argv[1]) + end) + + vis:map(vis.modes.NORMAL, '', '') + vis:map(vis.modes.NORMAL, '', '') + vis:map(vis.modes.NORMAL, ' K', ':q', 'close previous window') + vis:map(vis.modes.NORMAL, ' J', ':q', 'close next window') + + vis:map(vis.modes.NORMAL, ' l[', ':lspc-prev-diagnostic') + vis:map(vis.modes.NORMAL, ' l]', ':lspc-next-diagnostic') + vis:map(vis.modes.NORMAL, ' l=', ':lspc-format') + + for num = 1, 9 do + vis:map(vis.modes.NORMAL, ' s' .. num, function() set_file_slot(num) end, 'set file slot ' .. num) + vis:map(vis.modes.NORMAL, ' ' .. num, function() open_file_slot(num, 'e') end, 'open file slot ' .. num) + vis:map(vis.modes.NORMAL, ' h' .. num, function() open_file_slot(num, 'o') end, 'open file slot ' .. num) + vis:map(vis.modes.NORMAL, ' v' .. num, function() open_file_slot(num, 'vsplit') end, + 'open file slot ' .. num) + end + + vis:map(vis.modes.NORMAL, ' fg', function() + search(fzf_reload(ripgrep)) + end, 'fzf: rg') + + vis:map(vis.modes.NORMAL, ' ff', function() + search('fd --type f | fzf') + end, 'fzf: files') + + vis:map(vis.modes.NORMAL, ' .', function() + local path = vis.win.file.path + if path then + local dir = path:match('^.*/') + local arg = escape_and_quoted(dir) + search('fd --type f "" ' .. arg .. ' | fzf') + else + search('fd --type f | fzf') + end + end, 'fzf: current dir files') + + vis:map(vis.modes.NORMAL, ' gf', function() + search('git ls-files | fzf') + end, 'fzf: git files') + + vis:map(vis.modes.NORMAL, ' gg', function() + search(fzf_reload('git grep --column --line-number --color=always')) + end, 'fzf: jj grep') + + vis:map(vis.modes.NORMAL, ' gl', function() + vis:command('!lazygit') + end, 'lazygit') + + vis:map(vis.modes.NORMAL, ' jf', function() + search('jj file list | fzf') + end, 'fzf: jj files') + + vis:map(vis.modes.NORMAL, ' jg', function() + search(fzf_reload(ripgrep .. ' {q} $(jj file list | xargs)')) + end, 'fzf: jj grep') + + vis:map(vis.modes.NORMAL, ' jl', function() + vis:command('!lazyjj') + end, 'fzf open') + + vis:map(vis.modes.NORMAL, ' ', function() + vis:command('fzfmru') + end, 'fzf recent') + + vis:map(vis.modes.NORMAL, 'gf', function() + open_file_current_line('o') + end, 'open file from current line (with line and col') +end) + +vis.events.subscribe(vis.events.WIN_OPEN, function(win) + vis:command('set relativenumber') +end)