spoom 1.1.11 → 1.1.13

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.
data/lib/spoom/git.rb CHANGED
@@ -6,119 +6,125 @@ require "time"
6
6
  module Spoom
7
7
  # Execute git commands
8
8
  module Git
9
- extend T::Sig
10
-
11
- # Execute a `command`
12
- sig { params(command: String, arg: String, path: String).returns(ExecResult) }
13
- def self.exec(command, *arg, path: '.')
14
- return ExecResult.new(
15
- out: "",
16
- err: "Error: `#{path}` is not a directory.",
17
- status: false,
18
- exit_code: 1
19
- ) unless File.directory?(path)
20
-
21
- T.unsafe(Open3).popen3(command, *arg, chdir: path) do |_, stdout, stderr, thread|
22
- status = T.cast(thread.value, Process::Status)
23
- ExecResult.new(
24
- out: stdout.read,
25
- err: stderr.read,
26
- status: T.must(status.success?),
27
- exit_code: T.must(status.exitstatus)
28
- )
9
+ class Commit < T::Struct
10
+ extend T::Sig
11
+
12
+ const :sha, String
13
+ const :time, Time
14
+
15
+ sig { returns(Integer) }
16
+ def timestamp
17
+ time.to_i
29
18
  end
30
19
  end
31
20
 
32
- # Git commands
21
+ class << self
22
+ extend T::Sig
23
+
24
+ # Execute a `command`
25
+ sig { params(command: String, arg: String, path: String).returns(ExecResult) }
26
+ def exec(command, *arg, path: ".")
27
+ return ExecResult.new(
28
+ out: "",
29
+ err: "Error: `#{path}` is not a directory.",
30
+ status: false,
31
+ exit_code: 1,
32
+ ) unless File.directory?(path)
33
+
34
+ T.unsafe(Open3).popen3(command, *arg, chdir: path) do |_, stdout, stderr, thread|
35
+ status = T.cast(thread.value, Process::Status)
36
+ ExecResult.new(
37
+ out: stdout.read,
38
+ err: stderr.read,
39
+ status: T.must(status.success?),
40
+ exit_code: T.must(status.exitstatus),
41
+ )
42
+ end
43
+ end
33
44
 
34
- sig { params(arg: String, path: String).returns(ExecResult) }
35
- def self.checkout(*arg, path: ".")
36
- exec("git checkout -q #{arg.join(' ')}", path: path)
37
- end
45
+ # Git commands
38
46
 
39
- sig { params(arg: String, path: String).returns(ExecResult) }
40
- def self.diff(*arg, path: ".")
41
- exec("git diff #{arg.join(' ')}", path: path)
42
- end
47
+ sig { params(arg: String, path: String).returns(ExecResult) }
48
+ def checkout(*arg, path: ".")
49
+ exec("git checkout -q #{arg.join(" ")}", path: path)
50
+ end
43
51
 
44
- sig { params(arg: String, path: String).returns(ExecResult) }
45
- def self.log(*arg, path: ".")
46
- exec("git log #{arg.join(' ')}", path: path)
47
- end
52
+ sig { params(arg: String, path: String).returns(ExecResult) }
53
+ def diff(*arg, path: ".")
54
+ exec("git diff #{arg.join(" ")}", path: path)
55
+ end
48
56
 
49
- sig { params(arg: String, path: String).returns(ExecResult) }
50
- def self.rev_parse(*arg, path: ".")
51
- exec("git rev-parse --short #{arg.join(' ')}", path: path)
52
- end
57
+ sig { params(arg: String, path: String).returns(ExecResult) }
58
+ def log(*arg, path: ".")
59
+ exec("git log #{arg.join(" ")}", path: path)
60
+ end
53
61
 
54
- sig { params(arg: String, path: String).returns(ExecResult) }
55
- def self.show(*arg, path: ".")
56
- exec("git show #{arg.join(' ')}", path: path)
57
- end
62
+ sig { params(arg: String, path: String).returns(ExecResult) }
63
+ def show(*arg, path: ".")
64
+ exec("git show #{arg.join(" ")}", path: path)
65
+ end
58
66
 
59
- sig { params(path: String).returns(T.nilable(String)) }
60
- def self.current_branch(path: ".")
61
- result = exec("git branch --show-current", path: path)
62
- return nil unless result.status
63
- result.out.strip
64
- end
67
+ sig { params(path: String).returns(T.nilable(String)) }
68
+ def current_branch(path: ".")
69
+ result = exec("git branch --show-current", path: path)
70
+ return nil unless result.status
65
71
 
