canopus 0.4.0 → 0.5.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 (137) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +55 -0
  3. data/README.md +191 -19
  4. data/assets/keymaps/emacs.jsonc +5 -0
  5. data/assets/keymaps/jetbrains.jsonc +5 -0
  6. data/assets/keymaps/sublime.jsonc +5 -0
  7. data/assets/keymaps/vscode.jsonc +5 -0
  8. data/docs/debugging.md +143 -0
  9. data/docs/distribution.md +40 -9
  10. data/docs/lsp.md +131 -0
  11. data/docs/performance.md +18 -0
  12. data/docs/providers.md +36 -0
  13. data/docs/release-log.md +12 -0
  14. data/docs/tasks.md +64 -0
  15. data/docs/testing.md +49 -0
  16. data/docs/vim.md +3 -0
  17. data/exe/canopus +4 -1
  18. data/lib/canopus/buffer.rb +291 -50
  19. data/lib/canopus/cli.rb +5 -2
  20. data/lib/canopus/command.rb +13 -4
  21. data/lib/canopus/controller.rb +183 -40
  22. data/lib/canopus/debug/breakpoints.rb +550 -0
  23. data/lib/canopus/debug/configuration.rb +291 -0
  24. data/lib/canopus/debug/console.rb +243 -0
  25. data/lib/canopus/debug/panel.rb +487 -0
  26. data/lib/canopus/debug/session.rb +354 -0
  27. data/lib/canopus/decoration.rb +4 -2
  28. data/lib/canopus/denebola_compat.rb +27 -0
  29. data/lib/canopus/diagnostics.rb +173 -0
  30. data/lib/canopus/display_map/overlay_map.rb +6 -2
  31. data/lib/canopus/editor/snippet_expandable.rb +3 -2
  32. data/lib/canopus/editor.rb +122 -31
  33. data/lib/canopus/git/state.rb +100 -0
  34. data/lib/canopus/language/background_analysis.rb +93 -14
  35. data/lib/canopus/language/document.rb +70 -34
  36. data/lib/canopus/language/symbol.rb +1 -0
  37. data/lib/canopus/language/syntax_worker.rb +61 -9
  38. data/lib/canopus/language.rb +3 -0
  39. data/lib/canopus/minimap.rb +201 -0
  40. data/lib/canopus/patch.rb +3 -1
  41. data/lib/canopus/plugins/api.rb +4 -2
  42. data/lib/canopus/plugins/isolated_runtime.rb +64 -7
  43. data/lib/canopus/plugins/registry.rb +114 -3
  44. data/lib/canopus/plugins.rb +8 -7
  45. data/lib/canopus/project.rb +15 -6
  46. data/lib/canopus/provider.rb +192 -0
  47. data/lib/canopus/regexp_compat.rb +36 -4
  48. data/lib/canopus/selection.rb +12 -0
  49. data/lib/canopus/settings/schema.rb +201 -0
  50. data/lib/canopus/settings.rb +328 -49
  51. data/lib/canopus/task/configuration.rb +356 -0
  52. data/lib/canopus/task/problem_matcher.rb +264 -0
  53. data/lib/canopus/task/runner.rb +314 -0
  54. data/lib/canopus/test_runner/bounded_ignore.rb +144 -0
  55. data/lib/canopus/test_runner/discovery.rb +97 -0
  56. data/lib/canopus/test_runner/execution.rb +194 -0
  57. data/lib/canopus/test_runner/minitest.rb +116 -0
  58. data/lib/canopus/test_runner/rspec.rb +103 -0
  59. data/lib/canopus/test_runner/safe_walker.rb +37 -0
  60. data/lib/canopus/test_runner.rb +54 -0
  61. data/lib/canopus/theme/import.rb +131 -0
  62. data/lib/canopus/theme.rb +28 -4
  63. data/lib/canopus/version.rb +1 -1
  64. data/lib/canopus/vim/motionable.rb +1 -1
  65. data/lib/canopus/vim.rb +10 -16
  66. data/lib/canopus/workspace/auto_savable.rb +83 -0
  67. data/lib/canopus/workspace/debug_aware.rb +600 -0
  68. data/lib/canopus/workspace/edit/plan.rb +2 -2
  69. data/lib/canopus/workspace/editor_configurable.rb +113 -0
  70. data/lib/canopus/workspace/file_change_aware.rb +11 -3
  71. data/lib/canopus/workspace/git_aware.rb +80 -34
  72. data/lib/canopus/workspace/git_blame.rb +175 -0
  73. data/lib/canopus/workspace/git_conflict_resolution.rb +410 -0
  74. data/lib/canopus/workspace/git_diff_view.rb +641 -0
  75. data/lib/canopus/workspace/git_history.rb +171 -0
  76. data/lib/canopus/workspace/git_remote.rb +267 -0
  77. data/lib/canopus/workspace/git_staging.rb +583 -0
  78. data/lib/canopus/workspace/hierarchy_aware.rb +477 -0
  79. data/lib/canopus/workspace/keymap_aware.rb +66 -0
  80. data/lib/canopus/workspace/language_aware.rb +3721 -135
  81. data/lib/canopus/workspace/language_server_configurable.rb +287 -71
  82. data/lib/canopus/workspace/persistent_undo.rb +169 -0
  83. data/lib/canopus/workspace/problems_aware.rb +131 -0
  84. data/lib/canopus/workspace/project_searchable.rb +88 -11
  85. data/lib/canopus/workspace/project_tree_editable.rb +3 -1
  86. data/lib/canopus/workspace/recoverable.rb +204 -0
  87. data/lib/canopus/workspace/session_persistable.rb +85 -13
  88. data/lib/canopus/workspace/settings_aware.rb +76 -2
  89. data/lib/canopus/workspace/task_aware.rb +194 -0
  90. data/lib/canopus/workspace/test_aware.rb +394 -0
  91. data/lib/canopus/workspace/trust.rb +73 -0
  92. data/lib/canopus/workspace/view/terminal_presentable.rb +298 -47
  93. data/lib/canopus/workspace/view.rb +399 -74
  94. data/lib/canopus/workspace.rb +688 -44
  95. data/lib/canopus.rb +20 -2
  96. data/sig/canopus.rbs +138 -31
  97. data/sig/controller.rbs +10 -3
  98. data/sig/debug.rbs +121 -0
  99. data/sig/decoration.rbs +12 -2
  100. data/sig/diagnostics.rbs +26 -0
  101. data/sig/minimap.rbs +20 -0
  102. data/sig/provider.rbs +29 -0
  103. data/sig/services.rbs +1 -16
  104. data/sig/task.rbs +92 -0
  105. data/sig/test_runner.rbs +109 -0
  106. data/sig/trust.rbs +17 -0
  107. data/sig/workspace_edits.rbs +2 -2
  108. data/sig/workspace_services.rbs +234 -2
  109. data/tools/check_dependencies.rb +21 -2
  110. data/tools/package.rb +172 -14
  111. data/tools/package_signature_test.rb +33 -0
  112. data/tools/package_test.rb +29 -0
  113. data/tools/sign_package.rb +123 -0
  114. data/tools/update.rb +189 -0
  115. data/tools/update_test.rb +71 -0
  116. metadata +206 -31
  117. data/lib/canopus/lsp/client.rb +0 -307
  118. data/lib/canopus/lsp/error.rb +0 -7
  119. data/lib/canopus/lsp/future/subscription.rb +0 -9
  120. data/lib/canopus/lsp/future.rb +0 -87
  121. data/lib/canopus/lsp/protocol.rb +0 -83
  122. data/lib/canopus/lsp/server_error.rb +0 -13
  123. data/lib/canopus/lsp/timeout.rb +0 -7
  124. data/lib/canopus/lsp/transport.rb +0 -123
  125. data/lib/canopus/lsp.rb +0 -19
  126. data/lib/canopus/project/search.rb +0 -164
  127. data/lib/canopus/project/search_worker/cancelled.rb +0 -3
  128. data/lib/canopus/project/search_worker/runner.rb +0 -9
  129. data/lib/canopus/project/search_worker.rb +0 -108
  130. data/lib/canopus/terminal/cell.rb +0 -7
  131. data/lib/canopus/terminal/grid.rb +0 -321
  132. data/lib/canopus/terminal/pty.rb +0 -178
  133. data/lib/canopus/terminal/scrollback.rb +0 -38
  134. data/lib/canopus/terminal/vt.rb +0 -398
  135. data/lib/canopus/terminal.rb +0 -13
  136. data/sig/lsp.rbs +0 -99
  137. data/sig/terminal.rbs +0 -130
