optimize the shit out of theme loading

switch neovim to vim.pack away from lazy
add sandboxagent package to netty
update defaults
This commit is contained in:
Harivansh Rathi 2026-03-30 23:44:32 -04:00
parent 6dfcfad05f
commit 30ac6bc674
24 changed files with 4764 additions and 646 deletions

View file

@ -1,34 +1,23 @@
local lsp = require('config.lsp')
local lsp = require "config.lsp"
vim.lsp.config('*', {
capabilities = lsp.capabilities(),
vim.lsp.config("*", {
on_attach = lsp.on_attach,
capabilities = lsp.capabilities(),
})
vim.api.nvim_create_autocmd('LspAttach', {
group = vim.api.nvim_create_augroup('UserLspConfig', {}),
callback = function(ev)
local client = vim.lsp.get_client_by_id(ev.data.client_id)
if client then
lsp.on_attach(client, ev.buf)
end
end,
})
for _, server in ipairs({
'lua_ls',
'pyright',
'ts_ls',
'rust_analyzer',
'gopls',
'clangd',
'bashls',
'jsonls',
'html',
'cssls',
}) do
local ok, config = pcall(require, 'lsp.' .. server)
if ok then
vim.lsp.config(server, config)
end
vim.lsp.enable(server)
for _, server in ipairs {
"lua_ls",
"pyright",
"ts_ls",
"rust_analyzer",
"gopls",
"clangd",
"bashls",
"jsonls",
"html",
"cssls",
} do
local ok, config = pcall(require, "lsp." .. server)
if ok and config then vim.lsp.config(server, config) end
vim.lsp.enable(server)
end

View file

@ -1,68 +1,56 @@
vim.g.mapleader = ' '
vim.g.maplocalleader = ','
vim.g.mapleader = " "
vim.g.maplocalleader = ","
local home = os.getenv('HOME') or ''
local local_bin = home .. '/.local/bin'
if not (os.getenv('PATH') or ''):find(local_bin, 1, true) then
local new_path = local_bin .. ':' .. (os.getenv('PATH') or '')
vim.env.PATH = new_path
vim.uv.os_setenv('PATH', new_path)
local home = os.getenv "HOME" or ""
local local_bin = home .. "/.local/bin"
if not (os.getenv "PATH" or ""):find(local_bin, 1, true) then
local new_path = local_bin .. ":" .. (os.getenv "PATH" or "")
vim.env.PATH = new_path
vim.uv.os_setenv("PATH", new_path)
end
function _G.map(mode, lhs, rhs, opts)
vim.keymap.set(mode, lhs, rhs, vim.tbl_extend('keep', opts or {}, { silent = true }))
vim.keymap.set(mode, lhs, rhs, vim.tbl_extend("keep", opts or {}, { silent = true }))
end
function _G.bmap(mode, lhs, rhs, opts)
_G.map(mode, lhs, rhs, vim.tbl_extend('force', opts or {}, { buffer = 0 }))
end
function _G.bmap(mode, lhs, rhs, opts) _G.map(mode, lhs, rhs, vim.tbl_extend("force", opts or {}, { buffer = 0 })) end
local disabled_plugins = {
'2html_plugin',
'bugreport',
'getscript',
'getscriptPlugin',
'gzip',
'logipat',
'matchit',
'netrw',
'netrwFileHandlers',
'netrwPlugin',
'netrwSettings',
'optwin',
'rplugin',
'rrhelper',
'synmenu',
'tar',
'tarPlugin',
'tohtml',
'tutor',
'vimball',
'vimballPlugin',
'zip',
'zipPlugin',
"2html_plugin",
"bugreport",
"getscript",
"getscriptPlugin",
"gzip",
"logipat",
"matchit",
"netrw",
"netrwFileHandlers",
"netrwPlugin",
"netrwSettings",
"optwin",
"rplugin",
"rrhelper",
"synmenu",
"tar",
"tarPlugin",
"tohtml",
"tutor",
"vimball",
"vimballPlugin",
"zip",
"zipPlugin",
}
for _, plugin in ipairs(disabled_plugins) do
vim.g['loaded_' .. plugin] = 1
vim.g["loaded_" .. plugin] = 1
end
local lazypath = vim.fn.stdpath('data') .. '/lazy/lazy.nvim'
local lazylock = vim.fn.stdpath('state') .. '/lazy-lock.json'
if not vim.uv.fs_stat(lazypath) then
vim.fn.system({
'git',
'clone',
'--filter=blob:none',
'--branch=stable',
'https://github.com/folke/lazy.nvim.git',
lazypath,
})
end
vim.opt.rtp:prepend(lazypath)
vim.g.lz_n = {
load = function(name) vim.cmd.packadd(name:match "[^/]+$" or name) end,
}
require('lazy').setup('plugins', {
defaults = { lazy = false },
change_detection = { enabled = false },
lockfile = lazylock,
})
vim.pack.add {
"https://github.com/lumen-oss/lz.n",
}
require("lz.n").load "plugins"

View file

@ -1,28 +1,19 @@
local M = {}
function M.on_attach(_, bufnr)
local function buf(mode, lhs, rhs)
bmap(mode, lhs, rhs, { buffer = bufnr })
end
local function buf(mode, lhs, rhs) bmap(mode, lhs, rhs, { buffer = bufnr }) end
buf('n', 'gd', vim.lsp.buf.definition)
buf('n', 'gD', vim.lsp.buf.declaration)
buf('n', '<C-]>', vim.lsp.buf.definition)
buf('n', 'gi', vim.lsp.buf.implementation)
buf('n', 'gr', vim.lsp.buf.references)
buf('n', 'K', vim.lsp.buf.hover)
buf('n', '<leader>rn', vim.lsp.buf.rename)
buf({ 'n', 'v' }, '<leader>ca', vim.lsp.buf.code_action)
buf('n', '<leader>f', function() vim.lsp.buf.format({ async = true }) end)
buf("n", "gd", vim.lsp.buf.definition)
buf("n", "gD", vim.lsp.buf.declaration)
buf("n", "<C-]>", vim.lsp.buf.definition)
buf("n", "gi", vim.lsp.buf.implementation)
buf("n", "gr", vim.lsp.buf.references)
buf("n", "K", vim.lsp.buf.hover)
buf("n", "<leader>rn", vim.lsp.buf.rename)
buf({ "n", "v" }, "<leader>ca", vim.lsp.buf.code_action)
buf("n", "<leader>f", function() vim.lsp.buf.format { async = true } end)
end
function M.capabilities()
local caps = vim.lsp.protocol.make_client_capabilities()
local ok, blink = pcall(require, 'blink.cmp')
if ok then
caps = blink.get_lsp_capabilities(caps)
end
return caps
end
function M.capabilities() return vim.lsp.protocol.make_client_capabilities() end
return M

View file

@ -1,48 +1,54 @@
vim.pack.add({
"https://github.com/saghen/blink.cmp",
}, { load = function() end })
return {
'saghen/blink.cmp',
version = '*',
event = { 'InsertEnter', 'LspAttach' },
opts = {
keymap = {
['<Tab>'] = { 'select_and_accept', 'snippet_forward', 'fallback' },
['<S-Tab>'] = { 'snippet_backward', 'fallback' },
['<c-p>'] = { 'select_prev', 'fallback' },
['<c-n>'] = { 'show', 'select_next', 'fallback' },
['<c-y>'] = { 'select_and_accept', 'fallback' },
['<c-e>'] = { 'cancel', 'fallback' },
['<c-u>'] = { 'scroll_documentation_up', 'fallback' },
['<c-d>'] = { 'scroll_documentation_down', 'fallback' },
"saghen/blink.cmp",
event = { "InsertEnter", "LspAttach" },
keys = { { "<c-n>", mode = "i" } },
after = function()
require("blink.cmp").setup {
keymap = {
["<Tab>"] = { "select_and_accept", "snippet_forward", "fallback" },
["<S-Tab>"] = { "snippet_backward", "fallback" },
["<c-p>"] = { "select_prev", "fallback" },
["<c-n>"] = { "show", "select_next", "fallback" },
["<c-y>"] = { "select_and_accept", "fallback" },
["<c-e>"] = { "cancel", "fallback" },
["<c-u>"] = { "scroll_documentation_up", "fallback" },
["<c-d>"] = { "scroll_documentation_down", "fallback" },
},
cmdline = { enabled = false },
completion = {
accept = {
auto_brackets = { enabled = true },
},
cmdline = { enabled = false },
completion = {
accept = {
auto_brackets = { enabled = true },
},
documentation = {
auto_show = true,
window = {
border = 'single',
scrollbar = false,
winhighlight = 'Normal:BlinkCmpDoc,FloatBorder:BlinkCmpDocBorder',
},
},
menu = {
auto_show = true,
border = 'single',
scrollbar = false,
winhighlight = 'Normal:BlinkCmpMenu,FloatBorder:BlinkCmpMenuBorder,CursorLine:BlinkCmpMenuSelection',
draw = {
treesitter = { 'lsp' },
columns = {
{ 'kind_icon', gap = 1 },
{ 'label', 'label_description', gap = 1 },
},
},
},
ghost_text = { enabled = true },
documentation = {
auto_show = true,
window = {
border = "single",
scrollbar = false,
winhighlight = "Normal:BlinkCmpDoc,FloatBorder:BlinkCmpDocBorder",
},
},
sources = {
default = { 'lsp', 'path', 'buffer', 'snippets' },
menu = {
auto_show = true,
border = "single",
scrollbar = false,
winhighlight = "Normal:BlinkCmpMenu,FloatBorder:BlinkCmpMenuBorder,CursorLine:BlinkCmpMenuSelection",
draw = {
treesitter = { "lsp" },
columns = {
{ "kind_icon", gap = 1 },
{ "label", "label_description", gap = 1 },
},
},
},
},
ghost_text = { enabled = true },
},
sources = {
default = { "lsp", "path", "buffer", "snippets" },
},
}
end,
}

View file

@ -1,171 +1,108 @@
vim.pack.add({
"https://github.com/windwp/nvim-autopairs",
"https://github.com/folke/flash.nvim",
"https://github.com/kylechui/nvim-surround",
"https://github.com/kevinhwang91/nvim-ufo",
"https://github.com/kevinhwang91/promise-async",
"https://github.com/barrettruth/pending.nvim",
"https://github.com/barrettruth/preview.nvim",
}, { load = function() end })
return {
{
'windwp/nvim-autopairs',
config = true,
},
{
'folke/flash.nvim',
opts = {
modes = { search = { enabled = true } },
},
config = function(_, opts)
require('flash').setup(opts)
map({ 'n', 'x', 'o' }, 's', function() require('flash').jump() end)
map({ 'n', 'x', 'o' }, 'S', function() require('flash').treesitter() end)
map('o', 'r', function() require('flash').remote() end)
map({ 'o', 'x' }, 'R', function() require('flash').treesitter_search() end)
map('c', '<c-s>', function() require('flash').toggle() end)
end,
},
{
'kylechui/nvim-surround',
config = true,
},
{
'kevinhwang91/nvim-ufo',
dependencies = { 'kevinhwang91/promise-async' },
opts = {
provider_selector = function()
return { 'treesitter', 'indent' }
end,
},
config = function(_, opts)
require('ufo').setup(opts)
map('n', 'zR', require('ufo').openAllFolds)
map('n', 'zM', require('ufo').closeAllFolds)
end,
},
{
enabled = false,
'barrettruth/cp.nvim',
dependencies = { 'ibhagwan/fzf-lua' },
init = function()
-- Keep uv cache in-project so cp.nvim scraping works in restricted environments.
if vim.env.UV_CACHE_DIR == nil or vim.env.UV_CACHE_DIR == '' then
local uv_cache_dir = vim.fn.getcwd() .. '/.uv-cache'
vim.fn.mkdir(uv_cache_dir, 'p')
vim.env.UV_CACHE_DIR = uv_cache_dir
end
vim.g.cp = {
languages = {
python = {
extension = 'py',
commands = {
run = { 'python3', '{source}' },
debug = { 'python3', '{source}' },
},
},
},
platforms = {
codeforces = {
enabled_languages = { 'python' },
default_language = 'python',
},
atcoder = {
enabled_languages = { 'python' },
default_language = 'python',
},
cses = {
enabled_languages = { 'python' },
default_language = 'python',
},
},
open_url = true,
ui = {
picker = 'fzf-lua',
},
}
end,
config = function()
local function open_url(url)
local ok_ui_open, opened = pcall(vim.ui.open, url)
if ok_ui_open and opened ~= false then
return
end
local opener = nil
if vim.fn.has('macunix') == 1 then
opener = 'open'
elseif vim.fn.has('unix') == 1 then
opener = 'xdg-open'
end
if opener then
vim.fn.jobstart({ opener, url }, { detach = true })
end
end
local function open_current_cp_problem_url()
local ok_state, state = pcall(require, 'cp.state')
local ok_cache, cache = pcall(require, 'cp.cache')
if not (ok_state and ok_cache) then
return
end
local platform = state.get_platform()
local contest_id = state.get_contest_id()
local problem_id = state.get_problem_id()
if not (platform and contest_id and problem_id) then
return
end
cache.load()
local contest = cache.get_contest_data(platform, contest_id)
if contest and contest.url then
open_url(contest.url:format(problem_id))
end
end
-- cp.nvim only opens URLs when first entering a contest; extend this locally for next/prev.
local ok_setup, setup = pcall(require, 'cp.setup')
local ok_config, cp_config = pcall(require, 'cp.config')
if ok_setup and ok_config and not setup._url_open_patch_applied then
local original_navigate_problem = setup.navigate_problem
setup.navigate_problem = function(direction, language)
local ok_state, state = pcall(require, 'cp.state')
local old_problem_id = ok_state and state.get_problem_id() or nil
original_navigate_problem(direction, language)
local cfg = cp_config.get_config()
local new_problem_id = ok_state and state.get_problem_id() or nil
local moved = old_problem_id ~= nil and new_problem_id ~= nil and old_problem_id ~= new_problem_id
if cfg and cfg.open_url and moved then
vim.schedule(open_current_cp_problem_url)
end
end
setup._url_open_patch_applied = true
end
map('n', '<leader>cr', '<cmd>CP run<cr>', { desc = 'CP run' })
map('n', '<leader>cp', '<cmd>CP panel<cr>', { desc = 'CP panel' })
map('n', '<leader>ce', '<cmd>CP edit<cr>', { desc = 'CP edit tests' })
map('n', '<leader>cn', '<cmd>CP next<cr>', { desc = 'CP next problem' })
map('n', '<leader>cN', '<cmd>CP prev<cr>', { desc = 'CP previous problem' })
map('n', '<leader>cc', '<cmd>CP pick<cr>', { desc = 'CP contest picker' })
map('n', '<leader>ci', '<cmd>CP interact<cr>', { desc = 'CP interact' })
map('n', '<leader>co', open_current_cp_problem_url, { desc = 'CP open problem url' })
end,
},
{
'barrettruth/pending.nvim',
init = function()
map('n', '<leader>p', '<cmd>Pending<cr><cmd>only<cr>')
end,
},
{
'barrettruth/preview.nvim',
init = function()
vim.g.preview = {
typst = true,
latex = true,
github = {
output = function(ctx)
return '/tmp/' .. vim.fn.fnamemodify(ctx.file, ':t:r') .. '.html'
end,
{
"windwp/nvim-autopairs",
event = "InsertEnter",
after = function() require("nvim-autopairs").setup() end,
},
{
"folke/flash.nvim",
after = function()
require("flash").setup {
modes = { search = { enabled = true } },
}
end,
keys = {
{
"s",
function() require("flash").jump() end,
mode = { "n", "x", "o" },
},
mermaid = true,
}
end,
},
{
"S",
function() require("flash").treesitter() end,
mode = { "n", "x", "o" },
},
{
"r",
function() require("flash").remote() end,
mode = "o",
},
{
"R",
function() require("flash").treesitter_search() end,
mode = { "o", "x" },
},
{
"<c-s>",
function() require("flash").toggle() end,
mode = "c",
},
},
},
{
"kylechui/nvim-surround",
after = function() require("nvim-surround").setup() end,
keys = {
{ "cs", mode = "n" },
{ "ds", mode = "n" },
{ "ys", mode = "n" },
{ "yS", mode = "n" },
{ "yss", mode = "n" },
{ "ySs", mode = "n" },
},
},
{
"kevinhwang91/nvim-ufo",
event = "BufReadPost",
before = function() vim.cmd.packadd "promise-async" end,
after = function()
require("ufo").setup {
provider_selector = function() return { "treesitter", "indent" } end,
}
end,
keys = {
{
"zR",
function() require("ufo").openAllFolds() end,
mode = "n",
},
{
"zM",
function() require("ufo").closeAllFolds() end,
mode = "n",
},
},
},
{
"barrettruth/pending.nvim",
cmd = "Pending",
keys = {
{ "<leader>p", "<cmd>Pending<cr><cmd>only<cr>" },
},
},
{
"barrettruth/preview.nvim",
cmd = "Preview",
ft = { "markdown", "tex", "typst" },
before = function()
vim.g.preview = {
typst = true,
latex = true,
github = {
output = function(ctx) return "/tmp/" .. vim.fn.fnamemodify(ctx.file, ":t:r") .. ".html" end,
},
mermaid = true,
}
end,
},
}

View file

@ -1,3 +1,7 @@
vim.pack.add({
"https://github.com/ibhagwan/fzf-lua",
}, { load = function() end })
---@param kind 'issue'|'pr'
---@param state 'all'|'open'|'closed'
local function gh_picker(kind, state)
@ -5,8 +9,10 @@ local function gh_picker(kind, state)
vim.notify("gh CLI not found", vim.log.levels.WARN)
return
end
local next_state = ({ all = "open", open = "closed", closed = "all" })[state]
local label = kind == "pr" and "PRs" or "Issues"
require("fzf-lua").fzf_exec(("gh %s list --limit 100 --state %s"):format(kind, state), {
prompt = ("%s (%s)> "):format(label, state),
header = ":: <c-o> to toggle all/open/closed",
@ -22,9 +28,27 @@ end
return {
"ibhagwan/fzf-lua",
dependencies = { "nvim-tree/nvim-web-devicons" },
config = function(_, opts)
cmd = "FzfLua",
before = function()
pcall(vim.cmd.packadd, "nvim-web-devicons")
pcall(vim.cmd.packadd, "nonicons.nvim")
end,
after = function()
local fzf = require "fzf-lua"
local opts = {
"default-title",
winopts = {
border = "single",
preview = {
layout = "vertical",
vertical = "down:50%",
},
},
fzf_opts = {
["--layout"] = "reverse",
},
}
fzf.setup(opts)
local ok, fzf_reload = pcall(require, "config.fzf_reload")
@ -32,45 +56,43 @@ return {
fzf_reload.setup(opts)
fzf_reload.reload()
end
map("n", "<C-f>", function()
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()
else
fzf.files()
end
end)
map("n", "<leader>ff", "<cmd>FzfLua files<cr>")
map("n", "<leader>fg", "<cmd>FzfLua live_grep<cr>")
map("n", "<leader>fb", "<cmd>FzfLua buffers<cr>")
map("n", "<leader>fh", "<cmd>FzfLua help_tags<cr>")
map("n", "<leader>fr", "<cmd>FzfLua resume<cr>")
map("n", "<leader>fo", "<cmd>FzfLua oldfiles<cr>")
map("n", "<leader>fc", "<cmd>FzfLua commands<cr>")
map("n", "<leader>fk", "<cmd>FzfLua keymaps<cr>")
map("n", "<leader>f/", "<cmd>FzfLua search_history<cr>")
map("n", "<leader>f:", "<cmd>FzfLua command_history<cr>")
map("n", "<leader>fe", "<cmd>FzfLua files cwd=~/.config<cr>")
map("n", "gq", "<cmd>FzfLua quickfix<cr>")
map("n", "gl", "<cmd>FzfLua loclist<cr>")
map("n", "<leader>GB", "<cmd>FzfLua git_branches<cr>")
map("n", "<leader>Gc", "<cmd>FzfLua git_commits<cr>")
map("n", "<leader>Gs", "<cmd>FzfLua git_status<cr>")
map("n", "<leader>Gp", function() gh_picker("pr", "open") end)
map("n", "<leader>Gi", function() gh_picker("issue", "open") end)
end,
opts = {
"default-title",
winopts = {
border = "single",
preview = {
layout = "vertical",
vertical = "down:50%",
},
keys = {
{
"<C-f>",
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()
else
fzf.files()
end
end,
},
fzf_opts = {
["--layout"] = "reverse",
{ "<leader>ff", "<cmd>FzfLua files<cr>" },
{ "<leader>fg", "<cmd>FzfLua live_grep<cr>" },
{ "<leader>fb", "<cmd>FzfLua buffers<cr>" },
{ "<leader>fh", "<cmd>FzfLua help_tags<cr>" },
{ "<leader>fr", "<cmd>FzfLua resume<cr>" },
{ "<leader>fo", "<cmd>FzfLua oldfiles<cr>" },
{ "<leader>fc", "<cmd>FzfLua commands<cr>" },
{ "<leader>fk", "<cmd>FzfLua keymaps<cr>" },
{ "<leader>f/", "<cmd>FzfLua search_history<cr>" },
{ "<leader>f:", "<cmd>FzfLua command_history<cr>" },
{ "<leader>fe", "<cmd>FzfLua files cwd=~/.config<cr>" },
{ "gq", "<cmd>FzfLua quickfix<cr>" },
{ "gl", "<cmd>FzfLua loclist<cr>" },
{ "<leader>GB", "<cmd>FzfLua git_branches<cr>" },
{ "<leader>Gc", "<cmd>FzfLua git_commits<cr>" },
{ "<leader>Gs", "<cmd>FzfLua git_status<cr>" },
{
"<leader>Gp",
function() gh_picker("pr", "open") end,
},
{
"<leader>Gi",
function() gh_picker("issue", "open") end,
},
},
}

View file

@ -1,102 +1,68 @@
local function file_loc()
local root = vim.trim(vim.fn.system('git rev-parse --show-toplevel'))
if vim.v.shell_error ~= 0 or root == '' then
return nil
end
local path = vim.api.nvim_buf_get_name(0)
if path == '' or path:sub(1, #root + 1) ~= root .. '/' then
return nil
end
return ('%s:%d'):format(path:sub(#root + 2), vim.fn.line('.'))
end
local function gh_browse()
if vim.fn.executable('gh') ~= 1 then
vim.notify('gh CLI not found', vim.log.levels.WARN)
return
end
local loc = file_loc()
if loc then
vim.system({ 'gh', 'browse', loc })
else
vim.system({ 'gh', 'browse' })
end
end
vim.pack.add({
"https://github.com/lewis6991/gitsigns.nvim",
"https://github.com/barrettruth/forge.nvim",
"https://github.com/barrettruth/diffs.nvim",
}, { load = function() end })
return {
{
'tpope/vim-fugitive',
config = function()
map('n', '<leader>gg', '<cmd>Git<cr><cmd>only<cr>')
map('n', '<leader>gc', '<cmd>Git commit<cr>')
map('n', '<leader>gp', '<cmd>Git push<cr>')
map('n', '<leader>gl', '<cmd>Git pull<cr>')
map('n', '<leader>gb', '<cmd>Git blame<cr>')
map('n', '<leader>gd', '<cmd>Gvdiffsplit<cr>')
map('n', '<leader>gr', '<cmd>Gread<cr>')
map('n', '<leader>gw', '<cmd>Gwrite<cr>')
map({ 'n', 'v' }, '<leader>go', gh_browse)
end,
},
{
'lewis6991/gitsigns.nvim',
opts = {
signs = {
add = { text = '██' },
change = { text = '██' },
delete = { text = '▄▄' },
topdelete = { text = '▀▀' },
changedelete = { text = '██' },
},
signs_staged = {
add = { text = '▓▓' },
change = { text = '▓▓' },
delete = { text = '▄▄' },
topdelete = { text = '▀▀' },
changedelete = { text = '▓▓' },
},
signs_staged_enable = true,
{
"lewis6991/gitsigns.nvim",
event = "BufReadPre",
after = function()
require("gitsigns").setup {
signs = {
add = { text = "██" },
change = { text = "██" },
delete = { text = "▄▄" },
topdelete = { text = "▀▀" },
changedelete = { text = "██" },
},
config = function(_, opts)
require('gitsigns').setup(opts)
map('n', ']g', '<cmd>Gitsigns next_hunk<cr>')
map('n', '[g', '<cmd>Gitsigns prev_hunk<cr>')
map('n', '<leader>ghs', '<cmd>Gitsigns stage_hunk<cr>')
map('n', '<leader>ghr', '<cmd>Gitsigns reset_hunk<cr>')
map('n', '<leader>ghp', '<cmd>Gitsigns preview_hunk<cr>')
map('n', '<leader>gB', '<cmd>Gitsigns toggle_current_line_blame<cr>')
end,
},
{
'barrettruth/forge.nvim',
dependencies = { 'ibhagwan/fzf-lua' },
init = function()
vim.g.forge = vim.g.forge or {}
end,
config = function()
map('n', '<c-t>', '<cmd>Forge<cr>', { desc = 'Forge picker' })
end,
},
{
'barrettruth/diffs.nvim',
enabled = true,
init = function()
vim.g.diffs = {
integrations = {
fugitive = {
enabled = true,
horizontal = false,
vertical = false,
},
},
hide_prefix = true,
highlights = {
warn_max_lines = false,
gutter = true,
blend_alpha = 0.5,
intra = { enabled = true },
},
}
end,
signs_staged = {
add = { text = "▓▓" },
change = { text = "▓▓" },
delete = { text = "▄▄" },
topdelete = { text = "▀▀" },
changedelete = { text = "▓▓" },
},
signs_staged_enable = true,
}
map("n", "]g", "<cmd>Gitsigns next_hunk<cr>")
map("n", "[g", "<cmd>Gitsigns prev_hunk<cr>")
map("n", "<leader>ghs", "<cmd>Gitsigns stage_hunk<cr>")
map("n", "<leader>ghr", "<cmd>Gitsigns reset_hunk<cr>")
map("n", "<leader>ghp", "<cmd>Gitsigns preview_hunk<cr>")
map("n", "<leader>gB", "<cmd>Gitsigns toggle_current_line_blame<cr>")
end,
},
{
"barrettruth/forge.nvim",
cmd = "Forge",
before = function() vim.g.forge = vim.g.forge or {} end,
after = function() pcall(vim.cmd.packadd, "fzf-lua") end,
keys = {
{ "<c-t>", "<cmd>Forge<cr>", desc = "Forge picker" },
},
},
{
"barrettruth/diffs.nvim",
before = function()
vim.g.diffs = {
integrations = {
fugitive = {
enabled = true,
horizontal = false,
vertical = false,
},
},
hide_prefix = true,
highlights = {
warn_max_lines = false,
gutter = true,
blend_alpha = 0.5,
intra = { enabled = true },
},
}
end,
},
}

View file

@ -1,4 +1,9 @@
vim.pack.add({
"https://github.com/neovim/nvim-lspconfig",
}, { load = function() end })
return {
'neovim/nvim-lspconfig',
lazy = false,
{
"neovim/nvim-lspconfig",
},
}

View file

@ -1,87 +1,92 @@
vim.pack.add({
"https://github.com/barrettruth/canola.nvim",
"https://github.com/barrettruth/canola-collection",
}, { load = function() end })
return {
{
'barrettruth/canola.nvim',
branch = 'canola',
dependencies = { 'nvim-tree/nvim-web-devicons' },
init = function()
vim.g.canola = {
columns = { 'icon' },
delete = { wipe = false, recursive = true },
hidden = { enabled = false },
keymaps = {
['g?'] = { callback = 'actions.show_help', mode = 'n' },
['<CR>'] = 'actions.select',
['<C-v>'] = { callback = 'actions.select', opts = { vertical = true } },
['<C-x>'] = { callback = 'actions.select', opts = { horizontal = true } },
['<C-p>'] = 'actions.preview',
['<C-c>'] = { callback = 'actions.close', mode = 'n' },
['-'] = { callback = 'actions.parent', mode = 'n' },
['g.'] = { callback = 'actions.toggle_hidden', mode = 'n' },
['<C-t>'] = false,
},
}
map('n', '-', '<cmd>Canola<cr>')
map('n', '<leader>e', '<cmd>Canola<cr>')
{
"barrettruth/canola.nvim",
cmd = "Canola",
before = function()
vim.g.canola = {
columns = { "icon" },
delete = { wipe = false, recursive = true },
hidden = { enabled = false },
keymaps = {
["g?"] = { callback = "actions.show_help", mode = "n" },
["<CR>"] = "actions.select",
["<C-v>"] = { callback = "actions.select", opts = { vertical = true } },
["<C-x>"] = { callback = "actions.select", opts = { horizontal = true } },
["<C-p>"] = "actions.preview",
["<C-c>"] = { callback = "actions.close", mode = "n" },
["-"] = { callback = "actions.parent", mode = "n" },
["g."] = { callback = "actions.toggle_hidden", mode = "n" },
["<C-t>"] = false,
},
}
end,
after = function()
vim.cmd.packadd "canola-collection"
local ns = vim.api.nvim_create_namespace('canola_git_trailing')
local symbols = {
M = { 'M', 'DiagnosticWarn' },
A = { 'A', 'DiagnosticOk' },
D = { 'D', 'DiagnosticError' },
R = { 'R', 'DiagnosticWarn' },
['?'] = { '?', 'DiagnosticInfo' },
['!'] = { '!', 'Comment' },
}
local ns = vim.api.nvim_create_namespace "canola_git_trailing"
local symbols = {
M = { "M", "DiagnosticWarn" },
A = { "A", "DiagnosticOk" },
D = { "D", "DiagnosticError" },
R = { "R", "DiagnosticWarn" },
["?"] = { "?", "DiagnosticInfo" },
["!"] = { "!", "Comment" },
}
local function apply_git_status(buf)
if not vim.api.nvim_buf_is_valid(buf) then return end
vim.api.nvim_buf_clear_namespace(buf, ns, 0, -1)
local function apply_git_status(buf)
if not vim.api.nvim_buf_is_valid(buf) then return end
vim.api.nvim_buf_clear_namespace(buf, ns, 0, -1)
local ok, canola = pcall(require, 'canola')
if not ok then return end
local ok, canola = pcall(require, "canola")
if not ok then return end
local dir = canola.get_current_dir(buf)
if not dir then return end
local dir = canola.get_current_dir(buf)
if not dir then return end
local git_ok, git = pcall(require, 'canola-git')
if not git_ok then return end
local git_ok, git = pcall(require, "canola-git")
if not git_ok then return end
local dir_cache = git._cache[dir]
if not dir_cache or not dir_cache.status then return end
local dir_cache = git._cache[dir]
if not dir_cache or not dir_cache.status then return end
local lines = vim.api.nvim_buf_line_count(buf)
for lnum = 0, lines - 1 do
local entry = canola.get_entry_on_line(buf, lnum + 1)
if entry then
local status = dir_cache.status[entry.name]
if status then
local ch = status:sub(1, 1)
if ch == ' ' then ch = status:sub(2, 2) end
local sym = symbols[ch]
if sym then
vim.api.nvim_buf_set_extmark(buf, ns, lnum, 0, {
virt_text = { { ' ' .. sym[1], sym[2] } },
virt_text_pos = 'eol',
invalidate = true,
})
end
end
end
end
local lines = vim.api.nvim_buf_line_count(buf)
for lnum = 0, lines - 1 do
local entry = canola.get_entry_on_line(buf, lnum + 1)
if entry then
local status = dir_cache.status[entry.name]
if status then
local ch = status:sub(1, 1)
if ch == " " then ch = status:sub(2, 2) end
local sym = symbols[ch]
if sym then
vim.api.nvim_buf_set_extmark(buf, ns, lnum, 0, {
virt_text = { { " " .. sym[1], sym[2] } },
virt_text_pos = "eol",
invalidate = true,
})
end
end
end
end
end
vim.api.nvim_create_autocmd('User', {
pattern = 'CanolaReadPost',
callback = function(args)
local buf = args.buf
apply_git_status(buf)
vim.defer_fn(function() apply_git_status(buf) end, 500)
end,
})
vim.api.nvim_create_autocmd("User", {
pattern = "CanolaReadPost",
callback = function(args)
local buf = args.buf
apply_git_status(buf)
vim.defer_fn(function() apply_git_status(buf) end, 500)
end,
})
end,
keys = {
{ "-", "<cmd>Canola<cr>" },
{ "<leader>e", "<cmd>Canola<cr>" },
},
{
'barrettruth/canola-collection',
dependencies = { 'barrettruth/canola.nvim' },
},
},
}

View file

@ -1,56 +1,71 @@
vim.pack.add({
"https://github.com/nvim-treesitter/nvim-treesitter",
"https://github.com/nvim-treesitter/nvim-treesitter-textobjects",
}, { load = function() end })
vim.api.nvim_create_autocmd("PackChanged", {
callback = function(ev)
local name, kind = ev.data.spec.name, ev.data.kind
if kind == "delete" then return end
if name == "nvim-treesitter" then vim.schedule(function() vim.cmd "TSUpdate all" end) end
end,
})
return {
{
'nvim-treesitter/nvim-treesitter',
build = ':TSUpdate',
dependencies = { 'nvim-treesitter/nvim-treesitter-textobjects' },
config = function()
require('nvim-treesitter-textobjects').setup({
select = {
enable = true,
lookahead = true,
keymaps = {
['af'] = '@function.outer',
['if'] = '@function.inner',
['ac'] = '@class.outer',
['ic'] = '@class.inner',
['aa'] = '@parameter.outer',
['ia'] = '@parameter.inner',
['ai'] = '@conditional.outer',
['ii'] = '@conditional.inner',
['al'] = '@loop.outer',
['il'] = '@loop.inner',
['ab'] = '@block.outer',
['ib'] = '@block.inner',
},
},
move = {
enable = true,
set_jumps = true,
goto_next_start = {
[']f'] = '@function.outer',
[']c'] = '@class.outer',
[']a'] = '@parameter.inner',
},
goto_next_end = {
[']F'] = '@function.outer',
[']C'] = '@class.outer',
},
goto_previous_start = {
['[f'] = '@function.outer',
['[c'] = '@class.outer',
['[a'] = '@parameter.inner',
},
goto_previous_end = {
['[F'] = '@function.outer',
['[C'] = '@class.outer',
},
},
swap = {
enable = true,
swap_next = { ['<leader>sn'] = '@parameter.inner' },
swap_previous = { ['<leader>sp'] = '@parameter.inner' },
},
})
end,
},
{
"nvim-treesitter/nvim-treesitter",
after = function() require("nvim-treesitter").setup { auto_install = true } end,
},
{
"nvim-treesitter/nvim-treesitter-textobjects",
after = function()
require("nvim-treesitter-textobjects").setup {
select = {
enable = true,
lookahead = true,
keymaps = {
["af"] = "@function.outer",
["if"] = "@function.inner",
["ac"] = "@class.outer",
["ic"] = "@class.inner",
["aa"] = "@parameter.outer",
["ia"] = "@parameter.inner",
["ai"] = "@conditional.outer",
["ii"] = "@conditional.inner",
["al"] = "@loop.outer",
["il"] = "@loop.inner",
["ab"] = "@block.outer",
["ib"] = "@block.inner",
},
},
move = {
enable = true,
set_jumps = true,
goto_next_start = {
["]f"] = "@function.outer",
["]c"] = "@class.outer",
["]a"] = "@parameter.inner",
},
goto_next_end = {
["]F"] = "@function.outer",
["]C"] = "@class.outer",
},
goto_previous_start = {
["[f"] = "@function.outer",
["[c"] = "@class.outer",
["[a"] = "@parameter.inner",
},
goto_previous_end = {
["[F"] = "@function.outer",
["[C"] = "@class.outer",
},
},
swap = {
enable = true,
swap_next = { ["<leader>sn"] = "@parameter.inner" },
swap_previous = { ["<leader>sp"] = "@parameter.inner" },
},
}
end,
},
}

View file

@ -1,15 +1,29 @@
vim.pack.add({
"https://github.com/harivansh-afk/cozybox.nvim",
"https://github.com/nvim-lualine/lualine.nvim",
"https://github.com/barrettruth/nonicons.nvim",
"https://github.com/nvim-tree/nvim-web-devicons",
}, { load = function() end })
return {
{
"harivansh-afk/cozybox.nvim",
lazy = false,
priority = 1000,
config = function() require("theme").setup() end,
after = function() require("theme").setup() end,
},
{
"nvim-tree/nvim-web-devicons",
},
{
"barrettruth/nonicons.nvim",
before = function() vim.cmd.packadd "nvim-web-devicons" end,
},
{
"nvim-lualine/lualine.nvim",
dependencies = { "nvim-tree/nvim-web-devicons" },
config = function()
local theme_status = function() return require("theme").statusline_label() end
before = function()
vim.cmd.packadd "nvim-web-devicons"
pcall(vim.cmd.packadd, "nonicons.nvim")
end,
after = function()
local theme = {
normal = {
a = { gui = "bold" },
@ -24,6 +38,7 @@ return {
a = { gui = "bold" },
},
}
require("lualine").setup {
options = {
icons_enabled = false,
@ -42,8 +57,4 @@ return {
}
end,
},
{
"barrettruth/nonicons.nvim",
dependencies = { "nvim-tree/nvim-web-devicons" },
},
}

View file

@ -0,0 +1,96 @@
{
"plugins": {
"blink.cmp": {
"rev": "451168851e8e2466bc97ee3e026c3dcb9141ce07",
"src": "https://github.com/saghen/blink.cmp"
},
"canola-collection": {
"rev": "888ee61c54873e0c57df07d35e38284e23bb978c",
"src": "https://github.com/barrettruth/canola-collection"
},
"canola.nvim": {
"rev": "4a0dd41ca39793342177b2cdb8e784243da5a936",
"src": "https://github.com/barrettruth/canola.nvim"
},
"cozybox.nvim": {
"rev": "be246810d74e3030cc5790685db3b9b8aacda5e3",
"src": "https://github.com/harivansh-afk/cozybox.nvim"
},
"diffs.nvim": {
"rev": "0cb16a0e2384f1d3dd6330f6ea517de8e07aa8e8",
"src": "https://github.com/barrettruth/diffs.nvim"
},
"flash.nvim": {
"rev": "fcea7ff883235d9024dc41e638f164a450c14ca2",
"src": "https://github.com/folke/flash.nvim"
},
"forge.nvim": {
"rev": "0dc433a32c1dac7bdfc313cf73070f03f27b2ef2",
"src": "https://github.com/barrettruth/forge.nvim"
},
"fzf-lua": {
"rev": "bde73a6886b607246095aa59f396de5e0d036890",
"src": "https://github.com/ibhagwan/fzf-lua"
},
"gitsigns.nvim": {
"rev": "50c205548d8b037b7ff6378fca6d21146f0b6161",
"src": "https://github.com/lewis6991/gitsigns.nvim"
},
"lualine.nvim": {
"rev": "47f91c416daef12db467145e16bed5bbfe00add8",
"src": "https://github.com/nvim-lualine/lualine.nvim"
},
"lz.n": {
"rev": "3a696418821fa8e4963a0a59dd1f8d40fedb6824",
"src": "https://github.com/lumen-oss/lz.n"
},
"nonicons.nvim": {
"rev": "2c5fad40a79d80338b49e6fbd3db9b2c1141a4ed",
"src": "https://github.com/barrettruth/nonicons.nvim"
},
"nvim-autopairs": {
"rev": "59bce2eef357189c3305e25bc6dd2d138c1683f5",
"src": "https://github.com/windwp/nvim-autopairs"
},
"nvim-lspconfig": {
"rev": "16812abf0e8d8175155f26143a8504e8253e92b0",
"src": "https://github.com/neovim/nvim-lspconfig"
},
"nvim-surround": {
"rev": "61319d4bd1c5e336e197defa15bd104c51f0fb29",
"src": "https://github.com/kylechui/nvim-surround"
},
"nvim-treesitter": {
"rev": "cf12346a3414fa1b06af75c79faebe7f76df080a",
"src": "https://github.com/nvim-treesitter/nvim-treesitter"
},
"nvim-treesitter-textobjects": {
"rev": "93d60a475f0b08a8eceb99255863977d3a25f310",
"src": "https://github.com/nvim-treesitter/nvim-treesitter-textobjects"
},
"nvim-ufo": {
"rev": "ab3eb124062422d276fae49e0dd63b3ad1062cfc",
"src": "https://github.com/kevinhwang91/nvim-ufo"
},
"nvim-web-devicons": {
"rev": "d7462543c9e366c0d196c7f67a945eaaf5d99414",
"src": "https://github.com/nvim-tree/nvim-web-devicons"
},
"pending.nvim": {
"rev": "e58cf6665b2d12cc63e1fd7a87169a9d2c20f7b5",
"src": "https://github.com/barrettruth/pending.nvim"
},
"preview.nvim": {
"rev": "ddf9b14c7f0fe00bb47833304625b648a97018a6",
"src": "https://github.com/barrettruth/preview.nvim"
},
"promise-async": {
"rev": "119e8961014c9bfaf1487bf3c2a393d254f337e2",
"src": "https://github.com/kevinhwang91/promise-async"
},
"vim-fugitive": {
"rev": "3b753cf8c6a4dcde6edee8827d464ba9b8c4a6f0",
"src": "https://github.com/tpope/vim-fugitive"
}
}
}

View file

@ -1,31 +1,46 @@
local api = vim.api
local augroup = api.nvim_create_augroup('UserAutocmds', { clear = true })
local augroup = api.nvim_create_augroup("UserAutocmds", { clear = true })
api.nvim_create_autocmd('TextYankPost', {
group = augroup,
callback = function()
vim.highlight.on_yank({ higroup = 'Visual', timeout = 200 })
end,
local function maybe_load_canola(bufnr)
local name = api.nvim_buf_get_name(bufnr)
if name == "" or vim.fn.isdirectory(name) == 0 then return end
pcall(vim.cmd, "silent keepalt Canola " .. vim.fn.fnameescape(name))
end
api.nvim_create_autocmd("TextYankPost", {
group = augroup,
callback = function() vim.highlight.on_yank { higroup = "Visual", timeout = 200 } end,
})
api.nvim_create_autocmd('BufReadPost', {
group = augroup,
callback = function()
if ({ gitcommit = true, gitrebase = true })[vim.bo.filetype] then
return
end
local mark = api.nvim_buf_get_mark(0, '"')
if mark[1] > 0 and mark[1] <= api.nvim_buf_line_count(0) then
pcall(api.nvim_win_set_cursor, 0, mark)
end
end,
api.nvim_create_autocmd("BufReadPost", {
group = augroup,
callback = function()
if ({ gitcommit = true, gitrebase = true })[vim.bo.filetype] then return end
local mark = api.nvim_buf_get_mark(0, '"')
if mark[1] > 0 and mark[1] <= api.nvim_buf_line_count(0) then pcall(api.nvim_win_set_cursor, 0, mark) end
end,
})
api.nvim_create_autocmd('VimResized', {
group = augroup,
callback = function()
local tab = vim.fn.tabpagenr()
vim.cmd('tabdo wincmd =')
vim.cmd('tabnext ' .. tab)
end,
api.nvim_create_autocmd("BufEnter", {
group = augroup,
nested = true,
callback = function(args)
if vim.v.vim_did_enter == 1 then maybe_load_canola(args.buf) end
end,
})
api.nvim_create_autocmd("VimEnter", {
group = augroup,
nested = true,
callback = function() maybe_load_canola(0) end,
})
api.nvim_create_autocmd("VimResized", {
group = augroup,
callback = function()
local tab = vim.fn.tabpagenr()
vim.cmd "tabdo wincmd ="
vim.cmd("tabnext " .. tab)
end,
})

View file

@ -0,0 +1,42 @@
vim.pack.add({
'https://github.com/tpope/vim-fugitive',
})
local function file_loc()
local root = vim.trim(vim.fn.system('git rev-parse --show-toplevel'))
if vim.v.shell_error ~= 0 or root == '' then
return nil
end
local path = vim.api.nvim_buf_get_name(0)
if path == '' or path:sub(1, #root + 1) ~= root .. '/' then
return nil
end
return ('%s:%d'):format(path:sub(#root + 2), vim.fn.line('.'))
end
local function gh_browse()
if vim.fn.executable('gh') ~= 1 then
vim.notify('gh CLI not found', vim.log.levels.WARN)
return
end
local loc = file_loc()
if loc then
vim.system({ 'gh', 'browse', loc })
else
vim.system({ 'gh', 'browse' })
end
end
map('n', '<C-g>', '<cmd>Git<cr><cmd>only<cr>')
map('n', '<leader>gg', '<cmd>Git<cr><cmd>only<cr>')
map('n', '<leader>gc', '<cmd>Git commit<cr>')
map('n', '<leader>gp', '<cmd>Git push<cr>')
map('n', '<leader>gl', '<cmd>Git pull<cr>')
map('n', '<leader>gb', '<cmd>Git blame<cr>')
map('n', '<leader>gd', '<cmd>Gvdiffsplit<cr>')
map('n', '<leader>gr', '<cmd>Gread<cr>')
map('n', '<leader>gw', '<cmd>Gwrite<cr>')
map({ 'n', 'v' }, '<leader>go', gh_browse)

View file

@ -1,21 +1,20 @@
map('n', '<leader>w', '<cmd>w<cr>')
map('n', '<leader>q', '<cmd>q<cr>')
map('n', '<C-g>', '<cmd>Git<cr><cmd>only<cr>')
map("n", "<leader>w", "<cmd>w<cr>")
map("n", "<leader>q", "<cmd>q<cr>")
map('n', '<Tab>', '<cmd>bnext<cr>')
map('n', '<S-Tab>', '<cmd>bprev<cr>')
map('n', '<leader>x', '<cmd>bdelete<cr>')
map('n', '<leader>b', '<cmd>enew<cr>')
map("n", "<Tab>", "<cmd>bnext<cr>")
map("n", "<S-Tab>", "<cmd>bprev<cr>")
map("n", "<leader>x", "<cmd>bdelete<cr>")
map("n", "<leader>b", "<cmd>enew<cr>")
map('n', '<C-h>', '<C-w>h')
map('n', '<C-j>', '<C-w>j')
map('n', '<C-k>', '<C-w>k')
map('n', '<C-l>', '<C-w>l')
map("n", "<C-h>", "<C-w>h")
map("n", "<C-j>", "<C-w>j")
map("n", "<C-k>", "<C-w>k")
map("n", "<C-l>", "<C-w>l")
map('n', 'J', 'mzJ`z')
map('x', 'x', '"_x')
map('x', 'p', '"_dP')
map('n', '<Esc>', '<cmd>nohlsearch<cr>')
map('n', '<leader>t', '<cmd>setlocal wrap!<cr>')
map("n", "J", "mzJ`z")
map("x", "x", '"_x')
map("x", "p", '"_dP')
map("n", "<Esc>", "<cmd>nohlsearch<cr>")
map("n", "<leader>t", "<cmd>setlocal wrap!<cr>")
map('t', '<Esc>', '<C-\\><C-n>')
map("t", "<Esc>", "<C-\\><C-n>")

60
flake.lock generated
View file

@ -76,6 +76,27 @@
"type": "github"
}
},
"flake-parts_2": {
"inputs": {
"nixpkgs-lib": [
"neovim-nightly",
"nixpkgs"
]
},
"locked": {
"lastModified": 1772408722,
"narHash": "sha256-rHuJtdcOjK7rAHpHphUb1iCvgkU3GpfvicLMwwnfMT0=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "f20dc5d9b8027381c474144ecabc9034d6a839a3",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"flake-utils": {
"inputs": {
"systems": "systems"
@ -153,6 +174,44 @@
"type": "github"
}
},
"neovim-nightly": {
"inputs": {
"flake-parts": "flake-parts_2",
"neovim-src": "neovim-src",
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1774915815,
"narHash": "sha256-LocQzkSjVS4G0AKMBiEIVdBKCNTMZXQFjQMWFId4Jpg=",
"owner": "nix-community",
"repo": "neovim-nightly-overlay",
"rev": "9001416dc5d0ca24c8e4b5a44bfe7cd6fbeb1dd1",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "neovim-nightly-overlay",
"type": "github"
}
},
"neovim-src": {
"flake": false,
"locked": {
"lastModified": 1774915197,
"narHash": "sha256-yor+eo8CVi7wBp7CjAMQnVoK+m197gsl7MvUzaqicns=",
"owner": "neovim",
"repo": "neovim",
"rev": "dbc4800dda2b0dc3290dc79955f857256e0694e2",
"type": "github"
},
"original": {
"owner": "neovim",
"repo": "neovim",
"type": "github"
}
},
"nix-darwin": {
"inputs": {
"nixpkgs": [
@ -264,6 +323,7 @@
"flake-parts": "flake-parts",
"googleworkspace-cli": "googleworkspace-cli",
"home-manager": "home-manager",
"neovim-nightly": "neovim-nightly",
"nix-darwin": "nix-darwin",
"nix-homebrew": "nix-homebrew",
"nixpkgs": "nixpkgs",

View file

@ -37,6 +37,11 @@
url = "github:nix-community/disko";
inputs.nixpkgs.follows = "nixpkgs";
};
neovim-nightly = {
url = "github:nix-community/neovim-nightly-overlay";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs =

View file

@ -8,10 +8,14 @@ let
nvimConfig = lib.cleanSourceWith {
src = ../config/nvim;
filter =
path: type: builtins.baseNameOf path != ".git" && builtins.baseNameOf path != "lazy-lock.json";
path: type:
let
baseName = builtins.baseNameOf path;
in
baseName != ".git" && baseName != "lazy-lock.json" && baseName != "nvim-pack-lock.json";
};
lazyLockSeed = ../config/nvim/lazy-lock.json;
lazyLockPath = "${config.xdg.stateHome}/nvim/lazy-lock.json";
packLockSeed = ../config/nvim/nvim-pack-lock.json;
packLockPath = "${config.xdg.stateHome}/nvim/nvim-pack-lock.json";
python = pkgs.writeShellScriptBin "python" ''
exec ${pkgs.python3}/bin/python3 "$@"
'';
@ -60,13 +64,16 @@ in
recursive = true;
};
home.activation.seedNvimLazyLock = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
xdg.configFile."nvim/nvim-pack-lock.json".source =
config.lib.file.mkOutOfStoreSymlink packLockPath;
home.activation.seedNvimPackLock = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
state_dir="${config.xdg.stateHome}/nvim"
lockfile="${lazyLockPath}"
lockfile="${packLockPath}"
if [ ! -e "$lockfile" ]; then
mkdir -p "$state_dir"
cp ${lazyLockSeed} "$lockfile"
cp ${packLockSeed} "$lockfile"
chmod u+w "$lockfile"
fi
'';

View file

@ -32,6 +32,10 @@
setopt localoptions noshwordsplit
unset prompt_pure_async_render_requested
prompt_pure_set_colors
_codex_pure_default_arrow=$prompt_pure_colors[git:arrow]
_codex_pure_default_success=$prompt_pure_colors[prompt:success]
typeset -g prompt_pure_git_branch_color=$prompt_pure_colors[git:branch]
[[ -n ''${prompt_pure_git_last_dirty_check_timestamp+x} ]] && prompt_pure_git_branch_color=$prompt_pure_colors[git:branch:cached]

View file

@ -9,6 +9,86 @@
}:
let
packageSets = import ../../lib/package-sets.nix { inherit inputs lib pkgs; };
sandboxAgentPackage = pkgs.callPackage ../../pkgs/sandbox-agent { };
sandboxAgentDir = "/home/${username}/.config/sandbox-agent";
sandboxAgentPath =
packageSets.core
++ packageSets.extras
++ [
pkgs.bubblewrap
pkgs.git
pkgs.nodejs
pkgs.pnpm
sandboxAgentPackage
];
sandboxAgentEnvCheck = pkgs.writeShellScript "sandbox-agent-env-check" ''
[ -f "${sandboxAgentDir}/agent.env" ] && [ -f "${sandboxAgentDir}/public.env" ]
'';
sandboxAgentWrapper = pkgs.writeShellScript "sandbox-agent-public" ''
set -euo pipefail
set -a
. "${sandboxAgentDir}/public.env"
. "${sandboxAgentDir}/agent.env"
set +a
exec sandbox-agent server \
--host 127.0.0.1 \
--port "''${SANDBOX_AGENT_PORT}" \
--token "''${SANDBOX_AGENT_TOKEN}"
'';
sandboxCorsProxy = pkgs.writeText "sandbox-agent-cors-proxy.mjs" ''
import http from "node:http";
const listenHost = "127.0.0.1";
const listenPort = 2468;
const targetHost = "127.0.0.1";
const targetPort = 2470;
function setCorsHeaders(headers, req) {
headers["access-control-allow-origin"] = "*";
headers["access-control-allow-methods"] = "GET,POST,PUT,PATCH,DELETE,OPTIONS";
headers["access-control-allow-headers"] =
req.headers["access-control-request-headers"] || "authorization,content-type";
headers["access-control-max-age"] = "86400";
return headers;
}
const server = http.createServer((req, res) => {
if (req.method === "OPTIONS") {
res.writeHead(204, setCorsHeaders({}, req));
res.end();
return;
}
const proxyReq = http.request(
{
host: targetHost,
port: targetPort,
method: req.method,
path: req.url,
headers: {
...req.headers,
host: `''${targetHost}:''${targetPort}`,
},
},
(proxyRes) => {
res.writeHead(
proxyRes.statusCode || 502,
setCorsHeaders({ ...proxyRes.headers }, req),
);
proxyRes.pipe(res);
},
);
proxyReq.on("error", () => {
res.writeHead(502, setCorsHeaders({ "content-type": "text/plain" }, req));
res.end("Upstream request failed");
});
req.pipe(proxyReq);
});
server.listen(listenPort, listenHost);
'';
in
{
imports = [
@ -103,6 +183,7 @@ in
pkgs.bubblewrap
pkgs.pnpm
pkgs.nodejs
sandboxAgentPackage
];
systemd.tmpfiles.rules = [
@ -122,7 +203,7 @@ in
recommendedTlsSettings = true;
clientMaxBodySize = "512m";
virtualHosts."sandbox.example.dev" = {
virtualHosts."netty.harivan.sh" = {
enableACME = true;
forceSSL = true;
locations."/".proxyPass = "http://127.0.0.1:2470";
@ -239,14 +320,17 @@ in
# --- Sandbox Agent (declarative systemd services) ---
systemd.services.sandbox-agent = {
description = "Sandbox Agent";
after = [ "network.target" ];
after = [ "network-online.target" ];
wants = [ "network-online.target" ];
wantedBy = [ "multi-user.target" ];
path = sandboxAgentPath;
serviceConfig = {
Type = "simple";
User = username;
Group = "users";
EnvironmentFile = "/home/${username}/.config/sandbox-agent/agent.env";
ExecStart = "/home/${username}/.local/bin/sandbox-agent";
WorkingDirectory = "/home/${username}";
ExecCondition = sandboxAgentEnvCheck;
ExecStart = sandboxAgentWrapper;
Restart = "on-failure";
RestartSec = 5;
};
@ -255,12 +339,15 @@ in
systemd.services.sandbox-cors-proxy = {
description = "Sandbox CORS Proxy";
after = [ "sandbox-agent.service" ];
requires = [ "sandbox-agent.service" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
Type = "simple";
User = username;
Group = "users";
ExecStart = "${pkgs.nodejs}/bin/node /home/${username}/.config/sandbox-agent/cors-proxy.js";
WorkingDirectory = "/home/${username}";
ExecCondition = sandboxAgentEnvCheck;
ExecStart = "${pkgs.nodejs}/bin/node ${sandboxCorsProxy}";
Restart = "on-failure";
RestartSec = 5;
};

View file

@ -46,6 +46,7 @@ in
);
nixpkgs.config.allowUnfree = true;
nixpkgs.overlays = [ inputs.neovim-nightly.overlays.default ];
programs.zsh.enable = true;
environment.shells = [ pkgs.zsh ];

View file

@ -11,19 +11,16 @@
taps = [
"humanlayer/humanlayer"
"gromgit/fuse"
"mutagen-io/mutagen"
];
brews = [
"gromgit/fuse/sshfs-mac"
"mutagen-io/mutagen/mutagen"
];
casks = [
"cap"
"karabiner-elements"
"macfuse"
"rectangle"
"raycast"
"riptide-beta"

3832
pkgs/sandbox-agent/Cargo.lock generated Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,38 @@
{
lib,
fetchFromGitHub,
rustPlatform,
}:
rustPlatform.buildRustPackage {
pname = "sandbox-agent";
version = "0.5.0-rc.1";
src = fetchFromGitHub {
owner = "rivet-dev";
repo = "sandbox-agent";
rev = "v0.5.0-rc.1";
hash = "sha256-oeOpWjaQlQZZzwQGts4yJgL3STDCd3Hz2qbOJ4N2HBM=";
};
cargoLock.lockFile = ./Cargo.lock;
prePatch = ''
cp ${./Cargo.lock} Cargo.lock
'';
cargoBuildFlags = [
"-p"
"sandbox-agent"
];
env.SANDBOX_AGENT_SKIP_INSPECTOR = "1";
doCheck = false;
meta = with lib; {
description = "Universal API for coding agents in sandboxes";
homepage = "https://sandboxagent.dev";
license = licenses.asl20;
mainProgram = "sandbox-agent";
platforms = platforms.unix;
};
}