66
- # Utils
72
+ result.out.strip
73
+ end
67
74
 
68
- # Get the commit epoch timestamp for a `sha`
69
- sig { params(sha: String, path: String).returns(T.nilable(Integer)) }
70
- def self.commit_timestamp(sha, path: ".")
71
- result = show("--no-notes --no-patch --pretty=%at #{sha}", path: path)
72
- return nil unless result.status
73
- result.out.strip.to_i
74
- end
75
+ # Utils
75
76
 
76
- # Get the commit Time for a `sha`
77
- sig { params(sha: String, path: String).returns(T.nilable(Time)) }
78
- def self.commit_time(sha, path: ".")
79
- timestamp = commit_timestamp(sha, path: path)
80
- return nil unless timestamp
81
- epoch_to_time(timestamp.to_s)
82
- end
77
+ # Get the last commit in the currently checked out branch
78
+ sig { params(path: String).returns(T.nilable(Commit)) }
79
+ def last_commit(path: ".")
80
+ result = log("HEAD --format='%h %at' -1", path: path)
81
+ return nil unless result.status
83
82
 
84
- # Get the last commit sha
85
- sig { params(path: String).returns(T.nilable(String)) }
86
- def self.last_commit(path: ".")
87
- result = rev_parse("HEAD", path: path)
88
- return nil unless result.status
89
- result.out.strip
90
- end
83
+ out = result.out.strip
84
+ return nil if out.empty?
91
85
 
92
- # Translate a git epoch timestamp into a Time
93
- sig { params(timestamp: String).returns(Time) }
94
- def self.epoch_to_time(timestamp)
95
- Time.strptime(timestamp, "%s")
96
- end
86
+ parse_commit(out)
87
+ end
97
88
 
98
- # Is there uncommited changes in `path`?
99
- sig { params(path: String).returns(T::Boolean) }
100
- def self.workdir_clean?(path: ".")
101
- diff("HEAD", path: path).out.empty?
102
- end
89
+ # Is there uncommited changes in `path`?
90
+ sig { params(path: String).returns(T::Boolean) }
91
+ def workdir_clean?(path: ".")
92
+ diff("HEAD", path: path).out.empty?
93
+ end
103
94
 
104
- # Get the hash of the commit introducing the `sorbet/config` file
105
- sig { params(path: String).returns(T.nilable(String)) }
106
- def self.sorbet_intro_commit(path: ".")
107
- result = Spoom::Git.log("--diff-filter=A --format='%h' -1 -- sorbet/config", path: path)
108
- return nil unless result.status
109
- out = result.out.strip
110
- return nil if out.empty?
111
- out
112
- end
95
+ # Get the commit introducing the `sorbet/config` file
96
+ sig { params(path: String).returns(T.nilable(Commit)) }
97
+ def sorbet_intro_commit(path: ".")
98
+ result = log("--diff-filter=A --format='%h %at' -1 -- sorbet/config", path: path)
99
+ return nil unless result.status
113
100
 
114
- # Get the hash of the commit removing the `sorbet/config` file
115
- sig { params(path: String).returns(T.nilable(String)) }
116
- def self.sorbet_removal_commit(path: ".")
117
- result = Spoom::Git.log("--diff-filter=D --format='%h' -1 -- sorbet/config", path: path)
118
- return nil unless result.status
119
- out = result.out.strip
120
- return nil if out.empty?
121
- out
101
+ out = result.out.strip
102
+ return nil if out.empty?
103
+
104
+ parse_commit(out)
105
+ end
106
+
107
+ # Get the commit removing the `sorbet/config` file
108
+ sig { params(path: String).returns(T.nilable(Commit)) }
109
+ def sorbet_removal_commit(path: ".")
110
+ result = log("--diff-filter=D --format='%h %at' -1 -- sorbet/config", path: path)
111
+ return nil unless result.status
112
+
113
+ out = result.out.strip
114
+ return nil if out.empty?
115
+
116
+ parse_commit(out)
117
+ end
118
+
119
+ # Parse a line formated as `%h %at` into a `Commit`
120
+ sig { params(string: String).returns(T.nilable(Commit)) }
121
+ def parse_commit(string)
122
+ sha, epoch = string.split(" ", 2)
123
+ return nil unless sha && epoch
124
+
125
+ time = Time.strptime(epoch, "%s")
126
+ Commit.new(sha: sha, time: time)
127
+ end
122
128
  end