data/sig/services.rbs CHANGED
@@ -10,24 +10,9 @@ module Canopus
10
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
11
  | (?include_hidden: bool, ?follow_symlinks: bool, ?include_symlinks: bool, ?include_directories: bool, ?extensions: Array[String]?, ?max_size: Integer?) { (String) -> void } -> self
12
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]
13
+ def ignore_matcher: () -> Thuban::IgnoreMatcher
14
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
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
16
  class Watcher
32
17
  class Event < Struct[untyped]
33
18
  attr_accessor type: :created | :modified | :deleted
data/sig/task.rbs ADDED
@@ -0,0 +1,92 @@
1
+ module Canopus::Task
2
+ type definition = Hash[String, Canopus::json]
3
+
4
+ class Configuration
5
+ RELATIVE_PATH: String
6
+ MAX_BYTES: Integer
7
+ MAX_TASKS: Integer
8
+ MAX_PROBLEM_MATCHERS: Integer
9
+ MAX_DEPTH: Integer
10
+ MAX_COLLECTION_SIZE: Integer
11
+ MAX_STRING_BYTES: Integer
12
+ MAX_EXPANDED_BYTES: Integer
13
+ MAX_ENVIRONMENT_BYTES: Integer
14
+ VARIABLE: Regexp
15
+
16
+ attr_reader root: String
17
+ attr_reader tasks: Array[definition]
18
+ attr_reader problem_matchers: Hash[String, definition]
19
+ def initialize: (root: String, ?environment: untyped) -> void
20
+ def problem_matcher: (String name) -> definition?
21
+ def resolve: (String | definition task, ?file: String?, ?line_number: Integer?, ?selected_text: String?) -> definition
22
+ end
23
+
24
+ class ProblemMatcher
25
+ MAX_LINE_BYTES: Integer
26
+ MAX_PENDING_BYTES: Integer
27
+ MAX_BUFFER_BYTES: Integer
28
+ MAX_DIAGNOSTICS: Integer
29
+ MATCH_TIMEOUT_SECONDS: Float
30
+ ANSI: Regexp
31
+ def initialize: (definition definition, root: String) -> void
32
+ | (definition definition, root: String) { (ProblemMatcher) -> void } -> void
33
+ def diagnostics: () -> Hash[String, Array[Sadr::object]]
34
+ def pending?: () -> bool
35
+ def feed: (String bytes, ?max_seconds: Numeric) -> bool
36
+ def finish: () -> Hash[String, Array[Sadr::object]]
37
+ end
38
+
39
+ class Runner
40
+ class Output < Data
41
+ attr_reader id: Integer
42
+ attr_reader label: String
43
+ attr_reader terminal: Tarazed::PTY
44
+ attr_reader presentation: definition
45
+ def self.new: (Integer id, String label, Tarazed::PTY terminal, definition presentation) -> instance
46
+ end
47
+
48
+ MAX_OUTPUTS: Integer
49
+ MAX_CLOSERS: Integer
50
+ STOP_GRACE_SECONDS: Float
51
+
52
+ attr_reader active_index: Integer
53
+ def initialize: (scrollback: Integer, queue_limit_bytes: Integer, ?terminal_factory: untyped, ?report: untyped) -> void
54
+ def entries: () -> Array[Output]
55
+ def active: () -> Output?
56
+ def terminal: () -> Tarazed::PTY?
57
+ def run: (definition task) -> Output
58
+ def activate: (Integer index) -> Output
59
+ def remove: (?Integer index) -> Output?
60
+ def stop: (?Output? output) -> bool
61
+ def running?: (?Output? output) -> bool
62
+ def completed: () -> Array[Output]
63
+ def drain: (max_bytes: Integer, ?max_seconds: Numeric) -> bool
64
+ | (max_bytes: Integer, ?max_seconds: Numeric) { (Output, String?, Numeric) -> untyped } -> bool
65
+ def pending?: () -> bool
66
+ def resize: (Integer columns, Integer rows) -> void
67
+ def close: () -> nil
68
+ end
69
+ end
70
+
71
+ module Canopus
72
+ class Workspace
73
+ attr_reader task_runner: Task::Runner
74
+ def initialize_tasks: () -> Task::Runner
75
+ def task_outputs: () -> Array[Task::Runner::Output]
76
+ def task_output: () -> Task::Runner::Output?
77
+ def task_terminal: () -> Tarazed::PTY?
78
+ def task_output_visible: () -> bool
79
+ def show_tasks: () -> (nil | false)
80
+ def run_task: (String | Task::definition task) -> Task::Runner::Output
81
+ def accept_task_palette: () -> Task::Runner::Output?
82
+ def show_task_output: (?Task::Runner::Output? output) -> Task::Runner::Output?
83
+ def toggle_task_output: () -> untyped
84
+ def activate_task_output: (Integer index) -> Task::Runner::Output
85
+ def close_task_output: (?Integer index) -> Task::Runner::Output?
86
+ def stop_task: (?Task::Runner::Output? output) -> bool
87
+ def drain_task_outputs: () -> bool
88
+ def resize_task_output: (Integer columns, Integer rows) -> void
89
+ def task_output_title: (Task::Runner::Output output) -> String
90
+ def close_tasks: () -> nil
91
+ end
92
+ end
@@ -0,0 +1,109 @@
1
+ module Canopus::TestRunner
2
+ MAX_PATH_BYTES: Integer
3
+
4
+ def self.normalize_path: (untyped path) -> String?
5
+ def self.framework_for: (untyped path) -> (:minitest | :rspec)?
6
+
7
+ interface _Adapter
8
+ def candidate?: (String path) -> bool
9
+ def discover: (untyped root, path: String, limit: Integer, cancelled: ^() -> bool) -> Array[Test]
10
+ end
11
+
12
+ class Test < Data
13
+ attr_reader framework: :minitest | :rspec
14
+ attr_reader path: String
15
+ attr_reader name: String
16
+ attr_reader groups: Array[String]
17
+ attr_reader line: Integer
18
+ attr_reader column: Integer
19
+ attr_reader offset: Integer
20
+ attr_reader selector: String
21
+ def self.new: (:minitest | :rspec framework, String path, String name, Array[String] groups,
22
+ Integer line, Integer column, Integer offset, String selector) -> instance
23
+ end
24
+
25
+ class Result < Data
26
+ attr_reader status: :running | :success | :failure | :skipped
27
+ attr_reader path: String?
28
+ attr_reader line: Integer?
29
+ attr_reader message: String?
30
+ def self.new: (:running | :success | :failure | :skipped status, String? path, Integer? line, String? message) -> instance
31
+ end
32
+
33
+ class Execution
34
+ MAX_OUTPUT_BYTES: Integer
35
+ MAX_PARSE_LINES: Integer
36
+ MAX_FILTER_BYTES: Integer
37
+ ANSI: Regexp
38
+ attr_reader test: Test
39
+ attr_reader tests: Array[Test]
40
+ attr_reader output: Canopus::Task::Runner::Output
41
+ attr_reader generation: Integer?
42
+ def self.task: (Test test, root: String, ?tests: Array[Test]) -> Canopus::Task::definition
43
+ def initialize: (Test test, Canopus::Task::Runner::Output output, ?generation: Integer?, ?tests: Array[Test]) -> void
44
+ def append: (String? bytes) -> nil
45
+ def cancel: () -> true
46
+ def finish: (untyped status) -> Result
47
+ end
48
+
49
+ class Minitest
50
+ MAX_NODES: Integer
51
+ MAX_GROUP_DEPTH: Integer
52
+ MAX_NAME_BYTES: Integer
53
+ SPEC_GROUPS: Array[Symbol]
54
+ SPEC_TESTS: Array[Symbol]
55
+ def candidate?: (String path) -> bool
56
+ def discover: (untyped root, path: String, limit: Integer, cancelled: ^() -> bool) -> Array[Test]
57
+ end
58
+
59
+ class BoundedIgnore
60
+ MAX_FILES: Integer
61
+ MAX_FILE_BYTES: Integer
62
+ MAX_TOTAL_BYTES: Integer
63
+ MAX_LINES: Integer
64
+ MAX_LINE_BYTES: Integer
65
+ MAX_GIT_POINTER_BYTES: Integer
66
+ def initialize: (String root, ?delegate: untyped, ?cancelled: ^() -> bool) -> void
67
+ def ignored?: (untyped path, ?directory: bool) -> bool
68
+ end
69
+
70
+ class RSpec
71
+ MAX_NODES: Integer
72
+ MAX_GROUP_DEPTH: Integer
73
+ MAX_NAME_BYTES: Integer
74
+ GROUPS: Array[Symbol]
75
+ EXAMPLES: Array[Symbol]
76
+ def candidate?: (String path) -> bool
77
+ def discover: (untyped root, path: String, limit: Integer, cancelled: ^() -> bool) -> Array[Test]
78
+ end
79
+
80
+ class Discovery
81
+ MAX_FILES: Integer
82
+ MAX_TEST_FILES: Integer
83
+ MAX_FILE_BYTES: Integer
84
+ MAX_TESTS: Integer
85
+ MAX_DEPTH: Integer
86
+ MAX_PATH_BYTES: Integer
87
+ MAX_ADAPTERS: Integer
88
+ MAX_NAME_BYTES: Integer
89
+ MAX_GROUPS: Integer
90
+ attr_reader root: String
91
+ def initialize: (root: String, ?ignore: untyped, ?adapters: Array[_Adapter]) -> void
92
+ def discover: (?cancelled: ^() -> bool) -> Array[Test]
93
+ end
94
+ end
95
+
96
+ module Canopus
97
+ class Workspace
98
+ attr_reader tests: Array[TestRunner::Test]
99
+ def test_results: () -> Hash[TestRunner::Test, TestRunner::Result]
100
+ def initialize_tests: () -> nil
101
+ def test_tree: () -> Zaniah::UI::TreeView
102
+ def refresh_tests: () -> Thread
103
+ def test_discovery_pending?: () -> bool
104
+ def run_test: (TestRunner::Test test) -> Canopus::Task::Runner::Output
105
+ def run_tests: (Array[TestRunner::Test] tests) -> Canopus::Task::Runner::Output
106
+ def toggle_tests: () -> nil
107
+ def close_tests: () -> nil
108
+ end
109
+ end
data/sig/trust.rbs ADDED
@@ -0,0 +1,17 @@
1
+ module Canopus
2
+ class Workspace
3
+ attr_reader trust: Workspace::Trust
4
+
5
+ class Trust
6
+ def initialize: (String root, ?state_path: String?) -> void
7
+ def trusted?: () -> bool
8
+ def status: () -> (:trusted | :untrusted)
9
+ def trust!: () -> bool
10
+ def untrust!: () -> bool
11
+ end
12
+
13
+ def workspace_trust: () -> Workspace::Trust
14
+ def toggle_workspace_trust: () -> (:trusted | :untrusted)
15
+ def show_workspace_trust: () -> (:trusted | :untrusted)
16
+ end
17
+ end
@@ -3,8 +3,8 @@ module Canopus
3
3
  # A preflighted, single-use plan. Resource changes still require explicit UI
