Initial rewrite
Signed-off-by: Timothy Pidashev <mail@timmypidashev.dev>
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
local map = vim.keymap.set
|
||||
|
||||
-- Reload config
|
||||
map("n", "<C-r>", "<cmd>source %<CR>", { desc = "Source current file" })
|
||||
|
||||
-- Save
|
||||
map({ "n", "i" }, "<C-s>", "<cmd>w<CR>", { desc = "Save" })
|
||||
|
||||
-- Clear search highlight
|
||||
map("n", "<Esc>", "<cmd>nohlsearch<CR>")
|
||||
@@ -0,0 +1,24 @@
|
||||
return {
|
||||
-- nvim / scripting
|
||||
"lua", "luadoc", "vim", "vimdoc", "query",
|
||||
"bash", "fish",
|
||||
-- web
|
||||
"javascript", "typescript", "tsx", "jsdoc",
|
||||
"html", "css", "scss",
|
||||
-- backend
|
||||
"python",
|
||||
"go", "gomod", "gosum", "gowork",
|
||||
"rust", "c", "cpp", "java",
|
||||
"apex", "soql",
|
||||
-- templating
|
||||
"templ",
|
||||
-- docs / data
|
||||
"markdown", "markdown_inline",
|
||||
"json", "yaml", "toml", "xml",
|
||||
-- infra / tooling
|
||||
"dockerfile", "make", "cmake", "sql",
|
||||
-- git
|
||||
"gitcommit", "gitignore", "git_config", "gitattributes", "git_rebase", "diff",
|
||||
-- misc
|
||||
"regex",
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
local opt = vim.o
|
||||
|
||||
-- Indent
|
||||
opt.tabstop = 2
|
||||
opt.softtabstop = 2
|
||||
opt.shiftwidth = 2
|
||||
opt.expandtab = true
|
||||
opt.autoindent = true
|
||||
|
||||
-- UI
|
||||
opt.number = true
|
||||
opt.relativenumber = true
|
||||
opt.termguicolors = true
|
||||
opt.laststatus = 3
|
||||
opt.wrap = false
|
||||
opt.signcolumn = "yes:1"
|
||||
opt.numberwidth = 2
|
||||
opt.fillchars = "eob: " -- hide ~ markers on end-of-buffer lines
|
||||
|
||||
-- Search
|
||||
opt.ignorecase = true
|
||||
opt.smartcase = true
|
||||
|
||||
-- Editing
|
||||
opt.undofile = true
|
||||
opt.backupcopy = "yes"
|
||||
|
||||
-- Neovide
|
||||
if vim.g.neovide then
|
||||
vim.opt.guifont = { "ComicCode Nerd Font", ":h16" }
|
||||
vim.g.neovide_scale_factor = 1.0
|
||||
vim.g.neovide_scroll_animation_length = 0.3
|
||||
end
|
||||
@@ -0,0 +1,75 @@
|
||||
-- Native 0.12 package manager (vim.pack)
|
||||
vim.pack.add({
|
||||
{ src = "https://git.timmypidashev.dev/timmypidashev/darkbox.nvim" },
|
||||
{ src = "https://github.com/nvim-tree/nvim-web-devicons" },
|
||||
{ src = "https://github.com/nvim-lualine/lualine.nvim" },
|
||||
{ src = "https://github.com/lewis6991/gitsigns.nvim" },
|
||||
{ src = "https://github.com/nvim-treesitter/nvim-treesitter", version = "main" },
|
||||
{ src = "https://github.com/mason-org/mason.nvim" },
|
||||
{ src = "https://github.com/WhoIsSethDaniel/mason-tool-installer.nvim" },
|
||||
{ src = "https://github.com/wakatime/vim-wakatime" },
|
||||
{ src = "https://github.com/nvim-lua/plenary.nvim" },
|
||||
{ src = "https://github.com/ThePrimeagen/harpoon", version = "harpoon2" },
|
||||
{ src = "https://github.com/romgrk/barbar.nvim" },
|
||||
{ src = "https://github.com/stevearc/oil.nvim" },
|
||||
|
||||
-- Completion
|
||||
{ src = "https://github.com/saghen/blink.cmp", version = vim.version.range("1") },
|
||||
|
||||
-- Picker
|
||||
{ src = "https://github.com/ibhagwan/fzf-lua" },
|
||||
|
||||
-- Formatter / Linter
|
||||
{ src = "https://github.com/stevearc/conform.nvim" },
|
||||
{ src = "https://github.com/mfussenegger/nvim-lint" },
|
||||
|
||||
-- Quality of life
|
||||
{ src = "https://github.com/folke/which-key.nvim" },
|
||||
{ src = "https://github.com/windwp/nvim-autopairs" },
|
||||
{ src = "https://github.com/kylechui/nvim-surround" },
|
||||
{ src = "https://github.com/akinsho/toggleterm.nvim" },
|
||||
{ src = "https://github.com/mbbill/undotree" },
|
||||
|
||||
-- UI
|
||||
{ src = "https://github.com/MunifTanjim/nui.nvim" },
|
||||
{ src = "https://github.com/rcarriga/nvim-notify" },
|
||||
{ src = "https://github.com/folke/noice.nvim" },
|
||||
{ src = "https://github.com/nvim-mini/mini.indentscope" },
|
||||
{ src = "https://github.com/nvim-mini/mini.animate" },
|
||||
|
||||
-- Fancy
|
||||
{ src = "https://github.com/zeybek/camouflage.nvim" },
|
||||
{ src = "https://github.com/Owen-Dechow/videre.nvim" },
|
||||
{ src = "https://github.com/rachartier/tiny-glimmer.nvim" },
|
||||
{ src = "https://github.com/MeanderingProgrammer/render-markdown.nvim" },
|
||||
})
|
||||
|
||||
-- Local dev plugins
|
||||
vim.opt.rtp:prepend(vim.fn.expand("~/Projects/timmypidashev/verse.nvim"))
|
||||
|
||||
require("timmypidashev.plugins.darkbox")
|
||||
require("timmypidashev.plugins.lualine")
|
||||
require("timmypidashev.plugins.gitsigns")
|
||||
require("timmypidashev.plugins.treesitter")
|
||||
require("timmypidashev.plugins.mason")
|
||||
require("timmypidashev.plugins.blink")
|
||||
require("timmypidashev.plugins.lsp")
|
||||
require("timmypidashev.plugins.starter")
|
||||
require("timmypidashev.plugins.harpoon")
|
||||
require("timmypidashev.plugins.barbar")
|
||||
require("timmypidashev.plugins.oil")
|
||||
require("timmypidashev.plugins.fzf")
|
||||
require("timmypidashev.plugins.conform")
|
||||
require("timmypidashev.plugins.lint")
|
||||
require("timmypidashev.plugins.whichkey")
|
||||
require("timmypidashev.plugins.autopairs")
|
||||
require("timmypidashev.plugins.surround")
|
||||
require("timmypidashev.plugins.toggleterm")
|
||||
require("timmypidashev.plugins.undotree")
|
||||
require("timmypidashev.plugins.noice")
|
||||
require("timmypidashev.plugins.indentscope")
|
||||
-- require("timmypidashev.plugins.animate") -- disabled: scroll/resize jank
|
||||
require("timmypidashev.plugins.camouflage")
|
||||
require("timmypidashev.plugins.videre")
|
||||
require("timmypidashev.plugins.tinyglimmer")
|
||||
require("timmypidashev.plugins.render-markdown")
|
||||
@@ -0,0 +1,14 @@
|
||||
-- Disabled: mini.animate was causing scroll lag and general jank.
|
||||
-- Re-enable by uncommenting and requiring setup below.
|
||||
--
|
||||
-- local animate = require("mini.animate")
|
||||
-- animate.setup({
|
||||
-- cursor = {
|
||||
-- enable = true,
|
||||
-- timing = animate.gen_timing.linear({ duration = 80, unit = "total" }),
|
||||
-- },
|
||||
-- scroll = { enable = false },
|
||||
-- resize = { enable = true },
|
||||
-- open = { enable = false },
|
||||
-- close = { enable = false },
|
||||
-- })
|
||||
@@ -0,0 +1,3 @@
|
||||
require("nvim-autopairs").setup({
|
||||
check_ts = true,
|
||||
})
|
||||
@@ -0,0 +1,95 @@
|
||||
vim.g.barbar_auto_setup = false
|
||||
|
||||
require("barbar").setup({
|
||||
animation = true,
|
||||
auto_hide = false,
|
||||
tabpages = true,
|
||||
exclude_ft = { "dashboard", "oil" },
|
||||
icons = {
|
||||
buffer_index = true,
|
||||
button = false, -- hide the close × on tabs
|
||||
filetype = { enabled = true },
|
||||
-- Barbar's default preset uses a different separator glyph for inactive
|
||||
-- tabs (▎ vs │), which visibly shifts the pipe when switching tabs.
|
||||
-- Explicitly set all states to the same glyph.
|
||||
separator = { left = "│", right = "" },
|
||||
inactive = { separator = { left = "│", right = "" } },
|
||||
visible = { separator = { left = "│", right = "" } },
|
||||
current = { separator = { left = "│", right = "" } },
|
||||
separator_at_end = false,
|
||||
modified = { button = "●" },
|
||||
pinned = { button = "", filename = true },
|
||||
},
|
||||
})
|
||||
|
||||
-- Personal barbar highlight tweaks on top of darkbox:
|
||||
-- 1. All separator pipes share one muted color (matches WinSeparator).
|
||||
-- 2. Active tab's index number is green so the selected tab pops.
|
||||
local function barbar_highlights()
|
||||
local bg = vim.api.nvim_get_hl(0, { name = "Normal", link = false }).bg
|
||||
local win_sep = vim.api.nvim_get_hl(0, { name = "WinSeparator", link = false })
|
||||
local sep_fg = win_sep and win_sep.fg
|
||||
|
||||
if sep_fg then
|
||||
for _, group in ipairs({
|
||||
"BufferCurrentSign",
|
||||
"BufferVisibleSign",
|
||||
"BufferInactiveSign",
|
||||
"BufferAlternateSign",
|
||||
}) do
|
||||
vim.api.nvim_set_hl(0, group, { fg = sep_fg, bg = bg })
|
||||
end
|
||||
end
|
||||
|
||||
local green = vim.api.nvim_get_hl(0, { name = "DarkboxGreen", link = false }).fg
|
||||
if green then
|
||||
vim.api.nvim_set_hl(0, "BufferCurrentIndex", { fg = green, bg = bg, bold = true })
|
||||
end
|
||||
end
|
||||
|
||||
barbar_highlights()
|
||||
vim.api.nvim_create_autocmd("ColorScheme", {
|
||||
callback = barbar_highlights,
|
||||
})
|
||||
|
||||
local map = vim.keymap.set
|
||||
local opts = { silent = true }
|
||||
|
||||
-- If the current window is the oil sidebar, refocus the main editor window
|
||||
-- first. Otherwise barbar commands (BufferGoto, BufferClose, etc.) act on the
|
||||
-- oil window instead of the file area.
|
||||
local function focus_main()
|
||||
if vim.bo.filetype ~= "oil" then return end
|
||||
for _, win in ipairs(vim.api.nvim_tabpage_list_wins(0)) do
|
||||
local buf = vim.api.nvim_win_get_buf(win)
|
||||
if vim.bo[buf].filetype ~= "oil" then
|
||||
vim.api.nvim_set_current_win(win)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function barbar_cmd(cmd)
|
||||
return function()
|
||||
focus_main()
|
||||
vim.cmd(cmd)
|
||||
end
|
||||
end
|
||||
|
||||
-- Leader + N → jump to tab N
|
||||
for i = 1, 9 do
|
||||
map("n", "<leader>" .. i, barbar_cmd("BufferGoto " .. i), opts)
|
||||
end
|
||||
map("n", "<leader>0", barbar_cmd("BufferLast"), opts)
|
||||
|
||||
-- Navigation
|
||||
map("n", "<leader>,", barbar_cmd("BufferPrevious"), opts)
|
||||
map("n", "<leader>.", barbar_cmd("BufferNext"), opts)
|
||||
|
||||
-- Reorder
|
||||
map("n", "<leader><", barbar_cmd("BufferMovePrevious"), opts)
|
||||
map("n", "<leader>>", barbar_cmd("BufferMoveNext"), opts)
|
||||
|
||||
-- Close
|
||||
map("n", "<leader>c", barbar_cmd("BufferClose"), opts)
|
||||
map("n", "<leader>bp", barbar_cmd("BufferPin"), opts)
|
||||
@@ -0,0 +1,33 @@
|
||||
require("blink.cmp").setup({
|
||||
keymap = { preset = "super-tab" },
|
||||
appearance = { nerd_font_variant = "mono" },
|
||||
sources = {
|
||||
default = { "lsp", "path", "snippets", "buffer" },
|
||||
},
|
||||
completion = {
|
||||
menu = { border = "single" },
|
||||
documentation = {
|
||||
auto_show = true,
|
||||
auto_show_delay_ms = 200,
|
||||
window = { border = "single" },
|
||||
},
|
||||
ghost_text = { enabled = true },
|
||||
},
|
||||
signature = {
|
||||
enabled = true,
|
||||
window = { border = "single" },
|
||||
},
|
||||
fuzzy = { implementation = "lua" },
|
||||
})
|
||||
|
||||
-- Personal preference: darkbox links BlinkCmpMenuSelection to PmenuSel (blue),
|
||||
-- which is too bright. Re-bind to a dim background_2 stripe.
|
||||
local function dim_selection()
|
||||
local bg2 = vim.api.nvim_get_hl(0, { name = "DarkboxBg2", link = false }).fg
|
||||
if bg2 then
|
||||
vim.api.nvim_set_hl(0, "BlinkCmpMenuSelection", { bg = bg2, bold = true })
|
||||
end
|
||||
end
|
||||
|
||||
dim_selection()
|
||||
vim.api.nvim_create_autocmd("ColorScheme", { callback = dim_selection })
|
||||
@@ -0,0 +1,10 @@
|
||||
require("camouflage").setup({
|
||||
enabled = true,
|
||||
mask_char = "*",
|
||||
-- Override the default pattern list. Defaults mask *.yaml, *.json, *.sh,
|
||||
-- *.toml, *.properties etc. which grabs false positives like Taskfile.yml
|
||||
-- and package-lock.json. Only mask real env files.
|
||||
patterns = {
|
||||
{ file_pattern = { ".env*", "*.env", ".envrc" }, parser = "env" },
|
||||
},
|
||||
})
|
||||
@@ -0,0 +1,28 @@
|
||||
require("conform").setup({
|
||||
formatters_by_ft = {
|
||||
lua = { "stylua" },
|
||||
javascript = { "prettierd", "prettier", stop_after_first = true },
|
||||
typescript = { "prettierd", "prettier", stop_after_first = true },
|
||||
javascriptreact = { "prettierd", "prettier", stop_after_first = true },
|
||||
typescriptreact = { "prettierd", "prettier", stop_after_first = true },
|
||||
json = { "prettierd" },
|
||||
yaml = { "prettierd" },
|
||||
markdown = { "prettierd" },
|
||||
html = { "prettierd" },
|
||||
css = { "prettierd" },
|
||||
scss = { "prettierd" },
|
||||
go = { "goimports", "gofumpt" },
|
||||
python = { "ruff_organize_imports", "ruff_format" },
|
||||
sh = { "shfmt" },
|
||||
bash = { "shfmt" },
|
||||
templ = { "templ" },
|
||||
},
|
||||
format_on_save = {
|
||||
timeout_ms = 1500,
|
||||
lsp_format = "fallback",
|
||||
},
|
||||
})
|
||||
|
||||
vim.keymap.set({ "n", "v" }, "<leader>fm", function()
|
||||
require("conform").format({ async = true, lsp_format = "fallback" })
|
||||
end, { desc = "Format buffer" })
|
||||
@@ -0,0 +1,4 @@
|
||||
require("darkbox").setup({
|
||||
contrast = "retro",
|
||||
})
|
||||
vim.cmd.colorscheme("darkbox")
|
||||
@@ -0,0 +1,17 @@
|
||||
local fzf = require("fzf-lua")
|
||||
fzf.setup({
|
||||
winopts = { border = "rounded", preview = { border = "rounded" } },
|
||||
})
|
||||
|
||||
local map = vim.keymap.set
|
||||
map("n", "<leader>ff", fzf.files, { desc = "Find files" })
|
||||
map("n", "<leader>fg", fzf.live_grep, { desc = "Live grep" })
|
||||
map("n", "<leader>fb", fzf.buffers, { desc = "Buffers" })
|
||||
map("n", "<leader>fh", fzf.helptags, { desc = "Help tags" })
|
||||
map("n", "<leader>fk", fzf.keymaps, { desc = "Keymaps" })
|
||||
map("n", "<leader>fs", fzf.lsp_document_symbols, { desc = "Document symbols" })
|
||||
map("n", "<leader>fS", fzf.lsp_workspace_symbols, { desc = "Workspace symbols" })
|
||||
map("n", "<leader>fd", fzf.diagnostics_document, { desc = "Diagnostics (buffer)" })
|
||||
map("n", "<leader>fD", fzf.diagnostics_workspace, { desc = "Diagnostics (workspace)" })
|
||||
map("n", "<leader>fr", fzf.resume, { desc = "Resume last picker" })
|
||||
map("n", "<leader>fo", fzf.oldfiles, { desc = "Recent files" })
|
||||
@@ -0,0 +1,13 @@
|
||||
require("gitsigns").setup({
|
||||
signs = {
|
||||
add = { text = "+" },
|
||||
change = { text = "~" },
|
||||
delete = { text = "_" },
|
||||
topdelete = { text = "‾" },
|
||||
changedelete = { text = "~" },
|
||||
untracked = { text = "+" },
|
||||
},
|
||||
signs_staged_enable = false, -- don't distinguish staged vs unstaged in signcolumn
|
||||
signcolumn = true,
|
||||
attach_to_untracked = true,
|
||||
})
|
||||
@@ -0,0 +1,15 @@
|
||||
local harpoon = require("harpoon")
|
||||
harpoon:setup()
|
||||
|
||||
local map = vim.keymap.set
|
||||
|
||||
map("n", "<leader>a", function() harpoon:list():add() end, { desc = "Harpoon add file" })
|
||||
map("n", "<C-e>", function() harpoon.ui:toggle_quick_menu(harpoon:list()) end, { desc = "Harpoon menu" })
|
||||
|
||||
map("n", "<C-1>", function() harpoon:list():select(1) end, { desc = "Harpoon slot 1" })
|
||||
map("n", "<C-2>", function() harpoon:list():select(2) end, { desc = "Harpoon slot 2" })
|
||||
map("n", "<C-3>", function() harpoon:list():select(3) end, { desc = "Harpoon slot 3" })
|
||||
map("n", "<C-4>", function() harpoon:list():select(4) end, { desc = "Harpoon slot 4" })
|
||||
|
||||
map("n", "<C-S-N>", function() harpoon:list():next() end, { desc = "Harpoon next" })
|
||||
map("n", "<C-S-P>", function() harpoon:list():prev() end, { desc = "Harpoon prev" })
|
||||
@@ -0,0 +1,13 @@
|
||||
require("mini.indentscope").setup({
|
||||
symbol = "│",
|
||||
draw = {
|
||||
delay = 50,
|
||||
animation = require("mini.indentscope").gen_animation.none(),
|
||||
},
|
||||
options = { try_as_border = true },
|
||||
})
|
||||
|
||||
vim.api.nvim_create_autocmd("FileType", {
|
||||
pattern = { "dashboard", "oil", "help", "man", "ministarter", "lazy", "mason", "notify" },
|
||||
callback = function() vim.b.miniindentscope_disable = true end,
|
||||
})
|
||||
@@ -0,0 +1,18 @@
|
||||
local lint = require("lint")
|
||||
|
||||
lint.linters_by_ft = {
|
||||
javascript = { "eslint_d" },
|
||||
typescript = { "eslint_d" },
|
||||
javascriptreact = { "eslint_d" },
|
||||
typescriptreact = { "eslint_d" },
|
||||
python = { "ruff" },
|
||||
sh = { "shellcheck" },
|
||||
bash = { "shellcheck" },
|
||||
markdown = { "markdownlint-cli2" },
|
||||
}
|
||||
|
||||
vim.api.nvim_create_autocmd({ "BufWritePost", "InsertLeave" }, {
|
||||
callback = function() lint.try_lint() end,
|
||||
})
|
||||
|
||||
vim.keymap.set("n", "<leader>l", function() lint.try_lint() end, { desc = "Lint buffer" })
|
||||
@@ -0,0 +1,79 @@
|
||||
vim.filetype.add({
|
||||
extension = {
|
||||
cls = "apex",
|
||||
trigger = "apex",
|
||||
apex = "apex",
|
||||
},
|
||||
})
|
||||
|
||||
-- Advertise blink completion capabilities to all servers
|
||||
vim.lsp.config("*", {
|
||||
capabilities = require("blink.cmp").get_lsp_capabilities(),
|
||||
})
|
||||
|
||||
vim.lsp.enable({
|
||||
"lua_ls",
|
||||
"ts_ls",
|
||||
"pyright",
|
||||
"gopls",
|
||||
"marksman",
|
||||
"templ",
|
||||
"html",
|
||||
"cssls",
|
||||
"jsonls",
|
||||
"yamlls",
|
||||
"taplo",
|
||||
"bashls",
|
||||
"apex_ls",
|
||||
"htmx",
|
||||
})
|
||||
|
||||
vim.diagnostic.config({
|
||||
virtual_text = true,
|
||||
signs = {
|
||||
text = {
|
||||
[vim.diagnostic.severity.ERROR] = "e",
|
||||
[vim.diagnostic.severity.WARN] = "w",
|
||||
[vim.diagnostic.severity.INFO] = "i",
|
||||
[vim.diagnostic.severity.HINT] = "h",
|
||||
},
|
||||
},
|
||||
underline = true,
|
||||
update_in_insert = false,
|
||||
severity_sort = true,
|
||||
float = { border = "single" },
|
||||
})
|
||||
|
||||
-- Give LSP hover/signature/rename floats the same dim border + black bg
|
||||
-- everything else uses.
|
||||
vim.lsp.buf.hover = (function(orig)
|
||||
return function(opts)
|
||||
opts = opts or {}
|
||||
opts.border = opts.border or "single"
|
||||
return orig(opts)
|
||||
end
|
||||
end)(vim.lsp.buf.hover)
|
||||
|
||||
vim.lsp.buf.signature_help = (function(orig)
|
||||
return function(opts)
|
||||
opts = opts or {}
|
||||
opts.border = opts.border or "single"
|
||||
return orig(opts)
|
||||
end
|
||||
end)(vim.lsp.buf.signature_help)
|
||||
|
||||
vim.api.nvim_create_autocmd("LspAttach", {
|
||||
callback = function(ev)
|
||||
local opts = { buffer = ev.buf }
|
||||
local map = vim.keymap.set
|
||||
map("n", "gd", vim.lsp.buf.definition, opts)
|
||||
map("n", "gD", vim.lsp.buf.declaration, opts)
|
||||
map("n", "gr", vim.lsp.buf.references, opts)
|
||||
map("n", "gi", vim.lsp.buf.implementation, opts)
|
||||
map("n", "K", vim.lsp.buf.hover, opts)
|
||||
map("n", "<leader>rn", vim.lsp.buf.rename, opts)
|
||||
map("n", "<leader>ca", vim.lsp.buf.code_action, opts)
|
||||
map("n", "[d", function() vim.diagnostic.jump({ count = -1, float = true }) end, opts)
|
||||
map("n", "]d", function() vim.diagnostic.jump({ count = 1, float = true }) end, opts)
|
||||
end,
|
||||
})
|
||||
@@ -0,0 +1,67 @@
|
||||
-- Custom lualine theme: pure black backgrounds everywhere, only the mode
|
||||
-- indicator (section `a`) gets a colored accent. Colors pulled from darkbox's
|
||||
-- retro palette so the statusline stays in sync with the editor.
|
||||
local bg = "#000000"
|
||||
local fg = "#bdae93" -- retro_foreground
|
||||
local dim = "#a89984" -- foreground_4
|
||||
local mode_colors = {
|
||||
normal = "#689d6a", -- retro_aqua
|
||||
insert = "#458588", -- retro_blue
|
||||
visual = "#b16286", -- retro_purple
|
||||
replace = "#cc241d", -- retro_red
|
||||
command = "#d79921", -- retro_yellow
|
||||
}
|
||||
|
||||
-- Mode indicator: colored capital letters, no block background.
|
||||
local function mode_section(color)
|
||||
return { fg = color, bg = bg, gui = "bold" }
|
||||
end
|
||||
|
||||
local darkbox_theme = {
|
||||
normal = {
|
||||
a = mode_section(mode_colors.normal),
|
||||
b = { fg = fg, bg = bg },
|
||||
c = { fg = fg, bg = bg },
|
||||
},
|
||||
insert = { a = mode_section(mode_colors.insert) },
|
||||
visual = { a = mode_section(mode_colors.visual) },
|
||||
replace = { a = mode_section(mode_colors.replace) },
|
||||
command = { a = mode_section(mode_colors.command) },
|
||||
inactive = {
|
||||
a = { fg = dim, bg = bg, gui = "bold" },
|
||||
b = { fg = dim, bg = bg },
|
||||
c = { fg = dim, bg = bg },
|
||||
},
|
||||
}
|
||||
|
||||
require("lualine").setup({
|
||||
options = {
|
||||
icons_enabled = true,
|
||||
theme = darkbox_theme,
|
||||
component_separators = { left = "", right = "" },
|
||||
section_separators = { left = "", right = "" },
|
||||
globalstatus = true,
|
||||
always_divide_middle = true,
|
||||
refresh = {
|
||||
statusline = 1000,
|
||||
tabline = 1000,
|
||||
winbar = 1000,
|
||||
},
|
||||
},
|
||||
sections = {
|
||||
lualine_a = { "mode" },
|
||||
lualine_b = { "diff", "diagnostics" },
|
||||
lualine_c = {},
|
||||
lualine_x = {},
|
||||
lualine_y = {},
|
||||
lualine_z = { "branch" },
|
||||
},
|
||||
inactive_sections = {
|
||||
lualine_a = {},
|
||||
lualine_b = {},
|
||||
lualine_c = { "filename" },
|
||||
lualine_x = { "location", "encoding", "fileformat", "filetype" },
|
||||
lualine_y = {},
|
||||
lualine_z = { "progress" },
|
||||
},
|
||||
})
|
||||
@@ -0,0 +1,45 @@
|
||||
require("mason").setup({
|
||||
ui = {
|
||||
border = "rounded",
|
||||
icons = {
|
||||
package_installed = "✓",
|
||||
package_pending = "➜",
|
||||
package_uninstalled = "✗",
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
require("mason-tool-installer").setup({
|
||||
ensure_installed = {
|
||||
-- LSP servers (mason package names)
|
||||
"lua-language-server",
|
||||
"typescript-language-server",
|
||||
"pyright",
|
||||
"gopls",
|
||||
"marksman",
|
||||
"templ",
|
||||
"html-lsp",
|
||||
"css-lsp",
|
||||
"json-lsp",
|
||||
"yaml-language-server",
|
||||
"taplo",
|
||||
"bash-language-server",
|
||||
"htmx-lsp",
|
||||
-- Apex LSP not in mason registry — install JAR manually, set APEX_JAR env
|
||||
|
||||
-- Formatters
|
||||
"stylua",
|
||||
"prettierd",
|
||||
"gofumpt",
|
||||
"goimports",
|
||||
"shfmt",
|
||||
|
||||
-- Linters
|
||||
"eslint_d",
|
||||
"ruff",
|
||||
"shellcheck",
|
||||
"markdownlint-cli2",
|
||||
},
|
||||
auto_update = false,
|
||||
run_on_start = true,
|
||||
})
|
||||
@@ -0,0 +1,29 @@
|
||||
require("notify").setup({
|
||||
background_colour = "#000000",
|
||||
render = "compact",
|
||||
stages = "fade",
|
||||
timeout = 2500,
|
||||
})
|
||||
vim.notify = require("notify")
|
||||
|
||||
require("noice").setup({
|
||||
cmdline = {
|
||||
view = "cmdline", -- classic bottom cmdline instead of floating popup
|
||||
},
|
||||
lsp = {
|
||||
override = {
|
||||
["vim.lsp.util.convert_input_to_markdown_lines"] = true,
|
||||
["vim.lsp.util.stylize_markdown"] = true,
|
||||
["cmp.entry.get_documentation"] = true,
|
||||
},
|
||||
signature = { enabled = false }, -- blink handles this
|
||||
hover = { enabled = true },
|
||||
},
|
||||
presets = {
|
||||
bottom_search = true,
|
||||
command_palette = false, -- keep cmdline at the bottom, not floating
|
||||
long_message_to_split = true,
|
||||
inc_rename = false,
|
||||
lsp_doc_border = true,
|
||||
},
|
||||
})
|
||||
@@ -0,0 +1,137 @@
|
||||
require("oil").setup({
|
||||
default_file_explorer = true,
|
||||
delete_to_trash = true,
|
||||
skip_confirm_for_simple_edits = false,
|
||||
view_options = {
|
||||
show_hidden = true,
|
||||
},
|
||||
keymaps = {
|
||||
["g?"] = "actions.show_help",
|
||||
["<CR>"] = {
|
||||
desc = "Open in main window if sidebar, else select",
|
||||
callback = function()
|
||||
local oil = require("oil")
|
||||
local entry = oil.get_cursor_entry()
|
||||
if not entry then return end
|
||||
|
||||
-- If this oil window isn't a sidebar, use default behavior.
|
||||
if not vim.wo.winfixwidth then
|
||||
oil.select()
|
||||
return
|
||||
end
|
||||
|
||||
-- Directory: navigate within sidebar.
|
||||
if entry.type == "directory" then
|
||||
oil.select()
|
||||
return
|
||||
end
|
||||
|
||||
-- File: find a non-oil window to open in.
|
||||
local main_win
|
||||
for _, w in ipairs(vim.api.nvim_tabpage_list_wins(0)) do
|
||||
local b = vim.api.nvim_win_get_buf(w)
|
||||
if vim.bo[b].filetype ~= "oil" then
|
||||
main_win = w
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
local path = oil.get_current_dir() .. entry.name
|
||||
if main_win then
|
||||
vim.api.nvim_set_current_win(main_win)
|
||||
vim.cmd("edit " .. vim.fn.fnameescape(path))
|
||||
else
|
||||
vim.cmd("rightbelow vsplit " .. vim.fn.fnameescape(path))
|
||||
end
|
||||
end,
|
||||
},
|
||||
["<C-s>"] = { "actions.select", opts = { vertical = true } },
|
||||
["<C-h>"] = { "actions.select", opts = { horizontal = true } },
|
||||
["<C-t>"] = { "actions.select", opts = { tab = true } },
|
||||
["<C-p>"] = "actions.preview",
|
||||
["<C-c>"] = "actions.close",
|
||||
["<C-r>"] = "actions.refresh",
|
||||
["-"] = "actions.parent",
|
||||
["_"] = "actions.open_cwd",
|
||||
["`"] = "actions.cd",
|
||||
["~"] = { "actions.cd", opts = { scope = "tab" } },
|
||||
["gs"] = "actions.change_sort",
|
||||
["gx"] = "actions.open_external",
|
||||
["g."] = "actions.toggle_hidden",
|
||||
["g\\"] = "actions.toggle_trash",
|
||||
},
|
||||
use_default_keymaps = false,
|
||||
})
|
||||
|
||||
local SIDEBAR_WIDTH = 30
|
||||
|
||||
-- Fish-style shortened cwd: ~/P/t/neovimrc
|
||||
local function fish_cwd()
|
||||
local cwd = vim.fn.getcwd()
|
||||
local home = vim.env.HOME or ""
|
||||
if home ~= "" and cwd:sub(1, #home) == home then
|
||||
cwd = "~" .. cwd:sub(#home + 1)
|
||||
end
|
||||
local parts = vim.split(cwd, "/", { plain = true })
|
||||
for i = 1, #parts - 1 do
|
||||
local p = parts[i]
|
||||
if p ~= "" and p ~= "~" then
|
||||
parts[i] = p:sub(1, 1)
|
||||
end
|
||||
end
|
||||
return table.concat(parts, "/")
|
||||
end
|
||||
|
||||
local function find_sidebar()
|
||||
for _, win in ipairs(vim.api.nvim_list_wins()) do
|
||||
local buf = vim.api.nvim_win_get_buf(win)
|
||||
if vim.bo[buf].filetype == "oil" and vim.api.nvim_win_get_config(win).relative == "" then
|
||||
return win
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function set_offset(width)
|
||||
local ok, api = pcall(require, "barbar.api")
|
||||
if ok then api.set_offset(width, fish_cwd()) end
|
||||
end
|
||||
|
||||
local function open_sidebar()
|
||||
local existing = find_sidebar()
|
||||
if existing then
|
||||
vim.api.nvim_set_current_win(existing)
|
||||
return
|
||||
end
|
||||
-- Suppress redraw so we don't flash the parent window's buffer in the new
|
||||
-- split before :Oil takes over.
|
||||
local save_lazyredraw = vim.o.lazyredraw
|
||||
vim.o.lazyredraw = true
|
||||
vim.cmd("topleft vsplit | vertical resize " .. SIDEBAR_WIDTH .. " | Oil")
|
||||
vim.wo.number = false
|
||||
vim.wo.relativenumber = false
|
||||
vim.wo.signcolumn = "no"
|
||||
vim.wo.winfixwidth = true
|
||||
set_offset(SIDEBAR_WIDTH)
|
||||
vim.o.lazyredraw = save_lazyredraw
|
||||
vim.cmd("redraw")
|
||||
end
|
||||
|
||||
local function close_sidebar()
|
||||
local existing = find_sidebar()
|
||||
if existing then
|
||||
vim.api.nvim_win_close(existing, true)
|
||||
set_offset(0)
|
||||
end
|
||||
end
|
||||
|
||||
-- Keep the barbar label in sync with cwd changes.
|
||||
vim.api.nvim_create_autocmd("DirChanged", {
|
||||
callback = function()
|
||||
if find_sidebar() then set_offset(SIDEBAR_WIDTH) end
|
||||
end,
|
||||
})
|
||||
|
||||
vim.keymap.set("n", "-", "<cmd>Oil<CR>", { desc = "Oil parent dir (current window)" })
|
||||
vim.keymap.set("n", "<leader>e", open_sidebar, { desc = "Open / focus Oil sidebar" })
|
||||
vim.keymap.set("n", "<leader>E", close_sidebar, { desc = "Close Oil sidebar" })
|
||||
vim.keymap.set("n", "<leader>o", "<C-w>w", { desc = "Cycle windows" })
|
||||
@@ -0,0 +1,14 @@
|
||||
require("render-markdown").setup({
|
||||
completions = { blink = { enabled = true } },
|
||||
code = {
|
||||
sign = false,
|
||||
width = "block",
|
||||
right_pad = 1,
|
||||
},
|
||||
heading = {
|
||||
sign = false,
|
||||
-- Drop the full-line backgrounds; let icon + colored text carry the heading.
|
||||
backgrounds = {},
|
||||
width = "block",
|
||||
},
|
||||
})
|
||||
@@ -0,0 +1,135 @@
|
||||
local verse = require("verse")
|
||||
verse.setup()
|
||||
|
||||
vim.api.nvim_set_hl(0, "DashHeader", { link = "DarkboxYellow" })
|
||||
vim.api.nvim_set_hl(0, "VerseText", { link = "Comment" })
|
||||
vim.api.nvim_set_hl(0, "VerseRef", { link = "DarkboxAqua" })
|
||||
|
||||
local ns = vim.api.nvim_create_namespace("dash")
|
||||
|
||||
-- Classic NVIM dashboard ASCII logo.
|
||||
local logo = {
|
||||
"███╗ ██╗██╗ ██╗██╗███╗ ███╗",
|
||||
"████╗ ██║██║ ██║██║████╗ ████║",
|
||||
"██╔██╗ ██║██║ ██║██║██╔████╔██║",
|
||||
"██║╚██╗██║╚██╗ ██╔╝██║██║╚██╔╝██║",
|
||||
"██║ ╚████║ ╚████╔╝ ██║██║ ╚═╝ ██║",
|
||||
"╚═╝ ╚═══╝ ╚═══╝ ╚═╝╚═╝ ╚═╝",
|
||||
}
|
||||
|
||||
local function build()
|
||||
local entries = {}
|
||||
for _, line in ipairs(logo) do
|
||||
table.insert(entries, { text = line, hl = "DashHeader" })
|
||||
end
|
||||
table.insert(entries, { text = "" })
|
||||
table.insert(entries, { text = tostring(os.date("%A, %B %d %Y")), hl = "DashHeader" })
|
||||
|
||||
local v = verse.get()
|
||||
if v then
|
||||
table.insert(entries, { text = "" })
|
||||
for line in (verse.format()):gmatch("([^\n]*)\n?") do
|
||||
local hl = line:match("^— ") and "VerseRef" or "VerseText"
|
||||
table.insert(entries, { text = line, hl = hl })
|
||||
end
|
||||
end
|
||||
return entries
|
||||
end
|
||||
|
||||
local function render(buf, win)
|
||||
if not (vim.api.nvim_buf_is_valid(buf) and vim.api.nvim_win_is_valid(win)) then return end
|
||||
local entries = build()
|
||||
local width = vim.api.nvim_win_get_width(win)
|
||||
local height = vim.api.nvim_win_get_height(win)
|
||||
local top = math.max(0, math.floor((height - #entries) / 3))
|
||||
|
||||
local lines, marks = {}, {}
|
||||
for _ = 1, top do table.insert(lines, "") end
|
||||
for _, e in ipairs(entries) do
|
||||
local pad = math.max(0, math.floor((width - vim.fn.strdisplaywidth(e.text)) / 2))
|
||||
local text = string.rep(" ", pad) .. e.text
|
||||
table.insert(lines, text)
|
||||
if e.hl and e.text ~= "" then
|
||||
table.insert(marks, { row = #lines - 1, s = pad, e = pad + #e.text, hl = e.hl })
|
||||
end
|
||||
end
|
||||
|
||||
vim.bo[buf].modifiable = true
|
||||
vim.api.nvim_buf_set_lines(buf, 0, -1, false, lines)
|
||||
vim.bo[buf].modifiable = false
|
||||
|
||||
vim.api.nvim_buf_clear_namespace(buf, ns, 0, -1)
|
||||
for _, m in ipairs(marks) do
|
||||
vim.api.nvim_buf_set_extmark(buf, ns, m.row, m.s, {
|
||||
end_col = m.e,
|
||||
hl_group = m.hl,
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
local function open()
|
||||
-- Remember the initial startup buffer so we can wipe it once the dashboard
|
||||
-- takes over — otherwise it lingers as an unnamed `[buffer 1]` and shows up
|
||||
-- in the tabline whenever the dashboard is later replaced by a real file.
|
||||
local startup_buf = vim.api.nvim_get_current_buf()
|
||||
|
||||
local buf = vim.api.nvim_create_buf(false, true)
|
||||
vim.bo[buf].buftype = "nofile"
|
||||
vim.bo[buf].bufhidden = "wipe"
|
||||
vim.bo[buf].swapfile = false
|
||||
vim.bo[buf].filetype = "dashboard"
|
||||
vim.api.nvim_set_current_buf(buf)
|
||||
|
||||
if startup_buf ~= buf
|
||||
and vim.api.nvim_buf_is_valid(startup_buf)
|
||||
and vim.api.nvim_buf_get_name(startup_buf) == ""
|
||||
and not vim.bo[startup_buf].modified
|
||||
and vim.api.nvim_buf_line_count(startup_buf) <= 1
|
||||
then
|
||||
pcall(vim.api.nvim_buf_delete, startup_buf, { force = true })
|
||||
end
|
||||
|
||||
local win = vim.api.nvim_get_current_win()
|
||||
vim.wo[win].number = false
|
||||
vim.wo[win].relativenumber = false
|
||||
vim.wo[win].signcolumn = "no"
|
||||
vim.wo[win].cursorline = false
|
||||
vim.wo[win].list = false
|
||||
vim.wo[win].statuscolumn = ""
|
||||
|
||||
-- Hide tabline while dashboard is shown
|
||||
local prev_showtabline = vim.o.showtabline
|
||||
vim.o.showtabline = 0
|
||||
|
||||
-- Restore tabline only when the dashboard buffer is actually gone, not just
|
||||
-- when focus moves away (e.g. opening oil sidebar). BufLeave fires too eagerly.
|
||||
vim.api.nvim_create_autocmd({ "BufWipeout", "BufHidden" }, {
|
||||
buffer = buf,
|
||||
once = true,
|
||||
callback = function() vim.o.showtabline = prev_showtabline end,
|
||||
})
|
||||
|
||||
render(buf, win)
|
||||
|
||||
verse.on_update(function()
|
||||
if vim.api.nvim_buf_is_valid(buf) then render(buf, win) end
|
||||
end)
|
||||
|
||||
vim.api.nvim_create_autocmd({ "VimResized", "WinResized", "WinNew", "WinClosed" }, {
|
||||
callback = function()
|
||||
if not (vim.api.nvim_buf_is_valid(buf) and vim.api.nvim_win_is_valid(win)) then
|
||||
return
|
||||
end
|
||||
if vim.api.nvim_win_get_buf(win) ~= buf then return end
|
||||
render(buf, win)
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
vim.api.nvim_create_autocmd("VimEnter", {
|
||||
callback = function()
|
||||
if vim.fn.argc() == 0 and vim.api.nvim_buf_get_name(0) == "" and vim.bo.filetype == "" then
|
||||
open()
|
||||
end
|
||||
end,
|
||||
})
|
||||
@@ -0,0 +1 @@
|
||||
require("nvim-surround").setup({})
|
||||
@@ -0,0 +1,9 @@
|
||||
require("tiny-glimmer").setup({
|
||||
default_animation = "fade",
|
||||
overwrite = {
|
||||
yank = { enabled = true },
|
||||
paste = { enabled = true },
|
||||
undo = { enabled = true },
|
||||
redo = { enabled = true },
|
||||
},
|
||||
})
|
||||
@@ -0,0 +1,8 @@
|
||||
require("toggleterm").setup({
|
||||
direction = "float",
|
||||
float_opts = { border = "curved" },
|
||||
start_in_insert = true,
|
||||
close_on_exit = true,
|
||||
})
|
||||
|
||||
vim.keymap.set({ "n", "t" }, "<C-t>", "<cmd>ToggleTerm<CR>", { desc = "Toggle terminal" })
|
||||
@@ -0,0 +1,17 @@
|
||||
local langs = require("timmypidashev.langs")
|
||||
|
||||
require("nvim-treesitter").install(langs)
|
||||
|
||||
vim.filetype.add({
|
||||
extension = { templ = "templ" },
|
||||
})
|
||||
|
||||
vim.api.nvim_create_autocmd("FileType", {
|
||||
callback = function(args)
|
||||
local ft = vim.bo[args.buf].filetype
|
||||
local lang = vim.treesitter.language.get_lang(ft) or ft
|
||||
if pcall(vim.treesitter.start, args.buf, lang) then
|
||||
vim.bo[args.buf].indentexpr = "v:lua.require'nvim-treesitter'.indentexpr()"
|
||||
end
|
||||
end,
|
||||
})
|
||||
@@ -0,0 +1 @@
|
||||
vim.keymap.set("n", "<leader>u", function() vim.cmd.UndotreeToggle() end, { desc = "Toggle undotree" })
|
||||
@@ -0,0 +1,3 @@
|
||||
require("videre").setup({})
|
||||
|
||||
vim.keymap.set("n", "<leader>vj", "<cmd>Videre<CR>", { desc = "Videre JSON graph" })
|
||||
@@ -0,0 +1,4 @@
|
||||
require("which-key").setup({
|
||||
preset = "modern",
|
||||
delay = 400,
|
||||
})
|
||||
Reference in New Issue
Block a user