canopus 0.1.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.
Files changed (146) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +5 -0
  3. data/LICENSE.txt +21 -0
  4. data/README.md +148 -0
  5. data/docs/adr/001-runtime-gem-components.md +24 -0
  6. data/docs/adr/002-bounded-diff-engine.md +22 -0
  7. data/docs/adr/003-background-language-analysis.md +22 -0
  8. data/docs/adr/004-persistent-display-map.md +23 -0
  9. data/docs/adr/005-windows-runtime.md +27 -0
  10. data/docs/adr/README.md +36 -0
  11. data/docs/distribution.md +27 -0
  12. data/docs/lsp.md +38 -0
  13. data/docs/performance.md +40 -0
  14. data/docs/snippets.md +32 -0
  15. data/docs/vim.md +24 -0
  16. data/docs/workspace_edits.md +32 -0
  17. data/examples/native_smoke.rb +25 -0
  18. data/examples/plugins/word_count.rb +11 -0
  19. data/exe/canopus +19 -0
  20. data/lib/canopus/block_map.rb +19 -0
  21. data/lib/canopus/buffer.rb +293 -0
  22. data/lib/canopus/cli.rb +171 -0
  23. data/lib/canopus/controller.rb +507 -0
  24. data/lib/canopus/data_compat.rb +25 -0
  25. data/lib/canopus/display_map/line_builder.rb +54 -0
  26. data/lib/canopus/display_map/line_set.rb +8 -0
  27. data/lib/canopus/display_map/pending_line_set.rb +9 -0
  28. data/lib/canopus/display_map/summary.rb +23 -0
  29. data/lib/canopus/display_map/worker.rb +89 -0
  30. data/lib/canopus/display_map.rb +350 -0
  31. data/lib/canopus/display_point.rb +5 -0
  32. data/lib/canopus/editor/snippet_expandable.rb +281 -0
  33. data/lib/canopus/editor.rb +445 -0
  34. data/lib/canopus/error.rb +5 -0
  35. data/lib/canopus/fold_map.rb +87 -0
  36. data/lib/canopus/git/blame.rb +50 -0
  37. data/lib/canopus/git/commit.rb +7 -0
  38. data/lib/canopus/git/corrupt_object.rb +7 -0
  39. data/lib/canopus/git/diff.rb +131 -0
  40. data/lib/canopus/git/index.rb +94 -0
  41. data/lib/canopus/git/object_database.rb +45 -0
  42. data/lib/canopus/git/pack.rb +186 -0
  43. data/lib/canopus/git/repository.rb +313 -0
  44. data/lib/canopus/git/status.rb +74 -0
  45. data/lib/canopus/git/tree_entry.rb +7 -0
  46. data/lib/canopus/git.rb +15 -0
  47. data/lib/canopus/icon_theme.rb +43 -0
  48. data/lib/canopus/language/background_analysis/job.rb +12 -0
  49. data/lib/canopus/language/background_analysis/scheduler.rb +70 -0
  50. data/lib/canopus/language/background_analysis.rb +280 -0
  51. data/lib/canopus/language/definition.rb +7 -0
  52. data/lib/canopus/language/document.rb +143 -0
  53. data/lib/canopus/language/symbol.rb +7 -0
  54. data/lib/canopus/language/syntax_worker.rb +91 -0
  55. data/lib/canopus/language.rb +42 -0
  56. data/lib/canopus/lazy_rope.rb +218 -0
  57. data/lib/canopus/lsp/client.rb +299 -0
  58. data/lib/canopus/lsp/error.rb +7 -0
  59. data/lib/canopus/lsp/future/subscription.rb +9 -0
  60. data/lib/canopus/lsp/future.rb +87 -0
  61. data/lib/canopus/lsp/protocol.rb +83 -0
  62. data/lib/canopus/lsp/server_error.rb +13 -0
  63. data/lib/canopus/lsp/timeout.rb +7 -0
  64. data/lib/canopus/lsp/transport.rb +123 -0
  65. data/lib/canopus/lsp.rb +19 -0
  66. data/lib/canopus/markdown.rb +69 -0
  67. data/lib/canopus/match_data_compat.rb +17 -0
  68. data/lib/canopus/multi_buffer.rb +266 -0
  69. data/lib/canopus/pane.rb +61 -0
  70. data/lib/canopus/patch/composite.rb +12 -0
  71. data/lib/canopus/patch/reload.rb +18 -0
  72. data/lib/canopus/patch.rb +27 -0
  73. data/lib/canopus/performance_recorder.rb +207 -0
  74. data/lib/canopus/plugins/api.rb +50 -0
  75. data/lib/canopus/plugins/isolated_runtime.rb +167 -0
  76. data/lib/canopus/plugins/local_runtime.rb +25 -0
  77. data/lib/canopus/plugins/permission_denied.rb +7 -0
  78. data/lib/canopus/plugins/registry.rb +30 -0
  79. data/lib/canopus/plugins.rb +11 -0
  80. data/lib/canopus/project/ignore_matcher.rb +104 -0
  81. data/lib/canopus/project/search.rb +164 -0
  82. data/lib/canopus/project/search_worker/cancelled.rb +3 -0
  83. data/lib/canopus/project/search_worker/runner.rb +9 -0
  84. data/lib/canopus/project/search_worker.rb +108 -0
  85. data/lib/canopus/project/tree.rb +48 -0
  86. data/lib/canopus/project/watcher.rb +59 -0
  87. data/lib/canopus/project.rb +127 -0
  88. data/lib/canopus/regexp_compat.rb +30 -0
  89. data/lib/canopus/save_conflict.rb +5 -0
  90. data/lib/canopus/selection.rb +11 -0
  91. data/lib/canopus/settings.rb +118 -0
  92. data/lib/canopus/snippet/transform.rb +209 -0
  93. data/lib/canopus/snippet.rb +183 -0
  94. data/lib/canopus/tab_map.rb +30 -0
  95. data/lib/canopus/terminal/cell.rb +7 -0
  96. data/lib/canopus/terminal/grid.rb +321 -0
  97. data/lib/canopus/terminal/pty.rb +103 -0
  98. data/lib/canopus/terminal/scrollback.rb +38 -0
  99. data/lib/canopus/terminal/vt.rb +398 -0
  100. data/lib/canopus/terminal.rb +13 -0
  101. data/lib/canopus/theme.rb +43 -0
  102. data/lib/canopus/version.rb +5 -0
  103. data/lib/canopus/vim/commandable.rb +148 -0
  104. data/lib/canopus/vim/motionable.rb +321 -0
  105. data/lib/canopus/vim/operator_capable.rb +377 -0
  106. data/lib/canopus/vim/text_object_selectable.rb +141 -0
  107. data/lib/canopus/vim.rb +426 -0
  108. data/lib/canopus/workspace/edit/executable.rb +139 -0
  109. data/lib/canopus/workspace/edit/node.rb +8 -0
  110. data/lib/canopus/workspace/edit/plan.rb +170 -0
  111. data/lib/canopus/workspace/edit/resource_preparable.rb +98 -0
  112. data/lib/canopus/workspace/edit.rb +6 -0
  113. data/lib/canopus/workspace/file_change_aware.rb +40 -0
  114. data/lib/canopus/workspace/file_previewable.rb +31 -0
  115. data/lib/canopus/workspace/git_aware.rb +140 -0
  116. data/lib/canopus/workspace/language_aware.rb +413 -0
  117. data/lib/canopus/workspace/language_server_configurable.rb +181 -0
  118. data/lib/canopus/workspace/project_searchable.rb +208 -0
  119. data/lib/canopus/workspace/project_tree_editable.rb +82 -0
  120. data/lib/canopus/workspace/session_persistable.rb +153 -0
  121. data/lib/canopus/workspace/settings_aware.rb +91 -0
  122. data/lib/canopus/workspace/view/terminal_presentable.rb +185 -0
  123. data/lib/canopus/workspace/view.rb +643 -0
  124. data/lib/canopus/workspace.rb +525 -0
  125. data/lib/canopus/wrap_map.rb +108 -0
  126. data/lib/canopus.rb +24 -0
  127. data/sig/canopus.rbs +375 -0
  128. data/sig/controller.rbs +55 -0
  129. data/sig/display_stages.rbs +49 -0
  130. data/sig/git.rbs +140 -0
  131. data/sig/lsp.rbs +99 -0
  132. data/sig/markdown.rbs +11 -0
  133. data/sig/performance_recorder.rbs +23 -0
  134. data/sig/search_services.rbs +8 -0
  135. data/sig/services.rbs +81 -0
  136. data/sig/snippet.rbs +42 -0
  137. data/sig/terminal.rbs +125 -0
  138. data/sig/vim.rbs +27 -0
  139. data/sig/workspace_edits.rbs +11 -0
  140. data/sig/workspace_services.rbs +117 -0
  141. data/tools/certify_snippet_regex.rb +35 -0
  142. data/tools/check_dependencies.rb +80 -0
  143. data/tools/native_check.rb +70 -0
  144. data/tools/package.rb +113 -0
  145. data/tools/package_test.rb +32 -0
  146. metadata +314 -0