4
4
  # confirmation at Workspace#apply_workspace_edit; construction does not write.
5
5
  class Plan
6
- def initialize: (Workspace workspace, LSP::object edit) -> void
7
- def apply: () -> LSP::object
6
+ def initialize: (Workspace workspace, Sadr::object edit) -> void
7
+ def apply: () -> Sadr::object
8
8
  def close: () -> void
9
9
  end
10
10
  end
@@ -1,4 +1,151 @@
1
1
  module Canopus
2
+ module Workspace::Recoverable
3
+ MAX_DRAFT_BYTES: Integer
4
+ MAX_SNAPSHOT_BYTES: Integer
5
+ SNAPSHOT_OVERHEAD_BYTES: Integer
6
+ JSON_ESCAPE_FACTOR: Integer
7
+
8
+ def recovery_directory: () -> String
9
+ def recovery_candidates: () -> Array[String]
10
+ def offer_recovery: () -> bool
11
+ def resolve_recovery: (:restore | :discard choice) -> bool
12
+ def poll_recovery: (?now: Numeric, ?force: bool) -> bool
13
+ def close_recovery: (?clean: bool) -> void
14
+ def preserve_recovery!: () -> true
15
+ end
16
+
17
+ module Workspace::AutoSavable
18
+ def poll_auto_save: (?now: Numeric) -> bool
19
+ def reset_auto_save: () -> nil
20
+ end
21
+
22
+ module Workspace::EditorConfigurable
23
+ EDITORCONFIG_MAX_BYTES: Integer
24
+ EDITORCONFIG_CACHE_LIMIT: Integer
25
+
26
+ def settings_for_path: (String? path, ?language: String?) -> Settings
27
+ def settings_for_editor: (Editor editor) -> Settings
28
+ def invalidate_editorconfig: () -> nil
29
+ def prepare_editorconfig_save: (Buffer buffer, String path) -> void
30
+ end
31
+
32
+ module Workspace::PersistentUndo
33
+ MAX_FILE_BYTES: Integer
34
+ MAX_PROJECT_BYTES: Integer
35
+
36
+ def persistent_undo_directory: () -> String
37
+ def load_persistent_undo: (Buffer buffer) -> bool
38
+ def save_persistent_undo: (Buffer buffer) -> bool
39
+ end
40
+
41
+ module Workspace::GitConflictResolution
42
+ MERGE_MAX_BYTES: Integer
43
+ MERGE_MAX_LINES: Integer
44
+ CONFLICT_MODES: Array[Integer]
45
+ CONFLICT_CHOICES: Array[Symbol]
46
+
47
+ def show_git_conflicts: (?String? path, ?async: bool) -> (Editor | Thread | nil)
48
+ def show_git_conflict: (?String? path, ?async: bool) -> (Editor | Thread | nil)
49
+ def resolve_git_conflict: ((:ours | :theirs | :both | :manual) choice, ?content: String?, ?mode: Integer?, ?async: bool, ?expected: untyped) -> (Editor | Thread | String)
50
+ def git_conflict_decorations: (Buffer buffer, Range[Integer] rows) -> Array[Decoration::Item]
51
+ def close_git: () -> untyped
52
+ end
53
+
54
+ module Workspace::GitDiffView
55
+ MAX_DIFF_BYTES: Integer
56
+ MAX_HISTORY: Integer
57
+ MAX_HISTORY_SCAN: Integer
58
+ MAX_PATH_BYTES: Integer
59
+ MAX_REVISION_BYTES: Integer
60
+ SIDE_COLUMN_WIDTH: Integer
61
+
62
+ def show_scm_diff: (?Hash[Symbol, untyped]? change, ?mode: :inline | :side_by_side, ?async: bool) -> (Editor | Thread)
63
+ def show_git_diff: (?mode: :inline | :side_by_side, ?async: bool) -> (Editor | Thread)
64
+ def compare_git_revisions: (String? before, String after, ?path: String?, ?mode: :inline | :side_by_side, ?async: bool) -> (Editor | Thread)
65
+ def show_git_revision_diff: (String? before, String after, ?path: String?, ?mode: :inline | :side_by_side, ?async: bool) -> (Editor | Thread)
66
+ def show_revision_diff: (String? before, String after, ?path: String?, ?mode: :inline | :side_by_side, ?async: bool) -> (Editor | Thread)
67
+ def toggle_git_diff_mode: (?Editor current, ?async: bool) -> (Editor | Thread)
68
+ def toggle_scm_diff_mode: (?Editor current, ?async: bool) -> (Editor | Thread)
69
+ def git_file_history: (?String? path, ?revision: String, ?limit: Integer) -> Array[GitHistoryEntry]
70
+ def show_git_file_history: (?String? path, ?revision: String, ?limit: Integer, ?async: bool) -> (Hash[Symbol, untyped] | Thread)
71
+ def show_git_revision_compare: (?String? path) -> Hash[Symbol, untyped]
72
+ def scm_diff_decorations: (Buffer buffer, Range[Integer] rows) -> Array[Decoration::Item]
73
+ def close_git: () -> untyped
74
+
75
+ class GitHistoryEntry < Data
76
+ attr_reader oid: String
77
+ attr_reader parent: String?
78
+ attr_reader subject: String
79
+ attr_reader author: String
80
+ attr_reader time: Integer
81
+ attr_reader path: String
82
+ def self.new: (String oid, String? parent, String subject, String author, Integer time, String path) -> instance
83
+ end
84
+ end
85
+
86
+ module Workspace::GitHistory
87
+ MAX_COMMITS: Integer
88
+ MAX_HISTORY_TREE_ENTRIES: Integer
89
+ MAX_COMMIT_PATHS: Integer
90
+
91
+ def git_commit_history: (?revision: String, ?limit: Integer) -> Array[GitCommitEntry]
92
+ def show_git_commit_history: (?revision: String, ?limit: Integer, ?async: bool) -> (Hash[Symbol, untyped] | Thread)
93
+ def open_git_commit: (GitCommitEntry entry) -> (Editor | Thread | Hash[Symbol, untyped] | nil)
94
+ def close_git: () -> untyped
95
+
96
+ class GitCommitEntry < Data
97
+ attr_reader oid: String
98
+ attr_reader parents: Array[String]
99
+ attr_reader subject: String
100
+ attr_reader author: String
101
+ attr_reader time: Integer
102
+ attr_reader paths: Array[String]
103
+ attr_reader graph: String
104
+ attr_reader paths_truncated: bool
105
+ def self.new: (String oid, Array[String] parents, String subject, String author, Integer time,
106
+ Array[String] paths, String graph, bool paths_truncated) -> instance
107
+ end
108
+ end
109
+
110
+ module Workspace::GitRemote
111
+ TRANSFER_PHASES: Array[Symbol]
112
+
113
+ def git_remotes: () -> Hash[String, String]
114
+ def fetch_git: (?String? remote, ?credentials: untyped) -> (Thread | Hash[Symbol, untyped])
115
+ def pull_git: (?String? remote, ?credentials: untyped) -> (Thread | Hash[Symbol, untyped])
116
+ def push_git: (?String? remote, ?credentials: untyped) -> (Thread | Hash[Symbol, untyped])
117
+ def cancel_git_transfer: () -> bool
118
+ def git_transfer_progress: () -> Hash[Symbol, untyped]?
119
+ def poll_git_changes: (?now: Numeric) -> void
120
+ def accept_git_credentials: () -> (Thread | Hash[Symbol, untyped])
121
+ def close_git: () -> untyped
122
+ end
123
+
124
+ module Workspace::GitBlame
125
+ BLAME_MAX_BYTES: Integer
126
+ BLAME_MAX_LINES: Integer
127
+ BLAME_CACHE_LIMIT: Integer
128
+
129
+ def git_blame_decorations: (Buffer buffer, Range[Integer] rows, ?Editor? current) -> Array[Decoration::Item]
130
+ def invalidate_git_blame: (?Buffer? buffer) -> nil
131
+ def invalidate_git: () -> nil
132
+ def close_git: () -> untyped
133
+
134
+ class GitBlameLine < Data
135
+ attr_reader commit: String
136
+ attr_reader author: String
137
+ attr_reader original_line: Integer
138
+ attr_reader path: String
139
+ def self.new: (String commit, String author, Integer original_line, String path) -> instance
140
+ end
141
+ class GitBlameSnapshot < Data
142
+ attr_reader key: Array[untyped]
143
+ attr_reader lines: Array[GitBlameLine?]
144
+ attr_reader reason: String?
145
+ def self.new: (Array[untyped] key, Array[GitBlameLine?] lines, String? reason) -> instance
146
+ end
147
+ end
148
+
2
149
  class Project::Tree
