canopus 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +33 -50
- data/README.md +32 -159
- data/docs/plugins.md +62 -0
- data/lib/canopus/decoration.rb +1 -1
- data/lib/canopus/plugins/api.rb +5 -1
- data/lib/canopus/plugins/host.rb +576 -0
- data/lib/canopus/plugins/isolated_runtime.rb +81 -8
- data/lib/canopus/plugins/local_runtime.rb +3 -2
- data/lib/canopus/plugins/vocabulary.rb +70 -0
- data/lib/canopus/plugins.rb +3 -0
- data/lib/canopus/provider.rb +1 -1
- data/lib/canopus/settings/schema.rb +9 -2
- data/lib/canopus/settings.rb +11 -0
- data/lib/canopus/version.rb +1 -1
- data/lib/canopus/workspace/file_change_aware.rb +1 -0
- data/lib/canopus/workspace/settings_aware.rb +1 -0
- data/lib/canopus/workspace/view.rb +9 -3
- data/lib/canopus/workspace.rb +44 -3
- data/sig/canopus.rbs +24 -1
- data/tools/check_dependencies.rb +3 -3
- metadata +20 -4
- data/docs/release-log.md +0 -17
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0cac04162944df2688afdf9c176a5fc0da5ae0d6bc624ea0435b83616ebcf57e
|
|
4
|
+
data.tar.gz: 95f7cc4d18be4aa3174d539096dc9365dd341ab94c339a3e236ec746f250c604
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 81ebc4d784dace467207f064df0004978397b7364a320c4a6cdfba16668fa6b3770e22e967dc9fa774986fb6bff4eccc96fa6a0e7b0b051088c7294623d8b03d
|
|
7
|
+
data.tar.gz: 1e480cb252250bf58ab4c868c03ef1757b1db20d472c78814c467645e3a502478b5b4863b0a1842472b42aefb20847abfbe2b8c395aa72418600f34c2252176c
|
data/CHANGELOG.md
CHANGED
|
@@ -2,58 +2,41 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
- Fix Windows terminal reads that could stop before the child process returned output.
|
|
6
|
+
- Complete the API v2 plugin host with declarative UI vocabulary, storage, external providers, and trust-aware operations.
|
|
7
|
+
|
|
8
|
+
## 0.6.0 — 2026-09-19
|
|
9
|
+
|
|
10
|
+
- Add the Gienah-backed API v2 plugin host and declarative plugin panels.
|
|
11
|
+
|
|
5
12
|
## 0.5.0 — 2026-09-19
|
|
6
13
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
-
|
|
10
|
-
|
|
11
|
-
- Add
|
|
12
|
-
|
|
13
|
-
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
-
|
|
23
|
-
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
-
|
|
32
|
-
-
|
|
33
|
-
- Publish bounded single-line, multi-line, and watch task problem matches through the shared diagnostics registry.
|
|
34
|
-
- Keep regex-backed task diagnostics responsive on Ruby 3.1 with one deferred complete-line retry before fail-closed disabling.
|
|
35
|
-
- Discover bounded Minitest and RSpec declarations with Alkaid and Prism and browse them in the Tests panel.
|
|
36
|
-
- Run discovered tests from the gutter, display bounded results, and publish navigable failure diagnostics.
|
|
37
|
-
- Preserve registration order for equal-priority decorations across Ruby versions and platforms.
|
|
38
|
-
- Show cached, viewport-scoped language-server inlay hints inline with clickable label locations.
|
|
39
|
-
- Show cached language-server code lenses above source lines and resolve them only when visible.
|
|
40
|
-
- Highlight language-server read, write, and text occurrences for each visible editor caret.
|
|
41
|
-
- Prefer language-server folding ranges with asynchronous Antares structure fallback.
|
|
42
|
-
- Expand and shrink multiple selections from language-server ranges or asynchronous Antares structure data.
|
|
43
|
-
- Validate rename targets asynchronously before opening the dialog when the language server supports preparation.
|
|
44
|
-
- Underline and safely open language-server document links, resolving targets only when clicked.
|
|
45
|
-
- Turn validated language-server linked ranges into multiple selections from the command palette, with a bounded HTML/XML tag fallback.
|
|
46
|
-
- Browse call and type hierarchies in a lazily loaded side panel.
|
|
47
|
-
- Color nested bracket pairs from Antares structure data and draw display-aware active indentation guides.
|
|
48
|
-
- Render configurable space, tab, and ideographic-space markers without changing display coordinates.
|
|
49
|
-
- Keep the active declaration chain visible with cached LSP symbols and an Antares fallback.
|
|
50
|
-
- Navigate files and the cached declaration hierarchy from editor breadcrumbs.
|
|
51
|
-
- Add an opt-in GUI minimap with shared, edit-aware line textures and Git, search, and diagnostic overview marks.
|
|
52
|
-
- Route LSP, snippet, and extension completion through a bounded provider registry with stable fuzzy ranking.
|
|
53
|
-
- Stage Git files, hunks, and lines and create or amend commits from the Source Control panel.
|
|
54
|
-
- Compare Git changes and revisions inline or side by side, with word highlights and per-file history.
|
|
55
|
-
- Resolve text merge regions in base/ours/theirs panes, stage the completed file atomically, and advance to the next conflict.
|
|
56
|
-
- Browse and search bounded commit graphs, run cancellable authenticated remote transfers, and show cached inline blame on clean or edited buffers.
|
|
14
|
+
### Editing and navigation
|
|
15
|
+
|
|
16
|
+
- Configure automatic pairs and selection surrounding globally or per language, and edit matching HTML/XML tags together when no language server provides linked ranges.
|
|
17
|
+
- Add rectangular selection, vertical cursor insertion, and multi-cursor commands for selected line starts, line ends, and regular-expression matches, including wrapped Unicode text.
|
|
18
|
+
- Add encoding detection, newline conversion, large-file handling, `.editorconfig` support, automatic save modes, persistent undo, and crash recovery.
|
|
19
|
+
- Add breadcrumbs, an optional minimap, whitespace markers, nested bracket colors, active indentation guides, and language-aware folding and selection expansion.
|
|
20
|
+
- Add inline diagnostics, inlay hints, code lenses, reference highlights, safe document links, rename preparation, and call/type hierarchies.
|
|
21
|
+
|
|
22
|
+
### Language tooling and debugging
|
|
23
|
+
|
|
24
|
+
- Support multiple language servers with merged completion, diagnostics, code actions, workspace symbols, and restart recovery; collect results in a filterable Problems panel and run configured formatting or source actions before saving.
|
|
25
|
+
- Add JSONC debug configurations, persistent conditional breakpoints, debug sessions, stack and variable inspection, watches, REPL and hover evaluation, and a Debug Console.
|
|
26
|
+
|
|
27
|
+
### Terminal, tasks, and tests
|
|
28
|
+
|
|
29
|
+
- Add shell integration for command boundaries, exit statuses, collapsible output, and working directories, plus split terminal layouts, profiles, and `--wait` for blocking editor invocations.
|
|
30
|
+
- Add interactive project tasks with problem matching in Output tabs, test discovery, and gutter-driven test execution with navigable failure diagnostics.
|
|
31
|
+
|
|
32
|
+
### Git
|
|
33
|
+
|
|
34
|
+
- Add source-control staging for files, hunks, and lines; commit and amend support; rich diff and merge-conflict views; history and blame; and authenticated remote operations.
|
|
35
|
+
|
|
36
|
+
### Settings, plugins, and distribution
|
|
37
|
+
|
|
38
|
+
- Add schema-driven settings editing and diagnostics, keymap presets, workspace trust, and a plugin registry with theme imports and sandboxed plugins.
|
|
39
|
+
- Add bundled Ruby to packages together with signed package verification, installers, and update feeds.
|
|
57
40
|
|
|
58
41
|
## 0.4.0 — 2026-09-15
|
|
59
42
|
|
data/README.md
CHANGED
|
@@ -31,32 +31,14 @@ installable.
|
|
|
31
31
|
|
|
32
32
|
## Features
|
|
33
33
|
|
|
34
|
-
- Native GPU windows on macOS, Linux, and Windows,
|
|
35
|
-
-
|
|
36
|
-
-
|
|
37
|
-
-
|
|
38
|
-
-
|
|
39
|
-
-
|
|
40
|
-
-
|
|
41
|
-
-
|
|
42
|
-
- LSP-aware selection expansion with an asynchronous Antares fallback
|
|
43
|
-
- LSP linked-range selection for starting a multi-cursor edit from the command palette
|
|
44
|
-
- Rectangular selection with Alt-drag and vertical cursor insertion
|
|
45
|
-
- Multi-cursor expansion to selected line starts, line ends, or every regular-expression match
|
|
46
|
-
- Lazy call and type hierarchy trees with bidirectional navigation
|
|
47
|
-
- Menkar-based encoding detection, newline display and conversion, and encoding-aware saves
|
|
48
|
-
- Ranked, extensible completion and inline-completion provider registry
|
|
49
|
-
- Viewport-scoped LSP inlay hints with clickable label locations
|
|
50
|
-
- Nested bracket colors and active indentation guides backed by Antares structure analysis
|
|
51
|
-
- Optional GPU minimap with shared line textures, viewport navigation, and overview markers
|
|
52
|
-
- Resizable integrated terminal with tabs, horizontal/vertical splits, profiles, scrollback, OSC 133 command history, colors, and clickable links
|
|
53
|
-
- Bounded JSONC project tasks with color-preserving, interactive Output tabs
|
|
54
|
-
- Git diff and staging, searchable commit graphs, cancellable fetch/pull/push, inline blame, and branch switching
|
|
55
|
-
- Editable project-wide search results and safe project file operations
|
|
56
|
-
- Optional Vim-compatible modes, motions, operators, registers, macros, and Ex commands
|
|
57
|
-
- Layered JSONC settings, keymaps, themes, snippets, and trusted Ruby plugins
|
|
58
|
-
- Overlay-aware wrapping and coordinates for inline hints and block decorations
|
|
59
|
-
- Rendered panel and decoration nodes expose stable `test_id` conventions for UI tests
|
|
34
|
+
- Native GPU windows on macOS, Linux, and Windows, with TUI and headless modes
|
|
35
|
+
- Language-aware editing with LSP completion, diagnostics, code actions, navigation, and multiple language-server support
|
|
36
|
+
- Multi-cursor and rectangular editing, Vim bindings, linked editing, and encoding-aware file handling
|
|
37
|
+
- An integrated terminal with tabs, splits, profiles, shell integration, and `EDITOR="canopus --wait"` support
|
|
38
|
+
- An integrated Git workflow with diff, staging, commits, history, merge-conflict resolution, and remote operations
|
|
39
|
+
- Built-in debugging, interactive tasks, test discovery, and a filterable Problems panel
|
|
40
|
+
- Workspace persistence for tabs, splits, and sessions, plus automatic save, undo history, and crash recovery
|
|
41
|
+
- Extensible JSONC settings, keymaps, themes, and trusted plugins with permission controls and an optional OS sandbox
|
|
60
42
|
|
|
61
43
|
## Installation
|
|
62
44
|
|
|
@@ -148,157 +130,44 @@ Run `settings.open` from the command palette to edit project settings. User
|
|
|
148
130
|
settings live at `$XDG_CONFIG_HOME/canopus/settings.jsonc` or
|
|
149
131
|
`~/.config/canopus/settings.jsonc`.
|
|
150
132
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
files are ignored.
|
|
133
|
+
Settings are layered as defaults, user settings, project settings, explicit
|
|
134
|
+
`--settings` values, and language overrides. Invalid saved values leave the
|
|
135
|
+
previous valid settings active. `.editorconfig` is enabled by default between
|
|
136
|
+
user and project settings and supports the common indentation, whitespace,
|
|
137
|
+
final-newline, and line-length keys.
|
|
157
138
|
|
|
158
139
|
```jsonc
|
|
159
140
|
{
|
|
160
141
|
"theme": "auto",
|
|
161
142
|
"font_size": 14,
|
|
162
143
|
"vim_mode": false,
|
|
163
|
-
"use_tabs": false,
|
|
164
|
-
"auto_pairs": [["(", ")"], ["[", "]"], ["{", "}"], ["\"", "\""], ["'", "'"]],
|
|
165
|
-
"diagnostics": { "inline": true, "inline_max_length": 80, "severity": "warning" },
|
|
166
|
-
"inlay_hints": { "enabled": true, "parameter_names": true, "types": true, "max_length": 30 },
|
|
167
|
-
"code_lens": { "enabled": true },
|
|
168
|
-
"bracket_colorization": true,
|
|
169
|
-
"indent_guides": { "enabled": true, "active": true },
|
|
170
|
-
"render_whitespace": "boundary",
|
|
171
|
-
"render_ideographic_space": true,
|
|
172
|
-
"sticky_scroll": { "enabled": true, "max_lines": 5 },
|
|
173
|
-
"breadcrumbs": { "enabled": true },
|
|
174
|
-
"minimap": { "enabled": false, "width": 100, "show_diagnostics": true },
|
|
175
144
|
"auto_save": "off",
|
|
176
|
-
"auto_save_delay": 1000,
|
|
177
|
-
"persistent_undo": { "enabled": true, "max_entries": 1000, "expire_days": 30 },
|
|
178
145
|
"format_on_save": false,
|
|
179
|
-
"
|
|
180
|
-
"format_on_save_timeout": 2000,
|
|
181
|
-
"git": { "inline_blame": "off", "autofetch": false, "autofetch_interval": 180 },
|
|
182
|
-
"recovery": { "enabled": true, "interval": 5000 },
|
|
183
|
-
"tabs": { "activate_on_close": "history", "reopen_history_limit": 20 },
|
|
184
|
-
"terminal": {
|
|
185
|
-
"working_directory": "project", "scrollback_lines": 10000, "shell_integration": true,
|
|
186
|
-
"profiles": { "bash": { "path": "/bin/bash", "args": ["--login"], "env": { "TERM_PROGRAM": "canopus" } } },
|
|
187
|
-
"default_profile": "bash"
|
|
188
|
-
},
|
|
189
|
-
"dock": {
|
|
190
|
-
"bottom": { "size": 280, "visible": false },
|
|
191
|
-
"panels": { "terminal": { "size": 280, "visible": false } }
|
|
192
|
-
},
|
|
193
|
-
"keymap": [
|
|
194
|
-
{ "context": "Editor && !vim_mode", "bindings": { "ctrl-k ctrl-s": "file.save" } }
|
|
195
|
-
],
|
|
146
|
+
"terminal": { "shell_integration": true },
|
|
196
147
|
"languages": { "ruby": { "tab_size": 2, "auto_pairs": [] } },
|
|
197
148
|
"language_servers": {
|
|
198
149
|
"ruby": [
|
|
199
150
|
{ "command": ["ruby-lsp"], "features": ["completion", "definition", "hover", "formatting"] },
|
|
200
151
|
{ "command": ["rubocop", "--lsp"], "features": ["diagnostics", "codeAction"] }
|
|
201
152
|
]
|
|
202
|
-
},
|
|
203
|
-
"debug_adapters": {
|
|
204
|
-
"ruby": { "command": ["rdbg", "--open", "--stop-at-load"], "transport": "tcp" }
|
|
205
153
|
}
|
|
206
154
|
}
|
|
207
155
|
```
|
|
208
156
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
set it to `[]` globally or for one language to disable automatic pairing and
|
|
224
|
-
selection surrounding. Each opener and closer must be one Unicode grapheme.
|
|
225
|
-
|
|
226
|
-
Sticky scroll keeps the declarations containing the first visible source byte
|
|
227
|
-
above the editor body. It prefers cached LSP document symbols and falls back to
|
|
228
|
-
cached Antares structure regions; `sticky_scroll.enabled` and
|
|
229
|
-
`sticky_scroll.max_lines` can also be overridden per language.
|
|
230
|
-
|
|
231
|
-
Breadcrumbs show the project-relative file, containing type, and callable above
|
|
232
|
-
sticky scroll. Selecting an item opens its same-directory files or same-parent
|
|
233
|
-
symbols in the palette. `breadcrumbs.enabled` can be overridden per language.
|
|
234
|
-
|
|
235
|
-
The GUI-only minimap is disabled by default. When enabled, it reserves its
|
|
236
|
-
configured width only in panes wide enough to keep the editor usable, reuses
|
|
237
|
-
bounded low-resolution line textures across splits, and shows Git, search, and
|
|
238
|
-
optionally diagnostic overview marks. Click or drag it to center that source
|
|
239
|
-
position without moving the selection. All minimap options can be overridden
|
|
240
|
-
per language.
|
|
241
|
-
|
|
242
|
-
Closing a dirty tab asks whether to save, discard, or cancel. Reopening restores
|
|
243
|
-
the file, selections, position, and pane while Canopus is running; discarded
|
|
244
|
-
unsaved changes are never restored. Dock and panel visibility and sizes are also
|
|
245
|
-
restored. Terminal session restoration, when enabled,
|
|
246
|
-
starts fresh shells with the saved tab count and working directories and does
|
|
247
|
-
not restore processes or scrollback.
|
|
248
|
-
|
|
249
|
-
Dirty buffers are also written every five seconds to private, atomically
|
|
250
|
-
replaced files under `.canopus/recovery/`. After an abnormal exit, the newest
|
|
251
|
-
valid snapshot is offered at startup; normal exit removes this run's snapshot.
|
|
252
|
-
Set `recovery.enabled` to `false` or change `recovery.interval` (milliseconds)
|
|
253
|
-
in settings. Recovery files contain local unsaved text, so disable the feature
|
|
254
|
-
for workspaces where even a mode-0600 local copy is unacceptable. Individual
|
|
255
|
-
buffers over 10 MiB and snapshots over 64 MiB are not retained.
|
|
256
|
-
|
|
257
|
-
Set `auto_save` to `after_delay` to save dirty named files after the debounce
|
|
258
|
-
interval in `auto_save_delay` milliseconds, or to `on_focus_change` to save a
|
|
259
|
-
file when switching away from it. Untitled, read-only, and conflicting files
|
|
260
|
-
are skipped or reported without forcing a write.
|
|
261
|
-
|
|
262
|
-
Persistent undo keeps up to `persistent_undo.max_entries` undo entries for
|
|
263
|
-
clean regular files under `.canopus/undo/`. Records are project- and file
|
|
264
|
-
identity-bound, expire after `expire_days`, and are ignored when corrupt or
|
|
265
|
-
when the file changes. Dirty buffers remain in recovery storage instead.
|
|
266
|
-
|
|
267
|
-
Settings are layered from defaults through user, project, explicit `--settings`,
|
|
268
|
-
and language overrides. Invalid saved settings leave the previous valid values
|
|
269
|
-
active. Keymap groups extend defaults; later matching bindings win, and `null`
|
|
270
|
-
removes a default binding.
|
|
271
|
-
|
|
272
|
-
Language servers are separate programs and are auto-detected or configured by
|
|
273
|
-
argument array. See [Language servers](docs/lsp.md) for configuration and
|
|
274
|
-
restart behavior.
|
|
275
|
-
|
|
276
|
-
Debug launch definitions and the persistent, edit-aware breakpoint gutter
|
|
277
|
-
are described in [Debug configurations](docs/debugging.md). `debug.start`
|
|
278
|
-
selects and starts a configuration, and `debug.stop` ends the active session.
|
|
279
|
-
When execution stops, the Debug panel provides safe stack navigation, lazy
|
|
280
|
-
variables, per-stop watch evaluation (`debug.watch.add` /
|
|
281
|
-
`debug.watch.remove`), and the breakpoint list. Variable expansion is restored
|
|
282
|
-
by name path rather than adapter reference IDs.
|
|
283
|
-
`debug.console.evaluate` accepts REPL input for the selected frame and
|
|
284
|
-
`panel.debug_console` toggles ordered adapter output. Hovering a simple
|
|
285
|
-
local, instance, class, or global variable while stopped evaluates it in the
|
|
286
|
-
selected frame.
|
|
287
|
-
Breakpoint files use an atomic rename
|
|
288
|
-
for normal same-user workspace consistency; concurrent malicious workspace
|
|
289
|
-
mutation is outside that guarantee.
|
|
290
|
-
|
|
291
|
-
Project task definitions, variables, Output tabs, and reveal behavior are
|
|
292
|
-
described in [Tasks](docs/tasks.md). `task.run` opens the task picker,
|
|
293
|
-
`task.stop` stops the selected running Output tab, and `panel.output` toggles
|
|
294
|
-
the panel. Single-line, multi-line, and watch problem matchers publish task
|
|
295
|
-
output into the shared Problems panel and editor diagnostics.
|
|
296
|
-
|
|
297
|
-
The [Test explorer](docs/testing.md) discovers Minitest and RSpec declarations
|
|
298
|
-
with a bounded Alkaid walk and Prism AST inspection. `panel.test` opens the
|
|
299
|
-
tree and `test.refresh` rescans it. Gutter buttons run static tests in bounded
|
|
300
|
-
Task Output tabs and show running, passed, failed, or skipped state; selecting
|
|
301
|
-
a failed test opens its reported failure line.
|
|
157
|
+
The example shows the settings most people change first. Use `auto_pairs`,
|
|
158
|
+
`render_whitespace`, `inlay_hints`, `code_lens`, `minimap`, `breadcrumbs`,
|
|
159
|
+
`persistent_undo`, `recovery`, `terminal.profiles`, `keymap`, and per-language
|
|
160
|
+
overrides for more control. Set `auto_pairs` to `[]` to disable automatic
|
|
161
|
+
pairing for a language.
|
|
162
|
+
|
|
163
|
+
Language servers can be configured with one command array or multiple server
|
|
164
|
+
entries. Completion, diagnostics, and code actions are merged across matching
|
|
165
|
+
servers; workspace symbols use all of them, while other capabilities use the
|
|
166
|
+
first matching server. See [Language servers](docs/lsp.md).
|
|
167
|
+
|
|
168
|
+
Debugging, tasks, and test discovery have dedicated guides:
|
|
169
|
+
[Debug configurations](docs/debugging.md), [Tasks](docs/tasks.md), and
|
|
170
|
+
[Test explorer](docs/testing.md).
|
|
302
171
|
|
|
303
172
|
Plugins require explicit trust and permissions:
|
|
304
173
|
|
|
@@ -312,6 +181,9 @@ The default separate process also requests Saiph's OS sandbox. Set
|
|
|
312
181
|
supported backend, or to `"off"` to retain the legacy process-only isolation.
|
|
313
182
|
The legacy `process` permission is accepted as an alias for `exec`.
|
|
314
183
|
|
|
184
|
+
Manifest-based isolated plugins use the Gienah host and declarative Zaniah UI;
|
|
185
|
+
see [Plugins](docs/plugins.md).
|
|
186
|
+
|
|
315
187
|
## Documentation
|
|
316
188
|
|
|
317
189
|
- [Language servers](docs/lsp.md)
|
|
@@ -320,6 +192,7 @@ The legacy `process` permission is accepted as an alias for `exec`.
|
|
|
320
192
|
- [Vim mode](docs/vim.md)
|
|
321
193
|
- [Snippets](docs/snippets.md)
|
|
322
194
|
- [Completion providers](docs/providers.md)
|
|
195
|
+
- [Plugins](docs/plugins.md)
|
|
323
196
|
- [Workspace edits](docs/workspace_edits.md)
|
|
324
197
|
- [Packaging](docs/distribution.md)
|
|
325
198
|
- [Profiling and local crash reports](docs/performance.md)
|
data/docs/plugins.md
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Plugins
|
|
2
|
+
|
|
3
|
+
Canopus supports two plugin APIs. Existing Ruby plugins use `Workspace#plugins`
|
|
4
|
+
and remain available for compatibility. New plugins use the isolated Gienah
|
|
5
|
+
host and a `plugin.json` manifest.
|
|
6
|
+
|
|
7
|
+
```json
|
|
8
|
+
{
|
|
9
|
+
"id": "word-count",
|
|
10
|
+
"name": "Word Count",
|
|
11
|
+
"version": "0.1.0",
|
|
12
|
+
"api_version": 2,
|
|
13
|
+
"entry": "plugin.rb",
|
|
14
|
+
"activation": ["onCommand:word-count.refresh"],
|
|
15
|
+
"capabilities": ["buffer.read", "ui.panel"],
|
|
16
|
+
"contributes": {
|
|
17
|
+
"commands": [{"id": "word-count.refresh", "title": "Refresh word count"}],
|
|
18
|
+
"panels": [{"id": "word-count", "title": "Word Count", "dock": "right"}]
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
The host discovers manifests without starting processes. A workspace must be
|
|
24
|
+
trusted before a manifest is activated. Capabilities are denied by default;
|
|
25
|
+
`process.exec`, filesystem, and network access additionally require Saiph.
|
|
26
|
+
|
|
27
|
+
Plugin entrypoints use Gienah's SDK and communicate with Canopus through the
|
|
28
|
+
declared host methods:
|
|
29
|
+
|
|
30
|
+
```ruby
|
|
31
|
+
require "gienah"
|
|
32
|
+
|
|
33
|
+
Gienah::Plugin.on("ui/event") { |event| Gienah::Plugin.call("workspace/notify", "text" => event["id"]) }
|
|
34
|
+
Gienah::Plugin.export("word-count.refresh") do
|
|
35
|
+
text = Gienah::Plugin.call("buffer/text")
|
|
36
|
+
Gienah::Plugin.call("ui/render", "panel" => "word-count", "tree" => {
|
|
37
|
+
"type" => "text", "props" => {"value" => "#{text.split.size} words"}, "children" => []
|
|
38
|
+
})
|
|
39
|
+
nil
|
|
40
|
+
end
|
|
41
|
+
Gienah::Plugin.run
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Panels use the allow-listed declarative vocabulary (`column`, `row`, `spacer`,
|
|
45
|
+
`scroll`, `divider`, `text`, `icon`, `badge`, `progress`, `code`, `button`,
|
|
46
|
+
`checkbox`, `text_field`, `select`, `list`, `tree`, and `section`). Raw colors,
|
|
47
|
+
images, fonts, and coordinates are not accepted. UI rendering is cached in the
|
|
48
|
+
editor, so a slow plugin cannot block a frame. Completion providers have a
|
|
49
|
+
200 ms response budget.
|
|
50
|
+
|
|
51
|
+
The host also exposes `storage/get`, `storage/set`, `process/exec`,
|
|
52
|
+
`net/fetch`, `ui/status`, `ui/quick_pick`, `ui/input`, and `ui/confirm`.
|
|
53
|
+
Storage is scoped to the workspace and plugin ID. Network requests must match
|
|
54
|
+
the manifest's `net:` host pattern, and dangerous operations remain gated by
|
|
55
|
+
the manifest capability and workspace trust.
|
|
56
|
+
|
|
57
|
+
`buffer/text` limits an unbounded request to 1 MiB; larger documents must be
|
|
58
|
+
read with a byte range. Calling `buffer/subscribe` with the active buffer URI
|
|
59
|
+
starts diff notifications for that plugin only. The host sends
|
|
60
|
+
`buffer/didChange`, `buffer/didOpen`, `buffer/didSave`, `buffer/didClose`, and
|
|
61
|
+
throttled `selection/didChange` notifications for the subscribed buffer, plus
|
|
62
|
+
`workspace/didChangeFiles` and `settings/didChange` to subscribed plugins.
|
data/lib/canopus/decoration.rb
CHANGED
|
@@ -123,7 +123,7 @@ module Canopus
|
|
|
123
123
|
unless item.row.nil? || (item.row.is_a?(Integer) && item.row >= 0)
|
|
124
124
|
raise ArgumentError, "decoration row must be nonnegative"
|
|
125
125
|
end
|
|
126
|
-
unless item.range.nil? || (item.range.is_a?(Range) && item.range.begin.is_a?(Integer) && item.range.end.is_a?(Integer))
|
|
126
|
+
unless item.range.nil? || (item.range.is_a?(Range) && item.range.begin.is_a?(Integer) && item.range.end.is_a?(Integer) && item.range.begin >= 0 && item.range.end >= item.range.begin)
|
|
127
127
|
raise ArgumentError, "decoration range must contain integer offsets"
|
|
128
128
|
end
|
|
129
129
|
raise ArgumentError, "decoration click handler must be callable" unless item.on_click.nil? || item.on_click.respond_to?(:call)
|
data/lib/canopus/plugins/api.rb
CHANGED
|
@@ -15,7 +15,11 @@ module Canopus
|
|
|
15
15
|
end
|
|
16
16
|
def text
|
|
17
17
|
permit!("read_buffer")
|
|
18
|
-
@workspace.editor
|
|
18
|
+
buffer = @workspace.editor&.buffer
|
|
19
|
+
raise Canopus::Error, "buffer is not available" unless buffer
|
|
20
|
+
raise Canopus::Error, "plugin buffer text exceeds 1 MiB" if buffer.rope.bytesize > Plugins::BUFFER_CONTEXT_LIMIT
|
|
21
|
+
|
|
22
|
+
buffer.text.dup.freeze
|
|
19
23
|
end
|
|
20
24
|
def replace(range, text)
|
|
21
25
|
permit!("edit_buffer")
|