A general purpose .. programming language written in zig ijadux2.tngl.sh/Rinnescript
zig language
README.md

Editor setup — LSP, formatter, linter #

One command installs everything for the editors it detects:

./tools/setup-editors.sh            # all detected editors
./tools/setup-editors.sh --nvim     # Neovim/Vim only
./tools/setup-editors.sh --vscode   # VS Code / Cursor only
./tools/setup-editors.sh --emacs    # Emacs only

The script first builds a ReleaseFast binary (zig build -Doptimize=ReleaseFast) and installs editor files from editors/. It is idempotent — safe to re-run after every git pull so the installed binary always matches your checkout. Re-running it also migrates away any config left behind by older versions (stale Neovim after/ftplugin/rinne.lua files are removed automatically).

Language server features (rinne lsp) #

The server speaks JSON-RPC over stdio and reuses the real compiler pipeline, so diagnostics are exactly what rinne run would report.

Capability What you get
Diagnostics Parse and compile errors on open/change (full sync), published after a short typing settle window. Ranges land on the real error line/column and extend to the end of the offending token — never a false underline of line 1.
Hover Docs for ~48 builtins (len, push, json_parse, tcp_listen, llm_load, …), including namespace calls like std.print.
Completion Keywords, all builtins with snippet insertions, plus document-local fn/const/var declarations. Trigger character . filters module members (std./ai./llm./net./c.) to imported namespaces.
Formatting textDocument/formatting runs the same formatter as rinne fmt, in-process — no shell-outs.
Document symbols Flat symbol list for the outline: functions, constants, variables.
Definition Same-file go-to-definition for top-level declarations.

What gets installed where #

Editor Files
Neovim / Vim ~/.config/nvim/{lua/rinne,ftplugin,plugin,ftdetect,syntax,indent,queries,snippets} + tree-sitter parser
VS Code packaged .vsix via vsce + code --install-extension (falls back to opening the folder)
Cursor copied to ~/.cursor/extensions/rinne-vscode
Emacs ~/.emacs.d/lisp/{rinne-mode.el,rinne-setup.el}

Neovim #

The plugin uses Neovim's built-in LSP framework (requires nvim ≥ 0.11) and no third-party LSP manager:

  • lua/rinne/init.lua registers the server via vim.lsp.config['rinne'] (cmd = {bin, "lsp"}, filetypes = {"rinne"}, root_markers = {"build.zig.zon", ".git"}) and enables it with vim.lsp.enable.
  • Binary resolution order: require("rinne").setup({ bin = ... }) override → vim.g.rinne_path → rinne on $PATH.

Keymaps (set in ftplugin/rinne.lua for .rg buffers):

  • K — hover docs
  • gd — go-to-definition (same file)
  • <leader>lf — format buffer via LSP

Format-on-save is on by default (vim.g.rinne_fmt_on_save ~= 0) and runs through the LSP capability in a BufWritePre autocmd — mirroring how the official zig.vim gates g:zig_fmt_autosave. Disable it with:

vim.g.rinne_fmt_on_save = 0

lazy.nvim / manual install #

Point your plugin manager at this repo's editors/nvim directory:

{
  dir = vim.fn.stdpath("config") .. "/rinne-nvim", -- or a git URL once hosted
  ft = "rinne",
  config = function() require("rinne").setup() end,
}

Or without a plugin manager, run tools/setup-editors.sh --nvim, which copies the same layout into ~/.config/nvim/ site directories.

Verify the attachment with :checkhealth vim.lsp while a .rg file is open.

Vim (no LSP) #

Syntax, indentation, ftdetect and snippets work in plain Vim too; only the LSP-backed features need Neovim ≥ 0.11.

VS Code / Cursor #

Install the extension (script handles it). Grammar + language configuration ship in editors/vscode/; manual route: npm i -g @vscode/vsce, then cd editors/vscode && vsce package && code --install-extension *.vsix. Formatting is exposed through the same LSP capability — bind editor.action.formatDocument or enable format-on-save.

Emacs #

rinne-setup.el registers rinne-mode, wires eglot:

(with-eval-after-load 'eglot
  (add-to-list 'eglot-server-programs '(rinne-mode . ("~/path/to/rinne" "lsp"))))

and adds a before-save-hook that formats .rg buffers.

Formatter CLI (rinne fmt) #

rinne fmt FILE           # format in place (comment-preserving, idempotent)
rinne fmt --check FILE   # exit 1 + "would be reformatted" when dirty

The editor paths above all use the identical formatter core, so CLI and LSP output can never disagree.

Linter (rinne lint) #

rinne lint src/**/*.rg   # warnings, never errors (exit 0)

Checks: unused variables, unused function parameters, unreachable code after return/break/continue.

Performance #

Build ReleaseFast for daily editor use — the server is a compiled binary with zero runtime dependencies, and every JSON-RPC message is handled from a reset arena allocator, so memory stays flat across long sessions:

zig build -Doptimize=ReleaseFast

(tools/setup-editors.sh does this for you.)

Troubleshooting #

  • LSP diagnostics stale after pulling new commits — re-run tools/setup-editors.sh; the installed config points at the freshly built binary.
  • No completions/hover — make sure the file has an .rg extension so the server attaches (ftdetect handles this in nvim), then check :checkhealth vim.lsp.
  • Server won't start on nvim < 0.11 — the plugin targets the native vim.lsp.config/vim.lsp.enable APIs; upgrade or use an eglot-based setup (see Emacs section).
  • fmt --check fails in CI but passes locally — your local binary differs from CI's; both must be built from the same commit.