3
150
  class Entry < Data
4
151
  attr_reader path: String
@@ -31,10 +178,19 @@ module Canopus
31
178
  attr_reader docks: Hash[Symbol, {visible: bool, size: Numeric}]
32
179
  attr_reader panels: Panel::Registry
33
180
  attr_reader decorations: Decoration::Registry
181
+ attr_reader providers: Provider::Registry
182
+ attr_reader diagnostics: Diagnostics::Registry
183
+ attr_reader breakpoints: Debug::Breakpoints
184
+ attr_reader debug_session: Debug::Session?
185
+ attr_reader debug_position: {path: String, row: Integer}?
186
+ attr_reader debug_panel: Debug::Panel
187
+ attr_reader debug_console: Debug::Console
188
+ def show_encoding_actions: (?Buffer? buffer) -> Hash[Symbol, untyped]?
189
+ def convert_line_endings: (:lf | :crlf | :cr to, ?confirmed: bool) -> void
34
190
  attr_accessor window: Zaniah::Platform::Headless::Window?
35
191
  attr_reader palette: palette_state?
36
192
  def palette=: (palette_state? value) -> void
37
- attr_accessor terminal: Terminal::PTY?
193
+ attr_accessor terminal: Tarazed::PTY?
38
194
  attr_accessor selected_project_path: String?
