canopus 0.1.0 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b3f1beb3dd3a5647f1ac04e7fc710356c5a90d4d8c3cefa01d676c463bd95950
4
- data.tar.gz: 5e4b81d47c4c442b3f74b4e87745d0c8e7e06b3a4119ee845205fd6c1628f22a
3
+ metadata.gz: 8f145122cb1995d72f9ddcf886fc40d2d00c60351b6d7a227ce69011c2ca7f61
4
+ data.tar.gz: 52b865cfbbda7a3e991748305282db47ce0f7f7903e50c763142defab18a0b7e
5
5
  SHA512:
6
- metadata.gz: ecb15f56e99c82bc6b7d7a1368096d5d4db4ea53b9993ea2ad3cd804ea5cd61fb6ca33a4470856d89a0e4ae22004d7876df992f8233a26e0864e2da27fbf5c71
7
- data.tar.gz: 91e0d07140b34dda056874ce090bc37507a055f8f8685e5678c458cdfe74dd7d8137598793c2c8fb11152828de307f2f2b7e85040719c85b80bc6f3bce8d0cc9
6
+ metadata.gz: 50e3e24430e992f3961e2838444ce5f8c6ab8337c75ebc504f863554f219736212b46a140d89208f223c6316a8d754860de598b70e69881bf65601196cdcbd55
7
+ data.tar.gz: 7ac119f37e6947ccebae40e63d6eb54bb243bc9ff149049ad02e623c4f3d210da45999ec2a3ee520c30cb87a924c8c0189a30e3333a9c39cd2e35ef14031d9bb
data/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.2.0 — 2026-09-12
4
+
5
+ - Read repositories through Thuban and keep text comparison in Porrima data objects.
6
+ - Use Porrima marks and indexed hunk lookup for Git gutter interactions.
7
+ - Delegate text diff calculation to Porrima without changing Git behavior.
8
+ - Add closable editor tabs and multiple terminal tabs with session persistence.
9
+ - Prevent duplicate `strscan` initialization in syntax workers.
10
+ - Avoid cross-test method replacement in background layout error coverage.
11
+
3
12
  ## 0.1.0 — 2026-09-11
4
13
 
5
14
  - Initial release.
