From f8b3501df1d69385ffe9ed85d4b8f85c2ab21389 Mon Sep 17 00:00:00 2001 From: Juliano Barbosa Date: Mon, 17 Feb 2025 21:59:19 -0300 Subject: [PATCH] feat: feat: add comprehensive documentation for Neovim configuration project Signed-off-by: juliano.barbosa --- lua/custom/plugins/custom_statusline.lua | 128 ++++++++++ lua/custom/plugins/mode_manager.lua | 285 +++++++++++++++++++++++ memory-bank/activeContext.md | 27 +++ memory-bank/decisionLog.md | 82 +++++++ memory-bank/productContext.md | 24 ++ memory-bank/progress.md | 63 +++++ memory-bank/systemPatterns.md | 73 ++++++ memory-bank/techContext.md | 45 ++++ 8 files changed, 727 insertions(+) create mode 100644 lua/custom/plugins/custom_statusline.lua create mode 100644 lua/custom/plugins/mode_manager.lua create mode 100644 memory-bank/activeContext.md create mode 100644 memory-bank/decisionLog.md create mode 100644 memory-bank/productContext.md create mode 100644 memory-bank/progress.md create mode 100644 memory-bank/systemPatterns.md create mode 100644 memory-bank/techContext.md diff --git a/lua/custom/plugins/custom_statusline.lua b/lua/custom/plugins/custom_statusline.lua new file mode 100644 index 00000000..7ad7c7ff --- /dev/null +++ b/lua/custom/plugins/custom_statusline.lua @@ -0,0 +1,128 @@ +-- Custom Statusline Configuration +local M = {} + +function M.setup() + -- Get reference to mini.statusline + local statusline = require('mini.statusline') + local mode_manager = require('custom.plugins.mode_manager') + + -- Store the original section_location function + local original_location = statusline.section_location + + -- Create function to get mode-specific content + local function get_mode_content() + local mode = mode_manager.get_mode() + local settings = mode_manager.setting(mode:lower(), 'status_info') or {} + + local parts = { + mode = string.format('[%s]', mode), + info = settings.text or '', + icon = settings.icon or '' + } + + if parts.icon ~= '' and parts.info ~= '' then + return string.format('%s %s %s', parts.mode, parts.icon, parts.info) + elseif parts.info ~= '' then + return string.format('%s %s', parts.mode, parts.info) + else + return parts.mode + end + end + + -- Override section_location to include enhanced mode indicator + ---@diagnostic disable-next-line: duplicate-set-field + statusline.section_location = function() + local color = mode_manager.get_mode_highlight() + + -- Create highlight groups for mode indicator + vim.api.nvim_set_hl(0, 'ModeIndicator', { + fg = color, + bold = true + }) + vim.api.nvim_set_hl(0, 'ModeIndicatorBg', { + bg = color, + fg = '#000000', + bold = true + }) + + -- Get mode-specific content + local mode_content = get_mode_content() + + -- Format: MODE LINE:COL with custom highlighting + return string.format( + '%%#ModeIndicator#%s%%#StatusLine# %s', + mode_content, + original_location() + ) + end + + -- Helper function to update mode-specific status info + local function update_mode_status(mode, info) + if type(info) == 'string' then + info = { text = info } + end + mode_manager.setting(mode:lower(), 'status_info', info) + end + + -- Register callback for mode changes to update statusline + mode_manager.register_post_hook(function(new_mode) + -- Example of setting mode-specific status info + if new_mode == 'plan' then + update_mode_status('plan', { + text = 'Planning Mode', + icon = '󰐉' -- Requires Nerd Font + }) + else + update_mode_status('act', { + text = 'Action Mode', + icon = '󰐊' -- Requires Nerd Font + }) + end + + vim.cmd('redrawstatus') + end) + + -- Set up status line with icons if using nerd font + statusline.setup({ + use_icons = vim.g.have_nerd_font, + content = { + active = function() + local mode = mode_manager.get_mode() + local mode_info = mode_manager.setting(mode:lower(), 'status_info') or {} + + -- Add mode-specific content to status line sections + return { + '%#ModeIndicator#' .. get_mode_content() .. '%#StatusLine#', + statusline.section_filename(), + statusline.section_modified(), + '%=', -- Right align + mode_info.extra or '', + statusline.section_searchcount(), + statusline.section_location(), + } + end + } + }) + + -- Create autocommand for ModeChanged event + vim.api.nvim_create_autocmd('User', { + pattern = 'ModeChanged', + callback = function(args) + if args.data then + local old_mode = args.data.old_mode + local new_mode = args.data.new_mode + + -- Trigger any mode-specific status line updates + vim.schedule(function() + -- Allow for async status updates + vim.cmd('redrawstatus') + end) + end + end, + }) + + -- Expose update_mode_status function + M.update_mode_status = update_mode_status +end + +return M \ No newline at end of file diff --git a/lua/custom/plugins/mode_manager.lua b/lua/custom/plugins/mode_manager.lua new file mode 100644 index 00000000..50a586be --- /dev/null +++ b/lua/custom/plugins/mode_manager.lua @@ -0,0 +1,285 @@ +-- Mode Manager Plugin +local M = {} + +-- Enhanced mode state management +M.state = { + current_mode = 'act', -- 'act' or 'plan' + callbacks = {}, -- Store mode change callbacks + history = {}, -- Track mode changes + settings = { -- Mode-specific settings store + act = {}, + plan = {}, + }, + contexts = { -- Context preservation + act = {}, + plan = {}, + }, + hooks = { -- Mode initialization hooks + pre_change = {}, -- Hooks to run before mode change + post_change = {}, -- Hooks to run after mode change + init = {}, -- Mode initialization hooks + } +} + +-- State validation schema +local state_schema = { + required_fields = {'current_mode', 'settings', 'contexts'}, + valid_modes = {'act', 'plan'}, + settings_required = {'act', 'plan'}, +} + +-- Validate state +local function validate_state() + local errors = {} + + -- Check required fields + for _, field in ipairs(state_schema.required_fields) do + if not M.state[field] then + table.insert(errors, string.format("Missing required field: %s", field)) + end + end + + -- Validate current mode + if not vim.tbl_contains(state_schema.valid_modes, M.state.current_mode) then + table.insert(errors, string.format("Invalid mode: %s", M.state.current_mode)) + end + + -- Validate settings structure + for _, mode in ipairs(state_schema.settings_required) do + if not M.state.settings[mode] then + table.insert(errors, string.format("Missing settings for mode: %s", mode)) + end + end + + return #errors == 0, errors +end + +-- Register a pre-change hook +function M.register_pre_hook(hook) + table.insert(M.state.hooks.pre_change, hook) +end + +-- Register a post-change hook +function M.register_post_hook(hook) + table.insert(M.state.hooks.post_change, hook) +end + +-- Register a mode initialization hook +function M.register_init_hook(hook) + table.insert(M.state.hooks.init, hook) +end + +-- Execute hooks +local function execute_hooks(hooks, ...) + for _, hook in ipairs(hooks) do + local success, err = pcall(hook, ...) + if not success then + vim.notify(string.format("Hook execution failed: %s", err), vim.log.levels.ERROR) + end + end +end + +-- Save context for current mode +local function save_context() + local current = M.state.current_mode + M.state.contexts[current] = { + buffers = vim.fn.getbufinfo({buflisted = 1}), + window = vim.fn.winsaveview(), + cursor = vim.api.nvim_win_get_cursor(0), + folding = vim.fn.getwinvar(0, '&foldenable') and vim.fn.getwinvar(0, '&foldmethod'), + } +end + +-- Restore context for new mode +local function restore_context(mode) + local ctx = M.state.contexts[mode] + if ctx then + -- Restore window view + if ctx.window then + vim.fn.winrestview(ctx.window) + end + -- Restore cursor position + if ctx.cursor then + vim.api.nvim_win_set_cursor(0, ctx.cursor) + end + -- Restore folding + if ctx.folding then + vim.wo.foldenable = true + vim.wo.foldmethod = ctx.folding + end + end +end + +-- Get or set mode-specific setting +function M.setting(mode, key, value) + if not M.state.settings[mode] then + M.state.settings[mode] = {} + end + if value ~= nil then + M.state.settings[mode][key] = value + end + return M.state.settings[mode][key] +end + +-- Register a callback to be called on mode change +function M.on_mode_change(callback) + table.insert(M.state.callbacks, callback) +end + +-- Function to execute all registered callbacks +local function execute_callbacks(old_mode, new_mode) + for _, callback in ipairs(M.state.callbacks) do + pcall(callback, old_mode, new_mode) + end +end + +-- Function to add mode change to history +local function log_mode_change(old_mode, new_mode) + table.insert(M.state.history, { + from = old_mode, + to = new_mode, + timestamp = os.time(), + }) +end + +-- Function to toggle between Plan and Act modes +function M.toggle_mode() + local old_mode = M.state.current_mode + + -- Execute pre-change hooks + execute_hooks(M.state.hooks.pre_change, old_mode) + + -- Save current context + save_context() + + -- Switch mode + M.state.current_mode = old_mode == 'act' and 'plan' or 'act' + + -- Validate state after mode change + local valid, errors = validate_state() + if not valid then + vim.notify("Mode state validation failed: " .. table.concat(errors, ", "), vim.log.levels.ERROR) + -- Revert mode change on validation failure + M.state.current_mode = old_mode + return + end + + -- Restore context for new mode + restore_context(M.state.current_mode) + + -- Log mode change + log_mode_change(old_mode, M.state.current_mode) + + -- Execute callbacks + execute_callbacks(old_mode, M.state.current_mode) + + -- Execute post-change hooks + execute_hooks(M.state.hooks.post_change, M.state.current_mode) + + -- Show notification of mode change + vim.notify('Switched to ' .. M.state.current_mode:upper() .. ' mode', vim.log.levels.INFO) + + -- Save state to a file + M.save_state() + + -- Trigger status line update + vim.cmd('redrawstatus') +end + +-- Function to get current mode +function M.get_mode() + return M.state.current_mode:upper() +end + +-- Function to get mode highlight color +function M.get_mode_highlight() + return M.state.current_mode == 'act' and '#98c379' or '#61afef' -- Green for Act, Blue for Plan +end + +-- Function to save state to file +function M.save_state() + local state_file = vim.fn.stdpath('data') .. '/mode_state.json' + local file = io.open(state_file, 'w') + if file then + -- Prepare state for persistence + local persist_state = { + current_mode = M.state.current_mode, + settings = M.state.settings, + contexts = M.state.contexts, + last_updated = os.time(), + version = '1.0' -- Added versioning + } + file:write(vim.fn.json_encode(persist_state)) + file:close() + end +end + +-- Function to load state from file +function M.load_state() + local state_file = vim.fn.stdpath('data') .. '/mode_state.json' + local file = io.open(state_file, 'r') + if file then + local content = file:read('*all') + file:close() + if content and content ~= '' then + local decoded = vim.fn.json_decode(content) + if decoded then + -- Restore state with validation + if decoded.version == '1.0' then + M.state.current_mode = decoded.current_mode + M.state.settings = decoded.settings or {act = {}, plan = {}} + M.state.contexts = decoded.contexts or {act = {}, plan = {}} + else + -- Handle older versions or invalid state + M.state.current_mode = decoded.current_mode or 'act' + M.state.settings = {act = {}, plan = {}} + M.state.contexts = {act = {}, plan = {}} + end + + -- Validate loaded state + local valid, errors = validate_state() + if not valid then + vim.notify("Loaded state validation failed: " .. table.concat(errors, ", "), vim.log.levels.WARN) + -- Reset to default state + M.state.current_mode = 'act' + M.state.settings = {act = {}, plan = {}} + M.state.contexts = {act = {}, plan = {}} + end + end + end + end +end + +-- Initialize the plugin +function M.setup() + -- Load saved state + M.load_state() + + -- Execute initialization hooks + execute_hooks(M.state.hooks.init) + + -- Add keybinding for mode toggle + vim.keymap.set('n', 'tm', function() + M.toggle_mode() + end, { desc = '[T]oggle [M]ode (Plan/Act)' }) + + -- Register default callback for logging + M.on_mode_change(function(old_mode, new_mode) + vim.api.nvim_exec_autocmds('User', { + pattern = 'ModeChanged', + data = { old_mode = old_mode, new_mode = new_mode } + }) + end) +end + +-- Get mode history +function M.get_history() + return M.state.history +end + +-- Clear mode history +function M.clear_history() + M.state.history = {} +end + +return M \ No newline at end of file diff --git a/memory-bank/activeContext.md b/memory-bank/activeContext.md new file mode 100644 index 00000000..947b9a3b --- /dev/null +++ b/memory-bank/activeContext.md @@ -0,0 +1,27 @@ +# Current Session Context +*Last Updated: 2025-02-17 21:57* + +## Current State +- Rolled back to v0.1.0 tag (commit 57f551e) +- Backup branch created for pre-rollback state + +## Recent Changes +- Created backup branch of pre-rollback state +- Rolled back codebase to v0.1.0 tag +- Previous state preserved in backup branch + +## Active Decisions +1. Using Memory Bank for configuration documentation +2. Following Kickstart.nvim's modular approach +3. Implementing comprehensive LSP integration +4. Using mode-based workflow with persistent Plan/Act toggle + +## Current Focus +- Verifying system stability after rollback +- Ensuring core functionality remains intact +- Planning next steps based on v0.1.0 state + +## Open Questions +- What were the key changes between v0.1.0 and the rolled back state? +- Which features need to be reimplemented or reconsidered? +- How to prevent future need for rollbacks? \ No newline at end of file diff --git a/memory-bank/decisionLog.md b/memory-bank/decisionLog.md new file mode 100644 index 00000000..0fe4d810 --- /dev/null +++ b/memory-bank/decisionLog.md @@ -0,0 +1,82 @@ +# Architectural Decisions Log + +## 2025-02-17 - Enhanced Mode State Management Architecture + +### Context +The current mode management system provides basic functionality for toggling between Plan and Act modes with simple state persistence. However, as the system grows, we need a more robust and feature-rich mode management system that can handle complex state management, mode-specific behaviors, and better integration with other components. + +### Decision +Implement an enhanced mode state management system with the following key components: + +1. **Advanced State Management** + - Implement mode-specific settings store + - Add context preservation between mode switches + - Create mode initialization hooks + - Add state validation and recovery mechanisms + +2. **Event System** + - Implement pre/post mode change hooks + - Add event queueing system + - Create mode-specific event handlers + - Support async event processing + +3. **Persistence Layer** + - Enhanced state file format with versioning + - State migration system + - Corruption detection and recovery + - Mode-specific context preservation + +4. **Integration System** + - Mode-aware plugin architecture + - LSP integration with mode context + - Buffer and window layout persistence + - Mode-specific UI elements + +### Rationale +- Current system lacks robust state management +- Need better integration with other components +- Require more sophisticated event handling +- Want to support mode-specific behaviors +- Need better error handling and recovery +- Desire for mode-specific UI/UX customization + +### Implementation +1. Phase 1: Core State Management + - Enhance state persistence + - Add validation system + - Implement context preservation + +2. Phase 2: Event System + - Add event hooks + - Implement queueing + - Create handlers + +3. Phase 3: Persistence Layer + - Update state format + - Add versioning + - Implement migration + +4. Phase 4: Integration + - Plugin integration + - LSP integration + - UI integration + +### Consequences +**Positive:** +- More robust state management +- Better error handling +- Enhanced user experience +- More flexible configuration +- Better integration capabilities + +**Negative:** +- Increased complexity +- More maintenance overhead +- Larger codebase +- More potential failure points + +### Status +- Decision approved +- Implementation planning in progress +- Initial architecture documented +- Ready for code mode implementation \ No newline at end of file diff --git a/memory-bank/productContext.md b/memory-bank/productContext.md new file mode 100644 index 00000000..871bc1c3 --- /dev/null +++ b/memory-bank/productContext.md @@ -0,0 +1,24 @@ +# Project Overview: Neovim Configuration + +## Purpose +This project is a personal Neovim configuration based on Kickstart.nvim framework, designed to provide a powerful yet maintainable development environment. + +## Goals +1. Create a productive and efficient development environment +2. Maintain a clean and organized configuration structure +3. Support multiple programming languages +4. Provide essential IDE-like features through LSP integration + +## Key Features +- LSP integration for multiple languages +- Fuzzy finding with Telescope +- Git integration +- Code formatting and linting +- Syntax highlighting with Treesitter +- Completion with nvim-cmp + +## User Experience Goals +- Fast and responsive editing +- Intuitive keybindings +- Clear visual feedback +- Minimal configuration needed for basic use \ No newline at end of file diff --git a/memory-bank/progress.md b/memory-bank/progress.md new file mode 100644 index 00000000..de80b9c3 --- /dev/null +++ b/memory-bank/progress.md @@ -0,0 +1,63 @@ +# Project Progress + +## Completed Work +- Initial Memory Bank setup +- Basic Plan/Act mode system implementation +- Mode persistence with JSON storage +- Simple event callback system +- Status line integration +- Basic mode toggling (`tm`) + +## Recent Changes +- Rolled back to v0.1.0 (commit 57f551e) +- Created backup branch of pre-rollback state + +## In Progress +- Verifying system stability post-rollback +- Reassessing implementation priorities +- Evaluating core functionality + +## Next Steps + +### Phase 1: Post-Rollback Stabilization +- [ ] Verify core functionality +- [ ] Document differences from rolled back state +- [ ] Reassess implementation priorities +- [ ] Review backup branch for salvageable improvements + +### Phase 2: Core State Management +- [ ] Implement mode-specific settings store +- [ ] Add mode context preservation +- [ ] Create mode initialization hooks +- [ ] Add state validation system +- [ ] Implement error recovery mechanisms + +### Phase 3: Event System Enhancement +- [ ] Add pre-mode-change hooks +- [ ] Implement post-mode-change hooks +- [ ] Create event queueing system +- [ ] Add mode-specific event handlers +- [ ] Implement async event processing + +### Phase 4: Integration Features +- [ ] Add mode-specific colorschemes +- [ ] Implement mode-specific keymaps +- [ ] Create mode-specific status line content +- [ ] Add mode-specific buffer handling +- [ ] Implement window layout persistence + +## Known Issues +- Current state persistence is basic +- No validation of stored state +- Limited error recovery options +- No mode-specific settings +- Basic event handling system + +## Future Considerations +- Custom mode creation system +- Mode-specific plugin configurations +- Advanced state synchronization +- Mode templates and presets +- Mode groups +- Mode transitions animations +- Mode-specific help system \ No newline at end of file diff --git a/memory-bank/systemPatterns.md b/memory-bank/systemPatterns.md new file mode 100644 index 00000000..b9ad443c --- /dev/null +++ b/memory-bank/systemPatterns.md @@ -0,0 +1,73 @@ +# System Architecture & Patterns + +## Core Architecture +- Plugin management via lazy.nvim +- LSP-based intellisense and code navigation +- Event-driven configuration loading +- Modular plugin configuration +- Enhanced mode state management system + +## Key Design Patterns + +1. Mode Management + - Advanced state persistence + - Event-driven mode transitions + - Mode-specific context preservation + - Pre/post mode change hooks + - Mode validation system + - Mode-specific settings store + +2. Event System + - Hierarchical event handling + - Event queueing mechanism + - Async event processing + - Event prioritization + - Mode-specific event handlers + +3. Persistence Layer + - Versioned state storage + - State migration system + - Corruption detection + - Fallback mechanisms + - Incremental state updates + +4. Integration Patterns + - Mode-aware plugin system + - LSP integration with mode context + - Buffer grouping by mode + - Window layout persistence + - Mode-specific UI elements + +5. Configuration Patterns + - Centralized keybinding management + - Plugin-specific configuration in separate modules + - Default options set through vim.opt + - Autocmd groups for event handling + - Mode-specific settings and behaviors + +6. LSP Integration + - Mason for LSP server management + - Uniform LSP configuration across languages + - Shared capabilities for completion + - Mode-specific language server configurations + +7. Component Relationships + - Mode Manager ↔ Event System + - Event System ↔ Persistence Layer + - Mode Manager ↔ Status Line + - LSP ↔ Mode Context + - Buffer Groups ↔ Mode State + - Window Layout ↔ Mode State + - Plugins ↔ Mode Context + +## Implementation Standards +- Lua for all configuration +- Consistent error handling +- Modular plugin organization +- Clear separation of concerns +- Mode-aware functionality +- State validation +- Event-driven architecture +- Robust error recovery +- Configuration versioning +- Context preservation \ No newline at end of file diff --git a/memory-bank/techContext.md b/memory-bank/techContext.md new file mode 100644 index 00000000..81745ca6 --- /dev/null +++ b/memory-bank/techContext.md @@ -0,0 +1,45 @@ +# Technical Context + +## Core Technologies +- Neovim (Text Editor) +- Lua (Configuration Language) +- Lazy.nvim (Plugin Manager) + +## Major Dependencies +1. LSP Servers & Tools + - lua_ls + - gopls + - pyright + - terraform-ls + - and many others managed by Mason + +2. Key Plugins + - nvim-lspconfig: LSP configuration + - telescope.nvim: Fuzzy finder + - nvim-treesitter: Syntax highlighting + - nvim-cmp: Completion engine + - conform.nvim: Code formatting + - which-key.nvim: Keybinding help + - mini.nvim: Collection of utilities + +## Development Setup +- Uses the Kickstart.nvim framework as base +- Nerd Font required for icons +- Python 3 support configured +- Git integration via fugitive and gitsigns + +## Technical Constraints +- Dependent on external LSP servers +- Requires Neovim 0.8.0 or higher +- Some features require system dependencies (make, git) +- Terminal with true color support recommended + +## Configuration Structure +``` +. +├── init.lua (Main configuration) +└── lua/ + ├── kickstart/ + │ └── plugins/ (Plugin-specific configs) + └── custom/ + └── plugins/ (Custom plugin configs) \ No newline at end of file