39
195
  attr_reader hover_card: String?
40
196
  attr_reader hover_markup: bool?
@@ -52,6 +208,10 @@ module Canopus
52
208
  def settings_path: () -> String
53
209
  def open_settings: () -> Editor
54
210
  def settings_completions: () -> palette_state
211
+ def settings_browse: (?changed_only: bool) -> palette_state
212
+ def settings_gui: (?changed_only: bool) -> palette_state
213
+ def keymap_gui: () -> palette_state
214
+ def keymap_presets: () -> palette_state
55
215
  def settings_document?: (Buffer buffer) -> bool?
56
216
  def configure_text_system: (?cache_dir: String?) -> Zaniah::TextSystem::Renderer
57
217
  def apply_settings: () -> void
@@ -59,8 +219,44 @@ module Canopus
59
219
  def dismiss_hover: () -> nil
60
220
  def close_language_documents: (?Buffer? buffer) -> void
61
221
  def semantic_spans_for: (Buffer buffer, Integer row) -> Array[[Integer, Integer, String]]
222
+ def diagnostic_decorations: (Buffer buffer, Range[Integer] rows) -> Array[Decoration::Item]
223
+ def breakpoint_decorations: (Buffer buffer, Range[Integer] rows, ?Editor? current) -> Array[Decoration::Item]
224
+ def toggle_breakpoint: (Editor editor, Integer row) -> Debug::Breakpoints::Entry?
225
+ def show_breakpoint_menu: (Editor editor, Integer row) -> palette_state?
226
+ def accept_breakpoint_palette: () -> untyped
227
+ def attach_breakpoints: (Buffer buffer) -> untyped
228
+ def relocate_breakpoints: (Buffer buffer) -> untyped
229
+ def detach_breakpoints: (Buffer buffer) -> bool
230
+ def start_debugging: (?String | Hash[String, json] configuration) -> Debug::Session?
231
+ def stop_debugging: () -> Debug::Session?
232
+ def debug_tree: () -> Zaniah::UI::TreeView
233
+ def debug_console_tree: () -> Zaniah::UI::TreeView
234
+ def debug_watches: () -> Array[String]
235
+ def add_debug_watch: (String expression) -> bool
236
+ def remove_debug_watch: (String expression) -> bool
237
+ def show_debug_watch_add: () -> palette_state
238
+ def show_debug_watch_remove: () -> (palette_state | bool)
239
+ def accept_debug_watch_palette: () -> untyped
240
+ def show_debug_console: () -> palette_state
241
+ def accept_debug_console_palette: () -> Megrez::Future
242
+ def debug_hover: (?Editor? editor, ?Integer? offset) -> bool
243
+ def debug_position_decorations: (Buffer buffer, Range[Integer] rows) -> Array[Decoration::Item]
244
+ def invalidate_diagnostics: (?Buffer? buffer) -> nil
245
+ def inlay_hint_decorations: (Buffer buffer, Range[Integer] rows) -> Array[Decoration::Item]
246
+ def request_inlay_hints: (Editor editor, Range[Integer] visible_rows, ?start: bool) -> bool
247
+ def request_visible_inlay_hints: (?Editor editor) -> bool
248
+ def visible_inlay_hint_ranges: (Editor editor, Range[Integer] display_rows) -> Array[Range[Integer]]
249
+ def invalidate_inlay_hints: (?Buffer? buffer, ?client: Sadr::Client?) -> nil
250
+ def code_lens_decorations: (Buffer buffer, Range[Integer] rows) -> Array[Decoration::Item]
251
+ def request_code_lenses: (Editor editor, Range[Integer] visible_rows, ?start: bool) -> bool
252
+ def request_visible_code_lenses: (?Editor editor) -> bool
253
+ def visible_code_lens_ranges: (Editor editor, Range[Integer] display_rows) -> Array[Range[Integer]]
254
+ def invalidate_code_lenses: (?Buffer? buffer, ?client: Sadr::Client?) -> nil
62
255
  def accept_language_result: (palette_state palette, Integer index) -> void