data/README.md CHANGED
@@ -1,42 +1,80 @@
1
- # Canopus
1
+ <p align="center">
2
+ <img src="assets/logo.png" alt="Canopus logo">
3
+ </p>
4
+
5
+ <p align="center">
6
+ <strong>Ruby-native code editor with GPU windows, language-server tools, a terminal, Git integration, and Vim bindings</strong>
7
+ </p>
8
+
9
+ <p align="center">
10
+ <a href="https://rubygems.org/gems/canopus"><img src="https://img.shields.io/gem/v/canopus.svg" alt="Gem version"></a>
11
+ <a href="https://rubygems.org/gems/canopus"><img src="https://img.shields.io/gem/dt/canopus.svg" alt="Gem downloads"></a>
12
+ <a href="https://github.com/noxdea/canopus/actions/workflows/main.yml"><img src="https://github.com/noxdea/canopus/actions/workflows/main.yml/badge.svg" alt="CI"></a>
13
+ <img src="https://img.shields.io/badge/CRuby-%3E%3D%203.1-cc342d.svg" alt="CRuby 3.1 or newer">
14
+ <a href="LICENSE.txt"><img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="MIT license"></a>
15
+ </p>
16
+
17
+ <p align="center">
18
+ <a href="#features">Features</a> ·
19
+ <a href="#installation">Installation</a> ·
20
+ <a href="#quick-start">Quick start</a> ·
21
+ <a href="#configuration">Configuration</a> ·
22
+ <a href="#development">Development</a>
23
+ </p>
24
+
25
+ ---
26
+
27
+ Canopus is a code editor implemented in Ruby. It combines persistent UTF-8
28
+ buffers with native rendering through [Zaniah](https://github.com/noxdea/zaniah),
29
+ while keeping language servers, shells, and other external tools independently
30
+ installable.
31
+
32
+ ## Features
33
+
34
+ - Native GPU windows on macOS, Linux, and Windows, plus TUI and headless modes
35
+ - Persistent buffers, tabs, splits, sessions, and explicit save-conflict handling
36
+ - LSP completion, diagnostics, hover, symbols, formatting, rename, and code actions
37
+ - Resizable integrated terminal with multiple tabs, scrollback, selection, colors, and clickable links
38
+ - Git diff, blame, hunk reversal, and branch switching
39
+ - Editable project-wide search results and safe project file operations
40
+ - Optional Vim-compatible modes, motions, operators, registers, macros, and Ex commands
41
+ - Layered JSONC settings, keymaps, themes, snippets, and trusted Ruby plugins
42
+
43
+ ## Installation
44
+
45
+ Install the released gem:
2
46
 
3
- A Ruby-native code editor built on Zaniah: persistent UTF-8 buffers, native GPU
4
- windows, language-server tools, a terminal, Git inspection, editable project
5
- search results, and Vim bindings.
47
+ ```sh
48
+ gem install canopus
49
+ canopus --version
50
+ ```
6
51
 
7
- The launcher requires CRuby 3.1+. It attempts to enable YJIT on macOS/Linux
8
- and falls back to ordinary Ruby when unavailable; Windows uses ordinary Ruby
9
- ([runtime decision](docs/adr/005-windows-runtime.md)). OS libraries use Fiddle; language
10
- servers and the terminal shell are user-installed programs. Ruby libraries are
11
- installed as gem dependencies; Prism is bundled with recent Ruby releases.
52
+ Canopus requires CRuby 3.1 or newer. The launcher enables YJIT when supported
53
+ and otherwise uses the interpreter. Native windows also require the `fiddle`
54
+ standard-library component; some Ruby distributions package it separately.
12
55
 
13
- Native windows need `require "fiddle"` to work in the chosen Ruby installation.
14
- On Ruby distributions that package it separately (including the Ruby 4.0 build
15
- used here), install that standard-library component first. Development Bundler
16
- configuration includes it; headless rendering does not load it.
56
+ macOS uses Metal. Linux requires Wayland/EGL/OpenGL or X11/GLX, XKB, and
57
+ `zenity` for file dialogs. Windows uses WGL. See [Packaging](docs/distribution.md)
58
+ for source-based desktop bundles and platform details.
17
59
 
18
- ## Run from this checkout
60
+ ## Quick start
61
+
62
+ Open the current project:
19
63
 
20
64
  ```sh
21
- bundle install
22
- bundle exec ruby exe/canopus --project . README.md
23
- ruby exe/canopus --headless /tmp/canopus.png README.md
24
- ruby exe/canopus --tui README.md
65
+ canopus --project .
25
66
  ```
26
67
 
27
- `--help` lists backend, session, settings, replay, cache, and plugin options.
28
- macOS uses Metal, Linux uses Wayland/EGL or X11/GLX, and Windows uses WGL.
29
-
30
- Install a local artifact with:
68
+ Open files directly, use the terminal interface, or render a headless frame:
31
69
 
32
70
  ```sh
33
- gem build canopus.gemspec
34
- gem install --local canopus-0.1.0.gem
35
- canopus --project .
71
+ canopus README.md lib/canopus.rb
72
+ canopus --tui --project .
73
+ canopus --headless /tmp/canopus.png README.md
36
74
  ```
37
75
 
38
- See [packaging](docs/distribution.md) for desktop bundles and platform
39
- requirements.
76
+ Run `canopus --help` for session, settings, replay, backend, profiling, and
77
+ plugin options.
40
78
 
41
79
  ## Everyday controls
42
80
 
@@ -49,43 +87,29 @@ requirements.
49
87
  | All occurrences / move lines | Cmd-Shift-L / Alt-Up or Down | Ctrl-Shift-L / Alt-Up or Down |
50
88
  | Completion / definition | Ctrl-Space / F12 | Ctrl-Space / F12 |
51
89
  | Split / terminal | Cmd-Backslash / Ctrl-Backtick | Ctrl-Backslash / Ctrl-Backtick |
90
+ | Close / reopen tab | Cmd-W / Cmd-Shift-T | Ctrl-W / Ctrl-Shift-T |
91
+ | New terminal tab | Ctrl-Shift-Backtick | Ctrl-Shift-Backtick |
92
+ | Next / previous terminal | Ctrl-Shift-] / Ctrl-Shift-[ | Ctrl-Shift-] / Ctrl-Shift-[ |
52
93
 
53
- The palette exposes Git diff/blame/hunk reversal/branch switching, language
54
- actions, project file operations, settings, themes, [Vim mode](docs/vim.md), and docks. Drag tabs
55
- to reorder or move them between panes; drag separators to resize panes and docks.
56
- Project deletion moves files into `.canopus/trash`. Dirty documents and disk
57
- save conflicts are preserved for an explicit decision.
94
+ The command palette also exposes Git operations, language actions, project file
95
+ operations, settings, themes, docks, and Vim mode. Project deletion moves files
96
+ to `.canopus/trash` instead of deleting them immediately.
58
97
 
59
- The file finder keeps recent files first and previews text without opening tabs.
60
- Completion supports additional edits and [snippets](docs/snippets.md), including
61
- mirrors, transforms, choices, and Tab / Shift-Tab navigation. Hover cards render
62
- bounded Markdown; only explicitly clicked HTTP(S) links open externally.
63
- Notifications are dismissible and expire automatically.
98
+ ## Configuration
64
99
 
65
- Project-search results are editable; Save writes changes back to their source
66
- files. Replacement changes remain unsaved until then.
67
-
68
- Search palettes use Ctrl-Alt-R for regular expressions, Ctrl-Alt-C for case sensitivity,
69
- Ctrl-Alt-W for whole words and Ctrl-Alt-S for the selection captured when search opened.
70
- Replacements support Ruby backreferences, and stale selections are rejected.
71
- Resource-changing LSP actions show the affected paths before confirmation;
72
- PageUp / PageDown scroll the list. See [workspace edits](docs/workspace_edits.md).
73
-
74
- ## Settings and extensions
75
-
76
- `settings.open` opens `.canopus/settings.jsonc`. User settings live at
77
- `$XDG_CONFIG_HOME/canopus/settings.jsonc` or
78
- `~/.config/canopus/settings.jsonc`. Layers are defaults, user, project, explicit
79
- `--settings`, then language overrides. Saved changes reload; invalid values
80
- preserve the previous valid settings. Ctrl-Space completes setting names.
100
+ Run `settings.open` from the command palette to edit project settings. User
101
+ settings live at `$XDG_CONFIG_HOME/canopus/settings.jsonc` or
102
+ `~/.config/canopus/settings.jsonc`.
81
103
 
82
104
  ```jsonc
83
105
  {
84
106
  "theme": "auto",
85
107
  "font_size": 14,
86
- "icon_theme": null,
87
108
  "vim_mode": false,
88
109
  "use_tabs": false,
110
+ "tabs": { "activate_on_close": "history", "reopen_history_limit": 20 },
111
+ "terminal": { "working_directory": "project", "scrollback_lines": 10000 },
112
+ "dock": { "bottom": { "size": 280, "visible": false } },
89
113
  "keymap": [
90
114
  { "context": "Editor && !vim_mode", "bindings": { "ctrl-k ctrl-s": "file.save" } }
91
115
  ],
@@ -94,55 +118,63 @@ preserve the previous valid settings. Ctrl-Space completes setting names.
94
118
  }
95
119
  ```
96
120
 
97
- See [language servers](docs/lsp.md) for server-specific options and reload
98
- behavior.
121
+ Closing a dirty tab asks whether to save, discard, or cancel. Reopening restores
122
+ the file, selections, position, and pane while Canopus is running; discarded
123
+ unsaved changes are never restored. Terminal session restoration, when enabled,
124
+ starts fresh shells with the saved tab count and working directories and does
125
+ not restore processes or scrollback.
99
126
 
100
- Keymap groups extend the defaults; later matching bindings win. Space-separated
101
- keys form a chord with a one-second timeout, and `null` removes a default action
102
- binding. Contexts support `Editor`, `vim_mode`, comparisons and boolean operators,
103
- not Ruby evaluation. Language-specific `keymap` arrays replace the global array.
104
- Saved keymaps reload atomically, including palette labels; invalid expressions
105
- leave the previous settings intact. Limits are 128 groups and 1,024 bindings.
127
+ Settings are layered from defaults through user, project, explicit `--settings`,
128
+ and language overrides. Invalid saved settings leave the previous valid values
129
+ active. Keymap groups extend defaults; later matching bindings win, and `null`
130
+ removes a default binding.
106
131
 
107
- An icon theme is a JSONC file with `file`, `directory`, `expanded_directory`, and
108
- an `extensions` map (for example `".rb": "ruby.svg"`). SVG paths are relative to
109
- that theme file and must remain inside its directory. Only the supported static
110
- SVG subset is drawn; scripts, external references and entities are not executed.
132
+ Language servers are separate programs and are auto-detected or configured by
133
+ argument array. See [Language servers](docs/lsp.md) for configuration and
134
+ restart behavior.
111
135
 
112
- Plugins require explicit trust:
136
+ Plugins require explicit trust and permissions:
113
137
 
114
138
  ```sh
115
- ruby exe/canopus --plugin examples/plugins/word_count.rb \
139
+ canopus --plugin examples/plugins/word_count.rb \
116
140
  --trust-plugins --grant read_buffer
117
141
  ```
118
142
 
119
- The default separate process contains crashes and timeouts. It is **not an OS
120
- security sandbox**: trusted Ruby retains the invoking user's OS privileges.
121
- API grants restrict the editor bridge, not arbitrary Ruby filesystem/network
122
- access. `--plugins-in-process` opts into direct execution.
143
+ The default separate process contains plugin crashes and timeouts, but it is not
144
+ an OS sandbox. Trusted Ruby code retains the invoking user's filesystem and
145
+ network privileges.
123
146
 
124
- ## Development and limits
147
+ ## Documentation
148
+
149
+ - [Language servers](docs/lsp.md)
150
+ - [Vim mode](docs/vim.md)
151
+ - [Snippets](docs/snippets.md)
152
+ - [Workspace edits](docs/workspace_edits.md)
153
+ - [Packaging](docs/distribution.md)
154
+ - [Profiling and local crash reports](docs/performance.md)
155
+ - [Architecture decisions](docs/adr)
156
+
157
+ ## Development
125
158
 
126
159
  ```sh
160
+ git clone https://github.com/noxdea/canopus.git
161
+ cd canopus
162
+ bundle install
127
163
  bundle exec rake test
128
- bundle exec rake bench
164
+ bundle exec rbs -I sig -r porrima -r thuban -r alhena -r antares -r denebola -r zaniah -r stringio -r strscan validate
129
165
  bundle exec ruby tools/check_dependencies.rb test/type/smoke.rb
130
- bundle exec rbs -I sig -r alhena -r antares -r denebola -r zaniah -r stringio -r strscan validate
131
166
  ```
132
167
 
133
- Components are Zaniah, Alhena, Denebola, Spica, Kochab and Antares.
134
- Rouge supplies lexers; REXML parses static SVG; unicode-display_width and
135
- unicode-emoji supply terminal-cell tables. They are installed from RubyGems.
168
+ Run `bundle exec rake bench` for performance checks. Contributions can be
169
+ submitted through [GitHub issues and pull requests](https://github.com/noxdea/canopus/issues).
136
170
 
137
- Files over 100MiB use a bounded-cache UTF-8 read-only path without wrapping or
138
- folding. Large-file UTF-16/legacy encodings are not supported there. Rouge
139
- lexers that cannot resume exactly use a documented bounded-window fallback,
140
- which can approximate long-distance syntax state. Git supports SHA-1 repositories,
141
- not every Git index/object extension. See the [architecture decisions](docs/adr).
171
+ ## Limits
142
172
 
143
- Opt-in [profiling and local crash reports](docs/performance.md) expose real
144
- frame times and allocations without uploading project data.
173
+ - Files larger than 100 MiB use a read-only UTF-8 path without wrapping or folding.
174
+ - Large-file UTF-16 and legacy encodings are unsupported.
175
+ - Git support targets SHA-1 repositories and does not implement every index or object extension.
176
+ - Desktop packages are unsigned and do not bundle Ruby or automatic updates.
145
177
 
146
178
  ## License
147
179
 
148
- MIT; see [LICENSE.txt](LICENSE.txt).
180
+ Canopus is released under the [MIT License](LICENSE.txt).
Binary file
data/assets/logo.png ADDED
Binary file
@@ -0,0 +1,24 @@
1
+ # ADR NNN: Implementation decision title
2
+
3
+ - Status: Proposed
4
+ - Date: YYYY-MM-DD
5
+
6
+ ## Context
7
+
8
+ Describe the concrete implementation question and its compatibility, data,
9
+ runtime, or component constraints. Operational workflow and release policy do
10
+ not belong in this directory; see [the scope](README.md).
11
+
12
+ Name the credible alternatives. If there was no meaningful alternative, record
13
+ the behavior in reference documentation instead of creating an ADR.
14
+
15
+ ## Decision
16
+
17
+ Describe the durable boundary or architecture choice. Leave command syntax,
18
+ field-by-field formats, test evidence, benchmark results, and migration steps
19
+ in their authoritative documents.
20
+
21
+ ## Consequences
22
+
23
+ Describe the important positive and negative trade-offs, including what would
24
+ make this decision worth revisiting.
@@ -16,7 +16,7 @@ switching algorithms by input size.
16
16
 
17
17
  ## Consequences
18
18
 
19
- Memory behavior and tie-breaking remain consistent across file sizes, but
20
- Canopus owns the implementation and its performance limits. Revisit this
21
- decision if a maintained implementation provides the same bounds and stable
22
- results with less maintenance.
19
+ Memory behavior and tie-breaking remain consistent across file sizes. Porrima
20
+ owns the implementation and its performance limits while Canopus retains
21
+ display and scheduling policy. Revisit this decision if Porrima no longer
22
+ provides the same bounds and stable results.
@@ -0,0 +1,25 @@
1
+ # ADR 006: Release buffers after their last live view
2
+
3
+ - Status: Accepted
4
+ - Date: 2026-09-11
5
+
6
+ ## Context
7
+
8
+ A buffer can be shown by editors in several panes and by a project-search
9
+ `MultiBuffer`. Closing one tab must dispose its editor subscriptions without
10
+ closing language-server documents or persistent ropes still used elsewhere.
11
+ The alternatives were an independent reference-counting store or deriving
12
+ owners from the workspace's existing editor and excerpt collections.
13
+
14
+ ## Decision
15
+
16
+ Dispose the editor immediately, then derive the remaining owners from panes and
17
+ `MultiBuffer` excerpts in the same close operation. Release the buffer and its
18
+ language-server document only when no owner remains. Keep closed-tab navigation
19
+ state in a bounded, process-local stack; never retain discarded buffer content.
20
+
21
+ ## Consequences
22
+
23
+ Ownership has one source of truth and cannot drift through unmatched increment
24
+ or decrement calls. The scan is linear in open views; revisit with explicit
25
+ owner IDs only if measured close latency becomes material.
@@ -0,0 +1,24 @@
1
+ # ADR 007: Route terminal keys with an explicit editor allowlist
2
+
3
+ - Status: Accepted
4
+ - Date: 2026-09-11
5
+
6
+ ## Context
7
+
8
+ Terminal applications need control and escape sequences that overlap editor
9
+ bindings. Dispatching editor shortcuts first breaks shells, while sending every
10
+ key to the PTY makes terminal tab management and application commands
11
+ unreachable.
12
+
13
+ ## Decision
14
+
15
+ When the terminal owns focus, dispatch only bindings whose context matches
16
+ `Terminal`; send every unmatched key to the active PTY. Default terminal
17
+ bindings cover panel and tab management, copy, paste, and the command palette.
18
+ User keymap groups remain later bindings and can override those defaults.
19
+
20
+ ## Consequences
21
+
22
+ Shell keys pass through by default and `Cmd-W`/`Ctrl-W` close the focused
23
+ terminal instead of an editor tab. New global shortcuts must be added to the
24
+ terminal context only when interception is intentional.