initial commit

This commit is contained in:
Barrett Ruth 2026-02-07 00:45:47 -05:00
commit 23d4795228
99 changed files with 6691 additions and 0 deletions

View 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

View 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

View 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,
}

View 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,
}

View 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

View 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

View 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

View 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 {}

View 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

View file

@ -0,0 +1,7 @@
local M = {}
function M.empty(s)
return s == '' or s == nil
end
return M

View file

@ -0,0 +1,9 @@
return {
on_attach = function(_, bufnr)
require('config.lsp').on_attach(_, bufnr)
local bufname = vim.api.nvim_buf_get_name(bufnr)
if string.match(bufname, '%.env') then
vim.diagnostic.enable(false, { bufnr = bufnr })
end
end,
}

View file

@ -0,0 +1,39 @@
local config = require('config.projects')
local clangd_settings = {
filetypes = { 'c', 'cpp', 'objc', 'objcpp', 'cuda' },
cmd = {
'clangd',
'--clang-tidy',
'-j=4',
'--background-index',
'--completion-style=bundled',
'--header-insertion=iwyu',
'--header-insertion-decorators=false',
},
capabilities = {
textDocument = {
completion = {
editsNearCursor = true,
},
},
},
}
local project_settings = (config.lsp and config.lsp.clangd)
and config.lsp.clangd
vim.api.nvim_create_autocmd('LspAttach', {
callback = function(args)
local client = vim.lsp.get_client_by_id(args.data.client_id)
if client and client.name == 'clangd' then
bmap(
{ 'n', 'gh', vim.cmd.ClangdSwitchSourceHeader },
{ buffer = args.buf }
)
end
end,
group = vim.api.nvim_creat_augroup('AClangdKeymap', { clear = true }),
})
return vim.tbl_extend('force', clangd_settings, project_settings or {})

View file

@ -0,0 +1,18 @@
return {
cmd = { 'vscode-css-language-server', '--stdio' },
filetypes = { 'css', 'scss', 'less' },
settings = {
css = {
lint = {
unknownAtRules = 'ignore',
},
},
},
capabilities = {
textDocument = {
completion = {
completionItem = { snippetSupport = true },
},
},
},
}

View file

@ -0,0 +1,30 @@
return {
cmd = { 'emmet-language-server', '--stdio' },
filetypes = {
'astro',
'css',
'eruby',
'html',
'htmlangular',
'htmldjango',
'javascriptreact',
'less',
'pug',
'sass',
'scss',
'svelte',
'templ',
'typescriptreact',
'vue',
},
init_options = {
showSuggestionsAsSnippets = true,
},
capabilities = {
textDocument = {
completion = {
completionItem = { snippetSupport = true },
},
},
},
}

View file

@ -0,0 +1,5 @@
return {
settings = {
format = false,
},
}

View file

@ -0,0 +1,9 @@
return {
capabilities = {
textDocument = {
completion = {
completionItem = { snippetSupport = true },
},
},
},
}

View file

@ -0,0 +1,15 @@
return {
capabilities = {
textDocument = {
completion = {
completionItem = { snippetSupport = true },
},
},
},
settings = {
json = {
schemas = require('schemastore').json.schemas(),
validate = { enable = true },
},
},
}

View file

@ -0,0 +1,19 @@
return {
settings = {
Lua = {
codeLens = { enable = true },
completion = { keywordSnippet = 'Disable' },
diagnostics = { globals = { 'vim' } },
hint = {
enable = true,
arrayIndex = 'Disable',
semicolon = 'Disable',
},
runtime = { version = 'LuaJIT' },
telemetry = { enable = false },
workspace = {
checkThirdParty = false,
},
},
},
}

View file

@ -0,0 +1,5 @@
return {
cmd = { 'mdx-language-server', '--stdio' },
filetypes = { 'mdx' },
root_markers = { 'package.json' },
}

View file

@ -0,0 +1,11 @@
return {
cmd = { 'pytest-language-server' },
filetypes = { 'python' },
root_markers = {
'pyproject.toml',
'setup.py',
'setup.cfg',
'pytest.ini',
'.git',
},
}

View file

@ -0,0 +1,28 @@
return {
standalone = false,
capabilities = { general = { positionEncodings = { 'utf-16' } } },
settings = {
['rust-analyzer'] = {
checkOnSave = {
overrideCommand = {
'cargo',
'clippy',
'--message-format=json',
'--',
'-W',
'clippy::expect_used',
'-W',
'clippy::pedantic',
'-W',
'clippy::unwrap_used',
},
},
},
},
on_attach = function(...)
require('config.lsp').on_attach(...)
bmap({ 'n', '\\Rc', '<cmd>RustLsp codeAction<cr>' })
bmap({ 'n', '\\Rm', '<cmd>RustLsp expandMacro<cr>' })
bmap({ 'n', '\\Ro', '<cmd>RustLsp openCargo<cr>' })
end,
}

View file

@ -0,0 +1,14 @@
return {
filetypes = {
'javascript',
'javascriptreact',
'typescript',
'typescriptreact',
},
root_markers = {
'tailwind.config.js',
'tailwind.config.ts',
'postcss.config.js',
'postcss.config.ts',
},
}

