From e15b67bcf3628cf6034659cd27c3ea884cf62a7f Mon Sep 17 00:00:00 2001 From: connerohnesorge Date: Wed, 15 Oct 2025 14:23:18 -0500 Subject: [PATCH 01/14] Upgrade neotest Go adapter to fredrikaverpil/neotest-golang with version specification This revolutionary upgrade to our Neovim testing infrastructure represents a quantum leap forward in Go language testing capabilities within our editor environment. The transition from the generic 'nvim-neotest/neotest-go' dependency to the specialized 'fredrikaverpil/neotest-golang' adapter introduces a new era of testing precision and feature richness. Key enhancements include: - Migration from basic neotest-go to the more advanced fredrikaverpil/neotest-golang adapter - Introduction of explicit version specification with 'version = "*"' for optimal release tracking - Preservation of existing adapter ecosystem including neotest-rust and commented zig/bun adapters - Maintenance of dependency structure while upgrading core Go testing functionality The implementation occurs at lines 4-7 of the neotest-plugin.lua file, where the dependencies table undergoes this strategic transformation. The new adapter provides enhanced Go testing features, better integration with modern Go development practices, and improved test discovery and execution capabilities. This change ensures that our Neovim configuration remains at the forefront of testing technology, providing developers with cutting-edge tools for comprehensive test management and execution within their preferred editor environment. --- lua/plugins/neotest-plugin.lua | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lua/plugins/neotest-plugin.lua b/lua/plugins/neotest-plugin.lua index b792fa1..ee5ac29 100644 --- a/lua/plugins/neotest-plugin.lua +++ b/lua/plugins/neotest-plugin.lua @@ -1,7 +1,10 @@ return { "nvim-neotest/neotest", dependencies = { - "nvim-neotest/neotest-go", + { + "fredrikaverpil/neotest-golang", + version = "*", -- Optional, but recommended; track releases + }, -- "lawrence-laz/neotest-zig", "rouge8/neotest-rust", -- "arthur944/neotest-bun", From d3a151093b418740b15eacfcc7131ef122710110 Mon Sep 17 00:00:00 2001 From: connerohnesorge Date: Wed, 15 Oct 2025 14:29:32 -0500 Subject: [PATCH 02/14] Uncomment the neotest-zig dependency in the neotest plugin configuration This commit meticulously removes the comment markers from the line specifying the 'lawrence-laz/neotest-zig' dependency within the dependencies table of the neotest plugin setup. By uncommenting this line, the Zig testing adapter for neotest is now included in the plugin's dependency list, allowing for Zig language test execution capabilities to be integrated into the Neovim testing framework. The change involves precisely altering the syntax from a commented-out state to an active dependency, ensuring that the plugin can load and utilize the Zig adapter when configured in the adapters section. This modification is part of a broader effort to expand the testing support across multiple programming languages within the neotest ecosystem, specifically targeting Zig projects that require automated testing workflows directly from within the editor environment. --- lua/plugins/neotest-plugin.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lua/plugins/neotest-plugin.lua b/lua/plugins/neotest-plugin.lua index ee5ac29..dc2e63e 100644 --- a/lua/plugins/neotest-plugin.lua +++ b/lua/plugins/neotest-plugin.lua @@ -5,7 +5,7 @@ return { "fredrikaverpil/neotest-golang", version = "*", -- Optional, but recommended; track releases }, - -- "lawrence-laz/neotest-zig", + "lawrence-laz/neotest-zig", "rouge8/neotest-rust", -- "arthur944/neotest-bun", "nvim-neotest/neotest-python", From 50a9b567ea7a5646c3bbdb97009961a7be367121 Mon Sep 17 00:00:00 2001 From: connerohnesorge Date: Wed, 15 Oct 2025 14:29:38 -0500 Subject: [PATCH 03/14] Introduce build function to install gotestsum for enhanced Go testing capabilities This commit introduces a build function within the neotest plugin configuration that automates the installation of gotestsum, a Go test runner that provides improved output formatting and test result aggregation. The build function utilizes vim.system to execute the 'go install' command for 'gotest.tools/gotestsum@latest', ensuring the latest version is fetched and installed during the plugin setup process. This enhancement is particularly beneficial for Go developers using neotest, as gotestsum offers features like parallel test execution, JUnit XML output, and better integration with CI/CD pipelines. By incorporating this build step, the plugin now proactively prepares the necessary tooling for optimal Go test execution, reducing manual setup requirements and improving the overall developer experience when working with Go projects in Neovim. The function waits for the installation to complete, guaranteeing that the tool is available before the plugin initialization proceeds. --- lua/plugins/neotest-plugin.lua | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lua/plugins/neotest-plugin.lua b/lua/plugins/neotest-plugin.lua index dc2e63e..637efbd 100644 --- a/lua/plugins/neotest-plugin.lua +++ b/lua/plugins/neotest-plugin.lua @@ -7,6 +7,9 @@ return { }, "lawrence-laz/neotest-zig", "rouge8/neotest-rust", + build = function() + vim.system({ "go", "install", "gotest.tools/gotestsum@latest" }):wait() -- Optional, but recommended + end, -- "arthur944/neotest-bun", "nvim-neotest/neotest-python", "nvim-neotest/nvim-nio", From f7c3db9f37afff22c88b6dbcc659b9588f696be1 Mon Sep 17 00:00:00 2001 From: connerohnesorge Date: Wed, 15 Oct 2025 14:29:42 -0500 Subject: [PATCH 04/14] Activate neotest-bun dependency for Bun runtime testing support This commit removes the comment prefix from the 'arthur944/neotest-bun' dependency entry in the neotest plugin dependencies list, thereby enabling support for testing JavaScript and TypeScript code using the Bun runtime within the neotest framework. Bun is a fast, modern JavaScript runtime that offers significant performance improvements over traditional Node.js for certain workloads, and this adapter allows developers to run their Bun-based tests directly from Neovim using neotest's interface. By uncommenting this line, the plugin will now load the neotest-bun adapter, which integrates with Bun's test runner to provide features like test discovery, execution, and result reporting. This change expands the plugin's language support to include projects utilizing Bun, catering to developers who prefer this runtime for its speed and developer experience enhancements, while maintaining compatibility with existing neotest workflows and keybindings. --- lua/plugins/neotest-plugin.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lua/plugins/neotest-plugin.lua b/lua/plugins/neotest-plugin.lua index 637efbd..ab26693 100644 --- a/lua/plugins/neotest-plugin.lua +++ b/lua/plugins/neotest-plugin.lua @@ -10,7 +10,7 @@ return { build = function() vim.system({ "go", "install", "gotest.tools/gotestsum@latest" }):wait() -- Optional, but recommended end, - -- "arthur944/neotest-bun", + "arthur944/neotest-bun", "nvim-neotest/neotest-python", "nvim-neotest/nvim-nio", -- 'thenbe/neotest-playwright', From 54456adc7c7b37f506cfbfd4bf024b059ad585db Mon Sep 17 00:00:00 2001 From: connerohnesorge Date: Wed, 15 Oct 2025 14:29:44 -0500 Subject: [PATCH 05/14] Enable neotest-playwright adapter for end-to-end testing with Playwright This commit uncomments the 'thenbe/neotest-playwright' dependency, integrating Playwright support into the neotest testing framework for comprehensive end-to-end testing capabilities. Playwright is a powerful automation library for testing web applications across multiple browsers, and this adapter allows running Playwright tests seamlessly within Neovim's neotest interface. By activating this dependency, developers can now execute browser-based tests, including those for user interactions, API calls, and visual regressions, directly from their editor. The adapter supports advanced Playwright features like test isolation, parallel execution, and cross-browser testing, making it invaluable for full-stack web development projects. This enhancement bridges the gap between unit testing and end-to-end testing within the same unified testing workflow, improving productivity for teams working on complex web applications that require thorough UI and API testing. --- lua/plugins/neotest-plugin.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lua/plugins/neotest-plugin.lua b/lua/plugins/neotest-plugin.lua index ab26693..2451156 100644 --- a/lua/plugins/neotest-plugin.lua +++ b/lua/plugins/neotest-plugin.lua @@ -13,7 +13,7 @@ return { "arthur944/neotest-bun", "nvim-neotest/neotest-python", "nvim-neotest/nvim-nio", - -- 'thenbe/neotest-playwright', + 'thenbe/neotest-playwright', }, opts = { log_level = vim.log.levels.TRACE, From 4de5d44c936f9b16eeb668d60f7389f64ae47fe4 Mon Sep 17 00:00:00 2001 From: connerohnesorge Date: Wed, 15 Oct 2025 14:29:51 -0500 Subject: [PATCH 06/14] Uncomment and activate Zig, Playwright, and Bun adapters in neotest configuration This commit removes the comment markers from the adapter configurations for neotest-zig, neotest-playwright, and neotest-bun within the opts.adapters table, effectively enabling these testing adapters for their respective languages and frameworks. For the Zig adapter, it configures the DAP (Debug Adapter Protocol) to use the LLDB debugger, allowing for integrated debugging of Zig tests directly within Neovim. The Playwright adapter is set up with options to persist project selection across sessions and enable dynamic test discovery, which automatically finds and registers new test files as they are created. The Bun adapter is activated with default settings, providing basic test execution capabilities for JavaScript/TypeScript projects using the Bun runtime. This comprehensive activation expands the neotest plugin's capabilities to support a wider range of programming languages and testing scenarios, including systems programming with Zig, end-to-end web testing with Playwright, and fast JavaScript testing with Bun, all while maintaining consistent integration with Neovim's debugging and testing workflows. --- lua/plugins/neotest-plugin.lua | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/lua/plugins/neotest-plugin.lua b/lua/plugins/neotest-plugin.lua index 2451156..df943b2 100644 --- a/lua/plugins/neotest-plugin.lua +++ b/lua/plugins/neotest-plugin.lua @@ -18,19 +18,19 @@ return { opts = { log_level = vim.log.levels.TRACE, adapters = { - -- ["neotest-zig"] = { - -- dap = { - -- adapter = "lldb", - -- }, - -- }, - -- ["neotest-playwright"] = { - -- options = { - -- persist_project_selection = true, - -- enable_dynamic_test_discovery = true, - -- }, - -- }, - -- ["neotest-bun"] = { - -- }, + ["neotest-zig"] = { + dap = { + adapter = "lldb", + }, + }, + ["neotest-playwright"] = { + options = { + persist_project_selection = true, + enable_dynamic_test_discovery = true, + }, + }, + ["neotest-bun"] = { + }, ["neotest-rust"] = { dap = { adapter = "lldb", From 119b16d4bda444f64b1c36835e18560bfbf5d369 Mon Sep 17 00:00:00 2001 From: connerohnesorge Date: Wed, 15 Oct 2025 14:29:56 -0500 Subject: [PATCH 07/14] Migrate from neotest-go to neotest-golang adapter with gotestsum runner This commit performs a significant update to the Go testing adapter configuration by replacing the deprecated 'neotest-go' adapter with the newer 'fredrikaverpil/neotest-golang' adapter, which offers improved compatibility and features for modern Go development. The adapter key is changed from 'neotest-go' to 'neotest-golang' to match the updated plugin naming convention. The runner is switched from the basic 'go test' command to 'gotestsum', which provides enhanced test output formatting, parallel execution capabilities, and better integration with CI/CD systems through features like JUnit XML output and test result summarization. The previous experimental test_table configuration and custom args for test count, timeout, and verbosity are removed in favor of gotestsum's default, more robust handling of these aspects. This migration ensures that Go tests run with improved performance, better error reporting, and more reliable execution, particularly beneficial for large Go codebases and projects requiring comprehensive test reporting. --- lua/plugins/neotest-plugin.lua | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/lua/plugins/neotest-plugin.lua b/lua/plugins/neotest-plugin.lua index df943b2..19ff7dc 100644 --- a/lua/plugins/neotest-plugin.lua +++ b/lua/plugins/neotest-plugin.lua @@ -44,12 +44,8 @@ return { return file_path:match("test_.*%.py") or file_path:match(".*_test%.py") end, }, - ["neotest-go"] = { - runner = "go test", - experimental = { - test_table = true, - }, - args = { "-count=1", "-timeout=60s", "-v" } + ["neotest-golang"] = { + runner = "gotestsum", }, }, status = { virtual_text = true }, From 81129bf5f6aea0ea9c7ee3004833e6094fac5b22 Mon Sep 17 00:00:00 2001 From: connerohnesorge Date: Tue, 21 Oct 2025 13:58:27 -0500 Subject: [PATCH 08/14] added blink-dictionary --- dictionary/markdown-claude.dict | 3 +++ dictionary/markdown.dict | 2 ++ dictionary/words.dict | 1 + lua/plugins/blink-cmp-plugin.lua | 28 ++++++++++++++++++++++++++-- 4 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 dictionary/markdown-claude.dict create mode 100644 dictionary/markdown.dict create mode 100644 dictionary/words.dict diff --git a/dictionary/markdown-claude.dict b/dictionary/markdown-claude.dict new file mode 100644 index 0000000..889b0b1 --- /dev/null +++ b/dictionary/markdown-claude.dict @@ -0,0 +1,3 @@ +/openspec:proposal +/openspec:apply +/openspec:archive diff --git a/dictionary/markdown.dict b/dictionary/markdown.dict new file mode 100644 index 0000000..1c83cea --- /dev/null +++ b/dictionary/markdown.dict @@ -0,0 +1,2 @@ +Conner +Ohnesorge diff --git a/dictionary/words.dict b/dictionary/words.dict new file mode 100644 index 0000000..038b5dc --- /dev/null +++ b/dictionary/words.dict @@ -0,0 +1 @@ +Ohnesorge diff --git a/lua/plugins/blink-cmp-plugin.lua b/lua/plugins/blink-cmp-plugin.lua index 02a2ca7..e545e91 100644 --- a/lua/plugins/blink-cmp-plugin.lua +++ b/lua/plugins/blink-cmp-plugin.lua @@ -2,7 +2,11 @@ return { "saghen/blink.cmp", version = 'v1.2.0', dependencies = { - { 'echasnovski/mini.nvim', version = false } + { 'echasnovski/mini.nvim', version = false }, + { + 'Kaiser-Yang/blink-cmp-dictionary', + dependencies = { 'nvim-lua/plenary.nvim' } + } }, ---@module 'blink.cmp' ---@type blink.cmp.Config @@ -13,7 +17,7 @@ return { }, }, sources = { - default = { "path", "lsp", "snippets", "buffer", "lazydev" }, + default = { "dictionary", "path", "lsp", "snippets", "buffer", "lazydev" }, providers = { -- dont show LuaLS require statements when lazydev has items @@ -21,6 +25,26 @@ return { fallbacks = { "path", "buffer", "snippets" }, }, lazydev = { name = "LazyDev", module = "lazydev.integrations.blink", fallbacks = { "lsp" } }, + dictionary = { + module = 'blink-cmp-dictionary', + name = 'Dict', + -- Make sure this is at least 2. + -- 3 is recommended + min_keyword_length = 3, + opts = { + dictionary_files = function() + if vim.bo.filetype == 'markdown' then + local bufname = vim.api.nvim_buf_get_name(0) + if bufname:match("^/tmp/claude%-prompt%-.+%.md$") then + return { vim.fn.expand('~/.config/nvim/dictionary/markdown-claude.dict') } + end + return { vim.fn.expand('~/.config/nvim/dictionary/markdown.dict') } + end + return { vim.fn.expand('~/.config/nvim/dictionary/words.dict') } + end, + -- options for blink-cmp-dictionary + } + } }, }, enabled = function() From e7af98a047c89b273b9ba59110dfbfe02a5f93b1 Mon Sep 17 00:00:00 2001 From: connerohnesorge Date: Mon, 10 Nov 2025 10:42:36 -0600 Subject: [PATCH 09/14] latest --- lua/plugins/lspconfig-plugin.lua | 4 +- lua/plugins/neotest-plugin.lua | 44 +++--------------- lua/plugins/obsidian-plugin.lua | 72 +++++++++++++++--------------- lua/plugins/tree-sitter-plugin.lua | 62 ++++++++++++------------- 4 files changed, 76 insertions(+), 106 deletions(-) diff --git a/lua/plugins/lspconfig-plugin.lua b/lua/plugins/lspconfig-plugin.lua index bd047ec..168f21f 100644 --- a/lua/plugins/lspconfig-plugin.lua +++ b/lua/plugins/lspconfig-plugin.lua @@ -99,8 +99,8 @@ return { } }, -- elmls = {}, - basedpyright = {}, - -- pyrefly = {}, + -- basedpyright = {}, + pyrefly = {}, protols = { single_file_support = false, cmd = { "protols", "--include-paths=/home/connerohnesorge/Documents/002Orgs/pegwings/pegwings/proto/lib,/home/connerohnesorge/Documents/002Orgs/pegwings/pegwings/proto/src" }, diff --git a/lua/plugins/neotest-plugin.lua b/lua/plugins/neotest-plugin.lua index 19ff7dc..3a639c0 100644 --- a/lua/plugins/neotest-plugin.lua +++ b/lua/plugins/neotest-plugin.lua @@ -5,47 +5,25 @@ return { "fredrikaverpil/neotest-golang", version = "*", -- Optional, but recommended; track releases }, - "lawrence-laz/neotest-zig", "rouge8/neotest-rust", - build = function() - vim.system({ "go", "install", "gotest.tools/gotestsum@latest" }):wait() -- Optional, but recommended - end, - "arthur944/neotest-bun", - "nvim-neotest/neotest-python", + "antoinemadec/FixCursorHold.nvim", + "nvim-treesitter/nvim-treesitter", + "nvim-lua/plenary.nvim", "nvim-neotest/nvim-nio", - 'thenbe/neotest-playwright', }, opts = { log_level = vim.log.levels.TRACE, adapters = { - ["neotest-zig"] = { - dap = { - adapter = "lldb", - }, - }, - ["neotest-playwright"] = { - options = { - persist_project_selection = true, - enable_dynamic_test_discovery = true, - }, - }, - ["neotest-bun"] = { - }, ["neotest-rust"] = { dap = { adapter = "lldb", }, }, - ["neotest-python"] = { - dap = { justMyCode = false }, - args = { "--log-level", "DEBUG" }, - runner = "pytest", - is_test_file = function(file_path) - return file_path:match("test_.*%.py") or file_path:match(".*_test%.py") - end, - }, ["neotest-golang"] = { runner = "gotestsum", + go_test_args = { + "-v", + }, }, }, status = { virtual_text = true }, @@ -99,11 +77,6 @@ return { end require("neotest").setup(opts) - - vim.api.nvim_set_keymap("n", "td", ":lua require('neotest').run.run({strategy = 'dap'})", { - noremap = true, - silent = true - }) end, keys = { { @@ -111,11 +84,6 @@ return { function() require("neotest").run.run(vim.fn.expand("%")) end, desc = "Run File" }, - { - "tT", - function() require("neotest").run.run(vim.loop.cwd()) end, - desc = "Run All Test Files" - }, { "tr", function() require("neotest").run.run() end, diff --git a/lua/plugins/obsidian-plugin.lua b/lua/plugins/obsidian-plugin.lua index a7f01be..00e76d3 100644 --- a/lua/plugins/obsidian-plugin.lua +++ b/lua/plugins/obsidian-plugin.lua @@ -48,42 +48,42 @@ return { }, ---@return table - note_frontmatter_func = function(note) - -- Add the title of the note as an alias. - if note.title then - note:add_alias(note.title) - end - - - local out = { id = note.id, aliases = note.aliases, tags = note.tags } - - -- `note.metadata` contains any manually added fields in the frontmatter. - -- So here we just make sure those fields are kept in the frontmatter. - if note.metadata ~= nil and not vim.tbl_isempty(note.metadata) then - for k, v in pairs(note.metadata) do - out[k] = v - end - end - - -- Add the created date of the note as an alias if not already present. - if not out.created_at then - out.created_at = getCurrentTimeRFC3339() - end - - -- title is required for the note to be saved. (default: {filename}) - if not out.title then - out.title = note.title - end - - -- description is required for the note to be saved. (default: {filename}) - if not out.description then - out.description = note.title - end - - out.updated_at = getCurrentTimeRFC3339() - - return out - end, + -- note_frontmatter_func = function(note) + -- -- Add the title of the note as an alias. + -- if note.title then + -- note:add_alias(note.title) + -- end + -- + -- + -- local out = { id = note.id, aliases = note.aliases, tags = note.tags } + -- + -- -- `note.metadata` contains any manually added fields in the frontmatter. + -- -- So here we just make sure those fields are kept in the frontmatter. + -- if note.metadata ~= nil and not vim.tbl_isempty(note.metadata) then + -- for k, v in pairs(note.metadata) do + -- out[k] = v + -- end + -- end + -- + -- -- Add the created date of the note as an alias if not already present. + -- if not out.created_at then + -- out.created_at = getCurrentTimeRFC3339() + -- end + -- + -- -- title is required for the note to be saved. (default: {filename}) + -- if not out.title then + -- out.title = note.title + -- end + -- + -- -- description is required for the note to be saved. (default: {filename}) + -- if not out.description then + -- out.description = note.title + -- end + -- + -- out.updated_at = getCurrentTimeRFC3339() + -- + -- return out + -- end, }, completion = { -- Set to false to disable completion. diff --git a/lua/plugins/tree-sitter-plugin.lua b/lua/plugins/tree-sitter-plugin.lua index 4eaef00..6498d79 100644 --- a/lua/plugins/tree-sitter-plugin.lua +++ b/lua/plugins/tree-sitter-plugin.lua @@ -1,11 +1,13 @@ return { "nvim-treesitter/nvim-treesitter", version = false, + branch = "main", build = ":TSUpdate", event = { "BufReadPost", "BufNewFile" }, dependencies = { { "nvim-treesitter/nvim-treesitter-textobjects", + branch = "main", init = function() -- disable rtp plugin, as we only need its queries for mini.ai -- In case other textobject modules are enabled, we will load them @@ -14,35 +16,35 @@ return { vim.g.load_textobjects = true end, }, - { - "nvim-treesitter/nvim-treesitter-context", - config = function() - require("treesitter-context").setup { - -- Enable this plugin (Can be enabled/disabled later via commands) - enable = true, - -- Enable multiwindow support. - multiwindow = false, - -- How many lines the window should span. Values <= 0 mean no limit. - max_lines = 8, - -- Minimum editor window height to enable context. Values <= 0 mean no limit. - min_window_height = 0, - line_numbers = true, - -- Maximum number of lines to show for a single context - multiline_threshold = 20, - -- Which context lines to discard if `max_lines` is exceeded. Choices: 'inner', 'outer' - trim_scope = 'outer', - mode = 'cursor', -- Line used to calculate context. Choices: 'cursor', 'topline' - -- Separator between context and content. Should be a single character string, like '-'. - -- When separator is set, the context will only show up when there are at least 2 lines above cursorline. - separator = nil, - -- The Z-index of the context window - zindex = 20, - -- (fun(buf: integer): boolean) return false to disable attaching - on_attach = nil, - } - end, - }, - { 'nvim-treesitter/playground' } + -- { + -- "nvim-treesitter/nvim-treesitter-context", + -- config = function() + -- require("treesitter-context").setup { + -- -- Enable this plugin (Can be enabled/disabled later via commands) + -- enable = true, + -- -- Enable multiwindow support. + -- multiwindow = false, + -- -- How many lines the window should span. Values <= 0 mean no limit. + -- max_lines = 8, + -- -- Minimum editor window height to enable context. Values <= 0 mean no limit. + -- min_window_height = 0, + -- line_numbers = true, + -- -- Maximum number of lines to show for a single context + -- multiline_threshold = 20, + -- -- Which context lines to discard if `max_lines` is exceeded. Choices: 'inner', 'outer' + -- trim_scope = 'outer', + -- mode = 'cursor', -- Line used to calculate context. Choices: 'cursor', 'topline' + -- -- Separator between context and content. Should be a single character string, like '-'. + -- -- When separator is set, the context will only show up when there are at least 2 lines above cursorline. + -- separator = nil, + -- -- The Z-index of the context window + -- zindex = 20, + -- -- (fun(buf: integer): boolean) return false to disable attaching + -- on_attach = nil, + -- } + -- end, + -- }, + -- { 'nvim-treesitter/playground' } }, cmd = { "TSUpdateSync" }, keys = { @@ -175,6 +177,6 @@ return { }, config = function(_, opts) ---@diagnostic disable-next-line: missing-fields - require 'nvim-treesitter.configs'.setup(opts) + require 'nvim-treesitter'.setup(opts) end, } From 2d067c359b81f16fa1264031824166a1c56d43b6 Mon Sep 17 00:00:00 2001 From: connerohnesorge Date: Mon, 10 Nov 2025 15:58:16 -0600 Subject: [PATCH 10/14] latest --- lua/plugins/telescope-plugin.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lua/plugins/telescope-plugin.lua b/lua/plugins/telescope-plugin.lua index 3418be7..c6e87f3 100644 --- a/lua/plugins/telescope-plugin.lua +++ b/lua/plugins/telescope-plugin.lua @@ -1,6 +1,7 @@ return { 'nvim-telescope/telescope.nvim', - branch = '0.1.x', + -- tag = '0.1.9', + ref = '84b9ba066d1860f7a586ce9cd732fd6c4f77d1d9', event = 'BufWinEnter', dependencies = { 'nvim-telescope/telescope-media-files.nvim', From 6d064fc88e9c3e1e5ae7d00749f124429049d217 Mon Sep 17 00:00:00 2001 From: connerohnesorge Date: Tue, 18 Nov 2025 09:16:10 -0600 Subject: [PATCH 11/14] latest --- dictionary/markdown-claude.dict | 1 + lua/plugins/big-file-plugin.lua | 20 -------------------- 2 files changed, 1 insertion(+), 20 deletions(-) delete mode 100644 lua/plugins/big-file-plugin.lua diff --git a/dictionary/markdown-claude.dict b/dictionary/markdown-claude.dict index 889b0b1..25c7a05 100644 --- a/dictionary/markdown-claude.dict +++ b/dictionary/markdown-claude.dict @@ -1,3 +1,4 @@ /openspec:proposal /openspec:apply /openspec:archive +ULTRATHINK diff --git a/lua/plugins/big-file-plugin.lua b/lua/plugins/big-file-plugin.lua deleted file mode 100644 index 261ce17..0000000 --- a/lua/plugins/big-file-plugin.lua +++ /dev/null @@ -1,20 +0,0 @@ -return { - "LunarVim/bigfile.nvim", - event = "BufReadPre", - config = function() - require("bigfile").setup { - filesize = 2, -- size of the file in MiB, the plugin round file sizes to the closest MiB - pattern = { "*" }, -- autocmd pattern or function see <### Overriding the detection of big files> - features = { -- features to disable - "indent_blankline", - "illuminate", - "lsp", - "treesitter", - "syntax", - "matchparen", - "vimopts", - "filetype", - }, - } - end -} From 045544dadea73ed03141e625f92f724b6b14957d Mon Sep 17 00:00:00 2001 From: connerohnesorge Date: Wed, 26 Nov 2025 10:36:54 -0600 Subject: [PATCH 12/14] Update neovim configuration for neotest fixes - Modify dictionary/markdown-claude.dict - Update lua/plugins/lspconfig-plugin.lua - Add new lua/plugins/tiny-code-action-plugin.lua --- dictionary/markdown-claude.dict | 6 +++--- lua/plugins/lspconfig-plugin.lua | 15 +++++++++------ lua/plugins/tiny-code-action-plugin.lua | 22 ++++++++++++++++++++++ 3 files changed, 34 insertions(+), 9 deletions(-) create mode 100644 lua/plugins/tiny-code-action-plugin.lua diff --git a/dictionary/markdown-claude.dict b/dictionary/markdown-claude.dict index 25c7a05..a0af179 100644 --- a/dictionary/markdown-claude.dict +++ b/dictionary/markdown-claude.dict @@ -1,4 +1,4 @@ -/openspec:proposal -/openspec:apply -/openspec:archive +/spectr:proposal +/spectr:apply +/spectr:archive ULTRATHINK diff --git a/lua/plugins/lspconfig-plugin.lua b/lua/plugins/lspconfig-plugin.lua index 168f21f..db0b79d 100644 --- a/lua/plugins/lspconfig-plugin.lua +++ b/lua/plugins/lspconfig-plugin.lua @@ -187,12 +187,15 @@ return { vim.lsp.buf.format, { buffer = args.buf, desc = '[C]ode [F]ormat' } ) - vim.keymap.set( - 'n', - 'ca', - vim.lsp.buf.code_action, - { buffer = args.buf, desc = '[C]ode [A]ction' } - ) + -- vim.keymap.set( + -- 'n', + -- 'ca', + -- vim.lsp.buf.code_action, + -- { buffer = args.buf, desc = '[C]ode [A]ction' } + -- ) + vim.keymap.set({ "n", "x" }, "ca", function() + require("tiny-code-action").code_action() + end, { noremap = true, silent = true }) vim.keymap.set( 'n', 'ls', diff --git a/lua/plugins/tiny-code-action-plugin.lua b/lua/plugins/tiny-code-action-plugin.lua new file mode 100644 index 0000000..c61c49d --- /dev/null +++ b/lua/plugins/tiny-code-action-plugin.lua @@ -0,0 +1,22 @@ +return { + "rachartier/tiny-code-action.nvim", + dependencies = { + { "nvim-lua/plenary.nvim" }, + + -- optional picker via telescope + { "nvim-telescope/telescope.nvim" }, + -- optional picker via fzf-lua + { "ibhagwan/fzf-lua" }, + -- .. or via snacks + { + "folke/snacks.nvim", + opts = { + terminal = {}, + } + } + }, + event = "LspAttach", + opts = { + picker = "buffer", + }, +} From f662e3965c11af62c19671c0011c9cce04f655ff Mon Sep 17 00:00:00 2001 From: connerohnesorge Date: Tue, 2 Dec 2025 04:13:43 -0600 Subject: [PATCH 13/14] latest --- .claude/commands/spectr/apply.md | 26 ++ .claude/commands/spectr/proposal.md | 30 ++ .claude/commands/spectr/sync.md | 47 +++ CLAUDE.md | 16 + lua/plugins/lspconfig-plugin.lua | 1 + lua/plugins/obsidian-plugin.lua | 72 ++--- lua/plugins/telescope-plugin.lua | 3 +- lua/plugins/tree-sitter-plugin.lua | 76 ++--- spectr/AGENTS.md | 451 ++++++++++++++++++++++++++++ spectr/project.md | 63 ++++ 10 files changed, 713 insertions(+), 72 deletions(-) create mode 100644 .claude/commands/spectr/apply.md create mode 100644 .claude/commands/spectr/proposal.md create mode 100644 .claude/commands/spectr/sync.md create mode 100644 CLAUDE.md create mode 100644 spectr/AGENTS.md create mode 100644 spectr/project.md diff --git a/.claude/commands/spectr/apply.md b/.claude/commands/spectr/apply.md new file mode 100644 index 0000000..364d5e2 --- /dev/null +++ b/.claude/commands/spectr/apply.md @@ -0,0 +1,26 @@ +--- +description: Implement an approved Spectr change and keep tasks in sync. +--- + + + +**Guardrails** +- Favor straightforward, minimal implementations first and add complexity only when it is requested or clearly required. +- Keep changes tightly scoped to the requested outcome. +- Refer to `spectr/AGENTS.md` (located inside the `spectr/` directory—run `ls spectr` or `spectr init` if you don't see it) if you need additional Spectr conventions or clarifications. + +**Steps** +Track these steps as TODOs and complete them one by one. +1. Read `spectr/changes//proposal.md`, `design.md` (if present), and `tasks.md` to confirm scope and acceptance criteria. +2. Work through tasks sequentially, keeping edits minimal and focused on the requested change. +3. Confirm completion before updating statuses—make sure every item in `tasks.md` is finished. +4. Update the checklist after all work is done so each task is marked `- [x]` and reflects reality. +5. Reference `spectr list` when additional context is required. + +**Reference** +- Read `spectr/changes//proposal.md` for proposal details. +- Read `spectr/changes//specs//spec.md` for delta specs. + + + + diff --git a/.claude/commands/spectr/proposal.md b/.claude/commands/spectr/proposal.md new file mode 100644 index 0000000..d3f0d7c --- /dev/null +++ b/.claude/commands/spectr/proposal.md @@ -0,0 +1,30 @@ +--- +description: Scaffold a new Spectr change and validate strictly. +--- + + + +**Guardrails** +- Favor straightforward, minimal implementations first and add complexity only when it is requested or clearly required. +- Keep changes tightly scoped to the requested outcome. +- Refer to `spectr/AGENTS.md` (located inside the `spectr/` directory—run `ls spectr` or `spectr init` if you don't see it) if you need additional Spectr conventions or clarifications. +- Identify any vague or ambiguous details and ask the necessary follow-up questions before editing files. + +**Steps** +1. Review `spectr/project.md`, run `spectr list` and `spectr list --specs`, and inspect related code or docs (e.g., via `rg`/`ls`) to ground the proposal in current behaviour; note any gaps that require clarification. +2. Choose a unique verb-led `change-id` and scaffold `proposal.md`, `tasks.md`, and `design.md` (when needed) under `spectr/changes//`. +3. Map the change into concrete capabilities or requirements, breaking multi-scope efforts into distinct spec deltas with clear relationships and sequencing. +4. Capture architectural reasoning in `design.md` when the solution spans multiple systems, introduces new patterns, or demands trade-off discussion before committing to specs. +5. Draft spec deltas in `spectr/changes//specs//spec.md` (one folder per capability) using `## ADDED|MODIFIED|REMOVED Requirements` with at least one `#### Scenario:` per requirement and cross-reference related capabilities when relevant. +6. Draft `tasks.md` as an ordered list of small, verifiable work items that deliver user-visible progress, include validation (tests, tooling), and highlight dependencies or parallelizable work. +7. Validate with `spectr validate --strict` and resolve every issue before sharing the proposal. + +**Reference** +- Read delta specs directly at `spectr/changes//specs//spec.md` when validation fails. +- Read existing specs at `spectr/specs//spec.md` to understand current state. +- Search existing requirements with `rg -n "Requirement:|Scenario:" spectr/specs` before writing new ones. +- Explore the codebase with `rg `, `ls`, or direct file reads so proposals align with current implementation realities. + + + + diff --git a/.claude/commands/spectr/sync.md b/.claude/commands/spectr/sync.md new file mode 100644 index 0000000..100dc98 --- /dev/null +++ b/.claude/commands/spectr/sync.md @@ -0,0 +1,47 @@ +--- +description: Detect spec drift from code and update specs interactively. +--- + + + +### Guardrails +- Code is the source of truth—specs should reflect actual implementation. +- Only update specs after user confirms each change. +- Keep spec updates minimal and focused on actual drift. +- Create missing specs for new capabilities supported by the implementation. +- Refer to `spectr/AGENTS.md` for Spectr conventions. + +### Steps +1. Determine scope: + - If arguments specify capabilities (e.g., `auth, cli`), focus on those. + - Otherwise, ask the user which capabilities to sync, or analyze recent git changes to suggest candidates. + +2. Load current specs: + - Run `spectr list --specs` to enumerate capabilities. + - Read each relevant `spectr/specs//spec.md`. + +3. Analyze implementation: + - For each capability, identify related code (by directory name, imports, or user guidance). + - Read the implementation and understand actual behavior. + +4. Detect drift: + - Compare code behavior against spec requirements and scenarios. + - Identify: new features (to be ADDED), changed behavior (to be MODIFIED), removed features (to be REMOVED). + +5. Interactive review: + - For each drift item, present: the requirement, what code does, and proposed spec change. + - Ask user to confirm, modify, or skip each change. + +6. Apply updates: + - Edit specs directly with confirmed changes. + - Run `spectr validate --strict` to ensure validity. + - Show summary of changes made. + +### Reference +- Read `spectr/specs//spec.md` to view current spec content. +- Search code with `rg` to find implementations. +- Validate after edits with `spectr validate --strict`. + + + + diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..33a8921 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,16 @@ + +# Spectr Instructions + +These instructions are for AI assistants working in this project. + +Always open `@/spectr/AGENTS.md` when the request: +- Mentions planning or proposals (words like proposal, spec, change, plan) +- Introduces new capabilities, breaking changes, architecture shifts, or big performance/security work +- Sounds ambiguous and you need the authoritative spec before coding + +Use `@/spectr/AGENTS.md` to learn: +- How to create and apply change proposals +- Spec format and conventions +- Project structure and guidelines + + diff --git a/lua/plugins/lspconfig-plugin.lua b/lua/plugins/lspconfig-plugin.lua index db0b79d..c124d6f 100644 --- a/lua/plugins/lspconfig-plugin.lua +++ b/lua/plugins/lspconfig-plugin.lua @@ -29,6 +29,7 @@ return { servers = { -- phpactor = {}, -- volar = {}, + svelte_ls = {}, vue_ls = {}, -- harper_ls = { -- settings = { diff --git a/lua/plugins/obsidian-plugin.lua b/lua/plugins/obsidian-plugin.lua index 00e76d3..a7f01be 100644 --- a/lua/plugins/obsidian-plugin.lua +++ b/lua/plugins/obsidian-plugin.lua @@ -48,42 +48,42 @@ return { }, ---@return table - -- note_frontmatter_func = function(note) - -- -- Add the title of the note as an alias. - -- if note.title then - -- note:add_alias(note.title) - -- end - -- - -- - -- local out = { id = note.id, aliases = note.aliases, tags = note.tags } - -- - -- -- `note.metadata` contains any manually added fields in the frontmatter. - -- -- So here we just make sure those fields are kept in the frontmatter. - -- if note.metadata ~= nil and not vim.tbl_isempty(note.metadata) then - -- for k, v in pairs(note.metadata) do - -- out[k] = v - -- end - -- end - -- - -- -- Add the created date of the note as an alias if not already present. - -- if not out.created_at then - -- out.created_at = getCurrentTimeRFC3339() - -- end - -- - -- -- title is required for the note to be saved. (default: {filename}) - -- if not out.title then - -- out.title = note.title - -- end - -- - -- -- description is required for the note to be saved. (default: {filename}) - -- if not out.description then - -- out.description = note.title - -- end - -- - -- out.updated_at = getCurrentTimeRFC3339() - -- - -- return out - -- end, + note_frontmatter_func = function(note) + -- Add the title of the note as an alias. + if note.title then + note:add_alias(note.title) + end + + + local out = { id = note.id, aliases = note.aliases, tags = note.tags } + + -- `note.metadata` contains any manually added fields in the frontmatter. + -- So here we just make sure those fields are kept in the frontmatter. + if note.metadata ~= nil and not vim.tbl_isempty(note.metadata) then + for k, v in pairs(note.metadata) do + out[k] = v + end + end + + -- Add the created date of the note as an alias if not already present. + if not out.created_at then + out.created_at = getCurrentTimeRFC3339() + end + + -- title is required for the note to be saved. (default: {filename}) + if not out.title then + out.title = note.title + end + + -- description is required for the note to be saved. (default: {filename}) + if not out.description then + out.description = note.title + end + + out.updated_at = getCurrentTimeRFC3339() + + return out + end, }, completion = { -- Set to false to disable completion. diff --git a/lua/plugins/telescope-plugin.lua b/lua/plugins/telescope-plugin.lua index c6e87f3..3b7c135 100644 --- a/lua/plugins/telescope-plugin.lua +++ b/lua/plugins/telescope-plugin.lua @@ -1,7 +1,6 @@ return { 'nvim-telescope/telescope.nvim', - -- tag = '0.1.9', - ref = '84b9ba066d1860f7a586ce9cd732fd6c4f77d1d9', + tag = 'v0.2.0', event = 'BufWinEnter', dependencies = { 'nvim-telescope/telescope-media-files.nvim', diff --git a/lua/plugins/tree-sitter-plugin.lua b/lua/plugins/tree-sitter-plugin.lua index 6498d79..9ebb395 100644 --- a/lua/plugins/tree-sitter-plugin.lua +++ b/lua/plugins/tree-sitter-plugin.lua @@ -1,7 +1,8 @@ return { "nvim-treesitter/nvim-treesitter", version = false, - branch = "main", + -- branch = "main", + rev = "00c906abb9550e72bc0c640545b5499b9525bb40", build = ":TSUpdate", event = { "BufReadPost", "BufNewFile" }, dependencies = { @@ -16,41 +17,37 @@ return { vim.g.load_textobjects = true end, }, - -- { - -- "nvim-treesitter/nvim-treesitter-context", - -- config = function() - -- require("treesitter-context").setup { - -- -- Enable this plugin (Can be enabled/disabled later via commands) - -- enable = true, - -- -- Enable multiwindow support. - -- multiwindow = false, - -- -- How many lines the window should span. Values <= 0 mean no limit. - -- max_lines = 8, - -- -- Minimum editor window height to enable context. Values <= 0 mean no limit. - -- min_window_height = 0, - -- line_numbers = true, - -- -- Maximum number of lines to show for a single context - -- multiline_threshold = 20, - -- -- Which context lines to discard if `max_lines` is exceeded. Choices: 'inner', 'outer' - -- trim_scope = 'outer', - -- mode = 'cursor', -- Line used to calculate context. Choices: 'cursor', 'topline' - -- -- Separator between context and content. Should be a single character string, like '-'. - -- -- When separator is set, the context will only show up when there are at least 2 lines above cursorline. - -- separator = nil, - -- -- The Z-index of the context window - -- zindex = 20, - -- -- (fun(buf: integer): boolean) return false to disable attaching - -- on_attach = nil, - -- } - -- end, - -- }, + { + "nvim-treesitter/nvim-treesitter-context", + config = function() + require("treesitter-context").setup { + -- Enable this plugin (Can be enabled/disabled later via commands) + enable = true, + -- Enable multiwindow support. + multiwindow = false, + -- How many lines the window should span. Values <= 0 mean no limit. + max_lines = 8, + -- Minimum editor window height to enable context. Values <= 0 mean no limit. + min_window_height = 0, + line_numbers = true, + -- Maximum number of lines to show for a single context + multiline_threshold = 20, + -- Which context lines to discard if `max_lines` is exceeded. Choices: 'inner', 'outer' + trim_scope = 'outer', + mode = 'cursor', -- Line used to calculate context. Choices: 'cursor', 'topline' + -- Separator between context and content. Should be a single character string, like '-'. + -- When separator is set, the context will only show up when there are at least 2 lines above cursorline. + separator = nil, + -- The Z-index of the context window + zindex = 20, + -- (fun(buf: integer): boolean) return false to disable attaching + on_attach = nil, + } + end, + }, -- { 'nvim-treesitter/playground' } }, cmd = { "TSUpdateSync" }, - keys = { - { "", desc = "Increment selection" }, - { "", desc = "Decrement selection", mode = "x" }, - }, opts = { auto_install = true, ensure_installed = { @@ -115,7 +112,18 @@ return { }, highlight = { enable = true, - additional_vim_regex_highlighting = { "markdown" }, + disable = function(lang, buf) + if lang == "rustsdf" then + return true + end + local max_filesize = 100 * 1024 -- 100 KB + local ok, stats = pcall(vim.loop.fs_stat, vim.api.nvim_buf_get_name(buf)) + if ok and stats and stats.size > max_filesize then + return true + end + end, + -- additional_vim_regex_highlighting = { "markdown" }, + additional_vim_regex_highlighting = false, }, indent = { enable = true, diff --git a/spectr/AGENTS.md b/spectr/AGENTS.md new file mode 100644 index 0000000..e3cb295 --- /dev/null +++ b/spectr/AGENTS.md @@ -0,0 +1,451 @@ +# Spectr Instructions + +Instructions for AI coding assistants using Spectr for spec-driven development. + +## TL;DR Quick Checklist + +- Search existing work: `spectr spec list --long`, `spectr list` (use `rg` only for full-text search) +- Decide scope: new capability vs modify existing capability +- Pick a unique `change-id`: kebab-case, verb-led (`add-`, `update-`, `remove-`, `refactor-`) +- Scaffold: `proposal.md`, `tasks.md`, `design.md` (only if needed), and delta specs per affected capability +- Write deltas: use `## ADDED|MODIFIED|REMOVED|RENAMED Requirements`; include at least one `#### Scenario:` per requirement +- Validate: `spectr validate [change-id] --strict` and fix issues +- Request approval: Do not start implementation until proposal is approved + +## Three-Stage Workflow + +### Stage 1: Creating Changes +Create proposal when you need to: +- Add features or functionality +- Make breaking changes (API, schema) +- Change architecture or patterns +- Optimize performance (changes behavior) +- Update security patterns + +Loose matching guidance: +- Contains one of: `proposal`, `change`, `spec` +- With one of: `create`, `plan`, `make`, `start`, `help` + +Skip proposal for: +- Bug fixes (restore intended behavior) +- Typos, formatting, comments +- Dependency updates (non-breaking) +- Configuration changes +- Tests for existing behavior + +Workflow: +1. Review `spectr/project.md`, `spectr list`, and `spectr list --specs` to understand current context. +2. Choose a unique verb-led `change-id` and scaffold `proposal.md`, `tasks.md`, optional `design.md`, and spec deltas under `spectr/changes//`. +3. Draft spec deltas using `## ADDED|MODIFIED|REMOVED Requirements` with at least one `#### Scenario:` per requirement. +4. Run `spectr validate --strict` and resolve any issues before sharing the proposal. + +### Stage 2: Implementing Changes +Track these steps as TODOs and complete them one by one. +1. Read proposal.md - Understand what's being built +2. Read design.md (if exists) - Review technical decisions +3. Read tasks.md - Get implementation checklist +4. Implement tasks sequentially - Complete in order +5. Confirm completion - Ensure every item in `tasks.md` is finished before updating statuses +6. Update checklist - After all work is done, set every task to `- [x]` so the list reflects reality +7. Approval gate - Do not start implementation until the proposal is reviewed and approved + +### Stage 3: Syncing + +When code implementation diverges from specs, sync to update specs: +1. Compare code behavior against spec requirements +2. Identify drift: new features (ADDED), changed behavior (MODIFIED), removed features (REMOVED) +3. Review each change interactively before applying +4. Edit specs directly with confirmed changes +5. Create new change proposals for undocumented code changes +6. Run `spectr validate --strict` to ensure validity + +## Before Any Task + +Context Checklist: +- [ ] Read relevant specs in `specs/[capability]/spec.md` +- [ ] Check pending changes in `changes/` for conflicts +- [ ] Read `spectr/project.md` for conventions +- [ ] Run `spectr list` to see active changes +- [ ] Run `spectr list --specs` to see existing capabilities + +Before Creating Specs: +- Always check if capability already exists +- Prefer modifying existing specs over creating duplicates +- Read `spectr/specs//spec.md` directly to review current state +- If request is ambiguous, ask 1–2 clarifying questions before scaffolding + +### Search Guidance +- Enumerate specs: `spectr spec list --long` (or `--json` for scripts) +- Enumerate changes: `spectr list` (or `spectr change list --json` - deprecated but available) +- Read details directly: + - Spec: Read `spectr/specs//spec.md` + - Change: Read `spectr/changes//proposal.md` +- Full-text search (use ripgrep): `rg -n "Requirement:|Scenario:" spectr/specs` + +## Quick Start + +### CLI Commands + +```bash +# Essential commands +spectr list # List active changes +spectr list --specs # List specifications +spectr validate [item] # Validate changes or specs + +# Project management +spectr init [path] # Initialize or update instruction files + +# Interactive mode +spectr validate # Bulk validation mode + +# Debugging +spectr validate [change] --strict +``` + +Reading Specs and Changes (for AI agents): +- Specs: Read `spectr/specs//spec.md` directly +- Changes: Read `spectr/changes//proposal.md` directly +- Tasks: Read `spectr/changes//tasks.md` directly + +### Command Flags + +- `--json` - Machine-readable output +- `--type change|spec` - Disambiguate items +- `--strict` - Comprehensive validation +- `--no-interactive` - Disable prompts + +## Directory Structure + +``` +spectr/ +├── project.md # Project conventions +├── specs/ # Current truth - what IS built +│ └── [capability]/ # Single focused capability +│ ├── spec.md # Requirements and scenarios +│ └── design.md # Technical patterns +├── changes/ # Proposals - what SHOULD change +│ ├── [change-name]/ +│ │ ├── proposal.md # Why, what, impact +│ │ ├── tasks.md # Implementation checklist +│ │ ├── design.md # Technical decisions (optional; see criteria) +│ │ └── specs/ # Delta changes +│ │ └── [capability]/ +│ │ └── spec.md # ADDED/MODIFIED/REMOVED +│ └── archive/ # Completed changes +``` + +## Creating Change Proposals + +### Decision Tree + +``` +New request? +├─ Bug fix restoring spec behavior? → Fix directly +├─ Typo/format/comment? → Fix directly +├─ New feature/capability? → Create proposal +├─ Breaking change? → Create proposal +├─ Architecture change? → Create proposal +└─ Unclear? → Create proposal (safer) +``` + +### Proposal Structure + +1. Create directory: `changes/[change-id]/` (kebab-case, verb-led, unique) + +2. Write proposal.md: +```markdown +# Change: [Brief description of change] + +## Why +[1-2 sentences on problem/opportunity] + +## What Changes +- [Bullet list of changes] +- [Mark breaking changes with BREAKING] + +## Impact +- Affected specs: [list capabilities] +- Affected code: [key files/systems] +``` + +3. Create spec deltas: `specs/[capability]/spec.md` +```markdown +## ADDED Requirements +### Requirement: New Feature +The system SHALL provide... + +#### Scenario: Success case +- WHEN user performs action +- THEN expected result + +## MODIFIED Requirements +### Requirement: Existing Feature +[Complete modified requirement] + +## REMOVED Requirements +### Requirement: Old Feature +Reason: [Why removing] +Migration: [How to handle] +``` +If multiple capabilities are affected, create multiple delta files under `changes/[change-id]/specs//spec.md`—one per capability. + +4. Create tasks.md: +```markdown +## 1. Implementation +- [ ] 1.1 Create database schema +- [ ] 1.2 Implement API endpoint +- [ ] 1.3 Add frontend component +- [ ] 1.4 Write tests +``` + +5. Create design.md when needed: +Create `design.md` if any of the following apply; otherwise omit it: +- Cross-cutting change (multiple services/modules) or a new architectural pattern +- New external dependency or significant data model changes +- Security, performance, or migration complexity +- Ambiguity that benefits from technical decisions before coding + +Minimal `design.md` skeleton: +```markdown +## Context +[Background, constraints, stakeholders] + +## Goals / Non-Goals +- Goals: [...] +- Non-Goals: [...] + +## Decisions +- Decision: [What and why] +- Alternatives considered: [Options + rationale] + +## Risks / Trade-offs +- [Risk] → Mitigation + +## Migration Plan +[Steps, rollback] + +## Open Questions +- [...] +``` + +## Spec File Format + +### Critical: Scenario Formatting + +CORRECT (use #### headers): +```markdown +#### Scenario: User login success +- WHEN valid credentials provided +- THEN return JWT token +``` + +WRONG (don't use bullets or bold): +```markdown +- Scenario: User login ❌ +Scenario: User login ❌ +### Scenario: User login ❌ +``` + +Every requirement MUST have at least one scenario. + +### Requirement Wording +- Use SHALL/MUST for normative requirements (avoid should/may unless intentionally non-normative) + +### Delta Operations + +- `## ADDED Requirements` - New capabilities +- `## MODIFIED Requirements` - Changed behavior +- `## REMOVED Requirements` - Deprecated features +- `## RENAMED Requirements` - Name changes + +Headers matched with `trim(header)` - whitespace ignored. + +#### When to use ADDED vs MODIFIED +- ADDED: Introduces a new capability or sub-capability that can stand alone as a requirement. Prefer ADDED when the change is orthogonal (e.g., adding "Slash Command Configuration") rather than altering the semantics of an existing requirement. +- MODIFIED: Changes the behavior, scope, or acceptance criteria of an existing requirement. Always paste the full, updated requirement content (header + all scenarios). The archiver will replace the entire requirement with what you provide here; partial deltas will drop previous details. +- RENAMED: Use when only the name changes. If you also change behavior, use RENAMED (name) plus MODIFIED (content) referencing the new name. + +Common pitfall: Using MODIFIED to add a new concern without including the previous text. This causes loss of detail at archive time. If you aren't explicitly changing the existing requirement, add a new requirement under ADDED instead. + +Authoring a MODIFIED requirement correctly: +1) Locate the existing requirement in `spectr/specs//spec.md`. +2) Copy the entire requirement block (from `### Requirement: ...` through its scenarios). +3) Paste it under `## MODIFIED Requirements` and edit to reflect the new behavior. +4) Ensure the header text matches exactly (whitespace-insensitive) and keep at least one `#### Scenario:`. + +Example for RENAMED: +```markdown +## RENAMED Requirements +- FROM: `### Requirement: Login` +- TO: `### Requirement: User Authentication` +``` + +## Troubleshooting + +### Common Errors + +"Change must have at least one delta" +- Check `changes/[name]/specs/` exists with .md files +- Verify files have operation prefixes (## ADDED Requirements) + +"Requirement must have at least one scenario" +- Check scenarios use `#### Scenario:` format (4 hashtags) +- Don't use bullet points or bold for scenario headers + +Silent scenario parsing failures +- Exact format required: `#### Scenario: Name` +- Debug by reading the delta spec file directly: `spectr/changes//specs//spec.md` + +### Validation Tips + +```bash +# Always use strict mode for comprehensive checks +spectr validate [change] --strict +``` + +For validation debugging: +- Read delta specs directly: `spectr/changes//specs//spec.md` +- Check spec content by reading: `spectr/specs//spec.md` + +## Happy Path Script + +```bash +# 1) Explore current state +spectr spec list --long +spectr list +# Optional full-text search: +# rg -n "Requirement:|Scenario:" spectr/specs +# rg -n "^#|Requirement:" spectr/changes + +# 2) Choose change id and scaffold +CHANGE=add-two-factor-auth +mkdir -p spectr/changes/$CHANGE/{specs/auth} +printf "## Why\\n...\\n\\n## What Changes\\n- ...\\n\\n## Impact\\n- ...\\n" > spectr/changes/$CHANGE/proposal.md +printf "## 1. Implementation\\n- [ ] 1.1 ...\\n" > spectr/changes/$CHANGE/tasks.md + +# 3) Add deltas (example) +cat > spectr/changes/$CHANGE/specs/auth/spec.md << 'EOF' +## ADDED Requirements +### Requirement: Two-Factor Authentication +Users MUST provide a second factor during login. + +#### Scenario: OTP required +- WHEN valid credentials are provided +- THEN an OTP challenge is required +EOF + +# 4) Validate +spectr validate $CHANGE --strict +``` + +## Multi-Capability Example + +``` +spectr/changes/add-2fa-notify/ +├── proposal.md +├── tasks.md +└── specs/ + ├── auth/ + │ └── spec.md # ADDED: Two-Factor Authentication + └── notifications/ + └── spec.md # ADDED: OTP email notification +``` + +auth/spec.md +```markdown +## ADDED Requirements +### Requirement: Two-Factor Authentication +... +``` + +notifications/spec.md +```markdown +## ADDED Requirements +### Requirement: OTP Email Notification +... +``` + +## Best Practices + +### Simplicity First +- Default to <100 lines of new code +- Single-file implementations until proven insufficient +- Avoid frameworks without clear justification +- Choose boring, proven patterns + +### Complexity Triggers +Only add complexity with: +- Performance data showing current solution too slow +- Concrete scale requirements (>1000 users, >100MB data) +- Multiple proven use cases requiring abstraction + +### Clear References +- Use `file.ts:42` format for code locations +- Reference specs as `specs/auth/spec.md` +- Link related changes and PRs + +### Capability Naming +- Use verb-noun: `user-auth`, `payment-capture` +- Single purpose per capability +- 10-minute understandability rule +- Split if description needs "AND" + +### Change ID Naming +- Use kebab-case, short and descriptive: `add-two-factor-auth` +- Prefer verb-led prefixes: `add-`, `update-`, `remove-`, `refactor-` +- Ensure uniqueness; if taken, append `-2`, `-3`, etc. + +## Tool Selection Guide + +| Task | Tool | Why | +|------|------|-----| +| Find files by pattern | Glob | Fast pattern matching | +| Search code content | Grep | Optimized regex search | +| Read specific files | Read | Direct file access | +| Explore unknown scope | Task | Multi-step investigation | + +## Error Recovery + +### Change Conflicts +1. Run `spectr list` to see active changes +2. Check for overlapping specs +3. Coordinate with change owners +4. Consider combining proposals + +### Validation Failures +1. Run with `--strict` flag +2. Check JSON output for details +3. Verify spec file format +4. Ensure scenarios properly formatted + +### Missing Context +1. Read project.md first +2. Check related specs +3. Review recent archives +4. Ask for clarification + +## Quick Reference + +### Stage Indicators +- `changes/` - Proposed, not yet built +- `specs/` - Built and deployed +- `archive/` - Completed changes + +### File Purposes +- `proposal.md` - Why and what +- `tasks.md` - Implementation steps +- `spec.md` - Requirements and behavior +- `design.md` - Technical decisions (optional) + +### CLI Essentials +```bash +spectr list # What's in progress? +spectr validate --strict # Is it correct? +spectr archive [--yes|-y] # Mark complete (add --yes for automation) +``` + +Reading Details (for AI agents): +- Read `spectr/specs//spec.md` for spec details +- Read `spectr/changes//proposal.md` for change details + +Remember: Specs are truth. Changes are proposals. Keep them in sync. diff --git a/spectr/project.md b/spectr/project.md new file mode 100644 index 0000000..b472ef9 --- /dev/null +++ b/spectr/project.md @@ -0,0 +1,63 @@ +# nvim Context + +## Purpose +Personal daily driver neovim configuration for polyglot development. Optimized for working across 30+ programming languages including Go, Rust, Python, TypeScript, Nix, C/C++, Zig, and many others. + +## Tech Stack +- **Neovim** - Editor (Lua-based configuration) +- **lazy.nvim** - Plugin management with lazy loading +- **nvim-lspconfig** - LSP client configuration for language servers +- **blink.cmp** - Completion engine +- **Tree-sitter** - Syntax highlighting and code analysis +- **Telescope** - Fuzzy finding and navigation +- **neotest** - Testing framework integration +- **Git integrations**: fugitive, gitsigns, signify, octo (GitHub) +- **oil.nvim** - File navigation +- **fidget.nvim** - LSP progress notifications + +## Project Conventions + +### Code Style +- **Formatter**: StyLua +- **Indentation**: Tabs (width: 2) +- **Column width**: 160 characters +- **Line endings**: Unix (LF) +- **Quote style**: Double quotes preferred +- **Leader key**: `\` (backslash) +- **Local leader**: `` + +### Architecture Patterns +- **Plugin files**: Named as `-plugin.lua` in `lua/plugins/` +- **Keymaps**: Organized by mode in `lua/keymaps/` (normal, visual, insert) +- **Core config**: `lua/conneroisu/` for options, debugger, keymaps, multigrep +- **Filetype overrides**: `after/ftplugin/` for language-specific settings +- **Lazy loading**: Plugins load on events (BufReadPost, BufNewFile) or filetypes + +### Testing Strategy +- Manual testing in neovim after changes +- `:checkhealth` for plugin/LSP diagnostics +- CI validation on push + +### Git Workflow +- **Trunk-based development**: Short-lived branches, frequent integration to main +- Commit messages should be descriptive +- Changes validated before merge + +## Domain Context +- This config is part of a larger NixOS dotfiles repository using the Denix framework +- LSP servers are typically installed via Nix, not Mason +- Format-on-save is enabled for most filetypes (Go uses vim-go instead) +- Custom filetypes registered: `templ`, `rasi`, `hyprlang` + +## Important Constraints +- **Performance focus**: Startup time and responsiveness are priorities +- **NixOS integration**: Managed via Home Manager; external tools come from Nix +- **Lazy loading**: Plugins should load lazily to minimize startup time +- **No Mason**: LSP servers managed by Nix, not neovim plugin managers + +## External Dependencies +- **Nix/NixOS**: Provides LSP servers, formatters, and external tools +- **Language servers**: gopls, rust-analyzer, lua_ls, nixd, pyrefly, ts_ls, etc. +- **Git**: Required for fugitive, gitsigns, octo integrations +- **ripgrep**: Used by Telescope for grep operations +- **fd**: Used by Telescope for file finding From 3ee4b5030da7fc7cf54e5f069973c1d067a7c00d Mon Sep 17 00:00:00 2001 From: connerohnesorge Date: Fri, 5 Dec 2025 07:36:02 -0600 Subject: [PATCH 14/14] Configure tailwindcss LSP for templ filetype support Add configuration to tailwindcss LSP server to support the 'templ' filetype by mapping it to 'html' language. This enables proper Tailwind CSS IntelliSense, autocomplete, and syntax highlighting when working with .templ files in Neovim, improving the development experience for projects using the templ template engine with Tailwind CSS styling. --- lua/plugins/lspconfig-plugin.lua | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/lua/plugins/lspconfig-plugin.lua b/lua/plugins/lspconfig-plugin.lua index c124d6f..c7937b7 100644 --- a/lua/plugins/lspconfig-plugin.lua +++ b/lua/plugins/lspconfig-plugin.lua @@ -111,7 +111,16 @@ return { rust_analyzer = {}, texlab = {}, vhdl_ls = {}, - tailwindcss = {}, + tailwindcss = { + filetypes = { "templ", "astro", "javascript", "typescript", "react" }, + settings = { + tailwindCSS = { + includeLanguages = { + templ = "html", + }, + }, + }, + }, hdl_checker = {}, jsonls = {}, yamlls = {},