Files
nuwiki/development/ONBOARDING.md
T
gffranco 87ba4c1764
CI / cargo fmt --check (push) Successful in 26s
CI / cargo clippy (push) Successful in 27s
CI / cargo test (push) Successful in 31s
CI / editor keymaps (push) Successful in 1m30s
test(calendar): add Vim + Neovim integration harnesses
Add headless harnesses covering the calendar-vim integration, wired into
CI alongside the existing keymap/config suites:

- test-calendar-vim.sh/.vim (+ -optout.vim): pure-VimL diary hooks
  (calendar_sign markers, calendar_action path resolution from wiki root,
  calendar window close), plugin/nuwiki.vim hook auto-wiring that
  overrides calendar-vim's defaults, and opt-out via g:nuwiki_use_calendar
  and g:nuwiki_no_calendar. Uses a stub calendar-vim on the runtimepath.
- test-calendar.sh/.lua: Neovim setup() wiring + window-close under the
  real window API, and opt-out via use_calendar = false.

Fixes surfaced by the suite:
- diary.vim: new diary entries set filetype 'vimwiki' (was the raw
  extension, e.g. 'wiki'); the stray FileType autocmd also blocked the
  calendar window from closing.
- init.lua: drop the redundant Neovim FileType autocmd (plugin/nuwiki.vim
  already wires both editors) and translate use_calendar=false into
  g:nuwiki_no_calendar so the opt-out actually disables wiring.
2026-05-31 21:45:50 -03:00

8.7 KiB

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

# 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

{
  'gffranco/nuwiki',
  build = ":lua require('nuwiki').install()",
  ft = { 'vimwiki' },
  opts = {
    wiki_root = '~/vimwiki',
  },
}

vim-plug

Plug 'gffranco/nuwiki', { 'do': 'vim -e -s -c \"source scripts/download_bin.vim\" -c \"q\"' }

Dein

call dein#add('gffranco/nuwiki', {
\ 'build': 'vim -e -s -c \"source scripts/download_bin.vim\" -c \"q\"'
\ })

Manual Installation (Plain Vim)

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

# 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

# Check formatting
cargo fmt -- --check

# Run Clippy
cargo clippy --workspace -- -D warnings

Running the LSP Server Manually (for debugging)

# 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/<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:

    git clone https://code.gfran.co/gffranco/nuwiki
    cd nuwiki
    
  2. Build the LSP binary:

    cargo build --release -p nuwiki-ls
    
  3. Set up a test wiki directory:

    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.