data/sig/lsp.rbs ADDED
@@ -0,0 +1,99 @@
1
+ module Canopus
2
+ module LSP
3
+ type json = nil | bool | Integer | Float | String | Array[json] | Hash[String | Symbol, json]
4
+ type object = Hash[String | Symbol, json]
5
+ type semantic_token = { line: Integer, character: Integer, length: Integer, type: Integer, modifiers: Integer }
6
+
7
+ class Error < StandardError
8
+ end
9
+ class Timeout < Error
10
+ end
11
+ class ServerError < Error
12
+ attr_reader code: Integer
13
+ attr_reader data: json
14
+ def initialize: (Hash[String, json] error) -> void
15
+ end
16
+
17
+ module Protocol
18
+ def self.uri: (String path) -> String
19
+ def self.path: (String uri) -> String
20
+ def self.position: (Denebola::Rope rope, Integer offset) -> { line: Integer, character: Integer }
21
+ def self.offset: (Denebola::Rope rope, Hash[String, Integer] position) -> Integer
22
+ def self.range: (Denebola::Rope rope, Range[Integer] range) -> object
23
+ def self.uint?: (untyped value) -> bool
24
+ def self.diagnostics: (Array[object] values) -> Array[object]
25
+ def self.semantic_delta: (Array[Integer] data, Array[Hash[String, json]] edits) -> Array[Integer]
26
+ def self.semantic_tokens: (Array[Integer] data, ?legend: Hash[String, Array[String]]?) -> Array[semantic_token]
27
+ end
28
+
29
+ class Future
30
+ class Subscription
31
+ def initialize: () { () -> untyped } -> void
32
+ def detach: () -> untyped
33
+ end
34
+ attr_reader id: Integer | String | nil
35
+ attr_reader callback_errors: Array[Error]
36
+ def initialize: (Integer | String | nil id, ?on_error: ^(Error) -> untyped) ?{ (Integer | String | nil) -> untyped } -> void
37
+ def fulfill: (?untyped value, ?error: Exception?) -> Future?
38
+ def then: () { (untyped, Exception?) -> untyped } -> Future
39
+ def done?: () -> bool
40
+ def on_complete: () { () -> untyped } -> Subscription
41
+ def await: (?timeout: Numeric?) -> untyped
42
+ def cancel: () -> bool
43
+ end
44
+
45
+ class Transport
46
+ MAX_MESSAGE: Integer
47
+ attr_reader stderr_lines: Array[String]
48
+ attr_reader pid: Integer
49
+ def initialize: (Array[String] command, ?cwd: String?, ?env: Hash[String, String?]) { (Hash[String, json]?, Exception?) -> untyped } -> void
50
+ def self.read_message: (IO | StringIO io) -> Hash[String, json]?
51
+ def self.validate_message: (untyped message) -> Hash[String, json]
52
+ def write: (object message) -> untyped
53
+ def alive?: () -> bool
54
+ def close: () -> untyped
55
+ end
56
+
57
+ class Client
58
+ attr_reader capabilities: Hash[String, json]
59
+ attr_reader transport: Transport?
60
+ attr_reader diagnostics: Hash[String, Array[object]]
61
+ attr_reader state: :stopped | :starting | :running | :failed
62
+ attr_reader errors: Array[Error]
63
+ attr_reader server_info: Hash[String, json]?
64
+ attr_reader position_encoding: String?
65
+ def initialize: (command: Array[String], ?root: String, ?dispatch: ^() { () -> untyped } -> untyped, ?restart: bool, ?env: Hash[String, String?], ?initialization_options: json, ?configuration: object) -> void
66
+ def start: (?timeout: Numeric) -> self
67
+ def stop: () -> untyped
68
+ def request: (String | Symbol method, ?json params) -> Future
69
+ def notify: (String | Symbol method, ?json params) -> untyped
70
+ def on: (String | Symbol method) { (untyped) -> untyped } -> Proc
71
+ def supports?: (String | Symbol capability) -> bool
72
+ def workspace_symbols: (String query) -> Future
73
+ def resolve_completion: (object item) -> Future
74
+ def resolve_code_action: (object action) -> Future
75
+ def resolve_code_lens: (object lens) -> Future
76
+ def execute_command: (String command, ?arguments: Array[json]) -> Future
77
+ def open_document: (Buffer buffer, language_id: String) -> String
78
+ def close_document: (String uri) -> untyped
79
+ def save_document: (String uri) -> untyped
80
+ def at: (String method, Buffer buffer, Integer offset, **json params) -> Future
81
+ def completion: (Buffer buffer, Integer offset, **json params) -> Future
82
+ def hover: (Buffer buffer, Integer offset, **json params) -> Future
83
+ def definition: (Buffer buffer, Integer offset, **json params) -> Future
84
+ def typeDefinition: (Buffer buffer, Integer offset, **json params) -> Future
85
+ def implementation: (Buffer buffer, Integer offset, **json params) -> Future
86
+ def references: (Buffer buffer, Integer offset, **json params) -> Future
87
+ def rename: (Buffer buffer, Integer offset, **json params) -> Future
88
+ def signatureHelp: (Buffer buffer, Integer offset, **json params) -> Future
89
+ def documentSymbol: (Buffer buffer, **json params) -> Future
90
+ def formatting: (Buffer buffer, **json params) -> Future
91
+ def codeAction: (Buffer buffer, **json params) -> Future
92
+ def inlayHint: (Buffer buffer, **json params) -> Future
93
+ def codeLens: (Buffer buffer, **json params) -> Future
94
+ def diagnostic: (Buffer buffer, **json params) -> Future
95
+ def semantic_tokens: (Buffer buffer) -> Array[semantic_token]
96
+ def apply_text_edits: (Buffer buffer, Array[object] edits) -> untyped
97
+ end
98
+ end
99
+ end
data/sig/markdown.rbs ADDED
@@ -0,0 +1,11 @@
1
+ module Canopus
2
+ class Markdown
3
+ class Run < Data
4
+ attr_reader text: String
5
+ attr_reader style: Symbol | String
6
+ attr_reader url: String?
7
+ end
8
+ def initialize: (String source, ?width: Integer, ?max_rows: Integer, ?markup: bool) -> void
9
+ attr_reader rows: Array[Array[Run]]
10
+ end
11
+ end
@@ -0,0 +1,23 @@
1
+ module Canopus
2
+ class PerformanceRecorder
3
+ type statistics = {
4
+ frames: Integer, retained_frames: Integer, last_frame_ms: Float?,
5
+ last_allocations: Integer?, last_draw_calls: Integer?, median_frame_ms: Numeric,
6
+ p95_frame_ms: Numeric, max_frame_ms: Numeric, mean_allocations: Numeric,
7
+ sampling_samples: Integer
8
+ }
9
+ def initialize: (Zaniah::Platform::Headless::Window window, ?trace_allocations: bool, ?sampling: bool,
10
+ ?capacity: Integer, ?sample_capacity: Integer, ?interval: Numeric) -> void
11
+ attr_reader sampler: Thread?
12
+ def start: () -> self
13
+ def stop: () -> self
14
+ def measure: [A] () { () -> A } -> A
15
+ def statistics: () -> statistics
16
+ def report: () -> Hash[Symbol, untyped]
17
+ def write: (String path) -> String
18
+ def self.context: (?Zaniah::Platform::Headless::Window? window) -> Hash[Symbol, untyped]
19
+ def self.validate_paths: (Array[String?] paths, ?protected: Array[String?]) -> Array[String]
20
+ def self.write_json: (String path, untyped report) -> String
21
+ def self.write_crash: (String path, Exception exception, ?window: Zaniah::Platform::Headless::Window?) -> String
22
+ end
23
+ end
@@ -0,0 +1,8 @@
1
+ module Canopus
2
+ class Buffer
3
+ def copy_anchor: (Buffer source, Anchor anchor) -> Anchor
4
+ end
5
+ class Workspace
6
+ def cancel_project_search: () -> void
7
+ end
8
+ end
data/sig/services.rbs ADDED
@@ -0,0 +1,81 @@
1
+ module Canopus
2
+ class Project
3
+ interface _NativeWatcher
4
+ def poll: (?timeout: Numeric) -> Array[untyped]
5
+ def close: () -> void
6
+ end
7
+ attr_reader root: String
8
+ def initialize: (String root) -> void
9
+ def path: (String relative) -> String
10
+ def files: (?include_hidden: bool, ?follow_symlinks: bool, ?include_symlinks: bool, ?include_directories: bool, ?extensions: Array[String]?, ?max_size: Integer?) -> Enumerator[String, self]
11
+ | (?include_hidden: bool, ?follow_symlinks: bool, ?include_symlinks: bool, ?include_directories: bool, ?extensions: Array[String]?, ?max_size: Integer?) { (String) -> void } -> self
12
+ def ignored?: (String relative, ?directory: bool) -> bool
13
+ def search: (String | Regexp pattern, ?workers: Integer, ?max_size: Integer?, ?extensions: Array[String]?, ?limit: Integer?, ?case_sensitive: bool, ?cancelled: ^() -> bool, ?paths: Array[String]?) ?{ (Search::Match) -> void } -> Array[Search::Match]
14
+ def replace: (String | Regexp pattern, String replacement, ?workers: Integer, ?max_size: Integer?, ?extensions: Array[String]?, ?limit: Integer?, ?case_sensitive: bool, ?cancelled: ^() -> bool, ?paths: Array[String]?) -> Hash[String, Integer]
15
+ def watcher: (?interval: Numeric, ?native: _NativeWatcher?) -> Watcher
16
+
17
+ class Search
18
+ DEFAULT_MAX_SIZE: Integer
19
+ class Match < Struct[untyped]
20
+ attr_accessor path: String
21
+ attr_accessor line: Integer
22
+ attr_accessor column: Integer
23
+ attr_accessor byte_offset: Integer
24
+ attr_accessor text: String
25
+ attr_accessor match: String
26
+ def self.new: (path: String, line: Integer, column: Integer, byte_offset: Integer, text: String, match: String) -> instance
27
+ end
28
+ def initialize: (Project project) -> void
29
+ def call: (String | Regexp pattern, ?workers: Integer, ?max_size: Integer?, ?extensions: Array[String]?, ?limit: Integer?, ?case_sensitive: bool, ?cancelled: ^() -> bool, ?paths: Array[String]?) ?{ (Match) -> void } -> Array[Match]
30
+ end
31
+ class IgnoreMatcher
32
+ class Rule < Struct[untyped]
33
+ attr_accessor base: String
34
+ attr_accessor expression: Regexp
35
+ attr_accessor negated: bool
36
+ attr_accessor directory: bool
37
+ def self.new: (base: String, expression: Regexp, negated: bool, directory: bool) -> instance
38
+ end
39
+ def initialize: (?Array[Rule] rules) -> void
40
+ def add: (String source, ?base: String) -> instance
41
+ def ignored?: (String path, ?directory: bool) -> bool
42
+ end
43
+ class Watcher
44
+ class Event < Struct[untyped]
45
+ attr_accessor type: :created | :modified | :deleted
46
+ attr_accessor path: String
47
+ def self.new: (type: :created | :modified | :deleted, path: String) -> instance
48
+ end
49
+ attr_reader backend: :native | :polling
50
+ attr_reader snapshot: Hash[String, [Integer, Integer, Time, Time]]
51
+ def initialize: (Project project, ?interval: Numeric, ?native: _NativeWatcher?) -> void
52
+ def poll: (?timeout: Numeric) -> Array[Event]
53
+ def start: () { (Event) -> void } -> self
54
+ def close: () -> self
55
+ end
56
+ end
57
+
58
+ class MultiBuffer < Buffer
59
+ class Excerpt < Struct[untyped]
60
+ attr_accessor buffer: Buffer
61
+ attr_accessor first: Buffer::Anchor
62
+ attr_accessor last: Buffer::Anchor
63
+ attr_accessor title: String
64
+ attr_accessor view_start: Integer?
65
+ attr_accessor view_end: Integer?
66
+ def self.new: (Buffer buffer, Buffer::Anchor first, Buffer::Anchor last, String title, ?Integer? view_start, ?Integer? view_end) -> instance
67
+ end
68
+ attr_reader excerpts: Array[Excerpt]
69
+ def initialize: (?excerpts: Array[[Buffer, Range[Integer]] | [Buffer, Range[Integer], String?]]) -> void
70
+ def add_excerpt: (Buffer buffer, Range[Integer] range, ?title: String?) -> self
71
+ def attach_sources: (Hash[Buffer, Buffer] replacements) -> self
72
+ def dirty?: () -> bool
73
+ def begin_undo_group: () -> self
74
+ def end_undo_group: () -> Array[Buffer]
75
+ def edit: (changes changes, ?kind: Symbol, ?selections: Array[Selection], ?before_selections: Array[Selection], ?time: Numeric, ?group: bool) -> patch?
76
+ def undo: () -> bool
77
+ def redo: () -> bool
78
+ def save: (?String? path, ?force: bool) -> self
79
+ def close: () -> void
80
+ end
81
+ end
data/sig/snippet.rbs ADDED
@@ -0,0 +1,42 @@
1
+ module Canopus
2
+ class Snippet
3
+ MAX_SOURCE: Integer
4
+ MAX_OUTPUT: Integer
5
+ MAX_DEPTH: Integer
6
+ MAX_NODES: Integer
7
+ VARIABLES: Array[String]
8
+
9
+ def initialize: (String source, ?variables: Hash[String | Symbol, String?]) -> void
10
+ attr_reader text: String
11
+ attr_reader tabstops: Hash[Integer, Array[Range[Integer]]]
12
+ attr_reader choices: Hash[Integer, Array[String]]
13
+ attr_reader transforms: Array[Occurrence]
14
+ attr_reader occurrences: Array[Occurrence]
15
+
16
+ class Occurrence < Data
17
+ attr_reader index: Integer
18
+ attr_reader range: Range[Integer]
19
+ attr_reader transform: Transform?
20
+ attr_reader parents: Array[Integer]
21
+ def self.new: (Integer index, Range[Integer] range, Transform? transform, Array[Integer] parents) -> instance
22
+ end
23
+
24
+ class Transform
25
+ TIMEOUT: Float
26
+ attr_reader pattern: String
27
+ attr_reader flags: String
28
+ def apply: (String value) -> String
29
+ end
30
+ end
31
+
32
+ class Editor
33
+ def insert_snippet: (String source, ?variables: Hash[String | Symbol, String?], ?workspace_root: String?, ?clipboard: String?) -> Snippet
34
+ def next_snippet: () -> bool
35
+ def previous_snippet: () -> bool
36
+ def snippet_active?: () -> bool
37
+ def snippet_choices: () -> Array[String]?
38
+ def choose_snippet: (String | Integer value) -> bool
39
+ def clear_snippet: () -> nil
40
+ def snippet_variables: (?workspace_root: String?, ?clipboard: String?, ?now: Time, ?selection: Selection, ?cursor_index: Integer) -> Hash[String, String?]
41
+ end
42
+ end
data/sig/terminal.rbs ADDED
@@ -0,0 +1,125 @@
1
+ module Canopus
2
+ module Terminal
3
+ type color = Integer | [Integer, Integer, Integer] | nil
4
+ type attributes = Hash[Symbol, bool | Integer | [Integer, Integer, Integer]]
5
+ type mouse_action = :press | :move | :release
6
+ class Cell < Struct[untyped]
7
+ attr_accessor text: String
8
+ attr_accessor width: Integer
9
+ attr_accessor foreground: color
10
+ attr_accessor background: color
11
+ attr_accessor attributes: attributes
12
+ attr_accessor hyperlink: String?
13
+ def self.new: (text: String, width: Integer, ?foreground: color, ?background: color, attributes: attributes, ?hyperlink: String?) -> instance
14
+ end
15
+ class Scrollback
16
+ include Enumerable[Array[Cell]]
17
+ class Count < Struct[untyped]
18
+ attr_accessor lines: Integer
19
+ def self.new: (Integer lines) -> instance
20
+ def self.zero: () -> instance
21
+ def +: (Count other) -> Count
22
+ end
23
+ class Row < Struct[untyped]
24
+ attr_accessor cells: Array[Cell]
25
+ def self.new: (Array[Cell] cells) -> instance
26
+ def summary: () -> Count
27
+ end
28
+ attr_reader tree: Denebola::Tree
29
+ attr_reader limit: Integer
30
+ def initialize: (Integer limit) -> void
31
+ def clear: () -> Denebola::Tree
32
+ def length: () -> Integer
33
+ alias size length
34
+ def []: (Integer index) -> Array[Cell]?
35
+ def each: () -> Enumerator[Array[Cell], Denebola::Tree]
36
+ | () { (Array[Cell]) -> void } -> Denebola::Tree
37
+ def push: (Array[Cell] cells) -> Denebola::Tree?
38
+ end
39
+ class Grid
40
+ attr_reader columns: Integer
41
+ attr_reader rows: Integer
42
+ attr_reader cells: Array[Array[Cell]]
43
+ attr_reader scrollback: Scrollback
44
+ attr_reader cursor_x: Integer
45
+ attr_reader cursor_y: Integer
46
+ attr_reader scroll_top: Integer
47
+ attr_reader scroll_bottom: Integer
48
+ attr_accessor foreground: color
49
+ attr_accessor background: color
50
+ attr_accessor attributes: attributes
51
+ attr_accessor hyperlink: String?
52
+ attr_accessor autowrap: bool
53
+ attr_accessor insert_mode: bool
54
+ attr_accessor origin_mode: bool
55
+ attr_accessor cursor_visible: bool
56
+ def initialize: (?columns: Integer, ?rows: Integer, ?scrollback: Integer) -> void
57
+ def reset: () -> void
58
+ def []: (Integer row, ?nil column) -> Array[Cell]?
59
+ | (Integer row, Integer column) -> Cell?
60
+ def alternate?: () -> bool
61
+ def lines: () -> Array[String]
62
+ def text: () -> String
63
+ def put: (String char) -> void
64
+ def self.width: (String char) -> Integer
65
+ def move: (?x: Integer, ?y: Integer, ?relative: bool) -> void
66
+ def position: (Integer row, Integer column) -> void
67
+ def carriage_return: () -> void
68
+ def backspace: () -> void
69
+ def linefeed: () -> void
70
+ def reverse_index: () -> void
71
+ def tab: (?Integer count, ?backward: bool) -> void
72
+ def tab_set: () -> Array[Integer]
73
+ def tab_clear: (?all: bool) -> void
74
+ def margins: (?Integer top, ?Integer bottom) -> void
75
+ def scroll_up: (?Integer count) -> void
76
+ def scroll_down: (?Integer count) -> void
77
+ def erase_display: (?Integer mode) -> void
78
+ def erase_line: (?Integer mode) -> void
79
+ def erase_characters: (?Integer count) -> void
80
+ def insert_characters: (?Integer count) -> void
81
+ def delete_characters: (?Integer count) -> void
82
+ def insert_lines: (?Integer count) -> void
83
+ def delete_lines: (?Integer count) -> void
84
+ def save_cursor: () -> void
85
+ def restore_cursor: () -> void
86
+ def alternate: (bool enable, ?save: bool) -> void
87
+ def resize: (columns: Integer, rows: Integer) -> void
88
+ def selection: ([Integer, Integer] start, [Integer, Integer] finish, ?history: bool) -> String
89
+ def links: (Integer row) -> Array[{url: String, column: Integer, end_column: Integer}]
90
+ def file_paths: (Integer row, ?cwd: String) -> Array[{path: String, line: Integer, column: Integer}]
91
+ end
92
+ class VT
93
+ DEC_GRAPHICS: Hash[String, String]
94
+ attr_reader grid: Grid
95
+ attr_reader title: String?
96
+ attr_reader cwd: String?
97
+ attr_reader modes: Hash[Integer, bool]
98
+ attr_reader replies: Array[String]
99
+ attr_reader bell_count: Integer
100
+ def initialize: (?Grid grid) ?{ (String) -> void } -> void
101
+ def feed: (String bytes) -> self
102
+ def paste: (String text) -> String
103
+ def mouse: (button: Symbol | Integer | nil, column: Integer, row: Integer, ?action: mouse_action, ?shift: bool, ?alt: bool, ?control: bool) -> String
104
+ def key: (String | Symbol name, ?shift: bool, ?alt: bool, ?control: bool) -> String
105
+ end
106
+ class PTY
107
+ attr_reader reader: IO?
108
+ attr_reader writer: IO?
109
+ attr_reader pid: Integer
110
+ attr_reader grid: Grid
111
+ attr_reader vt: VT
112
+ attr_reader status: Process::Status?
113
+ def initialize: (?command: String | Array[String], ?cwd: String, ?columns: Integer, ?rows: Integer, ?env: Hash[String, String?], ?scrollback: Integer) -> void
114
+ def read: (?timeout: Numeric?, ?max_bytes: Integer) -> String?
115
+ def write: (String bytes) -> Integer
116
+ def paste: (String text) -> Integer
117
+ def key: (String | Symbol name, ?shift: bool, ?alt: bool, ?control: bool) -> Integer
118
+ def mouse: (button: Symbol | Integer | nil, column: Integer, row: Integer, ?action: mouse_action, ?shift: bool, ?alt: bool, ?control: bool) -> Integer
119
+ def resize: (columns: Integer, rows: Integer) -> void
120
+ def signal: (?String | Integer name) -> void
121
+ def alive?: () -> bool
122
+ def close: () -> void
123
+ end
124
+ end
125
+ end
data/sig/vim.rbs ADDED
@@ -0,0 +1,27 @@
1
+ module Canopus
2
+ class Vim
3
+ type mode = :normal | :insert | :replace | :visual | :visual_line | :visual_block
4
+ type register = [String, bool | :block] | [String, :block, Integer]
5
+
6
+ OPERATORS: Array[String]
7
+ VISUAL_MODES: Array[Symbol]
8
+
9
+ def initialize: (Editor editor) -> void
10
+ attr_reader mode: mode
11
+ attr_reader registers: Hash[String, register]
12
+ attr_reader marks: Hash[String, Buffer::Anchor]
13
+ attr_reader macros: Hash[String, Array[String]]
14
+ attr_reader command_line: String?
15
+ attr_reader status: String
16
+ attr_accessor on_command: (^(String) -> void)?
17
+
18
+ # Input is a single grapheme or a normalized key such as "esc" or "ctrl-v".
19
+ def feed: (String key) -> void
20
+ # Zero-based UTF-8 byte offset of the active edge, including visual mode.
21
+ def cursor_position: () -> Integer
22
+ # On blur: finish insert history and return to Normal, preserving registers.
23
+ def deactivate: () -> self
24
+ # On close: finish history and release every owned buffer anchor.
25
+ def dispose: () -> void
26
+ end
27
+ end
@@ -0,0 +1,11 @@
1
+ module Canopus
2
+ module Workspace::Edit
3
+ # A preflighted, single-use plan. Resource changes still require explicit UI
4
+ # confirmation at Workspace#apply_workspace_edit; construction does not write.
5
+ class Plan
6
+ def initialize: (Workspace workspace, LSP::object edit) -> void
7
+ def apply: () -> LSP::object
8
+ def close: () -> void
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,117 @@
1
+ module Canopus
2
+ class Project::Tree
3
+ class Entry < Data
4
+ attr_reader path: String
5
+ attr_reader name: String
6
+ attr_reader depth: Integer
7
+ attr_reader directory: bool
8
+ attr_reader expanded: bool
9
+ def self.new: (String path, String name, Integer depth, bool directory, bool expanded) -> instance
10
+ end
11
+ attr_reader expanded: Set[String]
12
+ def initialize: (Array[String] files, ?expanded: Set[String]) -> void
13
+ def toggle: (String path) -> void
14
+ def reveal: (String path) -> void
15
+ def visible: () -> Array[Entry]
16
+ end
17
+ class IconTheme
18
+ FILE: String
19
+ FOLDER: String
20
+ def initialize: (?String? path) -> void
21
+ def texture: (String path, ?directory: bool, ?expanded: bool, ?size: Numeric, ?scale: Numeric, ?color: String) -> Zaniah::GPU::Texture
22
+ end
23
+ class Workspace
24
+ type layout_node = {pane: Pane} | {direction: :horizontal | :vertical, children: Array[layout_node]}
25
+ type palette_state = Hash[Symbol, untyped]
26
+ type search_options = { ?case_sensitive: bool, ?whole_word: bool, ?range: Range[Integer] }
27
+ type semantic_style = {line: Integer, character: Integer, length: Integer, type: Integer, modifiers: Integer, name: String?}
28
+ attr_reader actions: Zaniah::Input::ActionRegistry
29
+ attr_reader project: Project?
30
+ attr_reader docks: Hash[Symbol, {visible: bool, size: Numeric}]
31
+ attr_reader panels: Hash[String, [Symbol, ^() -> (Zaniah::Element | String)]]
32
+ attr_accessor window: Zaniah::Platform::Headless::Window?
33
+ attr_reader palette: palette_state?
34
+ def palette=: (palette_state? value) -> void
35
+ attr_accessor terminal: Terminal::PTY?
36
+ attr_accessor selected_project_path: String?
37
+ attr_reader hover_card: String?
38
+ attr_reader hover_markup: bool?
39
+ attr_reader semantic_styles: Hash[Buffer, [Integer, Array[semantic_style]]]?
40
+ def layout: () -> layout_node
41
+ def project_tree: () -> Project::Tree
42
+ def project_path: (String relative) -> String
43
+ def create_project_entry: (String relative, ?directory: bool) -> String
44
+ def rename_project_entry: (String relative, String destination) -> String
45
+ def trash_project_entry: (String relative) -> String
46
+ def file_preview: (String path) -> Array[String]
47
+ def start_watching: () -> void
48
+ def poll_changes: () -> void
49
+ def icon_theme: () -> IconTheme
50
+ def settings_path: () -> String
51
+ def open_settings: () -> Editor
52
+ def settings_completions: () -> palette_state
53
+ def settings_document?: (Buffer buffer) -> bool?
54
+ def configure_text_system: (?cache_dir: String?) -> Zaniah::TextSystem::Renderer
55
+ def apply_settings: () -> void
56
+ def poll_settings: (?force: bool) -> void
57
+ def dismiss_hover: () -> nil
58
+ def close_language_documents: (?Buffer? buffer) -> void
59
+ def semantic_spans_for: (Buffer buffer, Integer row) -> Array[[Integer, Integer, String]]
60
+ def accept_language_result: (palette_state palette, Integer index) -> void
61
+ def show_diagnostics: () -> void
62
+ def show_outline: () -> void
63
+ def git: () -> Git::Repository?
64
+ def git_status: () -> Hash[String, String]
65
+ def invalidate_git: () -> nil
66
+ def poll_git_changes: (?now: Numeric) -> void
67
+ def git_relative_path: (?Buffer buffer) -> String
68
+ def git_hunks: (?Buffer buffer, ?async: bool) -> Array[Git::Diff::Hunk]
69
+ def show_git_diff: () -> Language::Document
70
+ def toggle_git_hunk: (?Editor current, ?row: Integer?) -> bool
71
+ def show_git_blame: () -> String
72
+ def revert_current_hunk: () -> patch?
73
+ def checkout_branch: (String name) -> String
74
+ def search_query: (String query, palette_state state) -> [String | Regexp, search_options]
75
+ def search_project: (String query, ?regexp: bool, ?case_sensitive: bool, ?whole_word: bool, ?async: bool) -> (Thread | MultiBuffer | nil)
76
+ def replace_in_buffer: (String | Regexp pattern, String replacement, ?case_sensitive: bool, ?whole_word: bool, ?range: Range[Integer]?) -> Integer
77
+ def fold_current: () -> untyped
78
+ def language_ready: (Editor editor, Language::Document document) -> void
79
+ end
80
+ class Editor
81
+ def replace_selections: (String | Array[String] texts, ?kind: Symbol, ?group: bool, ?cursor_back: Integer, ?before_selections: Array[Selection]) -> Array[Selection]
82
+ end
83
+ class Language::Document
84
+ def invalidate: (patch patch) -> void
85
+ # Prism is a lazy optional parser; its native types are not a runtime or RBS
86
+ # dependency for applications which use other languages/headless rendering.
87
+ def ruby_syntax: () -> untyped
88
+ end
89
+ module Plugins
90
+ class API
91
+ def initialize: (Workspace workspace, Array[String] permissions) -> void
92
+ def permit!: (String permission) -> void
93
+ end
94
+ end
95
+ class Buffer::Transaction
96
+ attr_writer before: rope
97
+ attr_writer after: rope
98
+ attr_writer before_selections: Array[Selection]
99
+ attr_writer after_selections: Array[Selection]
100
+ attr_writer patch: patch
101
+ attr_writer kind: Symbol
102
+ attr_writer time: Numeric
103
+ end
104
+ class Snippet::Transform
105
+ type format_nodes = Array[String | Format]
106
+ class Format < Data
107
+ attr_reader index: Integer
108
+ attr_reader operation: String | Symbol
109
+ attr_reader positive: format_nodes
110
+ attr_reader negative: format_nodes
111
+ def self.new: (Integer index, String | Symbol operation, format_nodes positive, format_nodes negative) -> instance
112
+ end
113
+ def self.parse: (StringScanner scanner, Integer depth) -> instance
114
+ def self.parse_format: (StringScanner scanner, Array[String] endings, Integer depth, ?Array[Integer] budget) -> format_nodes
115
+ def initialize: (String pattern, format_nodes replacement, String flags) -> void
116
+ end
117
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Development oracle only. Node is never required by Canopus at runtime.
4
+ require "json"
5
+ require "open3"
6
+ require_relative "../lib/canopus"
7
+
8
+ patterns = ["", "a", ".", ".*", "^", "$", "^.$", "^a", "a$", '[a-z]+', '[^a]', '(a)?', '(a+)(b*)',
9
+ '(?=a)', '(?<=a)b', '(?:a|b)+', '\d+', '\w+', '\s+', '\S+', '\b', '\B', '[a\s]', '[\S]', '[a[b]']
10
+ flags = ["", "g", "i", "gi", "m", "gm", "s", "gs", "u", "gu", "ims", "gimsu"]
11
+ values = ["", "a", "A", "ab", "aab", "abc123", "aa\nbb", "a\r\nb", "a\rb", "\n", "日本", "a日本b",
12
+ "\u00a0", "x\ufeffy", "a\u2028b", "a\u2029b", "😀", "a😀b"]
13
+ cases = patterns.product(flags, values).reject { |pattern, options, value| (!options.include?("u") || pattern == '\B') && value.match?(/[\u{10000}-\u{10ffff}]/) }
14
+ javascript = <<~JS
15
+ let input = '';
16
+ process.stdin.setEncoding('utf8');
17
+ process.stdin.on('data', part => input += part);
18
+ process.stdin.on('end', () => {
19
+ const result = JSON.parse(input).map(([pattern, flags, value]) =>
20
+ Buffer.from(value.replace(new RegExp(pattern, flags), (...args) => {
21
+ const captures = args.slice(0, -2);
22
+ return [0, 1, 2].map(index => '[' + (captures[index] || '') + ']').join('');
23
+ })).toString('base64')
24
+ );
25
+ process.stdout.write(JSON.stringify(result));
26
+ });
27
+ JS
28
+ output, error, status = Open3.capture3("node", "-e", javascript, stdin_data: JSON.generate(cases))
29
+ abort error unless status.success?
30
+ expected = JSON.parse(output).map { |encoded| encoded.unpack1("m0").force_encoding(Encoding::UTF_8) }
31
+ cases.each_with_index do |(pattern, options, value), index|
32
+ snippet = Canopus::Snippet.new("${VALUE/#{pattern}/[$0][$1][$2]/#{options}}", variables: {"VALUE" => value})
33
+ abort "Mismatch #{cases[index].inspect}: expected #{expected[index].inspect}, got #{snippet.text.inspect}" unless snippet.text == expected[index]
34
+ end
35
+ puts "Certified #{cases.length} snippet transform cases against JavaScript RegExp (#{patterns.length} patterns, #{flags.length} flag combinations, #{values.length} inputs)."