# nuwiki Developer Onboarding ## Overview nuwiki is a vimwiki-compatible Vim/Neovim plugin backed by a Rust language server. It provides full vimwiki syntax support while keeping the original file format, keymaps, and command surface intact. The substantive work happens in a Rust LSP daemon — Vim and Neovim are thin client layers that wire up keystrokes and display results. ## Repository Structure ``` nuwiki/ ├── Cargo.toml # Rust workspace root ├── Cargo.lock ├── crates/ │ ├── nuwiki-ls/ # Binary crate — thin main.rs, starts stdio LSP server │ │ ├── Cargo.toml │ │ └── src/main.rs │ │ │ ├── nuwiki-core/ # Library crate — parser, AST, renderer (no editor deps) │ │ ├── Cargo.toml │ │ └── src/ │ │ ├── lib.rs │ │ ├── syntax/ # Syntax plugins (vimwiki, future markdown) │ │ │ ├── mod.rs │ │ │ ├── registry.rs │ │ │ └── vimwiki/ │ │ │ ├── mod.rs │ │ │ ├── lexer.rs │ │ │ └── parser.rs │ │ ├── ast/ # Abstract Syntax Tree node definitions │ │ │ ├── mod.rs │ │ │ ├── block.rs │ │ │ ├── inline.rs │ │ │ └── link.rs │ │ └── render/ # Renderers (HTML, etc.) │ │ ├── mod.rs │ │ └── html.rs │ │ │ └── nuwiki-lsp/ # Library crate — LSP protocol bridge │ ├── Cargo.toml │ └── src/lib.rs │ ├── plugin/ # Universal Vim/Neovim entry point │ └── nuwiki.vim │ ├── lua/ # Neovim-specific Lua layer │ └── nuwiki/ │ ├── init.lua │ ├── config.lua │ ├── lsp.lua │ └── install.lua # Binary download / build-from-source logic │ ├── autoload/ # Lazy-loaded VimL (Vim compat layer) │ └── nuwiki/ │ └── lsp.vim │ ├── ftdetect/ # Filetype detection for .wiki files │ └── nuwiki.vim │ ├── ftplugin/ # Per-filetype buffer settings │ └── nuwiki.vim │ ├── syntax/ # Static fallback syntax highlighting (no LSP required) │ └── nuwiki.vim │ ├── doc/ # Vim help documentation │ └── nuwiki.txt │ ├── scripts/ # Plugin-runtime scripts only │ └── download_bin.vim # VimL binary download (used by Dein/vim-plug build hooks) │ ├── development/ # Developer-only tooling and docs (not shipped) │ ├── ONBOARDING.md # This file │ ├── SPEC.md # Technical reference (architecture, LSP, commands) │ ├── nuwiki-architecture.html │ ├── start-nvim.sh # Launch Neovim against a generated sample wiki │ ├── start-vim.sh # Launch Vim against a generated sample wiki │ ├── syntax-diag.vim # Dump highlighting state for debugging │ └── tests/ # Editor keymap/command harnesses (run in CI) │ ├── test-keymaps.sh # Neovim keymap harness │ ├── test-keymaps.lua │ ├── test-keymaps-vim.sh # Vim keymap harness │ ├── test-keymaps-vim.vim │ ├── test-calendar.sh # Neovim calendar-vim integration harness │ ├── test-calendar.lua │ ├── test-calendar-vim.sh # Vim calendar-vim integration harness │ ├── test-calendar-vim.vim │ └── test-calendar-vim-optout.vim │ └── .gitea/ └── workflows/ ├── ci.yaml # Lint, test, fmt check on every push/PR └── release.yaml # Cross-compile + release on v* tag ``` ## Key Crates 1. **nuwiki-core**: Contains the parser, lexer, AST, and renderer. This is the pure-Rust core with no editor dependencies. 2. **nuwiki-lsp**: Bridges the core to the LSP protocol using tower-lsp. Handles LSP requests/responses and manages the document store. 3. **nuwiki-ls**: Binary crate that starts the stdio LSP server. Very thin — just initializes the LSP server and runs it. ## Build & Installation ### Prerequisites - Rust toolchain (1.83+ stable) - Cargo - For editor integration: Vim 9+ or Neovim 0.5+ with an LSP client (vim-lsp recommended for Vim, built-in for Neovim 0.11+) ### Development Build ```bash # From the repository root cargo build --release -p nuwiki-ls # Builds the LSP binary ``` The binary will be placed at `target/release/nuwiki-ls`. ### Installation via Plugin Managers #### lazy.nvim ```lua { 'gffranco/nuwiki', build = ":lua require('nuwiki').install()", ft = { 'vimwiki' }, opts = { wiki_root = '~/vimwiki', }, } ``` #### vim-plug ```vim Plug 'gffranco/nuwiki', { 'do': 'vim -e -s -c \"source scripts/download_bin.vim\" -c \"q\"' } ``` #### Dein ```vim call dein#add('gffranco/nuwiki', { \ 'build': 'vim -e -s -c \"source scripts/download_bin.vim\" -c \"q\"' \ }) ``` ### Manual Installation (Plain Vim) ```bash git clone https://code.gfran.co/gffranco/nuwiki ~/.vim/pack/gffranco/start/nuwiki cd ~/.vim/pack/gffranco/start/nuwiki cargo build --release -p nuwiki-ls mkdir -p bin && ln -s ../target/release/nuwiki-ls bin/nuwiki-ls ``` Plain Vim users also need an LSP client — vim-lsp is recommended. ## Development Workflow ### Testing ```bash # Run all tests (workspace) cargo test --workspace # Run tests for a specific crate cargo test -p nuwiki-core cargo test -p nuwiki-lsp cargo test -p nuwiki-ls ``` ### Linting & Formatting ```bash # Check formatting cargo fmt -- --check # Run Clippy cargo clippy --workspace -- -D warnings ``` ### Running the LSP Server Manually (for debugging) ```bash # Build and run the binary cargo run -p nuwiki-ls -- --help ``` The LSP server communicates over stdio. You can test it with an LSP client like `lspci` or by connecting from Neovim. ### Health Check (Neovim) After installing the plugin, run: ``` :checkhealth nuwiki ``` This verifies: - Binary exists at `{plugin_dir}/bin/nuwiki-ls` - Binary is executable and responds to `--version` - LSP client is running - Filetype detection works for `.wiki` files ## Editor Layers ### VimL Layer (`plugin/nuwiki.vim`, `autoload/`) - Universal entry point for all plugin managers - Detects whether running in Neovim or Vim - For Neovim: delegates to Lua layer - For Vim: starts the LSP server via `nuwiki#lsp#start()` ### Neovim Lua Layer (`lua/nuwiki/`) - `init.lua`: Main setup function - `config.lua`: Configuration schema and defaults - `lsp.lua`: Starts the LSP client using `vim.lsp.start()` - `install.lua`: Handles binary download/build and places it in the plugin's `bin/` directory ### Vim Compatibility Layer (`autoload/nuwiki/lsp.vim`) - Provides the `nuwiki#lsp#start()` function for Vim - Handles binary location and LSP client startup via vim-lsp or coc.nvim ## Important Notes - The core library (`nuwiki-core`) is completely editor-agnostic and can be tested independently. - The LSP layer (`nuwiki-lsp`) depends only on the core and tower-lsp. - The binary crate (`nuwiki-ls`) is intentionally thin — it just initializes and runs the LSP server. - Editor layers (VimL/Lua) contain zero logic — they are pure wiring only. - All syntax-specific code lives in `nuwiki-core/src/syntax//` making it easy to add new syntaxes (e.g., markdown) in the future. - The project uses a workspace Cargo.toml with resolver v2 (edition 2021). ## Getting Started 1. Clone the repository: ```bash git clone https://code.gfran.co/gffranco/nuwiki cd nuwiki ``` 2. Build the LSP binary: ```bash cargo build --release -p nuwiki-ls ``` 3. Set up a test wiki directory: ```bash mkdir -p ~/test-wiki echo "# Test Wiki" > ~/test-wiki/index.wiki ``` 4. Install the plugin in your Neovim/Vim configuration using your preferred plugin manager (see above examples). 5. Open a .wiki file and verify: - Syntax highlighting works - `:VimwikiIndex` opens the index page - LSP features (go-to-definition, hover, completions) work via `:checkhealth nuwiki` ## CI/CD The project uses Gitea Actions: - CI (`.gitea/workflows/ci.yaml`): Runs on every push/PR — checks formatting, Clippy, and runs tests. - Release (`.gitea/workflows/release.yaml`): Triggers on `v*` tag — cross-compiles for Linux targets and creates a Gitea release. ## License Dual-licensed under MIT or Apache-2.0 at your option.