49 lines
4.3 KiB
Markdown
49 lines
4.3 KiB
Markdown
# Development
|
|
|
|
[README](../README.md)
|
|
|
|
Local verification and implementation constraints. See [architecture](architecture.md) for ownership and frontend contracts.
|
|
|
|
## Verify
|
|
|
|
```sh
|
|
cargo test
|
|
cargo clippy --all-targets -- -D warnings
|
|
cargo fmt --check
|
|
for file in src/ruby_*.rb examples/config.rb examples/plugins/greeting.rb; do
|
|
ruby -c "$file" || exit
|
|
done
|
|
rubocop
|
|
```
|
|
|
|
## Ruby types
|
|
|
|
Use YARD `@param`, `@return`, and `@yieldparam` annotations for Ruby APIs, and `@type` for locals where inference needs help. Examples annotate DSL block parameters before the call, without adding runtime assignments or dependencies. `Vamp::Action` / `Vamp::Mode` field types and the dynamically defined mode methods use Solargraph-supported directives.
|
|
|
|
Core action methods are generated from Rust's authoritative catalog at host startup. Their namespace is annotated, but static Solargraph analysis cannot enumerate those generated members: CLI `typecheck` can misidentify `config.core.select` as inherited `Kernel#select`. Do not maintain a second action list in Ruby comments; use the [configuration action reference](configuration.md#action-reference). Runtime catalog validation remains authoritative.
|
|
|
|
## Ruby implementation and style
|
|
|
|
Rust embeds the Ruby implementation at compile time: [`ruby_values.rb`](../src/ruby_values.rb) owns value validation and core action/mode objects, [`ruby_config.rb`](../src/ruby_config.rb) owns configuration and editor contexts, [`ruby_plugin.rb`](../src/ruby_plugin.rb) owns registration and callbacks, and [`ruby_host.rb`](../src/ruby_host.rb) owns framed subprocess I/O. Rebuild the editor after changing these files; installed binaries do not load implementation files from the filesystem.
|
|
|
|
`.rubocop.yml` uses RuboCop defaults with double-quoted strings (including interpolation) and Ruby 2.6-compatible syntax. Ruby implementation and example files use frozen string literals. Narrow inline style exceptions retain physical `STDIN`/`STDOUT`/`STDERR` capture/redirection and native exception state at the process boundary; plugin output must not corrupt the protocol, and errors including `SystemExit` and `Interrupt` must discard effects and report a failure.
|
|
|
|
## Test organization
|
|
|
|
Rust tests live alongside their modules; native LSP integration checks are in [`tests/lsp.rs`](../tests/lsp.rs).
|
|
|
|
- Editor checks cover Unicode editing, multi-target state, undo/redo, saving failures, and modal paste acceptance and rejection atomicity.
|
|
- Session and Ruby checks exercise real Ruby execution, command/capability ownership, effect validation, configuration fallback, plugin retirement, crash/timeout recovery, and inherited-pipe cleanup.
|
|
- Unix terminal-hook checks use isolated child processes and real PTYs to keep process-global hooks out of the parallel runner. They cover cleanup on entry failure, normal return, I/O errors, and panics, including original panic-payload propagation.
|
|
- Native LSP integration checks launch framed-protocol fixture subprocesses, covering initialization/settings, opt-in startup, synchronization, UTF-16/file-URI conversion, dirty targets, stale requests/diagnostics, and transport failures. Stack checks cover independent initialization, diagnostic merging/clearing, sibling failure isolation in active/parked buffers, same-revision rename/close identity, aggregate limits, first-server position routing, and both shutdowns. Semantic ordering uses protocol/file gates; elapsed deadlines only bound stuck subprocesses.
|
|
- Hover regression checks cover content forms, sanitization, cancelled/superseded replies, invalid results, scrolling/dismissal, Unicode clipping, and preserved editing state.
|
|
|
|
Clipboard checks use isolated providers rather than reading or overwriting the desktop clipboard.
|
|
|
|
## Performance and process limits
|
|
|
|
- Undo uses full-buffer snapshots and movement scans the current line. This favors straightforward correctness over large-file performance.
|
|
- Legacy synchronous plugin invocation may pause input for up to 500 ms before a host timeout. Async plugins opt into background replies; pending requests and transport queues are bounded. Config/plugin startup has a 2-second deadline per host. Buffer context/document snapshots must fit within a 4 MiB JSON frame; a too-large frame disables that plugin, not editing.
|
|
|
|
See [syntax caches](architecture.md#syntax-caches) for the current full-tree highlighting ceiling.
|