View file

@ -0,0 +1,12 @@
return {
filetypes = { 'typst' },
settings = {
formatterMode = 'typstyle',
semanticTokens = 'disable',
lint = {
enabled = true,
when = 'onType',
-- when = 'onSave'
},
},
}

View file

@ -0,0 +1,169 @@
local default_cpp_lang = {
extension = 'cc',
commands = {
build = {
'g++',
'-std=c++23',
'-O2',
'-Wall',
'-Wextra',
'-Wpedantic',
'-Wshadow',
'-Wconversion',
'-Wformat=2',
'-Wfloat-equal',
'-Wundef',
'-fdiagnostics-color=always',
'-DLOCAL',
'{source}',
'-o',
'{binary}',
},
run = { '{binary}' },
debug = {
'g++',
'-std=c++23',
'-g3',
'-fsanitize=address,undefined',
'-fno-omit-frame-pointer',
'-fstack-protector-all',
'-D_GLIBCXX_DEBUG',
'-DLOCAL',
'{source}',
'-o',
'{binary}',
},
},
}
local default_python_lang = {
extension = 'py',
commands = {
run = { 'python', '{source}' },
debug = { 'python', '{source}' },
},
}
local clang_format_content = [[BasedOnStyle: LLVM
IndentWidth: 2
UseTab: Never
AllowShortIfStatementsOnASingleLine: Never
AllowShortLoopsOnASingleLine: false
AllowShortFunctionsOnASingleLine: None
AllowShortLambdasOnASingleLine: None
AllowShortBlocksOnASingleLine: Never
AllowShortEnumsOnASingleLine: false
AllowShortCaseExpressionOnASingleLine: false
BreakBeforeBraces: Attach
ColumnLimit: 100
AlignAfterOpenBracket: Align
BinPackArguments: false
BinPackParameters: false]]
return {
'barrettruth/cp.nvim',
dir = '~/dev/cp.nvim',
cmd = 'CP',
keys = {
{ '<leader>ce', '<cmd>CP edit<cr>' },
{ '<leader>cp', '<cmd>CP panel<cr>' },
{ '<leader>cP', '<cmd>CP pick<cr>' },
{ '<leader>cr', '<cmd>CP run<cr>' },
{ '<leader>cd', '<cmd>CP run --debug<cr>' },
{ '<leader>cc', '<cmd>CP cache read<cr>' },
{ ']c', '<cmd>CP next<cr>' },
{ '[c', '<cmd>CP prev<cr>' },
},
dependencies = {
'L3MON4D3/LuaSnip',
'nvim-telescope/telescope.nvim',
},
config = function()
require('cp').setup({
languages = {
cpp = default_cpp_lang,
python = default_python_lang,
},
platforms = {
codeforces = {
enabled_languages = { 'cpp', 'python' },
default_language = 'cpp',
},
atcoder = {
enabled_languages = { 'cpp', 'python' },
default_language = 'cpp',
},
cses = {},
},
ui = { picker = 'fzf-lua' },
hooks = {
setup_io_input = function(buf)
require('cp.helpers').clearcol(buf)
end,
setup_io_output = function(buf)
require('cp.helpers').clearcol(buf)
end,
before_run = function(_)
require('config.lsp').format({ async = true })
end,
before_debug = function(_)
require('config.lsp').format({ async = true })
end,
setup_code = function(state)
vim.opt_local.winbar = ''
vim.opt_local.foldlevel = 0
vim.opt_local.foldmethod = 'marker'
vim.opt_local.foldmarker = '{{{,}}}'
vim.opt_local.foldtext = ''
vim.diagnostic.enable(false)
local buf = vim.api.nvim_get_current_buf()
local lines = vim.api.nvim_buf_get_lines(buf, 0, 1, true)
if #lines > 1 or (#lines == 1 and lines[1] ~= '') then
local pos = vim.api.nvim_win_get_cursor(0)
vim.cmd('normal! zx')
vim.api.nvim_win_set_cursor(0, pos)
return
end
local trigger = state.get_platform() or ''
vim.api.nvim_buf_set_lines(buf, 0, -1, false, { trigger })
vim.api.nvim_win_set_cursor(0, { 1, #trigger })
vim.cmd.startinsert({ bang = true })
vim.schedule(function()
local ls = require('luasnip')
if ls.expandable() then
vim.api.nvim_create_autocmd('TextChanged', {
buffer = buf,
once = true,
callback = function()
vim.schedule(function()
local pos =
vim.api.nvim_win_get_cursor(0)
vim.cmd('normal! zx')
vim.api.nvim_win_set_cursor(0, pos)
end)
end,
})
ls.expand()
end
vim.cmd.stopinsert()
end)
local clang_format_path = vim.fn.getcwd()
.. '/.clang-format'
if vim.fn.filereadable(clang_format_path) == 0 then
vim.fn.writefile(
vim.split(clang_format_content, '\n'),
clang_format_path
)
end
end,
},
filename = function(_, _, problem_id)
return problem_id
end,
})
end,
}

View file

@ -0,0 +1,149 @@
return {
'ibhagwan/fzf-lua',
config = function(_, opts)
require('fzf-lua').setup(opts)
vim.api.nvim_create_autocmd('FileType', {
pattern = 'fzf',
callback = function()
vim.opt_local.number = false
vim.opt_local.relativenumber = false
end,
group = vim.api.nvim_create_augroup(
'AFzfHighlights',
{ clear = true }
),
})
local ok, fzf_reload = pcall(require, 'config.fzf_reload')
if ok then
fzf_reload.setup(opts)
fzf_reload.reload(true)
end
end,
keys = {
{
'<c-t>',
function()
local fzf = require('fzf-lua')
local git_dir = vim.fn
.system('git rev-parse --git-dir 2>/dev/null')
:gsub('\n', '')
if vim.v.shell_error == 0 and git_dir ~= '' then
fzf.git_files({ cwd_prompt = false })
else
fzf.files()
end
end,
},
{ '<c-l>', '<cmd>FzfLua live_grep<cr>' },
{ '<leader>f/', '<cmd>FzfLua search_history<cr>' },
{ '<leader>f:', '<cmd>FzfLua command_history<cr>' },
{ '<leader>fa', '<cmd>FzfLua autocmds<cr>' },
{ '<leader>fB', '<cmd>FzfLua builtin<cr>' },
{ '<leader>fb', '<cmd>FzfLua buffers<cr>' },
{ '<leader>fc', '<cmd>FzfLua commands<cr>' },
{
'<leader>fe',
'<cmd>FzfLua files cwd=~/.config<cr>',
},
{
'<leader>ff',
function()
require('fzf-lua').files({ cwd = vim.fn.expand('%:h') })
end,
},
{
'<leader>fg',
function()
require('fzf-lua').live_grep({ cwd = vim.fn.expand('%:h') })
end,
},
{ '<leader>fH', '<cmd>FzfLua highlights<cr>' },
{ '<leader>fh', '<cmd>FzfLua help_tags<cr>' },
{ '<leader>fl', '<cmd>FzfLua loclist<cr>' },
{ '<leader>fm', '<cmd>FzfLua man_pages<cr>' },
{ '<leader>fq', '<cmd>FzfLua quickfix<cr>' },
{ '<leader>fr', '<cmd>FzfLua resume<cr>' },
{
'<leader>fs',
'<cmd>FzfLua files cwd=~/.local/bin/scripts<cr>',
},
{ '<leader>GB', '<cmd>FzfLua git_branches<cr>' },
{ '<leader>Gb', '<cmd>FzfLua git_worktrees<cr>' },
{ 'gq', '<cmd>FzfLua quickfix<cr>' },
{ 'gl', '<cmd>FzfLua loclist<cr>' },
},
opts = {
files = {
cmd = vim.env.FZF_CTRL_T_COMMAND,
file_icons = false,
no_header_i = true,
},
fzf_args = (vim.env.FZF_DEFAULT_OPTS or ''):gsub(
'%-%-color=[^%s]+',
''
),
grep = {
file_icons = false,
no_header_i = true,
RIPGREP_CONFIG_PATH = vim.env.RIPGREP_CONFIG_PATH,
},
lsp = {
includeDeclaration = false,
jump1 = true,
symbols = {
symbol_hl_prefix = '@',
symbol_style = 3,
},
},
winopts = {
border = 'single',
preview = {
hidden = 'hidden',
},
},
actions = {
files = {
default = function(...)
require('fzf-lua.actions').file_edit(...)
end,
['ctrl-l'] = function(...)
local a = require('fzf-lua.actions')
a.file_sel_to_ll(...)
vim.cmd.lclose()
end,
['ctrl-q'] = function(...)
local a = require('fzf-lua.actions')
a.file_sel_to_qf(...)
vim.cmd.cclose()
end,
['ctrl-h'] = function(...)
require('fzf-lua.actions').toggle_hidden(...)
end,
['ctrl-v'] = function(...)
require('fzf-lua.actions').file_vsplit(...)
end,
['ctrl-x'] = function(...)
require('fzf-lua.actions').file_split(...)
end,
},
},
border = 'single',
git = {
files = {
cmd = 'git ls-files --cached --others --exclude-standard',
},
worktrees = {
fzf_args = ((vim.env.FZF_DEFAULT_OPTS or '')
:gsub('%-%-bind=ctrl%-a:select%-all', '')
:gsub('--color=[^%s]+', '')),
},
branches = {
fzf_args = ((vim.env.FZF_DEFAULT_OPTS or '')
:gsub('%-%-bind=ctrl%-a:select%-all', '')
:gsub('--color=[^%s]+', '')),
},
},
},
}

View file

@ -0,0 +1,57 @@
---@type number|nil
local git_tab = nil
---@type string|nil
local prev = nil
return {
{
'tpope/vim-fugitive',
cmd = 'Git',
},
{
'folke/snacks.nvim',
---@type snacks.Config
opts = { gitbrowse = {} },
keys = {
{ '<leader>Go', '<cmd>lua Snacks.gitbrowse()<cr>' },
{ '<leader>Gi', '<cmd>lua Snacks.picker.gh_issue()<cr>' },
{ '<leader>Gp', '<cmd>lua Snacks.picker.gh_pr()<cr>' },
},
},
{
'lewis6991/gitsigns.nvim',
keys = {
{ '[g', '<cmd>Gitsigns next_hunk<cr>' },
{ ']g', '<cmd>Gitsigns prev_hunk<cr>' },
{ '<leader>Gb', '<cmd>Gitsigns toggle_current_line_blame<cr>' },
{
'<leader>Gs',
function()
if vim.opt.signcolumn:get() == 'no' then
prev = vim.opt.signcolumn:get()
vim.opt.signcolumn = 'yes'
else
vim.opt.signcolumn = prev
end
vim.cmd.Gitsigns('toggle_signs')
end,
},
},
event = 'VeryLazy',
opts = {
current_line_blame_formatter_nc = function()
return {}
end,
signs = {
-- use boxdraw chars
add = { text = '' },
change = { text = '' },
delete = { text = '_' },
topdelete = { text = '' },
changedelete = { text = '' },
},
signcolumn = false,
},
},
}

View file

@ -0,0 +1,374 @@
return {
'neovim/nvim-lspconfig',
{
'folke/lazydev.nvim',
ft = 'lua',
opts = {
library = {
{ path = '${3rd}/luv/library' },
},
},
},
{
'saghen/blink.cmp',
build = 'cargo build --release',
dependencies = 'folke/lazydev.nvim',
---@module 'blink.cmp'
---@type blink.cmp.Config
event = { 'InsertEnter', 'CmdlineEnter' },
config = function(_, opts)
vim.o.pumheight = 15
opts.completion.menu.max_height = vim.o.pumheight
require('blink.cmp').setup(opts)
end,
opts = {
keymap = {
['<c-p>'] = { 'select_prev' },
['<c-n>'] = { 'show', 'select_next' },
['<c-space>'] = {},
['<c-y>'] = {
function(cmp)
return cmp.snippet_active() and cmp.accept()
or cmp.select_and_accept()
end,
'snippet_forward',
},
},
completion = {
menu = {
auto_show = false,
scrollbar = false,
draw = {
columns = function(ctx)
if ctx.mode == 'cmdline' then
return {
{ 'label', 'label_description', gap = 1 },
}
else
return {
{ 'label', 'label_description' },
{ 'kind' },
}
end
end,
},
},
},
cmdline = {
completion = {
menu = {
auto_show = true,
},
},
keymap = {
['<left>'] = false,
['<right>'] = false,
},
},
sources = {
default = { 'lsp', 'path', 'snippets', 'buffer' },
providers = {
lazydev = {
name = 'LazyDev',
module = 'lazydev.integrations.blink',
score_offset = 100,
},
},
},
},
keys = { { '<c-n>', mode = 'i' } },
opts_extend = { 'sources.default' },
},
{
'nvimtools/none-ls.nvim',
config = function()
local null_ls = require('null-ls')
local builtins = null_ls.builtins
local code_actions, diagnostics, formatting, hover =
builtins.code_actions,
builtins.diagnostics,
builtins.formatting,
builtins.hover
null_ls.setup({
border = 'single',
sources = {
require('none-ls.code_actions.eslint_d'),
code_actions.gitrebase,
diagnostics.buf,
diagnostics.checkmake,
require('none-ls.diagnostics.cpplint').with({
extra_args = {
'--filter',
'-legal/copyright',
'-whitespace/indent',
},
prepend_extra_args = true,
}),
require('none-ls.diagnostics.eslint_d'),
diagnostics.hadolint,
diagnostics.mypy.with({
extra_args = { '--check-untyped-defs' },
runtime_condition = function(params)
return vim.fn.executable('mypy') == 1
and require('null-ls.utils').path.exists(
params.bufname
)
end,
}),
diagnostics.selene,
diagnostics.vacuum,
diagnostics.zsh,
formatting.black,
formatting.isort.with({
extra_args = { '--profile', 'black' },
}),
formatting.buf,
formatting.cbfmt,
formatting.cmake_format,
require('none-ls.formatting.latexindent'),
formatting.prettierd.with({
env = {
XDG_RUNTIME_DIR = vim.env.XDG_RUNTIME_DIR
or (
(
vim.env.XDG_DATA_HOME
or (vim.env.HOME .. '/.local/share')
)
.. '/prettierd'
),
},
extra_args = function(params)
if params.ft == 'jsonc' then
return { '--trailing-comma', 'none' }
end
return {}
end,
filetypes = {
'css',
'graphql',
'html',
'javascript',
'javascriptreact',
'json',
'jsonc',
'markdown',
'mdx',
'typescript',
'typescriptreact',
'yaml',
},
}),
formatting.shfmt.with({
extra_args = { '-i', '2' },
}),
formatting.stylua.with({
condition = function(utils)
return utils.root_has_file({
'stylua.toml',
'.stylua.toml',
})
end,
}),
hover.dictionary,
hover.printenv,
},
on_attach = require('config.lsp').on_attach,
debounce = 0,
})
end,
dependencies = 'nvimtools/none-ls-extras.nvim',
},
{
'b0o/SchemaStore.nvim',
},
{
'saecki/live-rename.nvim',
event = 'LspAttach',
config = function(_, opts)
local live_rename = require('live-rename')
live_rename.setup(opts)
vim.api.nvim_create_autocmd('LspAttach', {
callback = function(o)
local clients = vim.lsp.get_clients({ buffer = o.buf })
for _, client in ipairs(clients) do
if client:supports_method('textDocument/rename') then
bmap(
{ 'n', 'grn', live_rename.rename },
{ buffer = o.buf }
)
end
end
end,
group = vim.api.nvim_create_augroup(
'ALiveRename',
{ clear = true }
),
})
end,
keys = { 'grn' },
},
{
'yioneko/nvim-vtsls',
config = function(_, opts)
require('vtsls').config(opts)
end,
dependencies = {
{
'davidosomething/format-ts-errors.nvim',
ft = {
'javascript',
'javascriptreact',
'typescript',
'typescriptreact',
},
},
},
ft = {
'javascript',
'javascriptreact',
'typescript',
'typescriptreact',
},
opts = {
on_attach = function(_, bufnr)
bmap(
{ 'n', 'gD', vim.cmd.VtsExec('goto_source_definition') },
{ buffer = bufnr }
)
end,
settings = {
typescript = {
inlayHints = {
parameterNames = { enabled = 'literals' },
parameterTypes = { enabled = true },
variableTypes = { enabled = true },
propertyDeclarationTypes = { enabled = true },
functionLikeReturnTypes = { enabled = true },
enumMemberValues = { enabled = true },
},
},
},
handlers = {
['textDocument/publishDiagnostics'] = function(_, result, ctx)
if not result.diagnostics then
return
end
local idx = 1
while idx <= #result.diagnostics do
local entry = result.diagnostics[idx]
local formatter =
require('format-ts-errors')[entry.code]
entry.message = formatter and formatter(entry.message)
or entry.message
if vim.tbl_contains({ 80001, 80006 }, entry.code) then
table.remove(result.diagnostics, idx)
else
idx = idx + 1
end
end
vim.lsp.diagnostic.on_publish_diagnostics(_, result, ctx)
end,
},
},
},
{
'pmizio/typescript-tools.nvim',
opts = {
on_attach = function(_, bufnr)
bmap(
{ 'n', 'gD', vim.cmd.TSToolsGoToSourceDefinition },
{ buffer = bufnr }
)
end,
handlers = {
['textDocument/publishDiagnostics'] = function(_, result, ctx)
if not result.diagnostics then
return
end
local idx = 1
while idx <= #result.diagnostics do
local entry = result.diagnostics[idx]
local formatter =
require('format-ts-errors')[entry.code]
entry.message = formatter and formatter(entry.message)
or entry.message
if vim.tbl_contains({ 80001, 80006 }, entry.code) then
table.remove(result.diagnostics, idx)
else
idx = idx + 1
end
end
vim.lsp.diagnostic.on_publish_diagnostics(_, result, ctx)
end,
},
settings = {
expose_as_code_action = 'all',
-- tsserver_path = vim.env.XDG_DATA_HOME .. '/pnpm/tsserver',
tsserver_file_preferences = {
includeInlayarameterNameHints = 'all',
includeInlayarameterNameHintsWhenArgumentMatchesName = false,
includeInlayFunctionParameterTypeHints = true,
includeInlayVariableTypeHints = true,
includeInlayVariableTypeHintsWhenTypeMatchesName = false,
includeInlayPropertyDeclarationTypeHints = true,
includeInlayFunctionLikeReturnTypeHints = true,
includeInlayEnumMemberValueHints = true,
},
},
},
dependencies = {
'nvim-lua/plenary.nvim',
},
ft = {
'javascript',
'javascriptreact',
'typescript',
'typescriptreact',
},
},
{
'mrcjkb/rustaceanvim',
ft = { 'rust' },
},
{
'SmiteshP/nvim-navic',
opts = {
depth_limit = 3,
depth_limit_indicator = '',
icons = {
enabled = false,
},
},
event = 'LspAttach',
},
{
'chomosuke/typst-preview.nvim',
ft = 'typst',
version = '1.*',
opts = {
open_cmd = ('%s %%s --new-window'):format(vim.env.BROWSER),
invert_colors = 'auto',
dependencies_bin = {
tinymist = vim.fn.exepath('tinymist'),
websocat = vim.fn.exepath('websocat'),
},
},
keys = { { '<leader>t', '<cmd>TypstPreviewToggle<cr>' } },
},
}

View file

@ -0,0 +1,430 @@
return {
{
'barrettruth/live-server.nvim',
build = 'pnpm add -g live-server',
cmd = { 'LiveServerStart', 'LiveServerStart' },
config = true,
keys = { { '<leader>L', '<cmd>LiveServerToggle<cr>' } },
},
{
'echasnovski/mini.pairs',
config = true,
event = 'InsertEnter',
},
{
'iamcco/markdown-preview.nvim',
build = 'pnpm up && cd app && pnpm install',
ft = { 'markdown' },
config = function()
vim.cmd([[
function OpenMarkdownPreview(url)
exec "silent !$BROWSER -n --args " . a:url
endfunction
]])
vim.g.mkdp_auto_close = 0
vim.g.mkdp_browserfunc = 'OpenMarkdownPreview'
vim.api.nvim_create_autocmd('FileType', {
pattern = 'markdown',
callback = function(opts)
bmap(
{ 'n', '<leader>m', vim.cmd.MarkdownPreviewToggle },
{ buffer = opts.buf }
)
end,
group = vim.api.nvim_create_augroup(
'AMarkdownKeybind',
{ clear = true }
),
})
end,
},
{
'lervag/vimtex',
init = function()
vim.g.vimtex_view_method = 'general'
vim.g.vimtex_compiler_method = 'latexmk'
vim.g.vimtex_callback_progpath = '/usr/bin/nvim'
vim.g.vimtex_quickfix_mode = 0
end,
ft = { 'plaintext', 'tex' },
},
{
'L3MON4D3/LuaSnip',
build = 'make install_jsregexp',
config = function()
local ls = require('luasnip')
ls.filetype_extend('htmldjango', { 'html' })
ls.filetype_extend('markdown', { 'html' })
ls.filetype_extend('javascriptreact', { 'javascript', 'html' })
ls.filetype_extend('typescript', { 'javascript' })
ls.filetype_extend(
'typescriptreact',
{ 'javascriptreact', 'javascript', 'html' }
)
require('luasnip.loaders.from_lua').lazy_load()
end,
keys = {
-- restore digraph mapping
{ '<c-d>', '<c-k>', mode = 'i' },
{
'<c-space>',
'<cmd>lua require("luasnip").expand()<cr>',
mode = 'i',
},
{
'<c-h>',
'<cmd>lua if require("luasnip").jumpable(-1) then require("luasnip").jump(-1) end<cr>',
mode = { 'i', 's' },
},
{
'<c-l>',
'<cmd>lua if require("luasnip").jumpable(1) then require("luasnip").jump(1) end<cr>',
mode = { 'i', 's' },
},
{
'<c-j>',
'<cmd>lua if require("luasnip").choice_active() then require("luasnip").change_choice(-1) end<cr>',
mode = 'i',
},
{
'<c-k>',
'<cmd>lua if require("luasnip").choice_active() then require("luasnip").change_choice(1) end<cr>',
mode = 'i',
},
},
opts = {
region_check_events = 'InsertEnter',
delete_check_events = {
'TextChanged',
'TextChangedI',
'InsertLeave',
},
ext_opts = {
[require('luasnip.util.types').choiceNode] = {
active = {
virt_text = {
{
' <- ',
vim.wo.cursorline and 'CursorLine' or 'Normal',
},
},
},
},
},
},
},
{
'laytan/cloak.nvim',
config = true,
keys = { { '<leader>Ct', '<cmd>CloakToggle<cr>' } },
event = 'BufReadPre .env*',
},
{
'maxmellon/vim-jsx-pretty',
ft = {
'javascript',
'javascriptreact',
'typescript',
'typescriptreact',
},
},
{
'monaqa/dial.nvim',
config = function(_)
local augend = require('dial.augend')
require('dial.config').augends:register_group({
default = {
augend.integer.alias.decimal_int,
augend.integer.alias.hex,
augend.integer.alias.octal,
augend.integer.alias.binary,
augend.constant.alias.bool,
augend.constant.alias.alpha,
augend.constant.alias.Alpha,
augend.semver.alias.semver,
},
})
end,
keys = {
{
'<c-a>',
function()
require('dial.map').manipulate('increment', 'normal')
end,
mode = 'n',
},
{
'<c-x>',
function()
require('dial.map').manipulate('decrement', 'normal')
end,
mode = 'n',
},
{
'g<c-a>',
function()
require('dial.map').manipulate('increment', 'gnormal')
end,
mode = 'n',
},
{
'g<c-x>',
function()
require('dial.map').manipulate('decrement', 'gnormal')
end,
mode = 'n',
},
{
'<c-a>',
function()
require('dial.map').manipulate('increment', 'visual')
end,
mode = 'v',
},
{
'<c-x>',
function()
require('dial.map').manipulate('decrement', 'visual')
end,
mode = 'v',
},
{
'g<c-a>',
function()
require('dial.map').manipulate('increment', 'gvisual')
end,
mode = 'v',
},
{
'g<c-x>',
function()
require('dial.map').manipulate('decrement', 'gvisual')
end,
mode = 'v',
},
},
},
{
'cbochs/grapple.nvim',
opts = {
scope = 'git_branch',
icons = false,
status = false,
win_opts = {
title = '',
footer = '',
},
},
keys = {
{ '<leader>ha', '<cmd>Grapple toggle<cr>' },
{ '<leader>hd', '<cmd>Grapple untag<cr>' },
{ '<leader>hq', '<cmd>Grapple toggle_tags<cr>' },
{ '<c-1>', '<cmd>Grapple select index=1<cr>' },
{ '<c-2>', '<cmd>Grapple select index=2<cr>' },
{ '<c-3>', '<cmd>Grapple select index=3<cr>' },
{ '<c-4>', '<cmd>Grapple select index=4<cr>' },
{ ']h', '<cmd>Grapple cycle_tags next<cr>' },
{ '[h', '<cmd>Grapple cycle_tags prev<cr>' },
},
},
{
'catgoose/nvim-colorizer.lua',
opts = {
user_default_options = {
names = false,
rrggbbaa = true,
css = true,
css_fn = true,
rgb_fn = true,
hsl_fn = true,
},
},
event = 'VeryLazy',
},
{
'stevearc/oil.nvim',
config = function(_, opts)
require('oil').setup(opts)
vim.api.nvim_create_autocmd('BufEnter', {
callback = function()
local ft = vim.bo.filetype
if ft == '' then
local path = vim.fn.expand('%:p')
if vim.fn.isdirectory(path) == 1 then
vim.cmd('Oil ' .. path)
end
end
end,
group = vim.api.nvim_create_augroup('AOil', { clear = true }),
})
end,
event = 'VeryLazy',
keys = {
{ '-', '<cmd>e .<cr>' },
{ '_', vim.cmd.Oil },
},
opts = {
skip_confirm_for_simple_edits = true,
prompt_save_on_select_new_entry = false,
float = { border = 'single' },
view_options = {
is_hidden_file = function(name, bufnr)
local dir = require('oil').get_current_dir(bufnr)
if not dir then
return false
end
if vim.startswith(name, '.') then
return false
end
local git_dir = vim.fn.finddir('.git', dir .. ';')
if git_dir == '' then
return false
end
local fullpath = dir .. '/' .. name
local result =
vim.fn.systemlist({ 'git', 'check-ignore', fullpath })
return #result > 0
end,
},
keymaps = {
['<C-h>'] = false,
['<C-t>'] = false,
['<C-l>'] = false,
['<C-r>'] = 'actions.refresh',
['<C-s>'] = { 'actions.select', opts = { vertical = true } },
['<C-x>'] = { 'actions.select', opts = { horizontal = true } },
['q'] = function()
local ok, bufremove = pcall(require, 'mini.bufremove')
if ok then
bufremove.delete()
else
vim.cmd.bd()
end
end,
},
},
},
{
'echasnovski/mini.misc',
config = true,
keys = {
{
'<c-w>m',
"<cmd>lua MiniMisc.zoom(0, { title = '', border = 'none' })<cr>",
},
},
},
{
'nvim-mini/mini.bufremove',
config = true,
keys = {
{
'<leader>bd',
'<cmd>lua MiniBufremove.delete()<cr>',
},
{
'<leader>bw',
'<cmd>lua MiniBufremove.wipeout()<cr>',
},
},
},
{ 'tpope/vim-abolish', event = 'VeryLazy' },
{ 'tpope/vim-sleuth', event = 'BufReadPost' },
{
'kylechui/nvim-surround',
config = true,
keys = {
{ 'cs', mode = 'n' },
{ 'ds', mode = 'n' },
{ 'ys', mode = 'n' },
{ 'yS', mode = 'n' },
{ 'yss', mode = 'n' },
{ 'ySs', mode = 'n' },
},
},
{
'tzachar/highlight-undo.nvim',
config = true,
keys = { 'u', 'U' },
},
{
'kana/vim-textobj-user',
dependencies = {
{
'kana/vim-textobj-entire',
keys = {
{ 'ae', mode = { 'o', 'x' } },
{ 'ie', mode = { 'o', 'x' } },
},
},
{
'kana/vim-textobj-line',
keys = {
{ 'al', mode = { 'o', 'x' } },
{ 'il', mode = { 'o', 'x' } },
},
},
{
'kana/vim-textobj-indent',
keys = {
{ 'ai', mode = { 'o', 'x' } },
{ 'ii', mode = { 'o', 'x' } },
},
},
{
'preservim/vim-textobj-sentence',
keys = {
{ 'as', mode = { 'o', 'x' } },
{ 'is', mode = { 'o', 'x' } },
},
},
{
'whatyouhide/vim-textobj-xmlattr',
keys = {
{ 'ax', mode = { 'o', 'x' } },
{ 'ix', mode = { 'o', 'x' } },
},
},
},
},
{
'saghen/blink.indent',
opts = {
blocked = {
filetypes = {
include_defaults = true,
'fugitive',
'markdown',
'typst',
},
},
static = {
char = '',
},
scope = { enabled = false },
},
},
{
'barrettruth/midnight.nvim',
dir = '~/dev/midnight.nvim',
init = function()
vim.api.nvim_create_autocmd({ 'OptionSet' }, {
pattern = 'background',
callback = function()
vim.cmd.colorscheme(
vim.o.background == 'dark' and 'midnight' or 'daylight'
)
end,
group = vim.api.nvim_create_augroup(
'AColorScheme',
{ clear = true }
),
})
end,
},
}

View file

@ -0,0 +1,30 @@
return {
'stevearc/overseer.nvim',
init = function()
vim.api.nvim_create_autocmd('VimLeavePre', {
callback = function()
local overseer = require('overseer')
for _, task in ipairs(overseer.list_tasks()) do
if task:is_running() then
task:stop()
end
task:dispose(true)
end
current_task = nil
end,
group = vim.api.nvim_create_augroup('AOverseer', { clear = true }),
})
end,
opts = {
strategy = 'terminal',
task_list = {
bindings = {
q = '<Cmd>OverseerClose<CR>',
},
},
},
keys = {
{ '<leader>Oa', '<cmd>OverseerTaskAction<cr>' },
{ '<leader>Ob', '<cmd>OverseerBuild<cr>' },
},
}

View file

@ -0,0 +1,156 @@
return {
{
'nvim-treesitter/nvim-treesitter',
branch = 'main',
build = ':TSUpdate',
lazy = false,
init = function()
vim.api.nvim_create_autocmd('FileType', {
pattern = '*',
callback = function()
local bufnr = vim.api.nvim_get_current_buf()
local lines = vim.api.nvim_buf_line_count(bufnr)
if lines < 5000 then
pcall(vim.treesitter.start)
else
vim.notify_once(
('Skipping tree-sitter for bufnr %s; file too large (%s >= 5000 lines)'):format(
bufnr,
lines
)
)
end
end,
group = vim.api.nvim_create_augroup(
'ATreeSitter',
{ clear = true }
),
})
end,
keys = {
{
'<leader>T',
function()
local lang_map = { htmldjango = 'html' }
local bufnr = vim.api.nvim_get_current_buf()
local parser = vim.treesitter.get_parser(bufnr)
local lang = parser:lang()
local path = (
vim.env.NVIM_APPNAME or vim.fn.stdpath('config')
)
.. ('/after/queries/%s/highlights.scm'):format(
lang_map[lang] or lang
)
if vim.loop.fs_stat(path) then
vim.fn.rename(path, path .. '.disabled')
elseif vim.loop.fs_stat(path .. '.disabled') then
vim.fn.rename(path .. '.disabled', path)
end
vim.cmd.TSBufToggle('highlight')
vim.cmd.TSBufToggle('highlight')
end,
},
},
},
{
'nvim-treesitter/nvim-treesitter-textobjects',
branch = 'main',
dependencies = 'nvim-treesitter/nvim-treesitter',
init = function()
vim.g.no_plugin_maps = true
end,
opts = {
select = {
enable = true,
lookahead = true,
},
move = {
enable = true,
set_jumps = true,
},
},
config = function(_, opts)
require('nvim-treesitter-textobjects').setup(opts)
local select = require('nvim-treesitter-textobjects.select')
local select_maps = {
{ 'aa', '@parameter.outer' },
{ 'ia', '@parameter.inner' },
{ 'ab', '@block.outer' },
{ 'ib', '@block.inner' },
{ 'as', '@class.outer' },
{ 'is', '@class.inner' },
{ 'aC', '@call.outer' },
{ 'iC', '@call.inner' },
{ 'af', '@function.outer' },
{ 'if', '@function.inner' },
{ 'ai', '@conditional.outer' },
{ 'ii', '@conditional.inner' },
{ 'aL', '@loop.outer' },
{ 'iL', '@loop.inner' },
}
for _, m in ipairs({ 'x', 'o' }) do
for _, t in ipairs(select_maps) do
map({
m,
t[1],
function()
select.select_textobject(t[2], 'textobjects', m)
end,
})
end
end
local move = require('nvim-treesitter-textobjects.move')
local move_maps = {
{ ']a', 'goto_next_start', '@parameter.inner' },
{ ']s', 'goto_next_start', '@class.outer' },
{ ']f', 'goto_next_start', '@function.outer' },
{ ']i', 'goto_next_start', '@conditional.outer' },
{ ']/', 'goto_next_start', '@comment.outer' },
{ ']A', 'goto_next_end', '@parameter.inner' },
{ ']F', 'goto_next_end', '@function.outer' },
{ ']I', 'goto_next_end', '@conditional.outer' },
{ '[a', 'goto_previous_start', '@parameter.inner' },
{ '[s', 'goto_previous_start', '@class.outer' },
{ '[f', 'goto_previous_start', '@function.outer' },
{ '[i', 'goto_previous_start', '@conditional.outer' },
{ '[/', 'goto_previous_start', '@comment.outer' },
{ '[A', 'goto_previous_end', '@parameter.inner' },
{ '[F', 'goto_previous_end', '@function.outer' },
{ '[I', 'goto_previous_end', '@conditional.outer' },
}
for _, m in ipairs({ 'n', 'x', 'o' }) do
for _, t in ipairs(move_maps) do
map({
m,
t[1],
function()
move[t[2]](t[3], 'textobjects')
end,
})
end
end
local ts_repeat =
require('nvim-treesitter-textobjects.repeatable_move')
for _, m in ipairs({ 'n', 'x', 'o' }) do
map({ m, ';', ts_repeat.repeat_last_move_next })
map({ m, ',', ts_repeat.repeat_last_move_previous })
map({ m, 'f', ts_repeat.builtin_f_expr }, { expr = true })
map({ m, 'F', ts_repeat.builtin_F_expr }, { expr = true })
map({ m, 't', ts_repeat.builtin_t_expr }, { expr = true })
map({ m, 'T', ts_repeat.builtin_T_expr }, { expr = true })
end
end,
},
{
'Wansmer/treesj',
config = true,
keys = {
{ 'gt', '<cmd>lua require("treesj").toggle()<cr>' },
},
},
}