initial commit
This commit is contained in:
commit
23d4795228
99 changed files with 6691 additions and 0 deletions
156
config/nvim/lua/config/fold.lua
Normal file
156
config/nvim/lua/config/fold.lua
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
--- @class Fold
|
||||
local M = {}
|
||||
|
||||
---@param bufnr number the buffer number
|
||||
---@return boolean whether the below foldexpr() is applicable to the buffer
|
||||
local function is_foldexpr(bufnr)
|
||||
local ok, parser = pcall(vim.treesitter.get_parser, bufnr)
|
||||
return ok and parser
|
||||
end
|
||||
|
||||
--- @return string Fold level (as string for foldexpr)
|
||||
function M.foldexpr()
|
||||
local line = vim.v.lnum
|
||||
local bufnr = vim.api.nvim_get_current_buf()
|
||||
local foldnestmax = vim.wo.foldnestmax
|
||||
local ok, parser = pcall(vim.treesitter.get_parser, bufnr)
|
||||
if not ok or not parser then
|
||||
return '0'
|
||||
end
|
||||
local trees = parser:parse()
|
||||
if not trees or #trees == 0 then
|
||||
return '0'
|
||||
end
|
||||
local root = trees[1]:root()
|
||||
local line_text = vim.fn.getline(line)
|
||||
local positions = {}
|
||||
local first_col = line_text:match('^%s*()')
|
||||
if first_col and first_col <= #line_text then
|
||||
table.insert(positions, first_col - 1)
|
||||
end
|
||||
local last_col = line_text:find('%S%s*$')
|
||||
if last_col then
|
||||
table.insert(positions, last_col - 1)
|
||||
end
|
||||
if #positions == 0 then
|
||||
table.insert(positions, 0)
|
||||
end
|
||||
local function is_foldable(node_type)
|
||||
return
|
||||
-- functions/methods
|
||||
node_type == 'function_definition'
|
||||
or node_type == 'function_declaration'
|
||||
or node_type == 'method_definition'
|
||||
or node_type == 'method_declaration'
|
||||
or node_type == 'function_item'
|
||||
-- structs/unions
|
||||
or node_type == 'class_definition'
|
||||
or node_type == 'class_declaration'
|
||||
or node_type == 'class_specifier'
|
||||
or node_type == 'struct_item'
|
||||
or node_type == 'struct_specifier'
|
||||
or node_type == 'struct_type'
|
||||
-- interfaces
|
||||
or node_type == 'union_specifier'
|
||||
or node_type == 'interface_declaration'
|
||||
or node_type == 'interface_definition'
|
||||
or node_type == 'interface_type'
|
||||
-- type decls/defs
|
||||
or node_type == 'type_declaration'
|
||||
or node_type == 'type_definition'
|
||||
-- traits
|
||||
or node_type == 'trait_item'
|
||||
-- enums
|
||||
or node_type == 'enum_declaration'
|
||||
or node_type == 'enum_specifier'
|
||||
-- namespace/modules
|
||||
or node_type == 'enum_item'
|
||||
or node_type == 'impl_item'
|
||||
or node_type == 'namespace_definition'
|
||||
or node_type == 'namespace_declaration'
|
||||
or node_type == 'internal_module'
|
||||
or node_type == 'mod_item'
|
||||
end
|
||||
local function should_fold(n)
|
||||
if not n then
|
||||
return false
|
||||
end
|
||||
local srow, _, erow, _ = n:range()
|
||||
return (erow - srow + 1) >= vim.wo.foldminlines
|
||||
end
|
||||
local function nested_fold_level(node)
|
||||
if not node then
|
||||
return 0
|
||||
end
|
||||
local level = 0
|
||||
local temp = node
|
||||
while temp do
|
||||
if is_foldable(temp:type()) and should_fold(temp) then
|
||||
level = level + 1
|
||||
end
|
||||
temp = temp:parent()
|
||||
end
|
||||
return level
|
||||
end
|
||||
local function starts_on_line(n)
|
||||
local srow, _, _, _ = n:range()
|
||||
return srow + 1 == line
|
||||
end
|
||||
local max_level = 0
|
||||
local is_start = false
|
||||
for _, col in ipairs(positions) do
|
||||
local node =
|
||||
root:named_descendant_for_range(line - 1, col, line - 1, col)
|
||||
if node then
|
||||
local raw_level = nested_fold_level(node)
|
||||
max_level = math.max(max_level, math.min(raw_level, foldnestmax))
|
||||
local temp = node
|
||||
while temp do
|
||||
local this_level = nested_fold_level(temp)
|
||||
if
|
||||
is_foldable(temp:type())
|
||||
and should_fold(temp)
|
||||
and starts_on_line(temp)
|
||||
and this_level <= foldnestmax
|
||||
then
|
||||
is_start = true
|
||||
end
|
||||
temp = temp:parent()
|
||||
end
|
||||
end
|
||||
end
|
||||
if max_level == 0 then
|
||||
return '0'
|
||||
end
|
||||
if is_start then
|
||||
return '>' .. max_level
|
||||
end
|
||||
return tostring(max_level)
|
||||
end
|
||||
|
||||
|
||||
function M.setup()
|
||||
vim.opt.fillchars:append({
|
||||
fold = ' ',
|
||||
foldopen = 'v',
|
||||
foldclose = '>',
|
||||
foldsep = ' ',
|
||||
})
|
||||
vim.o.foldlevel = 1
|
||||
vim.o.foldtext = ''
|
||||
vim.o.foldnestmax = 2
|
||||
vim.o.foldminlines = 5
|
||||
vim.api.nvim_create_autocmd('FileType', {
|
||||
pattern = '*',
|
||||
callback = function(opts)
|
||||
-- do not override fold settings if not applicable
|
||||
if is_foldexpr(opts.bufnr) then
|
||||
vim.wo.foldmethod = 'expr'
|
||||
vim.wo.foldexpr = 'v:lua.require("config.fold").foldexpr()'
|
||||
end
|
||||
end,
|
||||
group = vim.api.nvim_create_augroup('AFold', { clear = true }),
|
||||
})
|
||||
end
|
||||
|
||||
return M
|
||||
32
config/nvim/lua/config/fzf_reload.lua
Normal file
32
config/nvim/lua/config/fzf_reload.lua
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
local M = {}
|
||||
M.opts = nil
|
||||
|
||||
function M.setup(opts)
|
||||
M.opts = vim.deepcopy(opts)
|
||||
-- allow connections from `theme` script
|
||||
local socket_path = ('/tmp/nvim-%d.sock'):format(vim.fn.getpid())
|
||||
vim.fn.serverstart(socket_path)
|
||||
end
|
||||
|
||||
---@disable_fzf_lua_reload boolean?
|
||||
function M.reload(disable_fzf_lua_reload)
|
||||
local lines = vim.fn.readfile(vim.fn.expand('~/.config/fzf/themes/theme'))
|
||||
if not lines or #lines == 0 then
|
||||
return
|
||||
end
|
||||
local colors = {}
|
||||
for color_spec in table.concat(lines, '\n'):gmatch('--color=([^%s]+)') do
|
||||
for k, v in color_spec:gmatch('([^:,]+):([^,]+)') do
|
||||
colors[k] = v
|
||||
end
|
||||
end
|
||||
if not M.opts then
|
||||
return
|
||||
end
|
||||
M.opts.fzf_colors = colors
|
||||
if not disable_fzf_lua_reload then
|
||||
require('fzf-lua').setup(M.opts)
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
||||
7
config/nvim/lua/config/lines/init.lua
Normal file
7
config/nvim/lua/config/lines/init.lua
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
return {
|
||||
setup = function()
|
||||
vim.o.statusline = '%!v:lua.require("config.lines.statusline").statusline()'
|
||||
vim.o.statuscolumn =
|
||||
'%!v:lua.require("config.lines.statuscolumn").statuscolumn()'
|
||||
end,
|
||||
}
|
||||
25
config/nvim/lua/config/lines/statuscolumn.lua
Normal file
25
config/nvim/lua/config/lines/statuscolumn.lua
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
return {
|
||||
num = function()
|
||||
if math.abs(vim.v.virtnum) > 0 then
|
||||
return ''
|
||||
elseif vim.v.relnum == 0 then
|
||||
return '%#CursorLineNr#' .. vim.v.lnum
|
||||
end
|
||||
|
||||
return '%#LineNr#' .. vim.v.relnum
|
||||
end,
|
||||
fold = function()
|
||||
local expr = require('config.fold').foldexpr()
|
||||
if expr:sub(1, 1) == '>' then
|
||||
if vim.fn.foldclosed(vim.v.lnum) ~= -1 then
|
||||
return '>'
|
||||
else
|
||||
return 'v'
|
||||
end
|
||||
end
|
||||
return ' '
|
||||
end,
|
||||
statuscolumn = function()
|
||||
return '%{%v:lua.require("config.lines.statuscolumn").fold()%}%s%=%{%v:lua.require("config.lines.statuscolumn").num()%} '
|
||||
end,
|
||||
}
|
||||
139
config/nvim/lua/config/lines/statusline.lua
Normal file
139
config/nvim/lua/config/lines/statusline.lua
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
local empty = require('config.utils').empty
|
||||
|
||||
local M = {}
|
||||
|
||||
local mode = {
|
||||
prefix = 'mode',
|
||||
-- highlight = 'white',
|
||||
value = function()
|
||||
local mode_to_text = {
|
||||
n = 'NORMAL',
|
||||
i = 'INSERT',
|
||||
v = 'VISUAL',
|
||||
V = 'V-LINE',
|
||||
['\22'] = 'V-BLOCK',
|
||||
R = 'REPLACE',
|
||||
c = 'COMMAND',
|
||||
}
|
||||
|
||||
return mode_to_text[vim.fn.mode()]
|
||||
end,
|
||||
}
|
||||
|
||||
local file = {
|
||||
prefix = 'fp',
|
||||
-- highlight = 'blue',
|
||||
value = function()
|
||||
return vim.fn.expand('%:~')
|
||||
-- return vim.fn.pathshorten(vim.fn.expand('%:~'))
|
||||
-- return vim.fn.fnamemodify(
|
||||
-- vim.fn.bufname(vim.api.nvim_get_current_buf()),
|
||||
-- ':~:.'
|
||||
-- )
|
||||
end,
|
||||
}
|
||||
|
||||
local git = {
|
||||
prefix = 'git',
|
||||
-- highlight = 'magenta',
|
||||
value = function()
|
||||
return vim.b.gitsigns_head
|
||||
end,
|
||||
}
|
||||
|
||||
local modified = {
|
||||
value = function()
|
||||
return vim.api.nvim_get_option_value('modified', { buf = 0 }) and '+w'
|
||||
or ''
|
||||
end,
|
||||
}
|
||||
|
||||
local navic = {
|
||||
prefix = 'loc',
|
||||
value = function()
|
||||
return require('nvim-navic').get_location()
|
||||
end,
|
||||
condition = function()
|
||||
local ok, _ = pcall(require, 'nvim-navic')
|
||||
return ok
|
||||
end,
|
||||
}
|
||||
|
||||
local search = {
|
||||
prefix = '/',
|
||||
value = function()
|
||||
local count = vim.fn.searchcount({ maxcount = 999 })
|
||||
|
||||
return string.format(
|
||||
'%s (%s/%d)',
|
||||
vim.fn.getreg('/'),
|
||||
count.current,
|
||||
count.total
|
||||
)
|
||||
end,
|
||||
condition = function()
|
||||
local status, searchcount = pcall(vim.fn.searchcount)
|
||||
|
||||
if not status or not searchcount or vim.tbl_isempty(searchcount) then
|
||||
return false
|
||||
end
|
||||
|
||||
return searchcount.total > 0
|
||||
end,
|
||||
}
|
||||
|
||||
local filetype = {
|
||||
prefix = function()
|
||||
return empty(
|
||||
vim.api.nvim_get_option_value(
|
||||
'filetype',
|
||||
{ buf = vim.api.nvim_get_current_buf() }
|
||||
)
|
||||
) and 'bt' or 'ft'
|
||||
end,
|
||||
-- highlight = 'green',
|
||||
value = function()
|
||||
local ft = vim.api.nvim_get_option_value(
|
||||
'filetype',
|
||||
{ buf = vim.api.nvim_get_current_buf() }
|
||||
)
|
||||
|
||||
if empty(ft) then
|
||||
ft = vim.bo.buftype
|
||||
end
|
||||
|
||||
return ft
|
||||
end,
|
||||
}
|
||||
|
||||
local lineinfo = {
|
||||
prefix = 'lnnr',
|
||||
-- highlight = 'yellow',
|
||||
value = '%c:%l/%L',
|
||||
}
|
||||
|
||||
M.components = {
|
||||
left = {
|
||||
[1] = mode,
|
||||
[2] = git,
|
||||
[3] = file,
|
||||
[4] = navic,
|
||||
[5] = modified,
|
||||
},
|
||||
right = {
|
||||
[1] = search,
|
||||
[2] = lineinfo,
|
||||
[3] = filetype,
|
||||
},
|
||||
}
|
||||
|
||||
local format_components = require('config.lines.utils').format_components
|
||||
|
||||
M.statusline = function()
|
||||
return ('%s%%=%s'):format(
|
||||
format_components(M.components.left),
|
||||
format_components(M.components.right)
|
||||
)
|
||||
end
|
||||
|
||||
return M
|
||||
41
config/nvim/lua/config/lines/utils.lua
Normal file
41
config/nvim/lua/config/lines/utils.lua
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
local utils = require('config.utils')
|
||||
|
||||
local M = {}
|
||||
|
||||
local function vorfn(val_or_fn)
|
||||
if type(val_or_fn) == 'function' then
|
||||
return val_or_fn()
|
||||
end
|
||||
|
||||
return val_or_fn
|
||||
end
|
||||
|
||||
function M.format_components(components)
|
||||
local side = {}
|
||||
|
||||
for i = 1, #components do
|
||||
local component = components[i]
|
||||
|
||||
local highlight = vim.env.THEME == 'midnight' and 'Normal'
|
||||
or component.highlight
|
||||
|
||||
if
|
||||
vorfn(component.condition) ~= false
|
||||
and not utils.empty(vorfn(component.value))
|
||||
then
|
||||
side[#side + 1] = ('%%#%s#%s%%#%s#'):format(
|
||||
highlight,
|
||||
vorfn(component.value),
|
||||
component.highlight or 'Normal'
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
if #side > 0 then
|
||||
return (' %s '):format(table.concat(side, ' │ '))
|
||||
end
|
||||
|
||||
return ''
|
||||
end
|
||||
|
||||
return M
|
||||
97
config/nvim/lua/config/lsp.lua
Normal file
97
config/nvim/lua/config/lsp.lua
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
local M = {}
|
||||
|
||||
local Methods = vim.lsp.protocol.Methods
|
||||
|
||||
function M.on_attach(client, bufnr)
|
||||
if client:supports_method(Methods.textDocument_hover) then
|
||||
bmap({ 'n', 'K', vim.lsp.buf.hover })
|
||||
end
|
||||
|
||||
if client:supports_method(Methods.textDocument_documentSymbol) then
|
||||
local ok, navic = pcall(require, 'nvim-navic')
|
||||
if ok then
|
||||
navic.attach(client, bufnr)
|
||||
end
|
||||
end
|
||||
|
||||
local ok, _ = pcall(require, 'fzf-lua')
|
||||
|
||||
local mappings = {
|
||||
{
|
||||
Methods.textDocument_codeAction,
|
||||
'gra',
|
||||
ok and '<cmd>FzfLua lsp_code_actions<CR>'
|
||||
or vim.lsp.buf.code_action,
|
||||
},
|
||||
{
|
||||
Methods.textDocument_declaration,
|
||||
'gD',
|
||||
ok and '<cmd>FzfLua lsp_declarations<CR>'
|
||||
or vim.lsp.buf.declaration,
|
||||
},
|
||||
{
|
||||
Methods.textDocument_definition,
|
||||
'gd',
|
||||
ok and '<cmd>FzfLua lsp_definitions<CR>' or vim.lsp.buf.definition,
|
||||
},
|
||||
{
|
||||
Methods.textDocument_implementation,
|
||||
'gri',
|
||||
ok and '<cmd>FzfLua lsp_implementations<CR>'
|
||||
or vim.lsp.buf.implementation,
|
||||
},
|
||||
{
|
||||
Methods.textDocument_references,
|
||||
'grr',
|
||||
ok and '<cmd>FzfLua lsp_references<CR>' or vim.lsp.buf.references,
|
||||
},
|
||||
{
|
||||
Methods.textDocument_typeDefinition,
|
||||
'grt',
|
||||
ok and '<cmd>FzfLua lsp_typedefs<CR>'
|
||||
or vim.lsp.buf.type_definition,
|
||||
},
|
||||
{
|
||||
Methods.textDocument_documentSymbol,
|
||||
'gs',
|
||||
ok and '<cmd>FzfLua lsp_document_symbols<CR>'
|
||||
or vim.lsp.buf.document_symbol,
|
||||
},
|
||||
{
|
||||
Methods.workspace_diagnostic,
|
||||
'gw',
|
||||
ok and '<cmd>FzfLua lsp_workspace_diagnostics<CR>'
|
||||
or vim.diagnostic.setqflist,
|
||||
},
|
||||
{
|
||||
Methods.workspace_symbol,
|
||||
'gS',
|
||||
ok and '<cmd>FzfLua lsp_workspace_symbols<CR>'
|
||||
or vim.lsp.buf.workspace_symbol,
|
||||
},
|
||||
}
|
||||
|
||||
for _, m in ipairs(mappings) do
|
||||
local method, key, cmd = unpack(m)
|
||||
if client:supports_method(method) then
|
||||
bmap({ 'n', key, cmd })
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local FORMAT_LSPS = { 'null-ls', 'clangd', 'tinymist', 'ruff' }
|
||||
|
||||
function M.format(opts)
|
||||
local format_opts = vim.tbl_extend('force', opts or {}, {
|
||||
filter = function(c)
|
||||
if c.name == 'typescript-tools' then
|
||||
vim.cmd.TSToolsOrganizeImports()
|
||||
end
|
||||
return vim.tbl_contains(FORMAT_LSPS, c.name)
|
||||
end,
|
||||
})
|
||||
vim.lsp.buf.format(format_opts)
|
||||
vim.cmd.w()
|
||||
end
|
||||
|
||||
return M
|
||||
15
config/nvim/lua/config/projects.lua
Normal file
15
config/nvim/lua/config/projects.lua
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
local project_configs = {
|
||||
cavauto = {
|
||||
lsp = {
|
||||
clangd = {
|
||||
cmd = { 'socat', '-', 'TCP:localhost:12345' },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
local function project_name()
|
||||
return vim.fn.fnamemodify(vim.fn.getcwd(), ':t')
|
||||
end
|
||||
|
||||
return project_configs[project_name()] or {}
|
||||
101
config/nvim/lua/config/tmux.lua
Normal file
101
config/nvim/lua/config/tmux.lua
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
local M = {}
|
||||
|
||||
local projects = {
|
||||
{
|
||||
name = 'bmath',
|
||||
paths = { vim.env.HOME .. '/dev/bmath' },
|
||||
cmd = 'cmake -B build -DCMAKE_BUILD_TYPE=Debug && cmake --build build && ctest --test-dir build --output-on-failure',
|
||||
},
|
||||
{
|
||||
name = 'neovim',
|
||||
paths = { vim.env.HOME .. '/dev/neovim' },
|
||||
cmd = 'make',
|
||||
},
|
||||
{
|
||||
name = 'barrettruth.com',
|
||||
paths = { vim.env.HOME .. '/dev/barrettruth.com' },
|
||||
cmd = 'pnpm dev',
|
||||
},
|
||||
{
|
||||
name = 'philipmruth.com',
|
||||
paths = { vim.env.HOME .. '/dev/philipmruth.com' },
|
||||
cmd = 'pnpm dev',
|
||||
},
|
||||
}
|
||||
|
||||
---@type overseer.Task|nil
|
||||
local current_task = nil
|
||||
|
||||
local actions = {
|
||||
nvim = function()
|
||||
local ok, oil = pcall(require, 'oil')
|
||||
|
||||
if not ok then
|
||||
return
|
||||
end
|
||||
|
||||
oil.open()
|
||||
end,
|
||||
git = function()
|
||||
vim.cmd.Git()
|
||||
vim.cmd.only()
|
||||
end,
|
||||
run = function()
|
||||
local ok, overseer = pcall(require, 'overseer')
|
||||
|
||||
if not ok then
|
||||
return
|
||||
end
|
||||
|
||||
local cwd = vim.fn.getcwd()
|
||||
local match = nil
|
||||
for _, p in ipairs(projects) do
|
||||
if vim.tbl_contains(p.paths, cwd) then
|
||||
match = p
|
||||
break
|
||||
end
|
||||
end
|
||||
if not match then
|
||||
vim.notify_once(
|
||||
'No task defined for this project',
|
||||
vim.log.levels.WARN
|
||||
)
|
||||
vim.cmd('q!')
|
||||
return
|
||||
end
|
||||
if
|
||||
current_task
|
||||
and (current_task.cwd ~= cwd or current_task.name ~= match.name)
|
||||
then
|
||||
if current_task:is_running() then
|
||||
current_task:stop()
|
||||
end
|
||||
current_task:dispose(true)
|
||||
current_task = nil
|
||||
end
|
||||
if not current_task or not current_task:is_running() then
|
||||
current_task = overseer.new_task({
|
||||
name = match.name,
|
||||
cmd = match.cmd,
|
||||
cwd = cwd,
|
||||
env = match.env,
|
||||
})
|
||||
current_task:start()
|
||||
end
|
||||
current_task:open_output()
|
||||
end,
|
||||
}
|
||||
|
||||
function M.run(subcmd)
|
||||
if not subcmd then
|
||||
error('No subcommand provided')
|
||||
end
|
||||
|
||||
if not vim.tbl_contains(vim.tbl_keys(actions), subcmd) then
|
||||
error('Invalid subcommand: ' .. subcmd)
|
||||
end
|
||||
|
||||
actions[subcmd]()
|
||||
end
|
||||
|
||||
return M
|
||||
7
config/nvim/lua/config/utils.lua
Normal file
7
config/nvim/lua/config/utils.lua
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
local M = {}
|
||||
|
||||
function M.empty(s)
|
||||
return s == '' or s == nil
|
||||
end
|
||||
|
||||
return M
|
||||
Loading…
Add table
Add a link
Reference in a new issue