99 lines
8.9 KiB
Markdown
99 lines
8.9 KiB
Markdown
# vamp
|
||
|
||
A modal Rust editor with a replaceable frontend and subprocess-isolated Ruby plugins.
|
||
|
||
## Run
|
||
|
||
Requires current stable Rust and an interactive terminal. Ruby 2.6+ with its standard-library JSON support is required only for configuration/plugins; no Ruby gems are needed to run vamp itself.
|
||
|
||
```sh
|
||
cargo run -- --no-config notes.txt
|
||
cargo run -- --config examples/config.rb notes.txt
|
||
```
|
||
|
||
Without a file, vamp opens an unnamed buffer. A nonexistent file opens an empty buffer. `cargo run -- --help` lists the command-line options.
|
||
|
||
### Manage local reviews without opening the editor
|
||
|
||
```sh
|
||
vamp --review list --repo .
|
||
vamp --review list --repo . --json
|
||
vamp --review show 1 --repo . --json
|
||
vamp --review show 1 --repo . --all
|
||
vamp --review delete 1 3 --repo . # Delete comment 3 from review 1
|
||
vamp --review resolve 1 3 --repo . # Mark comment 3 resolved, preserving its feedback
|
||
```
|
||
|
||
The review CLI discovers the Git/Jujutsu checkout from `--repo` (default: current directory). It uses the same default configuration, `--config PATH`, `--no-config`, and `review_directory` as the editor, but starts no editor workers or terminal UI. Missing storage lists no reviews without creating a database; incompatible storage is rejected and preserved.
|
||
|
||
Local reviews are scoped to the canonical checkout and ordered, resolved Before/After pair. Opening a different comparison selects its own review; reopening the same pair resumes its feedback and progress. In-place Working refreshes retain the active review. Ordinary source-buffer comments use separate source reviews. CLI listings identify each review's scope; JSON exposes it as `comparison` (an endpoint pair, or `null` for source reviews).
|
||
|
||
Review storage now uses SQLite schema 4 and JSON export version 5. Older formats are rejected and preserved without migration or reset.
|
||
|
||
Use the persistent **Review ID** printed by `list`, not a list position. IDs are shared across repositories; listing filters them to the selected checkout, so its first review need not be ID 1. Human-readable listings include a command to show each review. The internal save revision is omitted from text but remains in JSON; it is not a Git/Jujutsu revision. `show all` is not supported: use `show ID --all` to include resolved comments in that review.
|
||
|
||
`show` includes unresolved comments by default; `--all` includes resolved comments too. Human-readable output is the default, with source excerpts in language-tagged Markdown code blocks. JSON includes the canonical repository root, storage review ID/revision, summary/verdict, total/resolved/unresolved counts, and comments with exact zero-based, end-exclusive grapheme anchors and raw selected source excerpts—not whole source files or Markdown fences. `list --json` returns the repository and review metadata/counts without comments. Explicit editor JSON exports still contain complete anchor source text.
|
||
|
||
`list` and `show` are read-only. `delete REVIEW_ID COMMENT_ID` immediately commits deletion of one resolved or unresolved comment. `resolve REVIEW_ID COMMENT_ID` instead marks that comment resolved, preserving its body and original anchor. Repeating resolution succeeds without writing or advancing the review revision. Both commands print the updated review with its remaining unresolved comments (`--json` is supported); use `show REVIEW_ID --all` to verify resolved feedback. Both IDs are required; missing reviews/comments and repository mismatches fail without changing stored reviews or creating missing storage. Deleting the last comment keeps the review, summary, and verdict. Concurrent saves use the same revision-conflict protection as the editor; an already-open editor must reload before saving after a CLI change. Existing JSON exports are not modified.
|
||
|
||
`vamp review` still opens a file named `review`; `vamp -- --review` opens a file named `--review`.
|
||
|
||
## Getting started
|
||
|
||
Vamp starts in Normal mode. Press `i`, type text, then Esc to return to Normal. Type `:save` (alias `:w`) and Enter to save, or `:save path` to name an unnamed buffer. Type `:quit` (alias `:q`) and Enter to quit; it refuses unsaved changes in any open buffer. `:force_quit` (alias `:q!`) explicitly discards changes and quits.
|
||
|
||
| Task | Default keys |
|
||
| --- | --- |
|
||
| Move in Normal | `h`/`j`/`k`/`l` or arrows; `w`/`b`/`e` for words |
|
||
| First/last line in Normal or Visual | `gt` / `gb`, at first nonblank; Visual extends the selection |
|
||
| Enter/leave Insert | `i` / Esc |
|
||
| Manual LSP completion in Insert | Ctrl+n starts/cycles next; Ctrl+j/k cycles next/previous, replacing text live |
|
||
| Edit completion snippet arguments | Type to replace the highlighted argument; Tab / Shift+Tab moves next/previous |
|
||
| Save in Normal | Space then `w`, or `:w` then Enter |
|
||
| Undo/redo in Normal | `u` / `U` (Shift+u) |
|
||
| Split panes in Normal | `_` above/below; `\|` left/right; Option/Alt+h/j/k/l changes focus |
|
||
| Close a pane | `:pane.close`; `:pane.force_close` explicitly discards exclusively displayed unsaved edits |
|
||
| Open/switch tabs in Normal | `:tab.new` opens the current buffer; Ctrl+Option/Alt+h/l switches previous/next |
|
||
| Close a tab | `:tab.close`; `:tab.force_close` explicitly discards exclusively displayed unsaved edits |
|
||
| Delete/change whole lines in Normal | `dd` / `cc`; leading counts work (`3dd`, `2cc`) |
|
||
| Search in Normal | `/`, type a literal query, Enter; `n`/`N` for next/previous |
|
||
| Select/copy/cut | `v` characterwise or `V` whole rows, move to extend, then `y`/`d` in Visual |
|
||
| Paste in Normal | `p`/`P` after/before the caret or row for linewise fragments; system clipboard by default |
|
||
| Paste over selected text | `p` / `P` in Visual replaces every selection, preserving the clipboard |
|
||
| Command palette | Ctrl+p; type to filter, arrows select, Enter accepts, Esc cancels |
|
||
| Buffer picker in Normal | Space then `b l` or `:buffers`; type to search, arrows select, Enter switches, Esc cancels |
|
||
| Floating/docked explorer in Normal or Visual | Space then `o` / Space then `e` |
|
||
| Repository diff in Normal | `:diff`; choose Before then After, Tab changes category, type to search; Esc closes the selector; Working or checkout-matched pinned After is editable; `:diff.close` exits the comparison |
|
||
| Diff layout in Normal | Space then `v` cycles split/unified; Space then `s` flips left/right vs above/below split |
|
||
| Resolve jj working-copy conflicts | `:resolve`; edit marker-free Draft versus Alternative, `:resolve.history` for inputs/base, `:w` to save and confirm with jj |
|
||
|
||
Space is the default leader: press its suffix keys in order, not simultaneously. The [editing guide](docs/editing.md) contains the complete key table and behavior reference.
|
||
|
||
## Configuration
|
||
|
||
By default, vamp loads `$XDG_CONFIG_HOME/vamp/config.rb`, or `~/.config/vamp/config.rb` when that environment variable is unset. `--config path` selects a file explicitly; `--no-config` bypasses Ruby entirely and uses defaults.
|
||
|
||
Start with [`examples/config.rb`](examples/config.rb). The [configuration reference](docs/configuration.md) covers preferences, bindings, and native LSP setup. Language servers are **disabled by default**; install a trusted server and explicitly enable it.
|
||
|
||
Ruby configuration and plugins run with your account's filesystem/process permissions. Subprocess isolation is **not a security sandbox**; load only trusted scripts.
|
||
|
||
## Current limits
|
||
|
||
- Terminal frontend only; no graphical frontend.
|
||
- Modal editing, not full Vim compatibility: characterwise and linewise Visual selections and counted `dd`/`cc`, but no block selection, named registers, or general operator–motion grammar. Search is literal, case-sensitive, and single-line.
|
||
- Native opt-in LSP supports diagnostics, go-to-definition, plain-text hover, manual primary-caret completion with snippet arguments, and automatic semantic highlighting—not rename, formatting, or code actions. Completion has no automatic popup or acceptance step; other carets are preserved and translated through the chosen edits. Snippet regex transforms and unresolved variables without defaults are omitted.
|
||
- System clipboard access supports macOS and Linux. Separate clipboard mode keeps internal editing available on unsupported/headless environments.
|
||
|
||
Performance and subprocess limits are documented in [development](docs/development.md#performance-and-process-limits).
|
||
|
||
## Documentation
|
||
|
||
| Guide | Contents |
|
||
| --- | --- |
|
||
| [Editing](docs/editing.md) | Keys, motions/counts, selections, repeat, clipboard, search, buffers, explorer, palette, syntax highlighting |
|
||
| [Configuration](docs/configuration.md) | Ruby startup, preferences, action/mode reference, key notation, leader/list/tree bindings, native LSP |
|
||
| [Plugins](docs/plugins.md) | Ruby API, capabilities, effects, asynchronous callbacks, isolation, messaging protocol |
|
||
| [Architecture](docs/architecture.md) | Module ownership, session/frontend contracts, terminal lifecycle, syntax caches, native workers |
|
||
| [Development](docs/development.md) | Verification commands, test organization, performance and process limits |
|
||
| [Project context](CONTEXT.md) | Terminology and configuration-interface conventions |
|