63
256
  def show_diagnostics: () -> void
257
+ def problems_tree: () -> Zaniah::UI::TreeView
258
+ def filter_problems: (?severity: Integer | Diagnostics::severity?, ?source: Diagnostics::source?, ?text: String?) -> Hash[Symbol, untyped]
259
+ def show_problem_filter: () -> void
64
260
  def show_outline: () -> void
65
261
  def git: () -> Thuban::Repository?
66
262
  def git_status: () -> Hash[String, String]
@@ -71,11 +267,47 @@ module Canopus
71
267
  def git_hunks: (?Buffer buffer, ?async: bool) -> Array[Porrima::Hunk]
72
268
  def git_gutter_marks: (?Buffer buffer) -> Array[Porrima::Mark]
73
269
  def git_decorations: (Buffer buffer, Range[Integer] rows) -> Array[Decoration::Item]
74
- def show_git_diff: () -> Language::Document
270
+ def show_git_diff: (?mode: :inline | :side_by_side, ?async: bool) -> (Editor | Thread)
75
271
  def toggle_git_hunk: (?Editor current, ?row: Integer?) -> bool
76
272
  def show_git_blame: () -> String
77
273
  def revert_current_hunk: () -> patch?
78
274
  def checkout_branch: (String name) -> String
275
+ def scm_tree: () -> Zaniah::UI::TreeView
276
+ def scm_panel: () -> Zaniah::Div
277
+ def refresh_scm: () -> nil
278
+ def commit_git: (?String? message, ?amend: bool?) -> Thread
279
+ def stage_git_file: (?String? path) -> String
280
+ def unstage_git_file: (?String? path) -> String
281
+ def stage_git_hunk: (?Integer? index, ?buffer: Buffer, ?row: Integer?) -> String
282
+ def unstage_git_hunk: (?Integer? index, ?buffer: Buffer, ?row: Integer?) -> String
283
+ def stage_git_line: (?Integer? index, ?buffer: Buffer, ?row: Integer?) -> String
284
+ def unstage_git_line: (?Integer? index, ?buffer: Buffer, ?row: Integer?) -> String
285
+ def show_scm_diff: (?Hash[Symbol, untyped]? change, ?mode: :inline | :side_by_side, ?async: bool) -> (Editor | Thread)
286
+ def scm_diff_decorations: (Buffer buffer, Range[Integer] rows) -> Array[Decoration::Item]
287
+ def compare_git_revisions: (String? before, String after, ?path: String?, ?mode: :inline | :side_by_side, ?async: bool) -> (Editor | Thread)
288
+ def show_git_revision_diff: (String? before, String after, ?path: String?, ?mode: :inline | :side_by_side, ?async: bool) -> (Editor | Thread)
289
+ def show_revision_diff: (String? before, String after, ?path: String?, ?mode: :inline | :side_by_side, ?async: bool) -> (Editor | Thread)
290
+ def toggle_git_diff_mode: (?Editor current, ?async: bool) -> (Editor | Thread)
291
+ def toggle_scm_diff_mode: (?Editor current, ?async: bool) -> (Editor | Thread)
292
+ def git_file_history: (?String? path, ?revision: String, ?limit: Integer) -> Array[Workspace::GitDiffView::GitHistoryEntry]
293
+ def show_git_file_history: (?String? path, ?revision: String, ?limit: Integer, ?async: bool) -> (palette_state | Thread)
294
+ def show_git_revision_compare: (?String? path) -> palette_state
295
+ def git_commit_history: (?revision: String, ?limit: Integer) -> Array[Workspace::GitHistory::GitCommitEntry]
296
+ def show_git_commit_history: (?revision: String, ?limit: Integer, ?async: bool) -> (palette_state | Thread)
297
+ def open_git_commit: (Workspace::GitHistory::GitCommitEntry entry) -> (Editor | Thread | palette_state | nil)
298
+ def git_remotes: () -> Hash[String, String]
299
+ def fetch_git: (?String? remote, ?credentials: untyped) -> (Thread | palette_state)
300
+ def pull_git: (?String? remote, ?credentials: untyped) -> (Thread | palette_state)
301
+ def push_git: (?String? remote, ?credentials: untyped) -> (Thread | palette_state)
302
+ def cancel_git_transfer: () -> bool
303
+ def git_transfer_progress: () -> Hash[Symbol, untyped]?
304
+ def accept_git_credentials: () -> (Thread | palette_state)
305
+ def git_blame_decorations: (Buffer buffer, Range[Integer] rows, ?Editor? current) -> Array[Decoration::Item]
306
+ def invalidate_git_blame: (?Buffer? buffer) -> nil
307
+ def show_git_conflicts: (?String? path, ?async: bool) -> (Editor | Thread | nil)
308
+ def show_git_conflict: (?String? path, ?async: bool) -> (Editor | Thread | nil)
309
+ def resolve_git_conflict: ((:ours | :theirs | :both | :manual) choice, ?content: String?, ?mode: Integer?, ?async: bool, ?expected: untyped) -> (Editor | Thread | String)
310
+ def git_conflict_decorations: (Buffer buffer, Range[Integer] rows) -> Array[Decoration::Item]
79
311
  def search_query: (String query, palette_state state) -> [String | Regexp, search_options]
