Initial rewrite

Signed-off-by: Timothy Pidashev <mail@timmypidashev.dev>
This commit is contained in:
2026-04-16 01:16:58 -07:00
parent face06a65d
commit 843d1ca3a1
50 changed files with 1315 additions and 1 deletions
+10
View File
@@ -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>")
+24
View File
@@ -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",
}
+33
View File
@@ -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
+75
View File
@@ -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")
+14
View File
@@ -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 },
-- })
+3
View File
@@ -0,0 +1,3 @@
require("nvim-autopairs").setup({
check_ts = true,
})
+95
View File
@@ -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)
+33
View File
@@ -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 })
+10
View File
@@ -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" },
},
})
+28
View File
@@ -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" })
+4
View File
@@ -0,0 +1,4 @@
require("darkbox").setup({
contrast = "retro",
})
vim.cmd.colorscheme("darkbox")
+17
View File
@@ -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" })
+13
View File
@@ -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,
})
+15
View File
@@ -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" })
+13
View File
@@ -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,
})
+18
View File
@@ -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" })
+79
View File
@@ -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,
})
+67
View File
@@ -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" },
},
})
+45
View File
@@ -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,
})
+29
View File
@@ -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,
},
})
+137
View File
@@ -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",
},
})
+135
View File
@@ -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,
})
+1
View File
@@ -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 },
},
})
+8
View File
@@ -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" })
+17
View File
@@ -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,
})
+1
View File
@@ -0,0 +1 @@
vim.keymap.set("n", "<leader>u", function() vim.cmd.UndotreeToggle() end, { desc = "Toggle undotree" })
+3
View File
@@ -0,0 +1,3 @@
require("videre").setup({})
vim.keymap.set("n", "<leader>vj", "<cmd>Videre<CR>", { desc = "Videre JSON graph" })
+4
View File
@@ -0,0 +1,4 @@
require("which-key").setup({
preset = "modern",
delay = 400,
})