Vis Editor updates.
This commit is contained in:
@@ -1,230 +0,0 @@
|
|||||||
-- ~/.config/vis/fzf.lua
|
|
||||||
-- Pickers: fuzzy file finder, live ripgrep, terminal file manager.
|
|
||||||
-- Loaded from visrc.lua. Each function is self-contained on purpose.
|
|
||||||
|
|
||||||
local M = {}
|
|
||||||
|
|
||||||
-- height of the drop-down fzf panel at the top ('100%' = full screen)
|
|
||||||
M.height = '50%'
|
|
||||||
|
|
||||||
-- ---------------------------------------------------------------------------
|
|
||||||
-- files: fuzzy-find a file, or create one from the query
|
|
||||||
-- enter open the highlighted file (or create the query if nothing matches)
|
|
||||||
-- ctrl-n new file named after the query, e.g. src/util/new.odin
|
|
||||||
-- ---------------------------------------------------------------------------
|
|
||||||
function M.files()
|
|
||||||
-- file list: fd, fdfind (Debian/Ubuntu), or plain find
|
|
||||||
local list = "find . -type f -not -path '*/.git/*' | sed 's|^\\./||'"
|
|
||||||
for _, name in ipairs({ 'fd', 'fdfind' }) do
|
|
||||||
local ok = os.execute('command -v ' .. name .. ' >/dev/null 2>&1')
|
|
||||||
if ok == true or ok == 0 then
|
|
||||||
list = name .. ' --type f --hidden --exclude .git'
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- preview: bat, batcat (Debian/Ubuntu), or head
|
|
||||||
local preview = 'head -n 500 {}'
|
|
||||||
for _, name in ipairs({ 'bat', 'batcat' }) do
|
|
||||||
local ok = os.execute('command -v ' .. name .. ' >/dev/null 2>&1')
|
|
||||||
if ok == true or ok == 0 then
|
|
||||||
preview = name .. ' --color=always --style=numbers --line-range=:500 {}'
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local cmd = list .. ' | fzf'
|
|
||||||
.. ' --height=' .. M.height .. ' --layout=reverse --border'
|
|
||||||
.. " --prompt 'files> '"
|
|
||||||
.. ' --print-query --expect=ctrl-n' -- line 1: query, line 2: key
|
|
||||||
.. " --header 'enter: open · ctrl-n: new file from query'"
|
|
||||||
.. " --preview '" .. preview .. "'"
|
|
||||||
.. " --preview-window 'right:60%:border-left'"
|
|
||||||
.. " --bind 'ctrl-/:toggle-preview'"
|
|
||||||
.. " --bind 'shift-up:preview-up,shift-down:preview-down'"
|
|
||||||
|
|
||||||
-- fzf's --height mode draws from the cursor down: start at the top-left
|
|
||||||
local tty = io.open('/dev/tty', 'w')
|
|
||||||
if tty then tty:write('\27[H') tty:close() end
|
|
||||||
|
|
||||||
local handle = io.popen(cmd)
|
|
||||||
if not handle then
|
|
||||||
vis:info('fzf: failed to start')
|
|
||||||
return
|
|
||||||
end
|
|
||||||
local out = {}
|
|
||||||
for line in handle:lines() do table.insert(out, line) end
|
|
||||||
local _, _, code = handle:close()
|
|
||||||
|
|
||||||
-- back onto the alternate screen (so quitting vis restores the
|
|
||||||
-- terminal), then repaint vis
|
|
||||||
tty = io.open('/dev/tty', 'w')
|
|
||||||
if tty then tty:write('\27[?1049h') tty:close() end
|
|
||||||
vis:redraw()
|
|
||||||
|
|
||||||
if code == 130 then return end -- Esc / Ctrl-C
|
|
||||||
|
|
||||||
local query, key, choice = out[1], out[2], out[3]
|
|
||||||
local is_new = key == 'ctrl-n' or not choice or choice == ''
|
|
||||||
local path = is_new and query or choice
|
|
||||||
if not path or path == '' then return end
|
|
||||||
|
|
||||||
-- open in the current window, unless it's already the current file
|
|
||||||
local win = vis.win
|
|
||||||
local current = win and win.file and win.file.path
|
|
||||||
local same = current ~= nil
|
|
||||||
and (current == path or current:sub(-#path - 1) == '/' .. path)
|
|
||||||
if not same then
|
|
||||||
if win and win.file and win.file.modified then
|
|
||||||
vis:info('Buffer has unsaved changes — :w first (or use :e! manually)')
|
|
||||||
return
|
|
||||||
end
|
|
||||||
vis:command(string.format("e '%s'", path))
|
|
||||||
end
|
|
||||||
|
|
||||||
if is_new then
|
|
||||||
vis:info('New file: ' .. path .. ' (written to disk on :w)')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- ---------------------------------------------------------------------------
|
|
||||||
-- grep: live ripgrep search across the project, jump to the match
|
|
||||||
-- ---------------------------------------------------------------------------
|
|
||||||
function M.grep()
|
|
||||||
local ok = os.execute('command -v rg >/dev/null 2>&1')
|
|
||||||
if not (ok == true or ok == 0) then
|
|
||||||
vis:info('ripgrep (rg) not found on PATH')
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
-- preview: bat/batcat with the match highlighted, or cat -n
|
|
||||||
-- {1} = path, {2} = line number (fields split on ':')
|
|
||||||
local preview = 'cat -n {1}'
|
|
||||||
for _, name in ipairs({ 'bat', 'batcat' }) do
|
|
||||||
local found = os.execute('command -v ' .. name .. ' >/dev/null 2>&1')
|
|
||||||
if found == true or found == 0 then
|
|
||||||
preview = name .. ' --color=always --style=numbers --highlight-line {2} {1}'
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- don't run rg on an empty query (it would match every line)
|
|
||||||
local reload = '[ -n {q} ] && rg --column --line-number --no-heading'
|
|
||||||
.. ' --color=always --smart-case --hidden --glob "!.git" -- {q} || true'
|
|
||||||
|
|
||||||
-- empty stdin: results only appear once you start typing
|
|
||||||
local cmd = ': | fzf'
|
|
||||||
.. ' --height=' .. M.height .. ' --layout=reverse --border'
|
|
||||||
.. " --prompt 'rg> '"
|
|
||||||
.. ' --ansi --disabled' -- let rg do the matching, not fzf
|
|
||||||
.. ' --delimiter :'
|
|
||||||
.. " --bind 'change:reload:" .. reload .. "'"
|
|
||||||
.. " --preview '" .. preview .. "'"
|
|
||||||
.. " --preview-window 'right:60%:border-left:+{2}/2'" -- centre match
|
|
||||||
.. " --bind 'ctrl-/:toggle-preview'"
|
|
||||||
.. " --bind 'shift-up:preview-up,shift-down:preview-down'"
|
|
||||||
|
|
||||||
-- fzf's --height mode draws from the cursor down: start at the top-left
|
|
||||||
local tty = io.open('/dev/tty', 'w')
|
|
||||||
if tty then tty:write('\27[H') tty:close() end
|
|
||||||
|
|
||||||
local handle = io.popen(cmd)
|
|
||||||
if not handle then
|
|
||||||
vis:info('fzf: failed to start')
|
|
||||||
return
|
|
||||||
end
|
|
||||||
local choice = handle:read('*l')
|
|
||||||
handle:close()
|
|
||||||
|
|
||||||
-- back onto the alternate screen, then repaint vis
|
|
||||||
tty = io.open('/dev/tty', 'w')
|
|
||||||
if tty then tty:write('\27[?1049h') tty:close() end
|
|
||||||
vis:redraw()
|
|
||||||
|
|
||||||
if not choice or choice == '' then return end
|
|
||||||
|
|
||||||
choice = choice:gsub('\27%[[%d;]*m', '') -- strip any colour codes
|
|
||||||
local path, line, col = choice:match('^(.-):(%d+):(%d+):')
|
|
||||||
if not path then return end
|
|
||||||
|
|
||||||
-- open in the current window, unless it's already the current file
|
|
||||||
local win = vis.win
|
|
||||||
local current = win and win.file and win.file.path
|
|
||||||
local same = current ~= nil
|
|
||||||
and (current == path or current:sub(-#path - 1) == '/' .. path)
|
|
||||||
if not same then
|
|
||||||
if win and win.file and win.file.modified then
|
|
||||||
vis:info('Buffer has unsaved changes — :w first (or use :e! manually)')
|
|
||||||
return
|
|
||||||
end
|
|
||||||
vis:command(string.format("e '%s'", path))
|
|
||||||
end
|
|
||||||
|
|
||||||
vis.win.selection:to(tonumber(line), tonumber(col))
|
|
||||||
end
|
|
||||||
|
|
||||||
-- ---------------------------------------------------------------------------
|
|
||||||
-- fm: browse/create/rename/delete in a terminal file manager, then open the
|
|
||||||
-- file you pick. Uses the first one found: yazi, lf, nnn, ranger
|
|
||||||
-- ---------------------------------------------------------------------------
|
|
||||||
function M.fm()
|
|
||||||
local tmp = os.tmpname()
|
|
||||||
local managers = {
|
|
||||||
{ 'yazi', "yazi --chooser-file='%s'" },
|
|
||||||
{ 'lf', "lf -selection-path '%s'" },
|
|
||||||
{ 'nnn', "nnn -p '%s'" },
|
|
||||||
{ 'ranger', "ranger --choosefile='%s'" },
|
|
||||||
}
|
|
||||||
|
|
||||||
local cmd
|
|
||||||
for _, m in ipairs(managers) do
|
|
||||||
local ok = os.execute('command -v ' .. m[1] .. ' >/dev/null 2>&1')
|
|
||||||
if ok == true or ok == 0 then
|
|
||||||
cmd = string.format(m[2], tmp)
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if not cmd then
|
|
||||||
os.remove(tmp)
|
|
||||||
vis:info('No file manager found (install yazi, lf, nnn or ranger)')
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
os.execute(cmd .. ' </dev/tty >/dev/tty 2>&1')
|
|
||||||
|
|
||||||
-- back onto the alternate screen, then repaint vis
|
|
||||||
local tty = io.open('/dev/tty', 'w')
|
|
||||||
if tty then tty:write('\27[?1049h') tty:close() end
|
|
||||||
vis:redraw()
|
|
||||||
|
|
||||||
local f = io.open(tmp, 'r')
|
|
||||||
local path = f and f:read('*l')
|
|
||||||
if f then f:close() end
|
|
||||||
os.remove(tmp)
|
|
||||||
if not path or path == '' then return end
|
|
||||||
|
|
||||||
-- open in the current window, unless it's already the current file
|
|
||||||
local win = vis.win
|
|
||||||
local current = win and win.file and win.file.path
|
|
||||||
if current ~= path then
|
|
||||||
if win and win.file and win.file.modified then
|
|
||||||
vis:info('Buffer has unsaved changes — :w first (or use :e! manually)')
|
|
||||||
return
|
|
||||||
end
|
|
||||||
vis:command(string.format("e '%s'", path))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- ---------------------------------------------------------------------------
|
|
||||||
-- create missing parent directories on save, so a new file from ctrl-n like
|
|
||||||
-- src/util/new.odin can be written even if src/util/ doesn't exist yet
|
|
||||||
-- ---------------------------------------------------------------------------
|
|
||||||
vis.events.subscribe(vis.events.FILE_SAVE_PRE, function(file, path) -- luacheck: no unused args
|
|
||||||
local dir = path and path:match('^(.*)/[^/]+$')
|
|
||||||
if dir and dir ~= '' then
|
|
||||||
os.execute("mkdir -p '" .. dir:gsub("'", "'\\''") .. "'")
|
|
||||||
end
|
|
||||||
return true
|
|
||||||
end)
|
|
||||||
|
|
||||||
return M
|
|
||||||
@@ -0,0 +1,179 @@
|
|||||||
|
--pickers: fuzzy file finder, live ripgrep, yazi file manager, gitu.
|
||||||
|
local M = {}
|
||||||
|
|
||||||
|
-- height of the drop-down fzf panel at the top ('100%' = full screen)
|
||||||
|
M.height = '100%'
|
||||||
|
|
||||||
|
-- ---------------------------------------------------------------------------
|
||||||
|
-- helper funcs
|
||||||
|
-- ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
-- write a raw escape sequence straight to the terminal
|
||||||
|
local function tty_write(seq)
|
||||||
|
local tty = io.open('/dev/tty', 'w')
|
||||||
|
if tty then
|
||||||
|
tty:write(seq)
|
||||||
|
tty:close()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- hand the terminal back to vis: re-enter the alt screen and repaint
|
||||||
|
local function restore_screen()
|
||||||
|
tty_write('\27[?1049h')
|
||||||
|
vis:redraw()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- run an fzf pipeline; returns its output lines and exit code
|
||||||
|
local function run_fzf(cmd)
|
||||||
|
-- --height mode draws from the cursor down, so start at the top-left
|
||||||
|
tty_write('\27[H')
|
||||||
|
|
||||||
|
local handle = io.popen(cmd)
|
||||||
|
if not handle then
|
||||||
|
vis:info('fzf: failed to start')
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
local lines = {}
|
||||||
|
for line in handle:lines() do table.insert(lines, line) end
|
||||||
|
local _, _, code = handle:close()
|
||||||
|
|
||||||
|
restore_screen()
|
||||||
|
return lines, code
|
||||||
|
end
|
||||||
|
|
||||||
|
-- open a path in the current window, unless it's already the current file.
|
||||||
|
-- returns false if the buffer has unsaved changes and nothing was opened
|
||||||
|
local function open_path(path)
|
||||||
|
local win = vis.win
|
||||||
|
local current = win and win.file and win.file.path
|
||||||
|
if current and (current == path or current:sub(-#path - 1) == '/' .. path) then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
if win and win.file and win.file.modified then
|
||||||
|
vis:info('Buffer has unsaved changes — :w first (or use :e! manually)')
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
vis:command(string.format("e '%s'", path))
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
-- ---------------------------------------------------------------------------
|
||||||
|
-- files: fuzzy-find a file, or create one from the query
|
||||||
|
-- enter open in the current window
|
||||||
|
-- ctrl-v open in a vertical split
|
||||||
|
-- alt-enter create a file named after the query
|
||||||
|
-- ctrl-n/p move down/up
|
||||||
|
-- ---------------------------------------------------------------------------
|
||||||
|
function M.files()
|
||||||
|
local preview = 'bat --theme=custom_zen --color=always --style=numbers --line-range=:500 {}'
|
||||||
|
|
||||||
|
local cmd = 'fd --type f --hidden --exclude .git | fzf'
|
||||||
|
.. ' --height=' .. M.height .. ' --layout=reverse --border'
|
||||||
|
.. " --prompt 'files> '"
|
||||||
|
.. ' --print-query --expect=alt-enter,ctrl-v' -- output: query, key, choice
|
||||||
|
.. " --header 'enter: open · alt-enter: new file · ctrl-v: vsplit'"
|
||||||
|
.. " --preview '" .. preview .. "'"
|
||||||
|
.. " --preview-window 'down:75%:border-top'"
|
||||||
|
.. " --bind 'ctrl-n:down,ctrl-p:up'"
|
||||||
|
.. " --bind 'ctrl-/:toggle-preview'"
|
||||||
|
.. " --bind 'shift-up:preview-up,shift-down:preview-down'"
|
||||||
|
|
||||||
|
local out, code = run_fzf(cmd)
|
||||||
|
if not out or code == 130 then return end -- failed, or Esc / Ctrl-C
|
||||||
|
|
||||||
|
local query, key, choice = out[1], out[2], out[3]
|
||||||
|
local is_new = key == 'alt-enter' or not choice or choice == ''
|
||||||
|
local path = is_new and query or choice
|
||||||
|
if not path or path == '' then return end
|
||||||
|
|
||||||
|
if key == 'ctrl-v' then
|
||||||
|
vis:command(string.format("vsplit '%s'", path))
|
||||||
|
elseif not open_path(path) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if is_new then
|
||||||
|
vis:info('New file: ' .. path .. ' (written to disk on :w)')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- ---------------------------------------------------------------------------
|
||||||
|
-- grep: live ripgrep search across the project, jump to the match
|
||||||
|
-- ---------------------------------------------------------------------------
|
||||||
|
function M.grep()
|
||||||
|
-- {1} = path, {2} = line number (fields split on ':')
|
||||||
|
local preview = 'bat --theme=custom_zen --color=always --style=numbers --highlight-line {2} {1}'
|
||||||
|
|
||||||
|
-- don't run rg on an empty query (it would match every line)
|
||||||
|
local reload = '[ -n {q} ] && rg --column --line-number --no-heading'
|
||||||
|
.. ' --color=always --smart-case --hidden --glob "!.git" -- {q} || true'
|
||||||
|
|
||||||
|
-- empty stdin: results only appear once you start typing
|
||||||
|
local cmd = ': | fzf'
|
||||||
|
.. ' --height=' .. M.height .. ' --layout=reverse --border'
|
||||||
|
.. " --prompt 'rg> '"
|
||||||
|
.. ' --ansi --disabled' -- let rg do the matching, not fzf
|
||||||
|
.. ' --delimiter :'
|
||||||
|
.. " --bind 'change:reload:" .. reload .. "'"
|
||||||
|
.. " --preview '" .. preview .. "'"
|
||||||
|
.. " --preview-window 'down:90%:border-top:+{2}/2'"
|
||||||
|
.. " --bind 'ctrl-/:toggle-preview'"
|
||||||
|
.. " --bind 'shift-up:preview-up,shift-down:preview-down'"
|
||||||
|
|
||||||
|
local out = run_fzf(cmd)
|
||||||
|
local choice = out and out[1]
|
||||||
|
if not choice or choice == '' then return end
|
||||||
|
|
||||||
|
choice = choice:gsub('\27%[[%d;]*m', '') -- strip colour codes
|
||||||
|
local path, line, col = choice:match('^(.-):(%d+):(%d+):')
|
||||||
|
if not path or not open_path(path) then return end
|
||||||
|
|
||||||
|
vis.win.selection:to(tonumber(line), tonumber(col))
|
||||||
|
end
|
||||||
|
|
||||||
|
-- ---------------------------------------------------------------------------
|
||||||
|
-- fm: browse/create/rename/delete in yazi, then open the file you pick
|
||||||
|
-- ---------------------------------------------------------------------------
|
||||||
|
function M.fm()
|
||||||
|
local tmp = os.tmpname()
|
||||||
|
|
||||||
|
os.execute(string.format("yazi --chooser-file='%s' </dev/tty >/dev/tty 2>&1", tmp))
|
||||||
|
restore_screen()
|
||||||
|
|
||||||
|
local f = io.open(tmp, 'r')
|
||||||
|
local path = f and f:read('*l')
|
||||||
|
if f then f:close() end
|
||||||
|
os.remove(tmp)
|
||||||
|
|
||||||
|
if path and path ~= '' then open_path(path) end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- ---------------------------------------------------------------------------
|
||||||
|
-- git: run gitu, then hand the screen back to vis
|
||||||
|
-- ---------------------------------------------------------------------------
|
||||||
|
function M.git()
|
||||||
|
os.execute('gitu </dev/tty >/dev/tty 2>&1')
|
||||||
|
restore_screen()
|
||||||
|
|
||||||
|
-- gitu may have changed files on disk (checkout, discard, stash, ...):
|
||||||
|
-- reload the current buffer if there's nothing unsaved to lose
|
||||||
|
local win = vis.win
|
||||||
|
if win and win.file and win.file.path and not win.file.modified then
|
||||||
|
vis:command('e!')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- ---------------------------------------------------------------------------
|
||||||
|
-- create missing parent directories on save, so a new file like
|
||||||
|
-- src/util/new.odin can be written even if src/util/ doesn't exist yet
|
||||||
|
-- ---------------------------------------------------------------------------
|
||||||
|
vis.events.subscribe(vis.events.FILE_SAVE_PRE, function(file, path) -- luacheck: no unused args
|
||||||
|
local dir = path and path:match('^(.*)/[^/]+$')
|
||||||
|
if dir and dir ~= '' then
|
||||||
|
os.execute("mkdir -p '" .. (dir:gsub("'", "'\\''")) .. "'")
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end)
|
||||||
|
|
||||||
|
return M
|
||||||
Submodule
+1
Submodule config/vis/plugins/vis-ctags added at 40a537beaf
@@ -0,0 +1,36 @@
|
|||||||
|
local lexers = vis.lexers
|
||||||
|
|
||||||
|
lexers.STYLE_DEFAULT = 'fore:#d7d7d7,back:#131313'
|
||||||
|
lexers.STYLE_NOTHING = ''
|
||||||
|
lexers.STYLE_CLASS = 'fore:#c4bd97'
|
||||||
|
lexers.STYLE_COMMENT = 'fore:#7d6d5d'
|
||||||
|
lexers.STYLE_CONSTANT = 'fore:#cdadad,bold'
|
||||||
|
lexers.STYLE_DEFINITION = 'fore:#f2d1af,bold'
|
||||||
|
lexers.STYLE_ERROR = 'fore:#8bc8aa,back:#303030,bold'
|
||||||
|
lexers.STYLE_FUNCTION = 'fore:#7a96b0'
|
||||||
|
lexers.STYLE_KEYWORD = 'fore:#787879,bold'
|
||||||
|
lexers.STYLE_LABEL = 'fore:#7a96b0'
|
||||||
|
lexers.STYLE_NUMBER = 'fore:#87d7d7'
|
||||||
|
lexers.STYLE_OPERATOR = 'fore:#d5ce90'
|
||||||
|
lexers.STYLE_REGEX = 'fore:#d0c195'
|
||||||
|
lexers.STYLE_STRING = 'fore:#6c836c'
|
||||||
|
lexers.STYLE_PREPROCESSOR = 'fore:#f2d1af,bold'
|
||||||
|
lexers.STYLE_TAG = 'fore:#cdadad,bold'
|
||||||
|
lexers.STYLE_TYPE = 'fore:#7a96b0,bold'
|
||||||
|
lexers.STYLE_VARIABLE = 'fore:#c9ba9c'
|
||||||
|
lexers.STYLE_WHITESPACE = ''
|
||||||
|
lexers.STYLE_EMBEDDED = 'fore:#c09494'
|
||||||
|
lexers.STYLE_IDENTIFIER = ''
|
||||||
|
|
||||||
|
lexers.STYLE_LINENUMBER = 'fore:#585858'
|
||||||
|
lexers.STYLE_LINENUMBER_CURSOR = 'fore:#666666'
|
||||||
|
lexers.STYLE_CURSOR = 'back:#585858,keep_attribute'
|
||||||
|
lexers.STYLE_CURSOR_PRIMARY = 'fore:#1c1c1c,back:#87afaf,bold,keep_attribute'
|
||||||
|
lexers.STYLE_CURSOR_LINE = 'back:#444444,keep_attribute'
|
||||||
|
lexers.STYLE_COLOR_COLUMN = 'back:#444444'
|
||||||
|
lexers.STYLE_SELECTION = 'back:#4a604a'
|
||||||
|
lexers.STYLE_STATUS = 'back:#262626,fore:#6c836c'
|
||||||
|
lexers.STYLE_STATUS_FOCUSED = 'back:#303030,fore:#cacaca,bold'
|
||||||
|
lexers.STYLE_SEPARATOR = ''
|
||||||
|
lexers.STYLE_INFO = ''
|
||||||
|
lexers.STYLE_EOF = 'fore:#585858'
|
||||||
+54
-30
@@ -1,51 +1,75 @@
|
|||||||
-- load the standard vis module (provides the Lua API)
|
|
||||||
require('vis')
|
require('vis')
|
||||||
|
|
||||||
-- ~/.config/vis/fzf.lua and ~/.config/vis/build.lua
|
local pickers = require('pickers')
|
||||||
local fzf = require('fzf')
|
|
||||||
local build = require('build')
|
local build = require('build')
|
||||||
|
|
||||||
|
require('plugins/vis-ctags')
|
||||||
|
|
||||||
-- ---------------------------------------------------------------------------
|
-- ---------------------------------------------------------------------------
|
||||||
-- Odin syntax highlighting (lexer lives in ~/.config/vis/lexers/odin.lua)
|
-- Syntax highlighting: ~/.config/vis/lexers/odin.lua
|
||||||
-- ---------------------------------------------------------------------------
|
-- ---------------------------------------------------------------------------
|
||||||
if vis.ftdetect then
|
if vis.ftdetect then
|
||||||
if vis.ftdetect.extensions then -- newer vis (git master)
|
-- vis 0.9 and earlier
|
||||||
vis.ftdetect.extensions.odin = 'odin'
|
if vis.ftdetect.filetypes then
|
||||||
end
|
vis.ftdetect.filetypes.odin = { ext = { '%.odin$' } }
|
||||||
if vis.ftdetect.filetypes then -- vis 0.9 and earlier
|
end
|
||||||
vis.ftdetect.filetypes.odin = { ext = { '%.odin$' } }
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- ---------------------------------------------------------------------------
|
-- ---------------------------------------------------------------------------
|
||||||
-- Global options, key mappings and commands
|
-- Global options, key mappings and commands
|
||||||
-- ---------------------------------------------------------------------------
|
-- ---------------------------------------------------------------------------
|
||||||
vis.events.subscribe(vis.events.INIT, function()
|
vis.events.subscribe(vis.events.INIT, function()
|
||||||
vis:command('set escdelay 15')
|
vis:command('set escdelay 1')
|
||||||
vis:command('set autoindent on')
|
vis:command('set autoindent off')
|
||||||
vis:command('set theme custom')
|
vis:command('set theme custom_zen')
|
||||||
|
|
||||||
-- pickers
|
-- pickers
|
||||||
vis:map(vis.modes.NORMAL, '<C-p>', fzf.files, 'Fuzzy find / create a file')
|
vis:map(vis.modes.NORMAL, '<C-p>', pickers.files, 'Fuzzy find / create a file')
|
||||||
vis:map(vis.modes.NORMAL, '<C-f>', fzf.grep, 'Live grep the project with ripgrep')
|
vis:map(vis.modes.NORMAL, '<C-f>', pickers.grep, 'Live grep the project with ripgrep')
|
||||||
vis:command_register('files', function() fzf.files() return true end, 'Fuzzy find / create a file')
|
vis:map(vis.modes.NORMAL, '<C-e>', pickers.fm, 'terminal file manager')
|
||||||
vis:command_register('grep', function() fzf.grep() return true end, 'Live grep the project with ripgrep')
|
-- picker commands
|
||||||
vis:command_register('fm', function() fzf.fm() return true end, 'Pick a file with a terminal file manager')
|
vis:command_register('files', function() pickers.files() return true end, 'Fuzzy find / create a file')
|
||||||
|
vis:command_register('grep', function() pickers.grep() return true end, 'Live grep the project with ripgrep')
|
||||||
|
vis:command_register('fm', function() pickers.fm() return true end, 'Pick a file with a terminal file manager')
|
||||||
|
vis:command_register('git', function() pickers.git() return true end, 'Open gitu')
|
||||||
|
|
||||||
|
-- build.sh setup
|
||||||
|
vis:map(vis.modes.NORMAL, '<C-b>', function() build.run({}) end, 'Run ./build.sh')
|
||||||
|
vis:command_register('build', function(argv)
|
||||||
|
local args = {}
|
||||||
|
for i = 1, #argv do table.insert(args, argv[i]) end
|
||||||
|
build.run(args)
|
||||||
|
return true
|
||||||
|
end, 'Run ./build.sh with optional flags, e.g. :build run')
|
||||||
|
|
||||||
|
-- system clipboard
|
||||||
|
local function clip_copy()
|
||||||
|
vis:feedkeys(':>wl-copy 2>/dev/null<Enter>')
|
||||||
|
vis:feedkeys('<Escape>') -- drop the selection / leave visual mode
|
||||||
|
end
|
||||||
|
|
||||||
|
local function clip_paste()
|
||||||
|
vis:feedkeys(':<wl-paste --no-newline<Enter>')
|
||||||
|
vis:feedkeys('<Escape>') -- clear any selection left on the pasted text
|
||||||
|
end
|
||||||
|
|
||||||
|
vis:map(vis.modes.VISUAL, '<C-y>', clip_copy, 'Copy selection to system clipboard')
|
||||||
|
vis:map(vis.modes.VISUAL, '<C-v>', clip_paste, 'Paste system clipboard at cursor')
|
||||||
|
vis:map(vis.modes.NORMAL, '<C-v>', clip_paste, 'Paste system clipboard at cursor')
|
||||||
|
|
||||||
|
|
||||||
|
-- ctags: 'gd' to jump to tag definition under cursor
|
||||||
|
-- vis-ctags binds <C-]> (jump) and <C-t> (back) itself;
|
||||||
|
vis:map(vis.modes.NORMAL, 'gd', '<C-]>')
|
||||||
|
|
||||||
vis:map(vis.modes.NORMAL, '<C-b>', function() build.run({}) end, 'Run ./build.sh')
|
|
||||||
vis:command_register('build', function(argv)
|
|
||||||
local args = {}
|
|
||||||
for i = 1, #argv do table.insert(args, argv[i]) end
|
|
||||||
build.run(args)
|
|
||||||
return true
|
|
||||||
end, 'Run ./build.sh with optional flags, e.g. :build run')
|
|
||||||
end)
|
end)
|
||||||
|
|
||||||
-- ---------------------------------------------------------------------------
|
-- ---------------------------------------------------------------------------
|
||||||
-- Per-window options
|
-- Per-window options
|
||||||
-- ---------------------------------------------------------------------------
|
-- ---------------------------------------------------------------------------
|
||||||
vis.events.subscribe(vis.events.WIN_OPEN, function(win) -- luacheck: no unused args
|
vis.events.subscribe(vis.events.WIN_OPEN, function(win)
|
||||||
vis:command('set tabwidth 4')
|
vis:command('set tabwidth 4')
|
||||||
vis:command('set expandtab on')
|
vis:command('set expandtab on')
|
||||||
vis:command('set number on')
|
vis:command('set number on')
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
|||||||
+112
-26
@@ -1,33 +1,119 @@
|
|||||||
# ~/.config/yazi/theme.toml
|
[app]
|
||||||
# Minimal status bar: same colours as the default, as text only.
|
overall = { bg = "#131313" }
|
||||||
# Anything not set here falls back to yazi's built-in theme.
|
|
||||||
|
[icon]
|
||||||
|
dirs = []
|
||||||
|
prepend_conds = [ { if = "dir", text = ">", fg = "#7a96b0" } ]
|
||||||
|
|
||||||
|
|
||||||
|
[mgr]
|
||||||
|
cwd = { fg = "#7a96b0", bold = true }
|
||||||
|
find_keyword = { fg = "#f2d1af", bold = true }
|
||||||
|
find_position = { fg = "#87d7d7" }
|
||||||
|
symlink_target = { fg = "#87afaf", italic = true }
|
||||||
|
|
||||||
|
marker_copied = { fg = "#6c836c", bg = "#6c836c" }
|
||||||
|
marker_cut = { fg = "#cdadad", bg = "#cdadad" }
|
||||||
|
marker_marked = { fg = "#f2d1af", bg = "#f2d1af" }
|
||||||
|
marker_selected = { fg = "#7a96b0", bg = "#7a96b0" }
|
||||||
|
|
||||||
|
count_copied = { fg = "#131313", bg = "#6c836c" }
|
||||||
|
count_cut = { fg = "#131313", bg = "#cdadad" }
|
||||||
|
count_selected = { fg = "#131313", bg = "#7a96b0" }
|
||||||
|
|
||||||
|
border_style = { fg = "#585858" }
|
||||||
|
|
||||||
|
# code preview uses the same theme file as bat
|
||||||
|
syntect_theme = "/home/jason/.config/bat/themes/custom_zen.tmTheme"
|
||||||
|
|
||||||
|
[indicator]
|
||||||
|
parent = { bg = "#303030" }
|
||||||
|
current = { bg = "#444444" }
|
||||||
|
preview = { bg = "#303030" }
|
||||||
|
|
||||||
|
[tabs]
|
||||||
|
active = { fg = "#131313", bg = "#7a96b0", bold = true }
|
||||||
|
inactive = { fg = "#d7d7d7", bg = "#303030" }
|
||||||
|
|
||||||
[mode]
|
[mode]
|
||||||
# mode label (NOR / SEL / UNS) and position counter
|
normal_main = { fg = "#131313", bg = "#7a96b0", bold = true }
|
||||||
normal_main = { fg = "blue", bold = true }
|
normal_alt = { fg = "#7a96b0", bg = "#303030" }
|
||||||
select_main = { fg = "red", bold = true }
|
select_main = { fg = "#131313", bg = "#6c836c", bold = true }
|
||||||
unset_main = { fg = "red", bold = true }
|
select_alt = { fg = "#6c836c", bg = "#303030" }
|
||||||
|
unset_main = { fg = "#131313", bg = "#cdadad", bold = true }
|
||||||
# file size and Top/Bot/% segments
|
unset_alt = { fg = "#cdadad", bg = "#303030" }
|
||||||
normal_alt = { fg = "blue" }
|
|
||||||
select_alt = { fg = "red" }
|
|
||||||
unset_alt = { fg = "red" }
|
|
||||||
|
|
||||||
[status]
|
[status]
|
||||||
overall = {}
|
overall = { fg = "#d7d7d7", bg = "#262626" }
|
||||||
|
perm_sep = { fg = "#585858" }
|
||||||
|
perm_type = { fg = "#7a96b0" }
|
||||||
|
perm_read = { fg = "#a0a0a0" }
|
||||||
|
perm_write = { fg = "#cdadad" }
|
||||||
|
perm_exec = { fg = "#6c836c" }
|
||||||
|
progress_label = { fg = "#d7d7d7", bold = true }
|
||||||
|
progress_normal = { fg = "#7a96b0", bg = "#303030" }
|
||||||
|
progress_error = { fg = "#cdadad", bg = "#303030" }
|
||||||
|
|
||||||
# no powerline arrows between segments
|
[which]
|
||||||
sep_left = { open = "", close = "" }
|
border = { fg = "#585858" }
|
||||||
sep_right = { open = "", close = "" }
|
mask = { bg = "#262626" }
|
||||||
|
cand = { fg = "#87d7d7" }
|
||||||
|
rest = { fg = "#585858" }
|
||||||
|
desc = { fg = "#a0a0a0" }
|
||||||
|
separator_style = { fg = "#585858" }
|
||||||
|
|
||||||
# permissions (unchanged from default)
|
[confirm]
|
||||||
perm_sep = { fg = "darkgray" }
|
border = { fg = "#7a96b0" }
|
||||||
perm_type = { fg = "green" }
|
title = { fg = "#7a96b0" }
|
||||||
perm_read = { fg = "yellow" }
|
btn_yes = { fg = "#131313", bg = "#7a96b0" }
|
||||||
perm_write = { fg = "red" }
|
btn_no = { fg = "#d7d7d7", bg = "#303030" }
|
||||||
perm_exec = { fg = "cyan" }
|
|
||||||
|
|
||||||
# task progress bar, without the black track behind it
|
[spot]
|
||||||
progress_label = { bold = true }
|
border = { fg = "#7a96b0" }
|
||||||
progress_normal = { fg = "green" }
|
title = { fg = "#7a96b0" }
|
||||||
progress_error = { fg = "red" }
|
tbl_col = { fg = "#7a96b0" }
|
||||||
|
tbl_cell = { fg = "#d7d7d7", bg = "#444444" }
|
||||||
|
|
||||||
|
[notify]
|
||||||
|
title_info = { fg = "#6c836c" }
|
||||||
|
title_warn = { fg = "#f2d1af" }
|
||||||
|
title_error = { fg = "#cdadad" }
|
||||||
|
|
||||||
|
[pick]
|
||||||
|
border = { fg = "#7a96b0" }
|
||||||
|
active = { fg = "#cdadad", bold = true }
|
||||||
|
|
||||||
|
[input]
|
||||||
|
border = { fg = "#7a96b0" }
|
||||||
|
selected = { bg = "#4a604a" }
|
||||||
|
|
||||||
|
[cmp]
|
||||||
|
border = { fg = "#7a96b0" }
|
||||||
|
active = { bg = "#444444" }
|
||||||
|
|
||||||
|
[tasks]
|
||||||
|
border = { fg = "#7a96b0" }
|
||||||
|
hovered = { fg = "#cdadad", underline = true }
|
||||||
|
|
||||||
|
[help]
|
||||||
|
border = { fg = "#585858" }
|
||||||
|
chord = { fg = "#87d7d7" }
|
||||||
|
action = { fg = "#6c836c" }
|
||||||
|
hovered = { bg = "#444444" }
|
||||||
|
|
||||||
|
[filetype]
|
||||||
|
rules = [
|
||||||
|
# images
|
||||||
|
{ mime = "image/*", fg = "#87d7d7" },
|
||||||
|
# audio / video
|
||||||
|
{ mime = "{audio,video}/*", fg = "#f2d1af" },
|
||||||
|
# archives
|
||||||
|
{ mime = "application/{zip,gzip,x-tar,x-bzip*,x-xz,x-7z-compressed,x-rar}", fg = "#cdadad" },
|
||||||
|
# documents
|
||||||
|
{ mime = "application/{pdf,doc,rtf}", fg = "#a0a0a0" },
|
||||||
|
# special files
|
||||||
|
{ url = "*", is = "orphan", fg = "#131313", bg = "#cdadad" },
|
||||||
|
{ url = "*", is = "exec", fg = "#6c836c" },
|
||||||
|
# directories
|
||||||
|
{ url = "*/", fg = "#7a96b0" },
|
||||||
|
]
|
||||||
Reference in New Issue
Block a user