80
312
  def search_project: (String query, ?regexp: bool, ?case_sensitive: bool, ?whole_word: bool, ?async: bool) -> (Thread | MultiBuffer | nil)
81
313
  def replace_in_buffer: (String | Regexp pattern, String replacement, ?case_sensitive: bool, ?whole_word: bool, ?range: Range[Integer]?) -> Integer
@@ -13,7 +13,7 @@ smoke = ARGV.first && File.expand_path(ARGV.fetch(0))
13
13
  abort "Usage: ruby tools/check_dependencies.rb [smoke.rb]" if ARGV.length > 1 || (smoke && !File.file?(smoke))
14
14
  specification = Gem::Specification.load(File.join(root, "#{entry}.gemspec"))
15
15
  dependencies = specification.runtime_dependencies.map(&:name).sort
16
- expected = %w[alhena antares denebola kochab porrima prism rouge spica thuban unicode-display_width zaniah]
16
+ expected = %w[alhena alkaid antares denebola editorconfig kochab megrez menkar porrima prism rexml rouge sadr saiph spica tarazed thuban timeout unicode-display_width zaniah]
17
17
  abort "unexpected runtime gem dependencies" unless dependencies == expected
18
18
  abort "native extension declaration" unless specification.extensions.empty?
19
19
  abort "packaged native binary" if specification.files.any? { |path| path.match?(/\.(?:so|bundle|dll|dylib|a|o)\z/i) }