123
129
  end
124
130
  end
data/lib/spoom/printer.rb CHANGED
@@ -38,6 +38,7 @@ module Spoom
38
38
  sig { params(string: T.nilable(String)).void }
39
39
  def print(string)
40
40
  return unless string
41
+
41
42
  @out.print(string)
42
43
  end
43
44
 
@@ -47,6 +48,7 @@ module Spoom
47
48
  sig { params(string: T.nilable(String), color: Color).void }
48
49
  def print_colored(string, *color)
49
50
  return unless string
51
+
50
52
  string = T.unsafe(self).colorize(string, *color)
51
53
  @out.print(string)
52
54
  end
@@ -61,6 +63,7 @@ module Spoom
61
63
  sig { params(string: T.nilable(String)).void }
62
64
  def printl(string)
63
65
  return unless string
66
+
64
67
  printt
65
68
  print(string)
66
69
  printn
@@ -76,6 +79,7 @@ module Spoom
76
79
  sig { params(string: String, color: Spoom::Color).returns(String) }
77
80
  def colorize(string, *color)
78
81
  return string unless @colors
82
+
79
83
  T.unsafe(self).set_color(string, *color)
80
84
  end
81
85
  end
@@ -4,10 +4,16 @@
4
4
  module Spoom
5
5
  module Sorbet
6
6
  module Errors
7
- extend T::Sig
8
-
9
7
  DEFAULT_ERROR_URL_BASE = "https://srb.help/"
10
8
 
9
+ class << self
10
+ extend T::Sig
11
+
12
+ sig { params(errors: T::Array[Error]).returns(T::Array[Error]) }
13
+ def sort_errors_by_code(errors)
14
+ errors.sort_by { |e| [e.code, e.file, e.line, e.message] }
15
+ end
16
+ end
11
17
  # Parse errors from Sorbet output
12
18
  class Parser
13
19
  extend T::Sig
@@ -20,10 +26,14 @@ module Spoom
20
26
  "or set SORBET_SILENCE_DEV_MESSAGE=1 in your shell environment.",
21
27
  ], T::Array[String])
22
28
 
23
- sig { params(output: String, error_url_base: String).returns(T::Array[Error]) }
24
- def self.parse_string(output, error_url_base: DEFAULT_ERROR_URL_BASE)
25
- parser = Spoom::Sorbet::Errors::Parser.new(error_url_base: error_url_base)
26
- parser.parse(output)
29
+ class << self
30
+ extend T::Sig
31
+
32
+ sig { params(output: String, error_url_base: String).returns(T::Array[Error]) }
33
+ def parse_string(output, error_url_base: DEFAULT_ERROR_URL_BASE)
34
+ parser = Spoom::Sorbet::Errors::Parser.new(error_url_base: error_url_base)
35
+ parser.parse(output)
36
+ end
27
37
  end
28
38
 
29
39
  sig { params(error_url_base: String).void }
@@ -85,12 +95,14 @@ module Spoom
85
95
  sig { params(error: Error).void }
86
96
  def open_error(error)
87
97
  raise "Error: Already parsing an error!" if @current_error
98
+
88
99
  @current_error = error
89
100
  end
90
101
 
91
102
  sig { void }
92
103
  def close_error
93
104
  raise "Error: Not already parsing an error!" unless @current_error
105
+
94
106
  @errors << @current_error
95
107
  @current_error = nil
96
108
  end
@@ -98,6 +110,11 @@ module Spoom
98
110
  sig { params(line: String).void }
99
111
  def append_error(line)
100
112
  raise "Error: Not already parsing an error!" unless @current_error
113
+
114
+ filepath_match = line.match(/^ (.*?):\d+/)
115
+ if filepath_match && filepath_match[1]
116
+ @current_error.files_from_error_sections << T.must(filepath_match[1])
117
+ end
101
118
  @current_error.more << line
102
119
  end
103
120
  end
@@ -115,13 +132,17 @@ module Spoom
115
132
  sig { returns(T::Array[String]) }
116
133
  attr_reader :more
117
134
 
135
+ # Other files associated with the error
136
+ sig { returns(T::Set[String]) }
137
+ attr_reader :files_from_error_sections
138
+
118
139
  sig do
