diff --git a/docs/ADDING_LANGUAGE.md b/docs/ADDING_LANGUAGE.md new file mode 100644 index 0000000..4df4146 --- /dev/null +++ b/docs/ADDING_LANGUAGE.md @@ -0,0 +1,120 @@ +# 🌍 Adding a Language + +## 1. Create the File + +```bash +cp lua/langs/_template.lua lua/langs/elixir.lua +nvim lua/langs/elixir.lua +``` + +## 2. Minimal Structure + +```lua +---@file lua/langs/elixir.lua +---@description Elixir language support +---@module "langs.elixir" + +local settings_ok, settings = pcall(require, "core.settings") +if settings_ok and not settings:is_language_enabled("elixir") then return {} end + +return { + -- Treesitter parser + { + "nvim-treesitter/nvim-treesitter", + opts = function(_, opts) + vim.list_extend(opts.ensure_installed, { "elixir", "heex", "eex" }) + end, + }, + + -- LSP + { + "neovim/nvim-lspconfig", + opts = { + servers = { + elixirls = {}, + }, + }, + }, + + -- Formatter + { + "stevearc/conform.nvim", + opts = { + formatters_by_ft = { + elixir = { "mix" }, + }, + }, + }, + + -- Linter (optional) + { + "mfussenegger/nvim-lint", + opts = { + linters_by_ft = { + elixir = { "credo" }, + }, + }, + }, +} +``` + +## 3. Enable in settings.lua + +```lua +-- settings.lua or users//settings.lua +languages = { + enabled = { "lua", "python", "elixir" }, +}, +``` + +## 4. Add the Runtime (if applicable) + +In `lua/core/platform.lua` β†’ `RUNTIME_EXECUTABLES`: + +```lua +elixir = "elixir", +``` + +## 5. Add Version Detection in Lualine + +In `lua/plugins/ui/lualine.lua`: +```lua +-- FT_TO_RUNTIME: +elixir = "elixir", + +-- VERSION_ARGS: +elixir = { args = "--version", pattern = "Elixir%s+(%S+)" }, +``` + +## 6. Mason β€” LSP/Formatter/Linter + +Verify availability: + +```vim +:Mason +``` + +Search for: `elixir-ls`, `credo` + +## 7. Testing + +```bash +nvim test.ex +:LspInfo # LSP attached? +:TSInstall elixir # Parser installed? +:ConformInfo # Formatter configured? +``` + +## Checklist + +``` +β–‘ lua/langs/.lua created +β–‘ Treesitter parser added +β–‘ LSP server configured +β–‘ Formatter configured +β–‘ Linter configured (optional) +β–‘ Runtime added to platform.lua (optional) +β–‘ Version added to lualine.lua (optional) +β–‘ Enabled in settings.lua +β–‘ Tested with a real file +``` diff --git a/docs/ADDING_PLUGIN.md b/docs/ADDING_PLUGIN.md new file mode 100644 index 0000000..3502670 --- /dev/null +++ b/docs/ADDING_PLUGIN.md @@ -0,0 +1,130 @@ +# πŸ”Œ Adding a Plugin + +## 1. Choose a Category + +| Folder | Content | +| --- | --- | +| `plugins/ai/` | AI assistants | +| `plugins/code/` | Completion, LSP, Treesitter, formatting | +| `plugins/editor/` | Navigation, files, search | +| `plugins/ui/` | Statusline, tabline, notifications | +| `plugins/tools/` | Terminal, Git, debugging | +| `plugins/misc/` | Everything else | + +## 2. Create the File + +```bash +nvim lua/plugins/editor/my-plugin.lua +``` + +## 3. Standard Structure + +```lua +---@file lua/plugins/editor/my-plugin.lua +---@description My Plugin β€” short description +---@module "plugins.editor.my-plugin" + +-- Guard: allows disabling from settings.lua +local settings_ok, settings = pcall(require, "core.settings") +if settings_ok and not settings:is_plugin_enabled("my-plugin") then return {} end + +return { + "author/my-plugin.nvim", + + -- Lazy loading (choose ONE trigger): + event = "VeryLazy", -- On first idle + -- cmd = "MyPluginCommand", -- On first command execution + -- ft = { "lua", "python" }, -- On first filetype match + -- keys = { "mp" }, -- On first keymap usage + + dependencies = { + "nvim-lua/plenary.nvim", -- If required + }, + + opts = { + -- Configuration passed to setup() + option1 = true, + option2 = "value", + }, + + -- OR config = function() for more control: + -- config = function(_, opts) + -- require("my-plugin").setup(opts) + -- -- Additional code here + -- end, +} +``` + +## 4. Make it Togglable + +In `lua/core/settings.lua`, add the default value: + +```lua +plugins = { + ["my-plugin"] = true, -- enabled by default +}, +``` + +## 5. Add Keymaps + +```lua +return { + "author/my-plugin.nvim", + keys = { + { "mp", "MyPlugin", desc = "My Plugin" }, + { "mt", "MyPluginToggle", desc = "Toggle My Plugin" }, + }, + -- ... +} +``` + +## 6. Testing + +```bash +nvim +:Lazy # Verify the plugin is listed +:Lazy load my-plugin # Force loading +:checkhealth my-plugin # If the plugin has a healthcheck +``` + +## Design Patterns + +### Pattern: pcall on external requires + +```lua +config = function(_, opts) + local ok, plugin = pcall(require, "my-plugin") + if not ok then return end + plugin.setup(opts) +end, +``` + +### Pattern: core.icons integration + +```lua +local icons_ok, icons = pcall(require, "core.icons") +local icon = icons_ok and icons.ui.MyIcon or "fallback" +``` + +### Pattern: core.platform integration + +```lua +local platform_ok, platform = pcall(require, "core.platform") +if platform_ok and platform.is_ssh then + -- Reduce features over SSH + opts.animations = false +end +``` + +## Checklist + +``` +β–‘ File created in the correct category +β–‘ Settings guard added +β–‘ Appropriate lazy trigger (event/cmd/ft/keys) +β–‘ Dependencies listed +β–‘ Default added to core/settings.lua +β–‘ Keymaps documented (desc =) +β–‘ Tested: :Lazy, loading, functionality +β–‘ stylua lua/ executed +``` diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md new file mode 100644 index 0000000..3bd4436 --- /dev/null +++ b/docs/ARCHITECTURE.md @@ -0,0 +1,108 @@ +# πŸ—οΈ Architecture + +## Overview + +``` +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ NvimEnterprise Stack β”‚ +β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ +β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ Users β”‚ β”‚ Langs β”‚ β”‚ Plugins β”‚ β”‚ AI β”‚ β”‚ +β”‚ β”‚Namespace β”‚ β”‚ Modules β”‚ β”‚ Registry β”‚ β”‚ Providers β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ Config Layer (Settings Β· Plugin Β· Colorscheme) β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β”‚ β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ Core Engine (OOP / Class System / Lua) β”‚ β”‚ +β”‚ β”‚ bootstrap Β· class Β· settings Β· platform Β· security Β· log β”‚ β”‚ +β”‚ β”‚ version Β· icons Β· health Β· utils Β· secrets β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β”‚ β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ Neovim 0.10+ Runtime β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +## Boot Pipeline (init.lua) + +``` +Phase 1 β€” Version Guard Neovim >= 0.10.0? +Phase 2 β€” Disable Built-ins ~15 built-in plugins disabled +Phase 3 β€” Cache References Localize vim.uv, stdpath(), etc. +Phase 4 β€” Load Version dofile(core/version.lua) +Phase 5 β€” Global Namespace _G.NvimConfig = { ... } +Phase 6 β€” Secrets .env sync + async loading +Phase 7 β€” Bootstrap Core require("core") +``` + +## Directory Structure + +``` +lua/ +β”œβ”€β”€ core/ Framework engine (low-level) +β”‚ β”œβ”€β”€ class.lua OOP: inheritance, mixins, types +β”‚ β”œβ”€β”€ platform.lua Detection: OS, SSH, Docker, WSL, runtimes +β”‚ β”œβ”€β”€ settings.lua Defaults + schema +β”‚ β”œβ”€β”€ version.lua SemVer (Single Source of Truth) +β”‚ β”œβ”€β”€ secrets.lua Secure .env loader +β”‚ β”œβ”€β”€ security.lua Sandbox, path validation +β”‚ β”œβ”€β”€ bootstrap.lua Deterministic init sequence +β”‚ β”œβ”€β”€ icons.lua Centralized icon registry +β”‚ β”œβ”€β”€ logger.lua Structured logging +β”‚ β”œβ”€β”€ health.lua :checkhealth integration +β”‚ └── utils.lua Shared utilities +β”‚ +β”œβ”€β”€ config/ Configuration layer +β”‚ β”œβ”€β”€ settings_manager.lua Deep-merge settings +β”‚ β”œβ”€β”€ plugin_manager.lua Per-plugin toggle logic +β”‚ β”œβ”€β”€ colorscheme_manager.lua Runtime theme switching +β”‚ β”œβ”€β”€ commands.lua Enterprise commands +β”‚ └── lazy.lua Lazy.nvim bootstrap +β”‚ +β”œβ”€β”€ langs/ 1 file = 1 language +β”‚ β”œβ”€β”€ _template.lua Template for new languages +β”‚ β”œβ”€β”€ lua.lua Treesitter + LSP + formatter +β”‚ β”œβ”€β”€ python.lua ... +β”‚ └── ... 45+ languages +β”‚ +β”œβ”€β”€ plugins/ Specs by category +β”‚ β”œβ”€β”€ ai/ Copilot, Avante, CodeCompanion +β”‚ β”œβ”€β”€ code/ CMP, Conform, Treesitter, LSP +β”‚ β”œβ”€β”€ editor/ Telescope, Neo-tree, Flash +β”‚ β”œβ”€β”€ ui/ Lualine, Bufferline, Noice +β”‚ β”œβ”€β”€ tools/ LazyGit, ToggleTerm +β”‚ └── misc/ StartupTime, Wakatime +β”‚ +└── users/ Isolated namespaces + β”œβ”€β”€ namespace.lua Isolation engine + β”œβ”€β”€ user_manager.lua User CRUD + β”œβ”€β”€ default/ Default profile + β”œβ”€β”€ jane/ Example profile + └── john/ Example profile +``` + +## Design Principles + +| Principle | Implementation | +| --- | --- | +| **Single Responsibility** | Each file has one dedicated role | +| **Defensive Programming** | `pcall()` on all external access/requires | +| **Single Source of Truth** | `version.lua`, `settings.lua`, `icons.lua` | +| **Lazy Loading** | Plugins loaded via event/cmd/ft/keys | +| **Caching** | Costly data cached (versions, env, hostname) | +| **Fallbacks** | Every module provides default values | + +## Singletons & Access Patterns + +| Module | Pattern | Access | +| --- | --- | --- | +| `platform` | Singleton via `get_instance()` | `require("core.platform")` | +| `settings` | Singleton via `Class:extend()` | `require("core.settings")` | +| `version` | Table module (non-OOP) | `require("core.version")` | +| `icons` | Table module (non-OOP) | `require("core.icons")` | + diff --git a/docs/HOOKS.md b/docs/HOOKS.md new file mode 100644 index 0000000..879cc5a --- /dev/null +++ b/docs/HOOKS.md @@ -0,0 +1,96 @@ +# πŸͺ Git Hooks Reference + +## Overview + +| Hook | When | Blocking | Checks | +| --- | --- | --- | --- | +| `pre-commit` | Before commit | Yes | Code quality | +| `commit-msg` | After message | Yes | Message format | +| `pre-push` | Before push | Yes | Syntax + formatting | +| `post-merge` | After pull/merge | No | Notifications | + +## pre-commit + +Verifies code quality **before** every commit. + +| # | Check | Impact | Description | +| --- | --- | --- | --- | +| 1 | Debug markers | ⚠️ Warning | TODO, FIXME, console.log, debugger | +| 2 | Backup files | 🚫 Block | .bak, .old, .swp, .tmp | +| 3 | Large files | 🚫 Block | > 5MB | +| 4 | Secrets | 🚫 Block | Passwords, API keys, tokens | +| 5 | Conflict markers | 🚫 Block | `<<<<<<<`, `=======`, `>>>>>>>` | +| 6 | StyLua | 🚫 Block | Lua formatting | +| 7 | Lua syntax | 🚫 Block | luajit > luac5.1 > luac | +| 8 | ShellCheck | ⚠️ Warning | Shell scripts | +| 9 | YAML/JSON | ⚠️/🚫 | Syntax validation | +| 10 | Trailing whitespace | ⚠️ Warning | Spaces at end of lines | +| 11 | .env files | 🚫 Block | Must not be committed | + +## commit-msg + +Validates the **Conventional Commits** format. + +```conf +(): +``` + +Accepted types: +feat | fix | docs | style | refactor | perf | test +build | ci | chore | revert | release + +Breaking change: `feat!` or `BREAKING CHANGE:` in footer. + +| Check | Blocking | Description | +| --- | --- | --- | +| Format | 🚫 | `type(scope): subject` | +| Subject length | ⚠️ | ≀ 72 characters | +| Ending period | ⚠️ | No `.` at the end | +| Imperative mood | ⚠️ | Use "add" instead of "added" | +| Blank line | ⚠️ | Between subject and body | +| Body length | ⚠️ | ≀ 100 per line | + +Auto-skip: merge commits, WIP, fixup!, squash!, `Revert "..."` + +## pre-push + +The final gatekeeper **before** code leaves your machine. + +| # | Check | Blocking | Description | +| --- | --- | --- | --- | +| 1 | WIP commits | 🚫 | fixup!, squash!, wip | +| 2 | Lua syntax | 🚫 | All .lua files | +| 3 | StyLua | 🚫 | Formatting check | +| 4 | Version (tags) | 🚫 | Tag must match version.lua | +| 5 | CHANGELOG (tags) | ⚠️ | Entry must exist | +| 6 | Protected branch | 🚫/βœ… | Interactive confirmation | +| 7 | Dirty tree | ⚠️ | Uncommitted changes | + +## post-merge + +Smart notifications **after** a pull or merge. + +| Info | Description | +| --- | --- | +| Files by area | core/, plugins/, langs/, config/ | +| lazy-lock.json | β†’ Reminder to run `:Lazy sync` | +| version.lua | β†’ Displays new version | +| CHANGELOG.md | β†’ Displays latest entry | +| New/deleted Lua files | β†’ Lists modules | +| Core config | β†’ Restart reminder for settings/options/keymaps | +| Commit count + authors | β†’ Summary | + +## Location + +.git/hooks/ +β”œβ”€β”€ pre-commit ← Code quality +β”œβ”€β”€ commit-msg ← Message format +β”œβ”€β”€ pre-push ← Final gate +└── post-merge ← Notifications + +## Bypass (Emergency) + +```bash +git commit --no-verify -m "hotfix: urgent" +git push --no-verify +``` diff --git a/docs/RELEASE_GUIDE.md b/docs/RELEASE_GUIDE.md new file mode 100644 index 0000000..b11dc59 --- /dev/null +++ b/docs/RELEASE_GUIDE.md @@ -0,0 +1,123 @@ +# πŸš€ Release Guide + +## Daily Workflow + +```bash +# Edit β†’ Format β†’ Commit β†’ Push +nvim lua/plugins/ui/lualine.lua +stylua lua/ +git add -A +git commit -m "fix(lualine): resolve separator glitch" +git push origin main +``` + +## Commit Convention + +``` +(): +``` + +| Type | SemVer | Usage | +| --- | --- | --- | +| `feat` | MINOR | New feature | +| `fix` | PATCH | Bug fix | +| `docs` | PATCH | Documentation | +| `style` | PATCH | Formatting (stylua) | +| `refactor` | PATCH | Restructuring without behavior change | +| `perf` | PATCH | Optimization | +| `test` | PATCH | Tests | +| `build` | PATCH | Build / dependencies | +| `ci` | PATCH | CI/CD | +| `chore` | PATCH | Maintenance | +| `revert` | PATCH | Revert | +| `release` | TAG | Version release | +| `feat!` | MAJOR | Breaking change | + +## Release Process + +### 1. Determine Version Number + +``` +PATCH (x.x.+1) β†’ fix, refactor, docs, style +MINOR (x.+1.0) β†’ feat (new feature, module, command) +MAJOR (+1.0.0) β†’ feat! or BREAKING CHANGE +``` + +### 2. Update CHANGELOG.md + +```bash +nvim CHANGELOG.md +``` + +```markdown +## [X.Y.Z] - YYYY-MM-DD + +### Added +- **module**: description + +### Changed +- **module**: description + +### Fixed +- **module**: description +``` + +### 3. Commit the CHANGELOG + +```bash +git add CHANGELOG.md +git commit -m "docs(changelog): add vX.Y.Z entry" +``` + +### 4. Run the Script + +```bash +./scripts/release.sh X.Y.Z "Short description" +``` + +The script automatically performs the following: + +1. Verifies a clean working tree +2. Updates `lua/core/version.lua` +3. Updates `init.lua` `@version` +4. Verifies CHANGELOG.md +5. Runs stylua + luajit checks +6. Creates an annotated commit + tag +7. Pushes main + tag (with confirmation) + +### 5. Verify CI + +```bash +gh run watch +gh release view vX.Y.Z --web +``` + +## Troubleshooting & Emergency Commands + +```bash +# Delete a tag +git tag -d vX.Y.Z +git push origin --delete vX.Y.Z + +# Delete a release +gh release delete vX.Y.Z --yes + +# Bypass hooks (Emergency only) +git commit --no-verify -m "hotfix: urgent" +git push --no-verify + +# View current version +grep -E '^\s+(major|minor|patch)' lua/core/version.lua +``` + +## Checklist + +``` +β–‘ Commits pushed to main +β–‘ Main CI is green +β–‘ CHANGELOG.md updated and committed +β–‘ Clean working tree +β–‘ ./scripts/release.sh X.Y.Z "description" +β–‘ Tag CI is green +β–‘ Release visible on GitHub + diff --git a/docs/TROUBLESHOUTING.md b/docs/TROUBLESHOUTING.md new file mode 100644 index 0000000..d2936e4 --- /dev/null +++ b/docs/TROUBLESHOUTING.md @@ -0,0 +1,183 @@ +# πŸ”§ Troubleshooting + +## Common Issues and Solutions + +### 1. `luac` error: attempt to assign to const variable + +**Cause**: System `luac` is likely Lua 5.4, while Neovim uses LuaJIT (Lua 5.1). In Lua 5.4, `for` loop variables are `const`. + +**Solution**: + +```lua +-- ❌ Lua 5.4 forbids this +for line in data:gmatch("[^\n]+") do + line = line:match("^%s*(.-)%s*$") +end + +-- βœ… Compatible with both 5.1 AND 5.4 +for raw_line in data:gmatch("[^\n]+") do + local line = raw_line:match("^%s*(.-)%s*$") +end +``` + +**Prevention**: The pre-push hook prioritizes `luajit` for syntax checking. + +### 2. `sed -i` fails on macOS + +**Cause**: macOS (BSD) `sed` requires a backup extension argument: `sed -i ''`. + +**Solution**: + +```bash +# macOS +sed -i '' 's/old/new/' file + +# Linux +sed -i 's/old/new/' file + +# Cross-platform (inside a script) +if [[ "$OSTYPE" == "darwin"* ]]; then + sed_i() { sed -i '' "$@"; } +else + sed_i() { sed -i "$@"; } +fi +``` + +### 3. Lualine: broken separator between sections + +**Cause**: An entirely empty section is removed by Lualine, which breaks the Powerline transition. + +**Solution**: The last component of each section must **always be visible** and **without a custom separator**. + +```lua +-- Section B: branch_or_cwd() always returns content +-- Section X: user_component always placed last +``` + +### 4. lua_ls warning: `doc-field-no-class` + +**Cause**: `@field` is used without a preceding `@class` definition. + +**Solution**: + +```lua +-- ❌ +---@type table +---@field name string ← warning + +-- βœ… +---@class MyType +---@field name string ← OK +``` + +### 5. lua_ls warning: `undefined-field` + +**Cause**: Accessing a field that wasn't declared on an inline type. + +**Solution**: Declare a separate `@class`: + +```lua +-- ❌ +---@param opts? { color: table, sep: string } +-- opts.sep β†’ undefined-field + +-- βœ… +---@class MyOpts +---@field color? table +---@field sep? string +---@param opts? MyOpts +``` + +### 6. CI: `luajit dofile()` fails + +**Cause**: The Lua file uses the `vim.*` API, which does not exist in standalone LuaJIT (outside of Neovim). + +**Solution**: Parse the file using `grep` in the CI pipeline: + +```bash +MAJOR=$(grep -E '^\s+major\s*=' lua/core/version.lua | grep -oE '[0-9]+') +``` + +### 7. Release: tag pushed before CI fix + +**Solution**: + +```bash +git push origin --delete vX.Y.Z +git tag -d vX.Y.Z +# Fix CI issues, push to main +git tag -a vX.Y.Z -m "vX.Y.Z β€” description" +git push origin vX.Y.Z +``` + +### 8. Hook blocks a commit message + +**Immediate workaround**: + +```bash +git commit --no-verify -m "message" +``` + +**Permanent solution**: Check `.git/hooks/commit-msg` and verify the regex pattern for allowed types. + +### 9. Plugin not loading + +```vim +:Lazy " Is the plugin listed? +:Lazy load " Force manual load +:lua print(vim.inspect(require("lazy.core.config").plugins[""])) +``` + +Check the guard inside the plugin file: + +```lua +if settings_ok and not settings:is_plugin_enabled("name") then return {} end +``` + +### 10. LSP not attaching + +```vim +:LspInfo " Active clients? +:LspLog " Any errors? +:Mason " Is the server installed? +:checkhealth lsp " Diagnostics +``` + +--- + +## Committing and Merging + +```bash +# Format +stylua lua/ + +# Commit +git add docs/ +git commit -m "docs: add project documentation (release, versioning, architecture, guides)" + +# Merge into main +git checkout main +git merge feat/docs + +# Push +git push origin main +``` + +--- + +## Add to README + +In the `Contributing` section of your `README.md`, add the following: + +## πŸ“š Documentation + +| Guide | Description | +| --- | --- | +| [Release Guide](https://www.google.com/search?q=docs/RELEASE_GUIDE.md) | Full release process | +| [Versioning](https://www.google.com/search?q=docs/VERSIONING.md) | SemVer strategy | +| [Architecture](https://www.google.com/search?q=docs/ARCHITECTURE.md) | Technical overview | +| [Adding a Language](https://www.google.com/search?q=docs/ADDING_LANGUAGE.md) | How to add a language | +| [Adding a Plugin](https://www.google.com/search?q=docs/ADDING_PLUGIN.md) | How to add a plugin | +| [Git Hooks](https://www.google.com/search?q=docs/HOOKS.md) | Hook documentation | +| [Troubleshooting](https://www.google.com/search?q=docs/TROUBLESHOOTING.md) | Common issues | + diff --git a/docs/VERSIONING.md b/docs/VERSIONING.md new file mode 100644 index 0000000..aef2c35 --- /dev/null +++ b/docs/VERSIONING.md @@ -0,0 +1,69 @@ +# πŸ“‹ Versioning Strategy + +## Semantic Versioning (SemVer) + +NvimEnterprise suit [SemVer 2.0.0](https://semver.org/) avec deux niveaux de version. + +``` +MAJOR.MINOR.PATCH[-pre] + β”‚ β”‚ β”‚ └─ Pre-release : alpha, beta, rc.1 + β”‚ β”‚ └─────── Patch : fix, refactor, docs, style + β”‚ └───────────── Minor : nouvelle feature, module, commande + └─────────────────── Major : breaking change, refonte architecture +``` + +## Deux niveaux de version + +| Niveau | Scope | Localisation | Exemple | +|---|---|---|---| +| **Projet** | Tout le dΓ©pΓ΄t | `lua/core/version.lua` + tag Git | `v1.1.0` | +| **Module** | Fichier individuel | `---@version` dans le header | `@version 2.2.0` | + +### Source unique : `lua/core/version.lua` + +```lua +local M = { + major = 1, + minor = 1, + patch = 0, + pre = nil, +} +``` + +Tous les autres fichiers **lisent** depuis cette source : +- `init.lua` β†’ `dofile("lua/core/version.lua")` +- `:Version` β†’ `require("core.version").show()` +- `release.sh` β†’ met Γ  jour via `sed` +- CI β†’ parse via `grep` + +### Version par module (indΓ©pendante) + +```lua +-- lua/plugins/ui/lualine.lua +---@version 2.2.0 ← version du MODULE, pas du projet +``` + +Un module peut Γͺtre en `v3.0.0` alors que le projet est en `v1.2.0`. + +## Fichiers impliquΓ©s + +| Fichier | RΓ΄le | +|---|---| +| `lua/core/version.lua` | Source unique (major, minor, patch) | +| `init.lua` | `@version` dans le header LuaDoc | +| `CHANGELOG.md` | Historique humain | +| `scripts/release.sh` | Met Γ  jour version.lua + init.lua | +| `.github/workflows/ci.yml` | VΓ©rifie tag = version.lua | + +## Diagramme + +``` +lua/core/version.lua (source unique) + β”‚ + β”œβ”€β”€β†’ init.lua dofile() β†’ _G.NvimConfig.version + β”œβ”€β”€β†’ :Version commande utilisateur + β”œβ”€β”€β†’ :NvimVersion alias + β”œβ”€β”€β†’ release.sh mise Γ  jour via sed + β”œβ”€β”€β†’ CI parse via grep + └──→ CHANGELOG.md rΓ©fΓ©rence humaine +```