@@ -32,14 +32,33 @@ Dir.mktmpdir("#{entry}-install-") do |directory|
32
32
  gem_command = File.join(RbConfig::CONFIG.fetch("bindir"), "gem")
33
33
  environment = ENV.each_key.grep(/\ABUNDLE/).to_h { |key| [key, nil] }.merge(
34
34
  "GEM_HOME" => installation, "GEM_PATH" => ([installation] + Gem.path).join(File::PATH_SEPARATOR),
35
- "RUBYLIB" => nil, "RUBYOPT" => nil
35
+ "RUBYLIB" => nil, "RUBYOPT" => nil, "ALKAID_PATH" => nil, "ANTARES_PATH" => nil,
36
+ "MEGREZ_PATH" => nil, "MENKAR_PATH" => nil, "SADR_PATH" => nil, "SAIPH_PATH" => nil, "TARAZED_PATH" => nil
36
37
  )
38
+ {"ALKAID_PATH" => "alkaid", "ANTARES_PATH" => "antares", "MEGREZ_PATH" => "megrez", "MENKAR_PATH" => "menkar", "SADR_PATH" => "sadr", "SAIPH_PATH" => "saiph",
39
+ "TARAZED_PATH" => "tarazed"}.each do |variable, name|
40
+ next unless ENV[variable]
41
+
42
+ dependency_root = File.realpath(ENV.fetch(variable))
43
+ dependency_specification = Gem::Specification.load(File.join(dependency_root, "#{name}.gemspec"))
44
+ requirement = specification.runtime_dependencies.find { |dependency| dependency.name == name }
45
+ abort "invalid #{variable}" unless dependency_specification&.name == name &&
46
+ requirement&.match?(dependency_specification.name, dependency_specification.version)
47
+ dependency_artifact = File.join(directory, "#{name}.gem")
48
+ Dir.chdir(dependency_root) { Gem::Package.build(dependency_specification, false, false, dependency_artifact) }
49
+ output, status = Open3.capture2e(environment, Gem.ruby, gem_command, "install", "--local", "--ignore-dependencies",
50
+ "--no-document", "--install-dir", installation, dependency_artifact, chdir: directory)
51
+ abort output unless status.success?
52
+ end
37
53
  output, status = Open3.capture2e(environment, Gem.ruby, gem_command, "install", "--local", "--ignore-dependencies", "--no-document", "--install-dir", installation, artifact, chdir: directory)
38
54
  abort output unless status.success?
39
55
  installed = File.join(installation, "gems", "#{specification.name}-#{specification.version}")
40
56
  script = <<~RUBY
41
57
  require "prism"
42
58
  require #{entry.inspect}
59
+ require "canopus/plugins/registry"
60
+ require "canopus/plugins/isolated_runtime"
61
+ require "canopus/theme/import"
43
62
  actual = $LOADED_FEATURES.find { |path| path.end_with?(#{"/lib/#{entry}.rb".inspect}) }
44
63
  raise "loaded outside clean installation: " + actual.to_s unless actual && File.realpath(actual).start_with?(#{File.realpath(installed).inspect} + File::SEPARATOR)
45
64
  load #{smoke.inspect} if #{!smoke.nil?}