119
140
  params(
120
141
  file: T.nilable(String),
121
142
  line: T.nilable(Integer),
122
143
  message: T.nilable(String),
123
144
  code: T.nilable(Integer),
124
- more: T::Array[String]
145
+ more: T::Array[String],
125
146
  ).void
126
147
  end
127
148
  def initialize(file, line, message, code, more = [])
@@ -130,12 +151,14 @@ module Spoom
130
151
  @message = message
131
152
  @code = code
132
153
  @more = more
154
+ @files_from_error_sections = T.let(Set.new, T::Set[String])
133
155
  end
134
156
 
135
157
  # By default errors are sorted by location
136
158
  sig { params(other: T.untyped).returns(Integer) }
137
159
  def <=>(other)
138
160
  return 0 unless other.is_a?(Error)
161
+
139
162
  [file, line, code, message] <=> [other.file, other.line, other.code, other.message]
140
163
  end
141
164
 
@@ -144,11 +167,6 @@ module Spoom
144
167
  "#{file}:#{line}: #{message} (#{code})"
145
168
  end
146
169
  end
147
-
148
- sig { params(errors: T::Array[Error]).returns(T::Array[Error]) }
149
- def self.sort_errors_by_code(errors)
150
- errors.sort_by { |e| [e.code, e.file, e.line, e.message] }
151
- end
152
170
  end
153
171
  end
154
172
  end
@@ -24,7 +24,7 @@ module Spoom
24
24
  def as_json
25
25
  instance_variables.each_with_object({}) do |var, obj|
26
26
  val = instance_variable_get(var)
27
- obj[var.to_s.delete('@')] = val if val
27
+ obj[var.to_s.delete("@")] = val if val
28
28
  end
29
29
  end
30
30
 
@@ -16,18 +16,23 @@ module Spoom
16
16
  sig { returns(T::Array[Diagnostic]) }
17
17
  attr_reader :diagnostics
18
18
 
19
- sig { params(json: T::Hash[T.untyped, T.untyped]).returns(Diagnostics) }
20
- def self.from_json(json)
21
- Diagnostics.new(
22
- json['uri'],
23
- json['diagnostics'].map { |d| Diagnostic.from_json(d) }
24
- )
19
+ class << self
20
+ extend T::Sig
21
+
22
+ sig { params(json: T::Hash[T.untyped, T.untyped]).returns(Diagnostics) }
23
+ def from_json(json)
24
+ Diagnostics.new(
25
+ json["uri"],
26
+ json["diagnostics"].map { |d| Diagnostic.from_json(d) },
27
+ )
28
+ end
25
29
  end
26
30
 
27
31
  sig { params(uri: String, diagnostics: T::Array[Diagnostic]).void }
28
32
  def initialize(uri, diagnostics)
29
33
  @uri = uri
30
34
  @diagnostics = diagnostics
35
+ super()
31
36
  end
32
37
  end
33
38
  end
@@ -38,25 +43,26 @@ module Spoom
38
43
  sig { returns(Integer) }
39
44
  attr_reader :code
40
45
 
41
- sig { returns(String) }
42
- attr_reader :message
43
-
44
46
  sig { returns(T::Hash[T.untyped, T.untyped]) }
45
47
  attr_reader :data
46
48
 
47
- sig { params(json: T::Hash[T.untyped, T.untyped]).returns(ResponseError) }
48
- def self.from_json(json)
49
- ResponseError.new(
50
- json['code'],
51
- json['message'],
52
- json['data']
53
- )
49
+ class << self
50
+ extend T::Sig
51
+
52
+ sig { params(json: T::Hash[T.untyped, T.untyped]).returns(ResponseError) }
53
+ def from_json(json)
54
+ ResponseError.new(
55
+ json["code"],
56
+ json["message"],
57
+ json["data"],
58
+ )
59
+ end
54
60
  end
55
61
 
56
62
  sig { params(code: Integer, message: String, data: T::Hash[T.untyped, T.untyped]).void }
57
63
  def initialize(code, message, data)
64
+ super(message)
58
65
  @code = code
59
- @message = message
60
66
  @data = data
61
67
  end
62
68
  end
@@ -23,12 +23,16 @@ module Spoom
23
23
  const :contents, String
24
24
  const :range, T.nilable(Range)
25
25
 
26
- sig { params(json: T::Hash[T.untyped, T.untyped]).returns(Hover) }
27
- def self.from_json(json)
28
- Hover.new(
29
- contents: json['contents']['value'],
30
- range: json['range'] ? Range.from_json(json['range']) : nil
31
- )
26
+ class << self
27
+ extend T::Sig
28
+
29
+ sig { params(json: T::Hash[T.untyped, T.untyped]).returns(Hover) }
30
+ def from_json(json)
31
+ Hover.new(
32
+ contents: json["contents"]["value"],
33
+ range: json["range"] ? Range.from_json(json["range"]) : nil,
34
+ )
35
+ end
32
36
  end
33
37
 
34
38
  sig { override.params(printer: SymbolPrinter).void }
@@ -50,12 +54,16 @@ module Spoom
50
54
  const :line, Integer
51
55
  const :char, Integer
52
56
 
53
- sig { params(json: T::Hash[T.untyped, T.untyped]).returns(Position) }
54
- def self.from_json(json)
55
- Position.new(
56
- line: json['line'].to_i,
57
- char: json['character'].to_i
58
- )
57
+ class << self
58
+ extend T::Sig
59
+
60
+ sig { params(json: T::Hash[T.untyped, T.untyped]).returns(Position) }
61
+ def from_json(json)
62
+ Position.new(
63
+ line: json["line"].to_i,
64
+ char: json["character"].to_i,
65
+ )
66
+ end
59
67
  end
60
68
 
61
69
  sig { override.params(printer: SymbolPrinter).void }
@@ -76,12 +84,16 @@ module Spoom
76
84
  const :start, Position
77
85
  const :end, Position
78
86
 
79
- sig { params(json: T::Hash[T.untyped, T.untyped]).returns(Range) }
80
- def self.from_json(json)
81
- Range.new(
82
- start: Position.from_json(json['start']),
83
- end: Position.from_json(json['end'])
84
- )
87
+ class << self
88
+ extend T::Sig
89
+
90
+ sig { params(json: T::Hash[T.untyped, T.untyped]).returns(Range) }
91
+ def from_json(json)
92
+ Range.new(
93
+ start: Position.from_json(json["start"]),
94
+ end: Position.from_json(json["end"]),
95
+ )
96
+ end
85
97
  end
86
98
 
87
99
  sig { override.params(printer: SymbolPrinter).void }
@@ -104,12 +116,16 @@ module Spoom
104
116
  const :uri, String
105
117
  const :range, LSP::Range
106
118
 
107
- sig { params(json: T::Hash[T.untyped, T.untyped]).returns(Location) }
108
- def self.from_json(json)
109
- Location.new(
110
- uri: json['uri'],
111
- range: Range.from_json(json['range'])
112
- )
119
+ class << self
120
+ extend T::Sig
121
+
122
+ sig { params(json: T::Hash[T.untyped, T.untyped]).returns(Location) }
123
+ def from_json(json)
124
+ Location.new(
125
+ uri: json["uri"],
126
+ range: Range.from_json(json["range"]),
127
+ )
128
+ end
113
129
  end
114
130
 
115
131
  sig { override.params(printer: SymbolPrinter).void }
@@ -132,20 +148,24 @@ module Spoom
132
148
  const :doc, Object # TODO
133
149
  const :params, T::Array[T.untyped] # TODO
134
150
 
135
- sig { params(json: T::Hash[T.untyped, T.untyped]).returns(SignatureHelp) }
136
- def self.from_json(json)
137
- SignatureHelp.new(
138
- label: json['label'],
139
- doc: json['documentation'],
140
- params: json['parameters'],
141
- )
151
+ class << self
152
+ extend T::Sig
153
+
154
+ sig { params(json: T::Hash[T.untyped, T.untyped]).returns(SignatureHelp) }
155
+ def from_json(json)
156
+ SignatureHelp.new(
157
+ label: json["label"],
158
+ doc: json["documentation"],
159
+ params: json["parameters"],
160
+ )
161
+ end
142
162
  end
143
163
 
144
164
  sig { override.params(printer: SymbolPrinter).void }
145
165
  def accept_printer(printer)
146
166
  printer.print(label)
147
167
  printer.print("(")
148
- printer.print(params.map { |l| "#{l['label']}: #{l['documentation']}" }.join(", "))
168
+ printer.print(params.map { |l| "#{l["label"]}: #{l["documentation"]}" }.join(", "))
149
169
  printer.print(")")
150
170
  end
151
171
 
@@ -164,14 +184,18 @@ module Spoom
164
184
  const :message, String
165
185
  const :informations, Object
166
186
 
167
- sig { params(json: T::Hash[T.untyped, T.untyped]).returns(Diagnostic) }
168
- def self.from_json(json)
169
- Diagnostic.new(
170
- range: Range.from_json(json['range']),
171
- code: json['code'].to_i,
172
- message: json['message'],
173
- informations: json['relatedInformation']
174
- )
187
+ class << self
188
+ extend T::Sig
189
+
190
+ sig { params(json: T::Hash[T.untyped, T.untyped]).returns(Diagnostic) }
191
+ def from_json(json)
192
+ Diagnostic.new(
193
+ range: Range.from_json(json["range"]),
194
+ code: json["code"].to_i,
195
+ message: json["message"],
196
+ informations: json["relatedInformation"],
197
+ )
198
+ end
175
199
  end
176
200
 
177
201
  sig { override.params(printer: SymbolPrinter).void }
@@ -196,35 +220,40 @@ module Spoom
196
220
  const :range, T.nilable(Range)
197
221
  const :children, T::Array[DocumentSymbol]
198
222
 
199
- sig { params(json: T::Hash[T.untyped, T.untyped]).returns(DocumentSymbol) }
200
- def self.from_json(json)
201
- DocumentSymbol.new(
202
- name: json['name'],
203
- detail: json['detail'],
204
- kind: json['kind'],
205
- location: json['location'] ? Location.from_json(json['location']) : nil,
206
- range: json['range'] ? Range.from_json(json['range']) : nil,
207
- children: json['children'] ? json['children'].map { |symbol| DocumentSymbol.from_json(symbol) } : [],
208
- )
223
+ class << self
224
+ extend T::Sig
225
+
226
+ sig { params(json: T::Hash[T.untyped, T.untyped]).returns(DocumentSymbol) }
227
+ def from_json(json)
228
+ DocumentSymbol.new(
229
+ name: json["name"],
230
+ detail: json["detail"],
231
+ kind: json["kind"],
232
+ location: json["location"] ? Location.from_json(json["location"]) : nil,
233
+ range: json["range"] ? Range.from_json(json["range"]) : nil,
234
+ children: json["children"] ? json["children"].map { |symbol| DocumentSymbol.from_json(symbol) } : [],
235
+ )
236
+ end
209
237
  end
210
238
 
211
239
  sig { override.params(printer: SymbolPrinter).void }
212
240
  def accept_printer(printer)
213
241
  h = serialize.hash
214
242
  return if printer.seen.include?(h)
243
+
215
244
  printer.seen.add(h)
216
245
 
217
246
  printer.printt
218
247
  printer.print(kind_string)
219
- printer.print(' ')
248
+ printer.print(" ")
220
249
  printer.print_colored(name, Color::BLUE, Color::BOLD)
221
- printer.print_colored(' (', Color::LIGHT_BLACK)
250
+ printer.print_colored(" (", Color::LIGHT_BLACK)
222
251
  if range
223
252
  printer.print_object(range)
224
253
  elsif location
225
254
  printer.print_object(location)
226
255
  end
227
- printer.print_colored(')', Color::LIGHT_BLACK)
256
+ printer.print_colored(")", Color::LIGHT_BLACK)
228
257
  printer.printn
229
258
  unless children.empty?
230
259
  printer.indent
@@ -288,7 +317,7 @@ module Spoom
288
317
  out: T.any(IO, StringIO),
289
318
  colors: T::Boolean,
290
319
  indent_level: Integer,
291
- prefix: T.nilable(String)
320
+ prefix: T.nilable(String),
292
321
  ).void
293
322
  end
294
323
  def initialize(out: $stdout, colors: true, indent_level: 0, prefix: nil)
@@ -303,6 +332,7 @@ module Spoom
303
332
  sig { params(object: T.nilable(PrintableSymbol)).void }
304
333
  def print_object(object)
305
334
  return unless object
335
+
306
336
  object.accept_printer(self)
307
337
  end
308
338
 
@@ -315,6 +345,7 @@ module Spoom
315
345
  def clean_uri(uri)
316
346
  prefix = self.prefix
317
347
  return uri unless prefix
348
+
318
349
  uri.delete_prefix(prefix)
319
350
  end
320
351
 
@@ -322,7 +353,7 @@ module Spoom
322
353
  def print_list(objects)
323
354
  objects.each do |object|
324
355
  printt
325
- print "* "
356
+ print("* ")
326
357
  print_object(object)
327
358
  printn
328
359
  end