mirror of
https://github.com/LazyVim/starter.git
synced 2026-07-24 21:41:04 +00:00
Merge 153a63750f into 803bc181d7
This commit is contained in:
commit
a00347ec9c
21 changed files with 1025 additions and 0 deletions
9
.claude/settings.local.json
Normal file
9
.claude/settings.local.json
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
"permissions": {
|
||||||
|
"allow": [
|
||||||
|
"Bash(grep -rn \"nvim_exec_autocmds\\\\|User.*ClaudeCode\\\\|ClaudeCode.*User\" /home/user/.local/share/nvim/lazy/claudecode.nvim/ --include=\"*.lua\" 2>/dev/null | grep -v test | grep -v spec)",
|
||||||
|
"Bash(grep:*)",
|
||||||
|
"Bash(python3:*)"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
45
lazy-lock.json
Normal file
45
lazy-lock.json
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
{
|
||||||
|
"CopilotChat.nvim": { "branch": "main", "commit": "ecea24a9a067c6f176b8e13eb11251c739caf055" },
|
||||||
|
"LazyVim": { "branch": "main", "commit": "fca0af57cc3851b14f96a795a9c9bfafc5096dd1" },
|
||||||
|
"blink-copilot": { "branch": "main", "commit": "7ad8209b2f880a2840c94cdcd80ab4dc511d4f39" },
|
||||||
|
"blink.cmp": { "branch": "main", "commit": "4b18c32adef2898f95cdef6192cbd5796c1a332d" },
|
||||||
|
"bufferline.nvim": { "branch": "main", "commit": "655133c3b4c3e5e05ec549b9f8cc2894ac6f51b3" },
|
||||||
|
"catppuccin": { "branch": "main", "commit": "12c004cde3f36cb1d57242f1e6aac46b09a0e5b4" },
|
||||||
|
"claudecode.nvim": { "branch": "main", "commit": "aa9a5cebebdbfa449c1c5ff229ba5d98e66bafed" },
|
||||||
|
"conform.nvim": { "branch": "master", "commit": "086a40dc7ed8242c03be9f47fbcee68699cc2395" },
|
||||||
|
"copilot.lua": { "branch": "master", "commit": "00446a63cba4cc59bb24fc1e210a555a3e4acdfb" },
|
||||||
|
"flash.nvim": { "branch": "main", "commit": "fcea7ff883235d9024dc41e638f164a450c14ca2" },
|
||||||
|
"friendly-snippets": { "branch": "main", "commit": "6cd7280adead7f586db6fccbd15d2cac7e2188b9" },
|
||||||
|
"gitsigns.nvim": { "branch": "main", "commit": "9f3c6dd7868bcc116e9c1c1929ce063b978fa519" },
|
||||||
|
"grug-far.nvim": { "branch": "main", "commit": "ac52ee2d87399dfd7b0d59d5b1d2bbaf2a4028f1" },
|
||||||
|
"lazy.nvim": { "branch": "main", "commit": "85c7ff3711b730b4030d03144f6db6375044ae82" },
|
||||||
|
"lazydev.nvim": { "branch": "main", "commit": "5231c62aa83c2f8dc8e7ba957aa77098cda1257d" },
|
||||||
|
"lualine.nvim": { "branch": "master", "commit": "47f91c416daef12db467145e16bed5bbfe00add8" },
|
||||||
|
"mason-lspconfig.nvim": { "branch": "main", "commit": "a324581a3c83fdacdb9804b79de1cbe00ce18550" },
|
||||||
|
"mason.nvim": { "branch": "main", "commit": "44d1e90e1f66e077268191e3ee9d2ac97cc18e65" },
|
||||||
|
"mini.ai": { "branch": "main", "commit": "4b0a6207341d895b6cfe9bcb1e4d3e8607bfe4f4" },
|
||||||
|
"mini.icons": { "branch": "main", "commit": "5b9076dae1bfbe47ba4a14bc8b967cde0ab5d77e" },
|
||||||
|
"mini.pairs": { "branch": "main", "commit": "b7fde3719340946feb75017ef9d75edebdeb0566" },
|
||||||
|
"mini.surround": { "branch": "main", "commit": "d205d1741d1fcc1f3117b4e839bf00f74ad72fa2" },
|
||||||
|
"noice.nvim": { "branch": "main", "commit": "7bfd942445fb63089b59f97ca487d605e715f155" },
|
||||||
|
"nui.nvim": { "branch": "main", "commit": "de740991c12411b663994b2860f1a4fd0937c130" },
|
||||||
|
"nvim-lint": { "branch": "master", "commit": "606b823a57b027502a9ae00978ebf4f5d5158098" },
|
||||||
|
"nvim-lspconfig": { "branch": "master", "commit": "ead0f5f342d8d323441e7d4b88f0fc436a81ad5f" },
|
||||||
|
"nvim-osc52": { "branch": "main", "commit": "04cfaba1865ae5c53b6f887c3ca7304973824fb2" },
|
||||||
|
"nvim-treesitter": { "branch": "main", "commit": "5cb05e1b0fa3c469958a2b26f36b3fe930af221c" },
|
||||||
|
"nvim-treesitter-textobjects": { "branch": "main", "commit": "4e91b5d0394329a229725b021a8ea217099826ef" },
|
||||||
|
"nvim-ts-autotag": { "branch": "main", "commit": "8e1c0a389f20bf7f5b0dd0e00306c1247bda2595" },
|
||||||
|
"persistence.nvim": { "branch": "main", "commit": "b20b2a7887bd39c1a356980b45e03250f3dce49c" },
|
||||||
|
"plenary.nvim": { "branch": "master", "commit": "b9fd5226c2f76c951fc8ed5923d85e4de065e509" },
|
||||||
|
"precognition.nvim": { "branch": "main", "commit": "06e4bfa339ddc55a49fd1adcbb403f6e0855c43b" },
|
||||||
|
"render-markdown.nvim": { "branch": "main", "commit": "1641b434bda26e0f4e3610985b3357fc213cf834" },
|
||||||
|
"snacks.nvim": { "branch": "main", "commit": "9912042fc8bca2209105526ac7534e9a0c2071b2" },
|
||||||
|
"todo-comments.nvim": { "branch": "main", "commit": "31e3c38ce9b29781e4422fc0322eb0a21f4e8668" },
|
||||||
|
"toggleterm.nvim": { "branch": "main", "commit": "50ea089fc548917cc3cc16b46a8211833b9e3c7c" },
|
||||||
|
"tokyonight.nvim": { "branch": "main", "commit": "5da1b76e64daf4c5d410f06bcb6b9cb640da7dfd" },
|
||||||
|
"transparent.nvim": { "branch": "main", "commit": "8ac59883de84e9cd1850ea25cf087031c5ba7d54" },
|
||||||
|
"trouble.nvim": { "branch": "main", "commit": "bd67efe408d4816e25e8491cc5ad4088e708a69a" },
|
||||||
|
"ts-comments.nvim": { "branch": "main", "commit": "123a9fb12e7229342f807ec9e6de478b1102b041" },
|
||||||
|
"typescript-tools.nvim": { "branch": "master", "commit": "c2f5910074103705661e9651aa841e0d7eea9932" },
|
||||||
|
"which-key.nvim": { "branch": "main", "commit": "3aab2147e74890957785941f0c1ad87d0a44c15a" }
|
||||||
|
}
|
||||||
14
lazyvim.json
Normal file
14
lazyvim.json
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
{
|
||||||
|
"extras": [
|
||||||
|
"lazyvim.plugins.extras.ai.claudecode",
|
||||||
|
"lazyvim.plugins.extras.ai.copilot",
|
||||||
|
"lazyvim.plugins.extras.ai.copilot-chat",
|
||||||
|
"lazyvim.plugins.extras.coding.mini-surround",
|
||||||
|
"lazyvim.plugins.extras.lang.markdown"
|
||||||
|
],
|
||||||
|
"install_version": 8,
|
||||||
|
"news": {
|
||||||
|
"NEWS.md": "11866"
|
||||||
|
},
|
||||||
|
"version": 8
|
||||||
|
}
|
||||||
|
|
@ -6,3 +6,10 @@
|
||||||
--
|
--
|
||||||
-- Or remove existing autocmds by their group name (which is prefixed with `lazyvim_` for the defaults)
|
-- Or remove existing autocmds by their group name (which is prefixed with `lazyvim_` for the defaults)
|
||||||
-- e.g. vim.api.nvim_del_augroup_by_name("lazyvim_wrap_spell")
|
-- e.g. vim.api.nvim_del_augroup_by_name("lazyvim_wrap_spell")
|
||||||
|
vim.api.nvim_create_autocmd("BufWritePre", {
|
||||||
|
pattern = { "*.tsx", "*.ts" },
|
||||||
|
callback = function()
|
||||||
|
local tstools_api = require("typescript-tools.api")
|
||||||
|
tstools_api.remove_unused_imports(true) -- true = sync
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,24 @@
|
||||||
-- Keymaps are automatically loaded on the VeryLazy event
|
-- Keymaps are automatically loaded on the VeryLazy event
|
||||||
-- Default keymaps that are always set: https://github.com/LazyVim/LazyVim/blob/main/lua/lazyvim/config/keymaps.lua
|
-- Default keymaps that are always set: https://github.com/LazyVim/LazyVim/blob/main/lua/lazyvim/config/keymaps.lua
|
||||||
-- Add any additional keymaps here
|
-- Add any additional keymaps here
|
||||||
|
|
||||||
|
---- Move lines
|
||||||
|
vim.keymap.set("v", "J", ":m '>+1<CR>gv=gv")
|
||||||
|
vim.keymap.set("v", "K", ":m '<-2<CR>gv=gv")
|
||||||
|
|
||||||
|
-- Cursor in middle when jumping
|
||||||
|
vim.keymap.set("n", "<C-j>", "<C-d>zz")
|
||||||
|
vim.keymap.set("n", "<C-k>", "<C-u>zz")
|
||||||
|
vim.keymap.set("n", "n", "nzzzv")
|
||||||
|
vim.keymap.set("n", "N", "Nzzzv")
|
||||||
|
|
||||||
|
-- Precognition
|
||||||
|
vim.keymap.set("n", "<leader>tp", require("precognition").toggle)
|
||||||
|
|
||||||
|
-- set the file picker to always open the cwd instead of root
|
||||||
|
vim.keymap.set("n", "<leader><leader>", function()
|
||||||
|
require("lazyvim.util").pick("files", { root = false })()
|
||||||
|
end, { desc = "Find Files (cwd)" })
|
||||||
|
|
||||||
|
-- Markdown task management
|
||||||
|
require("config.markdown-tasks").setup()
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,13 @@ require("lazy").setup({
|
||||||
spec = {
|
spec = {
|
||||||
-- add LazyVim and import its plugins
|
-- add LazyVim and import its plugins
|
||||||
{ "LazyVim/LazyVim", import = "lazyvim.plugins" },
|
{ "LazyVim/LazyVim", import = "lazyvim.plugins" },
|
||||||
|
|
||||||
|
-- language extras
|
||||||
|
{ import = "lazyvim.plugins.extras.lang.typescript" },
|
||||||
|
|
||||||
|
-- formatting extras
|
||||||
|
{ import = "lazyvim.plugins.extras.formatting.prettier" },
|
||||||
|
|
||||||
-- import/override with your plugins
|
-- import/override with your plugins
|
||||||
{ import = "plugins" },
|
{ import = "plugins" },
|
||||||
},
|
},
|
||||||
|
|
|
||||||
500
lua/config/markdown-tasks.lua
Normal file
500
lua/config/markdown-tasks.lua
Normal file
|
|
@ -0,0 +1,500 @@
|
||||||
|
-- Markdown task management
|
||||||
|
-- Keymaps are registered only in markdown buffers via FileType autocmd.
|
||||||
|
--
|
||||||
|
-- File structure expected:
|
||||||
|
-- # TODO Lists
|
||||||
|
-- ## General Section 📜 1/2 📜
|
||||||
|
-- - [ ] undated task
|
||||||
|
-- - [x] done task
|
||||||
|
-- ## DD-MM-YYYY ⏳ 0/2 ⏳ (date sections sorted newest first)
|
||||||
|
-- - [ ] task
|
||||||
|
-- - [ ] another task
|
||||||
|
--
|
||||||
|
-- Section stat icons (auto-updated on toggle and InsertLeave):
|
||||||
|
-- ✅ all tasks done (any section)
|
||||||
|
-- 🚨 today, 0 done, ≥2 total
|
||||||
|
-- ⏳ today (default)
|
||||||
|
-- 📅 future date
|
||||||
|
-- ❌ past date
|
||||||
|
-- 📜 general (non-date heading)
|
||||||
|
--
|
||||||
|
-- Features:
|
||||||
|
-- Toggle cascades to children; unchecking a child unchecks parent,
|
||||||
|
-- checking last sibling checks parent. Spacing is auto-normalized
|
||||||
|
-- (blank lines around headings, none between sibling tasks).
|
||||||
|
-- Tasks can be moved between date sections and a general section.
|
||||||
|
|
||||||
|
local M = {}
|
||||||
|
|
||||||
|
-- ── Core task operations ─────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
local function new_task()
|
||||||
|
local line = vim.api.nvim_get_current_line()
|
||||||
|
if line:match("^%s*$") then
|
||||||
|
vim.api.nvim_set_current_line("- [ ] ")
|
||||||
|
vim.cmd("startinsert!")
|
||||||
|
else
|
||||||
|
vim.cmd("normal! o- [ ] ")
|
||||||
|
vim.cmd("startinsert!")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function toggle_task()
|
||||||
|
local lines = vim.api.nvim_buf_get_lines(0, 0, -1, false)
|
||||||
|
local row = vim.api.nvim_win_get_cursor(0)[1]
|
||||||
|
local line = lines[row]
|
||||||
|
if not line:find("%[[ x]%]") then return end
|
||||||
|
|
||||||
|
-- Toggle current line
|
||||||
|
local new_state
|
||||||
|
if line:find("%[ %]") then
|
||||||
|
lines[row] = line:gsub("%[ %]", "[x]", 1)
|
||||||
|
new_state = "[x]"
|
||||||
|
else
|
||||||
|
lines[row] = line:gsub("%[x%]", "[ ]", 1)
|
||||||
|
new_state = "[ ]"
|
||||||
|
end
|
||||||
|
|
||||||
|
local cur_indent = #(line:match("^(%s*)") or "")
|
||||||
|
|
||||||
|
-- Cascade down: set all deeper-indented children to same state
|
||||||
|
for i = row + 1, #lines do
|
||||||
|
local l = lines[i]
|
||||||
|
if not l:match("^%s*%-") then break end
|
||||||
|
local indent = #(l:match("^(%s*)") or "")
|
||||||
|
if indent <= cur_indent then break end
|
||||||
|
if new_state == "[x]" then
|
||||||
|
lines[i] = l:gsub("%[ %]", "[x]", 1)
|
||||||
|
else
|
||||||
|
lines[i] = l:gsub("%[x%]", "[ ]", 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Cascade up: find parent (less indent, is a task)
|
||||||
|
local parent_row
|
||||||
|
for i = row - 1, 1, -1 do
|
||||||
|
local l = lines[i]
|
||||||
|
if not l:match("^%s*%-") then break end
|
||||||
|
local indent = #(l:match("^(%s*)") or "")
|
||||||
|
if indent < cur_indent and l:find("%[[ x]%]") then
|
||||||
|
parent_row = i
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if parent_row then
|
||||||
|
if new_state == "[ ]" and lines[parent_row]:find("%[x%]") then
|
||||||
|
-- Unchecking child: uncheck parent
|
||||||
|
lines[parent_row] = lines[parent_row]:gsub("%[x%]", "[ ]", 1)
|
||||||
|
elseif new_state == "[x]" then
|
||||||
|
-- Checking child: check parent if all siblings are now done
|
||||||
|
local parent_indent = #(lines[parent_row]:match("^(%s*)") or "")
|
||||||
|
local all_done = true
|
||||||
|
for i = parent_row + 1, #lines do
|
||||||
|
local l = lines[i]
|
||||||
|
if not l:match("^%s*%-") then break end
|
||||||
|
local indent = #(l:match("^(%s*)") or "")
|
||||||
|
if indent <= parent_indent then break end
|
||||||
|
if indent == cur_indent and l:find("%[ %]") then
|
||||||
|
all_done = false
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if all_done then
|
||||||
|
lines[parent_row] = lines[parent_row]:gsub("%[ %]", "[x]", 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
vim.api.nvim_buf_set_lines(0, 0, -1, false, lines)
|
||||||
|
vim.api.nvim_win_set_cursor(0, { row, vim.api.nvim_win_get_cursor(0)[2] })
|
||||||
|
local update = require("config.markdown-tasks")._update_stats
|
||||||
|
if update then update() end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function toggle_task_format()
|
||||||
|
local line = vim.api.nvim_get_current_line()
|
||||||
|
if line:find("^%s*%- %[.%] ") then
|
||||||
|
-- "- [ ] text" → "- text"
|
||||||
|
vim.api.nvim_set_current_line((line:gsub("^(%s*)%- %[.%] ", "%1- ", 1)))
|
||||||
|
elseif line:find("^%s*%- ") then
|
||||||
|
-- "- text" → "- [ ] text"
|
||||||
|
vim.api.nvim_set_current_line((line:gsub("^(%s*)%- ", "%1- [ ] ", 1)))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function jump_next_task() vim.fn.search("- \\[ \\]", "W") end
|
||||||
|
local function jump_prev_task() vim.fn.search("- \\[ \\]", "bW") end
|
||||||
|
|
||||||
|
local function list_tasks_in_file()
|
||||||
|
require("snacks").picker.grep({ search = "- \\[ \\]", buffers = true })
|
||||||
|
end
|
||||||
|
|
||||||
|
local function search_all_tasks()
|
||||||
|
require("snacks").picker.grep({ search = "- \\[ \\]" })
|
||||||
|
end
|
||||||
|
|
||||||
|
-- ── Section task stats ────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
-- Parses a "DD-MM-YYYY" string into a Unix timestamp for comparison.
|
||||||
|
local function date_to_time(s)
|
||||||
|
local d, m, y = s:match("(%d+)-(%d+)-(%d+)")
|
||||||
|
if not d then return 0 end
|
||||||
|
return os.time({ year = tonumber(y), month = tonumber(m), day = tonumber(d) })
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Strips the stats suffix from a heading line, returning the bare heading.
|
||||||
|
local function strip_stats(line)
|
||||||
|
return (line
|
||||||
|
:gsub("%s+✅ ?%d+/%d+ ?✅%s*$", "")
|
||||||
|
:gsub("%s+❌ ?%d+/%d+ ?❌%s*$", "")
|
||||||
|
:gsub("%s+📜 ?%d+/%d+ ?📜%s*$", "")
|
||||||
|
:gsub("%s+⏳ ?%d+/%d+ ?⏳%s*$", "")
|
||||||
|
:gsub("%s+📅 ?%d+/%d+ ?📅%s*$", "")
|
||||||
|
:gsub("%s+🚨 ?%d+/%d+ ?🚨%s*$", ""))
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Counts [x] and [ ] tasks in a section starting at header_line (1-indexed).
|
||||||
|
local function count_section_tasks(lines, header_line)
|
||||||
|
local done, todo = 0, 0
|
||||||
|
for i = header_line + 1, #lines do
|
||||||
|
if lines[i]:match("^## ") then break end
|
||||||
|
if lines[i]:match("^%s*%- %[x%]") then
|
||||||
|
done = done + 1
|
||||||
|
elseif lines[i]:match("^%s*%- %[ %]") then
|
||||||
|
todo = todo + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return done, todo
|
||||||
|
end
|
||||||
|
|
||||||
|
local function classify_section(base)
|
||||||
|
local date_str = base:match("^## (%d%d%-%d%d%-%d%d%d%d)$")
|
||||||
|
if not date_str then return "general" end
|
||||||
|
local section_time = date_to_time(date_str)
|
||||||
|
local today_start = date_to_time(os.date("%d-%m-%Y"))
|
||||||
|
if section_time == today_start then return "today" end
|
||||||
|
return section_time > today_start and "future" or "past"
|
||||||
|
end
|
||||||
|
|
||||||
|
local section_icons = {
|
||||||
|
general = "📜", today = "⏳", future = "📅", past = "❌",
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Updates every ## heading with a live task count suffix.
|
||||||
|
local function update_section_stats()
|
||||||
|
local lines = vim.api.nvim_buf_get_lines(0, 0, -1, false)
|
||||||
|
local changed = false
|
||||||
|
for i, line in ipairs(lines) do
|
||||||
|
if line:match("^## ") then
|
||||||
|
local base = strip_stats(line)
|
||||||
|
local done, todo = count_section_tasks(lines, i)
|
||||||
|
local total = done + todo
|
||||||
|
local kind = classify_section(base)
|
||||||
|
local icon
|
||||||
|
if total > 0 and done == total then
|
||||||
|
icon = "✅"
|
||||||
|
elseif kind == "today" and done == 0 and total >= 2 then
|
||||||
|
icon = "🚨"
|
||||||
|
else
|
||||||
|
icon = section_icons[kind]
|
||||||
|
end
|
||||||
|
local new_line = base .. " " .. icon .. " " .. done .. "/" .. total .. " " .. icon
|
||||||
|
if new_line ~= line then
|
||||||
|
lines[i] = new_line
|
||||||
|
changed = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if changed then
|
||||||
|
local cursor = vim.api.nvim_win_get_cursor(0)
|
||||||
|
vim.api.nvim_buf_set_lines(0, 0, -1, false, lines)
|
||||||
|
vim.api.nvim_win_set_cursor(0, cursor)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Expose so toggle_task can call it without a forward-ref issue.
|
||||||
|
M._update_stats = update_section_stats
|
||||||
|
|
||||||
|
-- ── Spacing normalizer ───────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
-- Enforces: one blank line before and after every heading line, no consecutive
|
||||||
|
-- blank lines, no blank lines between sibling task lines.
|
||||||
|
local function normalize_spacing()
|
||||||
|
local lines = vim.api.nvim_buf_get_lines(0, 0, -1, false)
|
||||||
|
|
||||||
|
-- Strip all blank lines first so we can re-insert them deterministically.
|
||||||
|
local stripped = {}
|
||||||
|
for _, l in ipairs(lines) do
|
||||||
|
if not l:match("^%s*$") then table.insert(stripped, l) end
|
||||||
|
end
|
||||||
|
|
||||||
|
local result = {}
|
||||||
|
|
||||||
|
local function ensure_blank()
|
||||||
|
if #result > 0 and not result[#result]:match("^%s*$") then
|
||||||
|
table.insert(result, "")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for i, l in ipairs(stripped) do
|
||||||
|
local is_heading = l:match("^#")
|
||||||
|
if is_heading and #result > 0 then ensure_blank() end
|
||||||
|
table.insert(result, l)
|
||||||
|
if is_heading and i < #stripped then ensure_blank() end
|
||||||
|
end
|
||||||
|
|
||||||
|
vim.api.nvim_buf_set_lines(0, 0, -1, false, result)
|
||||||
|
update_section_stats()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- ── Date helpers ─────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
-- Returns date string "DD-MM-YYYY" with an optional day offset.
|
||||||
|
local function date_string(offset_days)
|
||||||
|
local t = os.time() + (offset_days or 0) * 86400
|
||||||
|
return os.date("%d-%m-%Y", t)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Returns 1-indexed line number of the "## DD-MM-YYYY" header, or nil.
|
||||||
|
local function find_date_section(date_str)
|
||||||
|
local lines = vim.api.nvim_buf_get_lines(0, 0, -1, false)
|
||||||
|
for i, line in ipairs(lines) do
|
||||||
|
if strip_stats(line) == "## " .. date_str then return i end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Returns the 1-indexed line of the last non-empty content line within a
|
||||||
|
-- section (from header_line until the next ## header or EOF).
|
||||||
|
local function section_end(header_line)
|
||||||
|
local lines = vim.api.nvim_buf_get_lines(0, 0, -1, false)
|
||||||
|
local last = header_line
|
||||||
|
for i = header_line + 1, #lines do
|
||||||
|
if lines[i]:match("^## ") then return i - 1 end
|
||||||
|
if not lines[i]:match("^%s*$") then last = i end
|
||||||
|
end
|
||||||
|
return last
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Inserts a new "## date_str" line in descending date order (newest first).
|
||||||
|
-- Blank lines are left to normalize_spacing.
|
||||||
|
local function insert_date_section(date_str)
|
||||||
|
local new_time = date_to_time(date_str)
|
||||||
|
local lines = vim.api.nvim_buf_get_lines(0, 0, -1, false)
|
||||||
|
-- Find the first existing date header that is strictly older → insert before it.
|
||||||
|
for i, line in ipairs(lines) do
|
||||||
|
local existing = strip_stats(line):match("^## (%d%d%-%d%d%-%d%d%d%d)$")
|
||||||
|
if existing and date_to_time(existing) < new_time then
|
||||||
|
vim.api.nvim_buf_set_lines(0, i - 1, i - 1, false, { "## " .. date_str })
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- All existing dates are newer (or there are none) → append at end.
|
||||||
|
vim.api.nvim_buf_set_lines(0, #lines, #lines, false, { "## " .. date_str })
|
||||||
|
end
|
||||||
|
|
||||||
|
-- ── Insert today's date header ────────────────────────────────────────────────
|
||||||
|
|
||||||
|
local function insert_date()
|
||||||
|
local header = "## " .. date_string(0)
|
||||||
|
local row = vim.api.nvim_win_get_cursor(0)[1]
|
||||||
|
local line = vim.api.nvim_get_current_line()
|
||||||
|
if line:match("^%s*$") then
|
||||||
|
vim.api.nvim_set_current_line(header)
|
||||||
|
else
|
||||||
|
vim.api.nvim_buf_set_lines(0, row, row, false, { header })
|
||||||
|
vim.api.nvim_win_set_cursor(0, { row + 1, 0 })
|
||||||
|
end
|
||||||
|
normalize_spacing()
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- ── Move task helpers ─────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
-- Removes the task at row (1-indexed), then deletes the owning date header if
|
||||||
|
-- it is now empty. Returns the task text.
|
||||||
|
local function remove_task(row)
|
||||||
|
local line = vim.api.nvim_buf_get_lines(0, row - 1, row, false)[1]
|
||||||
|
|
||||||
|
-- Find the ## header that owns this task before deleting it.
|
||||||
|
local all = vim.api.nvim_buf_get_lines(0, 0, -1, false)
|
||||||
|
local src_hdr = nil
|
||||||
|
for i = row, 1, -1 do
|
||||||
|
if all[i] and all[i]:match("^##") then
|
||||||
|
src_hdr = i; break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
vim.api.nvim_buf_set_lines(0, row - 1, row, false, {})
|
||||||
|
|
||||||
|
-- If the source was a date section that is now empty, remove its header.
|
||||||
|
if src_hdr then
|
||||||
|
local updated = vim.api.nvim_buf_get_lines(0, 0, -1, false)
|
||||||
|
local hdr = updated[src_hdr]
|
||||||
|
if hdr and strip_stats(hdr):match("^## %d%d%-%d%d%-%d%d%d%d$") then
|
||||||
|
local empty = true
|
||||||
|
for i = src_hdr + 1, #updated do
|
||||||
|
if updated[i]:match("^## ") then break end
|
||||||
|
if not updated[i]:match("^%s*$") then
|
||||||
|
empty = false; break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if empty then
|
||||||
|
vim.api.nvim_buf_set_lines(0, src_hdr - 1, src_hdr, false, {})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return line
|
||||||
|
end
|
||||||
|
|
||||||
|
-- ── Move task to a date section ───────────────────────────────────────────────
|
||||||
|
|
||||||
|
local function move_task_to(date_str)
|
||||||
|
local row = vim.api.nvim_win_get_cursor(0)[1]
|
||||||
|
local line = vim.api.nvim_get_current_line()
|
||||||
|
|
||||||
|
if not line:match("^%s*%- %[") then
|
||||||
|
vim.notify("Not on a task line", vim.log.levels.WARN)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
remove_task(row)
|
||||||
|
|
||||||
|
local target = find_date_section(date_str)
|
||||||
|
if not target then
|
||||||
|
insert_date_section(date_str)
|
||||||
|
target = find_date_section(date_str)
|
||||||
|
end
|
||||||
|
|
||||||
|
local insert_at = section_end(target)
|
||||||
|
vim.api.nvim_buf_set_lines(0, insert_at, insert_at, false, { line })
|
||||||
|
|
||||||
|
normalize_spacing()
|
||||||
|
end
|
||||||
|
|
||||||
|
local function move_to_general()
|
||||||
|
local row = vim.api.nvim_win_get_cursor(0)[1]
|
||||||
|
local line = vim.api.nvim_get_current_line()
|
||||||
|
|
||||||
|
if not line:match("^%s*%- %[") then
|
||||||
|
vim.notify("Not on a task line", vim.log.levels.WARN)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
remove_task(row)
|
||||||
|
|
||||||
|
-- The general section is the first ## heading that isn't a date heading.
|
||||||
|
local lines = vim.api.nvim_buf_get_lines(0, 0, -1, false)
|
||||||
|
local general = nil
|
||||||
|
for i, l in ipairs(lines) do
|
||||||
|
local base = strip_stats(l)
|
||||||
|
if base:match("^## ") and not base:match("^## %d%d%-%d%d%-%d%d%d%d$") then
|
||||||
|
general = i; break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if not general then
|
||||||
|
vim.notify("No general section found", vim.log.levels.WARN)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local insert_at = section_end(general)
|
||||||
|
vim.api.nvim_buf_set_lines(0, insert_at, insert_at, false, { line })
|
||||||
|
|
||||||
|
normalize_spacing()
|
||||||
|
end
|
||||||
|
|
||||||
|
local function move_to_today() move_task_to(date_string(0)) end
|
||||||
|
local function move_to_tomorrow() move_task_to(date_string(1)) end
|
||||||
|
local function move_to_yesterday() move_task_to(date_string(-1)) end
|
||||||
|
|
||||||
|
-- Parses flexible date input into "DD-MM-YYYY". Accepts separators - / or none.
|
||||||
|
-- If the year is omitted (DDMM or DD-MM or DD/MM), assumes the current year.
|
||||||
|
local function parse_date_input(input)
|
||||||
|
if not input or input == "" then return nil end
|
||||||
|
input = input:match("^%s*(.-)%s*$") -- trim
|
||||||
|
|
||||||
|
local current_year = tonumber(os.date("%Y"))
|
||||||
|
local d, m, y
|
||||||
|
|
||||||
|
-- With separator: DD-MM-YYYY or DD/MM/YYYY (year optional)
|
||||||
|
d, m, y = input:match("^(%d%d?)[%-%/](%d%d?)[%-%/](%d%d%d%d)$")
|
||||||
|
if d then
|
||||||
|
return string.format("%02d-%02d-%04d", tonumber(d), tonumber(m), tonumber(y))
|
||||||
|
end
|
||||||
|
|
||||||
|
d, m = input:match("^(%d%d?)[%-%/](%d%d?)$")
|
||||||
|
if d then
|
||||||
|
return string.format("%02d-%02d-%04d", tonumber(d), tonumber(m), current_year)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- No separator: DDMMYYYY or DDMM
|
||||||
|
d, m, y = input:match("^(%d%d)(%d%d)(%d%d%d%d)$")
|
||||||
|
if d then
|
||||||
|
return string.format("%02d-%02d-%04d", tonumber(d), tonumber(m), tonumber(y))
|
||||||
|
end
|
||||||
|
|
||||||
|
d, m = input:match("^(%d%d)(%d%d)$")
|
||||||
|
if d then
|
||||||
|
return string.format("%02d-%02d-%04d", tonumber(d), tonumber(m), current_year)
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
local function move_to_date()
|
||||||
|
vim.ui.input({ prompt = "Date (DD-MM-YYYY): " }, function(input)
|
||||||
|
local parsed = parse_date_input(input)
|
||||||
|
if parsed then
|
||||||
|
move_task_to(parsed)
|
||||||
|
elseif input and input ~= "" then
|
||||||
|
vim.notify("Unrecognised date: " .. input, vim.log.levels.WARN)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- ── Setup ────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
function M.setup()
|
||||||
|
local group = vim.api.nvim_create_augroup("MarkdownTasks", { clear = true })
|
||||||
|
|
||||||
|
local function setup_buf(buf)
|
||||||
|
local o = function(desc) return { buffer = buf, desc = desc } end
|
||||||
|
vim.keymap.set("n", "<leader>mn", new_task, o("New task"))
|
||||||
|
vim.keymap.set("n", "<leader>mx", toggle_task, o("Toggle done"))
|
||||||
|
vim.keymap.set("n", "<leader>mf", toggle_task_format, o("Toggle task format"))
|
||||||
|
vim.keymap.set("n", "<leader>mj", jump_next_task, o("Next task"))
|
||||||
|
vim.keymap.set("n", "<leader>mk", jump_prev_task, o("Prev task"))
|
||||||
|
vim.keymap.set("n", "<leader>ml", list_tasks_in_file, o("List tasks (file)"))
|
||||||
|
vim.keymap.set("n", "<leader>ms", search_all_tasks, o("Search all tasks"))
|
||||||
|
vim.keymap.set("n", "<leader>mt", insert_date, o("Insert date header"))
|
||||||
|
vim.keymap.set("n", "<leader>mmg", move_to_general, o("Move → general"))
|
||||||
|
vim.keymap.set("n", "<leader>mmt", move_to_today, o("Move → today"))
|
||||||
|
vim.keymap.set("n", "<leader>mmT", move_to_tomorrow, o("Move → tomorrow"))
|
||||||
|
vim.keymap.set("n", "<leader>mmy", move_to_yesterday, o("Move → yesterday"))
|
||||||
|
vim.keymap.set("n", "<leader>mmd", move_to_date, o("Move → date…"))
|
||||||
|
-- Update stats after leaving insert mode (covers new_task completions).
|
||||||
|
vim.api.nvim_create_autocmd("InsertLeave", {
|
||||||
|
buffer = buf,
|
||||||
|
group = group,
|
||||||
|
callback = update_section_stats,
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
vim.api.nvim_create_autocmd("FileType", {
|
||||||
|
pattern = "markdown",
|
||||||
|
group = group,
|
||||||
|
callback = function(ev) setup_buf(ev.buf) end,
|
||||||
|
})
|
||||||
|
|
||||||
|
-- VeryLazy fires after the initial buffer's FileType event, so apply
|
||||||
|
-- keymaps to any markdown buffers that are already open.
|
||||||
|
for _, buf in ipairs(vim.api.nvim_list_bufs()) do
|
||||||
|
if vim.api.nvim_buf_is_loaded(buf) and vim.bo[buf].filetype == "markdown" then
|
||||||
|
setup_buf(buf)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return M
|
||||||
|
|
@ -1,3 +1,22 @@
|
||||||
-- Options are automatically loaded before lazy.nvim startup
|
-- Options are automatically loaded before lazy.nvim startup
|
||||||
-- Default options that are always set: https://github.com/LazyVim/LazyVim/blob/main/lua/lazyvim/config/options.lua
|
-- Default options that are always set: https://github.com/LazyVim/LazyVim/blob/main/lua/lazyvim/config/options.lua
|
||||||
-- Add any additional options here
|
-- Add any additional options here
|
||||||
|
vim.schedule(function()
|
||||||
|
vim.o.clipboard = "unnamedplus"
|
||||||
|
end)
|
||||||
|
|
||||||
|
vim.o.scrolloff = 10
|
||||||
|
|
||||||
|
-- Semantic highlighting
|
||||||
|
vim.g.lazyvim_semantic_highlighting = false
|
||||||
|
vim.g.lazyvim_prettier_needs_config = false
|
||||||
|
|
||||||
|
-- Kill any orphaned tsserver processes when Neovim exits
|
||||||
|
vim.api.nvim_create_autocmd("ExitPre", {
|
||||||
|
callback = function()
|
||||||
|
vim.fn.system("pkill -f 'tsserver.js'")
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
|
-- Leave ai completion to copilot
|
||||||
|
vim.g.ai_cmp = false
|
||||||
|
|
|
||||||
55
lua/plugins/claude-code.lua
Normal file
55
lua/plugins/claude-code.lua
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
return {
|
||||||
|
"coder/claudecode.nvim",
|
||||||
|
lazy = false,
|
||||||
|
dependencies = { "folke/snacks.nvim" },
|
||||||
|
opts = {
|
||||||
|
log_level = "info",
|
||||||
|
focus_after_send = true,
|
||||||
|
terminal = {
|
||||||
|
git_repo_cwd = true,
|
||||||
|
-- split_side = "left",
|
||||||
|
-- split_width_percentage = 0.25,
|
||||||
|
-- provider = "toggleterm", -- "snacks" or "toggleterm"...
|
||||||
|
-- auto_close = true,
|
||||||
|
snacks_win_opts = {
|
||||||
|
-- Floating window options
|
||||||
|
position = "float",
|
||||||
|
width = 0.85,
|
||||||
|
height = 0.85,
|
||||||
|
border = "rounded",
|
||||||
|
keys = {
|
||||||
|
hide = {
|
||||||
|
"<leader>jj",
|
||||||
|
function(self)
|
||||||
|
self:hide()
|
||||||
|
end,
|
||||||
|
mode = "t",
|
||||||
|
desc = "Hide Claude",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
keys = {
|
||||||
|
{ "<leader>j", nil, desc = "Claude Code" },
|
||||||
|
-- { "<C-/>", "<cmd>ClaudeCode<cr>", desc = "Toggle Claude" }, -- not working
|
||||||
|
{ "<leader>jj", "<cmd>ClaudeCode<cr>", desc = "Toggle Claude" },
|
||||||
|
{ "<leader>jb", "<cmd>ClaudeCodeAdd %<cr>", desc = "Add current buffer" },
|
||||||
|
{ "<leader>js", "<cmd>ClaudeCodeSend<cr>", mode = { "n", "v" }, desc = "Send selection / file" },
|
||||||
|
|
||||||
|
-- I use snacks_picker_list, not supported yet. Claude Code currently only supports these 5.
|
||||||
|
-- {
|
||||||
|
-- "<leader>js",
|
||||||
|
-- "<cmd>ClaudeCodeTreeAdd<cr>",
|
||||||
|
-- desc = "Add file",
|
||||||
|
-- ft = { "NvimTree", "neo-tree", "oil", "minifiles", "netrw" },
|
||||||
|
-- },
|
||||||
|
{ "<leader>jr", "<cmd>ClaudeCode --resume<cr>", desc = "Resume session" },
|
||||||
|
{ "<leader>jc", "<cmd>ClaudeCode --continue<cr>", desc = "Continue session" },
|
||||||
|
{ "<leader>jm", "<cmd>ClaudeCodeSelectModel<cr>", desc = "Select model" },
|
||||||
|
|
||||||
|
-- Diff actions
|
||||||
|
{ "<leader>ja", "<cmd>ClaudeCodeDiffAccept<cr>", desc = "Accept diff" },
|
||||||
|
{ "<leader>jd", "<cmd>ClaudeCodeDiffDeny<cr>", desc = "Deny diff" },
|
||||||
|
},
|
||||||
|
}
|
||||||
26
lua/plugins/conform.lua
Normal file
26
lua/plugins/conform.lua
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
local util = require("conform.util")
|
||||||
|
|
||||||
|
return {
|
||||||
|
"stevearc/conform.nvim",
|
||||||
|
opts = {
|
||||||
|
formatters = {
|
||||||
|
prettier = {
|
||||||
|
command = util.from_node_modules(".yarn/sdks/prettier/bin/prettier.cjs"),
|
||||||
|
},
|
||||||
|
eslint = {
|
||||||
|
-- Run project ESLint through Yarn
|
||||||
|
command = "yarn",
|
||||||
|
args = { "eslint", "--fix-dry-run", "--stdin", "--stdin-filename", "$FILENAME" },
|
||||||
|
stdin = true,
|
||||||
|
cwd = util.root_file({ "eslint.config.mjs", ".pnp.cjs", "package.json" }),
|
||||||
|
timeout = 10000, -- 10s; adjust if needed
|
||||||
|
},
|
||||||
|
},
|
||||||
|
formatters_by_ft = {
|
||||||
|
typescript = { "prettier" },
|
||||||
|
typescriptreact = { "prettier" },
|
||||||
|
javascript = { "prettier" },
|
||||||
|
javascriptreact = { "prettier" },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
11
lua/plugins/copilot.lua
Normal file
11
lua/plugins/copilot.lua
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
return {
|
||||||
|
{
|
||||||
|
"zbirenbaum/copilot.lua",
|
||||||
|
opts = {
|
||||||
|
suggestion = {
|
||||||
|
enabled = true,
|
||||||
|
auto_trigger = true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
15
lua/plugins/git.lua
Normal file
15
lua/plugins/git.lua
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
return {
|
||||||
|
{
|
||||||
|
"lewis6991/gitsigns.nvim",
|
||||||
|
keys = {
|
||||||
|
-- Override LazyVim Git Blame popup with inline toggle
|
||||||
|
{
|
||||||
|
"<leader>tb",
|
||||||
|
function()
|
||||||
|
require("gitsigns").toggle_current_line_blame()
|
||||||
|
end,
|
||||||
|
desc = "Toggle Inline Blame",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
19
lua/plugins/osc52.lua
Normal file
19
lua/plugins/osc52.lua
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
return {
|
||||||
|
{
|
||||||
|
"ojroques/nvim-osc52",
|
||||||
|
config = function()
|
||||||
|
require("osc52").setup({
|
||||||
|
max_length = 0, -- Maximum length of selection (0 for no limit)
|
||||||
|
silent = false, -- Disable message on successful copy
|
||||||
|
trim = false, -- Trim surrounding whitespaces before copy
|
||||||
|
})
|
||||||
|
local function copy()
|
||||||
|
if (vim.v.event.operator == "y" or vim.v.event.operator == "d") and vim.v.event.regname == "" then
|
||||||
|
require("osc52").copy_register("")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
vim.api.nvim_create_autocmd("TextYankPost", { callback = copy })
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
}
|
||||||
53
lua/plugins/precognition.lua
Normal file
53
lua/plugins/precognition.lua
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
return {
|
||||||
|
-- Other options
|
||||||
|
-- nvim-spider
|
||||||
|
-- leap.nvim
|
||||||
|
"tris203/precognition.nvim",
|
||||||
|
event = "VeryLazy",
|
||||||
|
opts = {
|
||||||
|
startVisible = false,
|
||||||
|
showBlankVirtLine = true,
|
||||||
|
highlightColor = { link = "Comment" },
|
||||||
|
hints = {
|
||||||
|
Caret = { text = "^", prio = 2 },
|
||||||
|
Dollar = { text = "$", prio = 1 },
|
||||||
|
MatchingPair = { text = "%", prio = 5 },
|
||||||
|
|
||||||
|
Zero = { text = "0", prio = 1 },
|
||||||
|
|
||||||
|
w = { text = "w", prio = 10 },
|
||||||
|
b = { text = "b", prio = 9 },
|
||||||
|
e = { text = "e", prio = 8 },
|
||||||
|
ge = { text = "ge", prio = 7 },
|
||||||
|
W = { text = "W", prio = 7 },
|
||||||
|
B = { text = "B", prio = 6 },
|
||||||
|
E = { text = "E", prio = 5 },
|
||||||
|
gE = { text = "gE", prio = 4 },
|
||||||
|
|
||||||
|
f = { text = "f", prio = 10 },
|
||||||
|
F = { text = "F", prio = 9 },
|
||||||
|
t = { text = "t", prio = 8 },
|
||||||
|
T = { text = "T", prio = 7 },
|
||||||
|
|
||||||
|
["("] = { text = "(", prio = 3 },
|
||||||
|
[")"] = { text = ")", prio = 3 },
|
||||||
|
},
|
||||||
|
gutterHints = {
|
||||||
|
G = { text = "G" },
|
||||||
|
gg = { text = "gg" },
|
||||||
|
PrevParagraph = { text = "{" },
|
||||||
|
NextParagraph = { text = "}" },
|
||||||
|
|
||||||
|
Top = { text = "H" },
|
||||||
|
Middle = { text = "M" },
|
||||||
|
Bottom = { text = "L" },
|
||||||
|
|
||||||
|
SearchForward = { text = "/" },
|
||||||
|
SearchBackward = { text = "?" },
|
||||||
|
NextMatch = { text = "n" },
|
||||||
|
PrevMatch = { text = "N" },
|
||||||
|
|
||||||
|
MarkJump = { text = "'" },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
22
lua/plugins/render-markdown.lua
Normal file
22
lua/plugins/render-markdown.lua
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
return {
|
||||||
|
"MeanderingProgrammer/render-markdown.nvim",
|
||||||
|
opts = {
|
||||||
|
heading = {
|
||||||
|
sign = false,
|
||||||
|
icons = { "> ", "> " },
|
||||||
|
width = { "full", "block" },
|
||||||
|
left_pad = 1,
|
||||||
|
right_pad = 2,
|
||||||
|
},
|
||||||
|
checkbox = {
|
||||||
|
enabled = true,
|
||||||
|
unchecked = { icon = " ", highlight = "RenderMarkdownUnchecked" },
|
||||||
|
checked = { icon = " ", highlight = "RenderMarkdownChecked" },
|
||||||
|
},
|
||||||
|
bullet = {
|
||||||
|
enabled = true,
|
||||||
|
icons = { "●", "○", "◆", "◇" },
|
||||||
|
},
|
||||||
|
anti_conceal = { enabled = false },
|
||||||
|
},
|
||||||
|
}
|
||||||
70
lua/plugins/snacks.lua
Normal file
70
lua/plugins/snacks.lua
Normal file
|
|
@ -0,0 +1,70 @@
|
||||||
|
return {
|
||||||
|
-- Import the snacks explorer extra
|
||||||
|
{ import = "lazyvim.plugins.extras.editor.snacks_explorer" },
|
||||||
|
|
||||||
|
-- Configure snacks.nvim
|
||||||
|
{
|
||||||
|
"folke/snacks.nvim",
|
||||||
|
-- keys = {
|
||||||
|
-- {
|
||||||
|
-- "\\",
|
||||||
|
-- function()
|
||||||
|
-- Snacks.explorer()
|
||||||
|
-- end,
|
||||||
|
-- desc = "Toggle Snacks Explorer (Picker)",
|
||||||
|
-- },
|
||||||
|
-- { "<leader>e", false },
|
||||||
|
-- },
|
||||||
|
opts = {
|
||||||
|
dashboard = {
|
||||||
|
preset = {
|
||||||
|
header = [[
|
||||||
|
|
||||||
|
████████╗███████╗███╗ ███╗ █████╗ ██╗ ██╗ ███████╗
|
||||||
|
╚══██╔══╝██╔════╝████╗ ████║██╔══██╗██║ ██║ ██╔════╝
|
||||||
|
██║ ███████╗██╔████╔██║███████║██║ ██║ ███████╗
|
||||||
|
██║ ╚════██║██║╚██╔╝██║██╔══██║██║ ██║ ╚════██║
|
||||||
|
██║ ███████║██║ ╚═╝ ██║██║ ██║███████╗███████╗███████║
|
||||||
|
╚═╝ ╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚══════╝╚══════╝
|
||||||
|
|
||||||
|
|
||||||
|
]],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
scroll = {
|
||||||
|
enabled = false, -- Disable scrolling animations
|
||||||
|
},
|
||||||
|
picker = {
|
||||||
|
sources = {
|
||||||
|
explorer = {
|
||||||
|
hidden = false, -- Show hidden files by default
|
||||||
|
layout = { preset = "right" }, -- Position on the right
|
||||||
|
ignored = false,
|
||||||
|
git_status = true, -- Show git status
|
||||||
|
diagnostics = true, -- Show diagnostics
|
||||||
|
follow_file = true, -- Follow current file
|
||||||
|
win = {
|
||||||
|
list = {
|
||||||
|
keys = {
|
||||||
|
["P"] = "toggle_preview", -- Custom key
|
||||||
|
["L"] = function()
|
||||||
|
-- Get current line and try to extract file path
|
||||||
|
local line = vim.api.nvim_get_current_line()
|
||||||
|
local filepath = line:match("%s*(.-)%s*$") -- trim whitespace
|
||||||
|
|
||||||
|
if filepath and vim.fn.filereadable(filepath) == 1 then
|
||||||
|
local explorer_win = vim.api.nvim_get_current_win()
|
||||||
|
vim.cmd("wincmd p")
|
||||||
|
vim.cmd("edit " .. vim.fn.fnameescape(filepath))
|
||||||
|
vim.api.nvim_set_current_win(explorer_win)
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
3
lua/plugins/telescope.lua
Normal file
3
lua/plugins/telescope.lua
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
return {
|
||||||
|
{ import = "lazyvim.plugins.extras.editor.telescope" },
|
||||||
|
}
|
||||||
19
lua/plugins/toggle-term.lua
Normal file
19
lua/plugins/toggle-term.lua
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
return {
|
||||||
|
"akinsho/toggleterm.nvim",
|
||||||
|
version = "*",
|
||||||
|
|
||||||
|
keys = {
|
||||||
|
{ "<leader>tt", "<cmd>ToggleTerm direction=float<cr>", desc = "Toggle Terminal" },
|
||||||
|
},
|
||||||
|
|
||||||
|
opts = {
|
||||||
|
open_mapping = [[<leader>tt]],
|
||||||
|
direction = "float",
|
||||||
|
float_opts = { border = "rounded" },
|
||||||
|
shell = (os.getenv("SHELL") or vim.fn.exepath("zsh") or vim.fn.exepath("bash")) .. " -l -i",
|
||||||
|
},
|
||||||
|
|
||||||
|
config = function(_, opts)
|
||||||
|
require("toggleterm").setup(opts)
|
||||||
|
end,
|
||||||
|
}
|
||||||
61
lua/plugins/transparency.lua
Normal file
61
lua/plugins/transparency.lua
Normal file
|
|
@ -0,0 +1,61 @@
|
||||||
|
local function apply_transparency()
|
||||||
|
local groups = {
|
||||||
|
"Normal",
|
||||||
|
"NormalNC",
|
||||||
|
"NormalFloat",
|
||||||
|
"FloatBorder",
|
||||||
|
"SignColumn",
|
||||||
|
"LineNr",
|
||||||
|
"CursorLineNr",
|
||||||
|
"EndOfBuffer",
|
||||||
|
"TelescopeNormal",
|
||||||
|
"TelescopeBorder",
|
||||||
|
"TelescopePromptBorder",
|
||||||
|
"TelescopeResultsBorder",
|
||||||
|
"TelescopePreviewBorder",
|
||||||
|
"NeoTreeNormal",
|
||||||
|
"NeoTreeNormalNC",
|
||||||
|
"NeoTreeWinSeparator",
|
||||||
|
"NeoTreeEndOfBuffer",
|
||||||
|
"Pmenu",
|
||||||
|
"PmenuSel",
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, group in ipairs(groups) do
|
||||||
|
vim.api.nvim_set_hl(0, group, { bg = "none" })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return {
|
||||||
|
{
|
||||||
|
"LazyVim/LazyVim",
|
||||||
|
opts = {
|
||||||
|
colorscheme = function()
|
||||||
|
vim.cmd("colorscheme tokyonight") -- or your theme
|
||||||
|
apply_transparency()
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
-- Automatically re-apply transparency when UI elements refresh
|
||||||
|
{
|
||||||
|
"xiyaowong/transparent.nvim",
|
||||||
|
event = "VeryLazy",
|
||||||
|
config = function()
|
||||||
|
-- when floats open
|
||||||
|
vim.api.nvim_create_autocmd("User", {
|
||||||
|
pattern = {
|
||||||
|
"SnacksPickerOpen",
|
||||||
|
"SnacksPickerClose",
|
||||||
|
"LazyVimFloat",
|
||||||
|
},
|
||||||
|
callback = apply_transparency,
|
||||||
|
})
|
||||||
|
|
||||||
|
-- when switching colorscheme
|
||||||
|
vim.api.nvim_create_autocmd("ColorScheme", {
|
||||||
|
callback = apply_transparency,
|
||||||
|
})
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
}
|
||||||
40
lua/plugins/typescript.lua
Normal file
40
lua/plugins/typescript.lua
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
return {
|
||||||
|
-- disable vtsls
|
||||||
|
{
|
||||||
|
"neovim/nvim-lspconfig",
|
||||||
|
opts = {
|
||||||
|
servers = {
|
||||||
|
vtsls = false,
|
||||||
|
tsserver = false,
|
||||||
|
},
|
||||||
|
inlay_hints = {
|
||||||
|
enabled = false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
-- enable typescript-tools
|
||||||
|
{
|
||||||
|
"pmizio/typescript-tools.nvim",
|
||||||
|
ft = {
|
||||||
|
"typescript",
|
||||||
|
"typescriptreact",
|
||||||
|
"javascript",
|
||||||
|
"javascriptreact",
|
||||||
|
},
|
||||||
|
opts = {
|
||||||
|
settings = {
|
||||||
|
tsserver_file_preferences = {
|
||||||
|
disableSuggestions = false,
|
||||||
|
includeInlayParameterNameHints = "all",
|
||||||
|
includeCompletionsForModuleExports = true,
|
||||||
|
},
|
||||||
|
tsserver_enable_partial_semantic_mode = true,
|
||||||
|
tsserver_watch_options = {
|
||||||
|
watchFile = "useFsEvents", -- recommended for remote/container
|
||||||
|
watchDirectory = "useFsEvents",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
9
lua/plugins/which-key.lua
Normal file
9
lua/plugins/which-key.lua
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
return {
|
||||||
|
"folke/which-key.nvim",
|
||||||
|
opts = {
|
||||||
|
spec = {
|
||||||
|
{ "<leader>m", group = "markdown" },
|
||||||
|
{ "<leader>mm", group = "move task" },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue