alda-rb 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6e35ecf8cca36fa942f004ba62c203226064ec3de09f21974ba57eb04cddd79a
4
- data.tar.gz: 96f6a6540591c4a890034b234a737b68a678c199e2f88a8f73b4eadd5f824477
3
+ metadata.gz: 41c00c8e704980367ff2ca3cef0028e08cd5483106a0df2d89bc70644fea33a1
4
+ data.tar.gz: da32c375756258266cd4eee3818d8697f2ced17605f2bfe19db69e9eebffa5ca
5
5
  SHA512:
6
- metadata.gz: b8eb886e53075b0d4d154c0f2f29415eb366ce0ad1ca38aa6a0757eee136b028d952dab3e42f557d4037fcc41704b64f9467de4c89205f0cbd8d040b1d3ce70e
7
- data.tar.gz: cec492d17877348e1023b5d488bd3cb2b6e874d13e13eaa1141eee5260853ff094e0daa9b412fbb7210f6a91b5fb2808bfe0831e932a84a510b1809a8df97b91
6
+ metadata.gz: dc03761923a96fd3c596cd034ef86f51f26b0b8055e33287e8fff772f1f1c062de55f0a009f07930c7bea8b2f9c491246b70ae44dc37aeec388cbc5f0669971f
7
+ data.tar.gz: f578e781ba699b774c9a22f30b65f8dd1c734d09fa4cd32d49416874cbab96203efd9b357ef9740854864ff445b408b4a55c85aaabdf236337b889f488819850
data/CHANGELOG.md CHANGED
@@ -1,5 +1,31 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## v0.3.1 (2023-06-03)
4
+
5
+ New features and new API:
6
+
7
+ - Added Alda::NREPLServerError#status.
8
+ - Added Alda::env.
9
+ - Alda::down? and Alda::up? is now useful in \Alda 2.
10
+ - Added Alda::REPL#reline.
11
+
12
+ BREAKING changes of API:
13
+
14
+ - Now `status` should be specified as a parameter of Alda::NREPLServerError::new.
15
+
16
+ Fixed bugs:
17
+
18
+ - Fixed: `alda-irb` does not run correctly in Ruby 3.
19
+ - Fixed: cannot handle unknown-op error of nREPL server.
20
+ - Fixed: an excess message printed when exiting \REPL on Windows.
21
+
22
+ Other changes:
23
+
24
+ - Fixed dependencies.
25
+ - Fixed some changelog of 0.3.0.
26
+ - Added a gem badge in README.
27
+ - Updated bundler version.
28
+
3
29
  ## v0.3.0 (2023-05-29)
4
30
 
5
31
  ### Changes for \Alda 2
@@ -8,12 +34,12 @@ Added API for support \Alda 2 while still being able to support \Alda 1:
8
34
 
9
35
  - Added Alda::COMMANDS_FOR_VERSIONS and Alda::GENERATIONS.
10
36
  - Added Alda::generation, which can be `:v1` or `:v2`.
11
- Specifically, one of the values in the array Alda::GENERATIONS.
37
+ Specifically, one of the values in the array Alda::GENERATIONS.
12
38
  - Added Alda::v1?, Alda::v2?, Alda::v1!, Alda::v2! (See Alda::GENERATIONS).
13
39
  - Added Alda::deduce_generation.
14
40
  - Added Alda::GenerationError.
15
41
  - In Alda::Chord#to_alda_code, considering an undocumented breaking change about chords,
16
- the behavior is slightly different for \Alda 1 and \Alda 2.
42
+ the behavior is slightly different for \Alda 1 and \Alda 2.
17
43
  - Added Thread#inside_alda_list.
18
44
  - Added Alda::REPL#message and Alda::REPL#raw_message.
19
45
 
@@ -25,7 +51,7 @@ APIs that are modified to support \Alda 2:
25
51
  - Because \Alda 2 does not have the notion of down and up, if we are in v2,
26
52
  Alda::down? will always return false and Alda::up? will always return true.
27
53
  - Array#to_alda_code and Hash#to_alda_code behaves differently for \Alda 1 and \Alda 2 regarding
28
- [a breaking change](https://github.com/alda-lang/alda/blob/master/doc/alda-2-migration-guide.md#attribute-syntax-has-changed-in-some-cases).
54
+ [a breaking change](https://github.com/alda-lang/alda/blob/master/doc/alda-2-migration-guide.md#attribute-syntax-has-changed-in-some-cases).
29
55
 
30
56
  Documents that modified for notice about \Alda 2:
31
57
 
@@ -47,11 +73,11 @@ Examples that are modified to work in \Alda 2:
47
73
  New features:
48
74
 
49
75
  - Added warnings about structures that probably trigger errors in \Alda.
50
- See Alda::EventContainer#check_in_chord, Alda::EventList#method_missing.
76
+ See Alda::EventContainer#check_in_chord, Alda::EventList#method_missing.
51
77
  - Now you can specify a parameter in Alda::Event#detach_from_parent to exclude some
52
- classes of parents that will be detached from.
78
+ classes of parents that will be detached from.
53
79
  - (Potentially BREAKING) Alda::Event#detach_from_parent now tries to detach the topmost container
54
- instead of the event itself from the parent.
80
+ instead of the event itself from the parent.
55
81
  - Added a commandline program called `alda-irb`. See Alda::REPL.
56
82
  - Traceback of exception will also be printed now if an Interrupt is caught in \REPL.
57
83
  - <kbd>Ctrl</kbd>+<kbd>C</kbd> can now be used to discard the current input in \REPL.
@@ -63,7 +89,7 @@ New APIs:
63
89
 
64
90
  - Added Alda::Raw.
65
91
  - Added Alda::Utils::warn, Alda::Utils::win_platform?,
66
- Alda::Utils::snake_to_slug, Alda::Utils::slug_to_snake.
92
+ Alda::Utils::snake_to_slug, Alda::Utils::slug_to_snake.
67
93
  - Added Alda::Event#is_event_of?. It is overridden in Alda::EventContainer#is_event_of?.
68
94
  - Added Alda::Event#== and Alda::EventList#==. It is overridden in many subclasses.
69
95
  - Added Alda::EventContainer#check_in_chord.
@@ -72,7 +98,7 @@ Alda::Utils::snake_to_slug, Alda::Utils::slug_to_snake.
72
98
  - Added Alda::REPL#color, Alda::REPL#preview.
73
99
  - Added Alda::REPL#setup_repl, Alda::REPL#readline.
74
100
  - Added Alda::REPL::TempScore#new_score, Alda::REPL::TempScore#score_text,
75
- Alda::REPL::TempScore#score_data, Alda::REPL::TempScore#score_events.
101
+ Alda::REPL::TempScore#score_data, Alda::REPL::TempScore#score_events.
76
102
  - Added Alda::pipe.
77
103
  - Added Alda::processes.
78
104
  - Added Alda::NREPLServerError.
@@ -81,10 +107,9 @@ Alda::REPL::TempScore#score_data, Alda::REPL::TempScore#score_events.
81
107
  Slightly improved docs:
82
108
 
83
109
  - Alda::EventContainer#event.
84
- - The overriding +to_alda_code+'s and +on_contained+'s.
110
+ - The overriding `to_alda_code`'s and `on_contained`'s.
85
111
  - Alda::Sequence, Alda::Sequence::RefineFlatten#flatten.
86
112
  - The patches to Ruby's core classes.
87
- - Alda::repl.
88
113
  - Kernel.
89
114
  - Alda::EventList::new.
90
115
  - Alda::OrderError::new.
@@ -109,7 +134,7 @@ Removed APIs:
109
134
 
110
135
  - Removed Alda::SetVariable#original_events.
111
136
  - Removed Alda::repl. Now calling `Alda.repl` will trigger commandline `alda repl`.
112
- For the old REPL function, use `Alda::REPL.new.run` instead.
137
+ For the old REPL function, use `Alda::REPL.new.run` instead.
113
138
  - Removed Alda::REPL::TempScore#history.
114
139
 
115
140
  Modified APIs or features:
@@ -120,11 +145,11 @@ Modified APIs or features:
120
145
  ### Fixed bugs
121
146
 
122
147
  - Fixed: sometimes Alda::Event#parent returns wrong result
123
- because it is not updated in some cases.
148
+ because it is not updated in some cases.
124
149
  - Fixed (potentially BREAKING): Hash#to_alda_code returns `[[k1 v1] [k2 v2]]`.
125
- Now, it returns `{k1 v1 k2 v2}`.
150
+ Now, it returns `{k1 v1 k2 v2}`.
126
151
  - Use reline instead of readline in Alda::REPL
127
- because Ruby 3.3 is dropping the shipment of readline-ext.
152
+ because Ruby 3.3 is dropping the shipment of readline-ext.
128
153
 
129
154
  ### Others
130
155
 
@@ -135,9 +160,9 @@ because Ruby 3.3 is dropping the shipment of readline-ext.
135
160
  ## v0.2.1 (2020-08-13)
136
161
 
137
162
  - Fixed the bug in `examples/bwv846_prelude.rb`.
138
- The file isn't changed when the version change
139
- from [v0.1.4](#v014-2020-04-23) to [v0.2.0](#v020-2020-05-08)
140
- but the new features in 0.2.0 made some codes in that file stop working.
163
+ The file isn't changed when the version change
164
+ from [v0.1.4](#v014-2020-04-23) to [v0.2.0](#v020-2020-05-08)
165
+ but the new features in 0.2.0 made some codes in that file stop working.
141
166
 
142
167
  ## v0.2.0 (2020-05-08)
143
168
 
@@ -178,9 +203,9 @@ c c c c c
178
203
  > exit
179
204
  ```
180
205
  - More than 2 events written together will become an Alda::Sequence object
181
- (contained by an Alda::EventContainer).
182
- Events that can use such sugar includes:
183
- part (supports dot accessor), note, rest, octave, voice, marker, at-marker.
206
+ (contained by an Alda::EventContainer).
207
+ Events that can use such sugar includes:
208
+ part (supports dot accessor), note, rest, octave, voice, marker, at-marker.
184
209
  ```ruby
185
210
  Alda::Score.new { p((c d e).event.class) } # => Alda::Sequence
186
211
  ```
data/Gemfile CHANGED
@@ -2,11 +2,11 @@ source "https://rubygems.org"
2
2
 
3
3
  gemspec
4
4
 
5
- gem "rake", "~> 12.0"
6
- gem "minitest", "~> 5.0"
7
5
  gem "colorize"
8
6
  gem "bencode"
9
7
  group :develop do
8
+ gem "rake", "~> 12.0"
9
+ gem "minitest", "~> 5.0"
10
10
  gem 'rubocop'
11
11
  gem 'rdoc'
12
12
  end
data/Gemfile.lock CHANGED
@@ -1,7 +1,9 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- alda-rb (0.3.0)
4
+ alda-rb (0.3.1)
5
+ bencode
6
+ colorize
5
7
 
6
8
  GEM
7
9
  remote: https://rubygems.org/
@@ -51,4 +53,4 @@ DEPENDENCIES
51
53
  rubocop
52
54
 
53
55
  BUNDLED WITH
54
- 2.4.1
56
+ 2.4.13
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # alda-rb
2
2
 
3
+ [![Gem Version](https://badge.fury.io/rb/alda-rb.svg)](https://badge.fury.io/rb/alda-rb)
4
+
3
5
  A Ruby library for live-coding music with [Alda](https://alda.io/).
4
6
  Also provides an alda DSL in Ruby.
5
7
 
data/alda-rb.gemspec CHANGED
@@ -3,29 +3,34 @@
3
3
  require_relative 'lib/alda-rb/version'
4
4
 
5
5
  Gem::Specification.new do |spec|
6
- spec.name = "alda-rb"
7
- spec.version = Alda::VERSION
8
- spec.authors = ["Ulysses Zhan"]
9
- spec.email = ["UlyssesZhan@gmail.com"]
10
-
11
- spec.summary = %q{A Ruby library for live-coding music with Alda.}
12
- # spec.description = %q{TODO: Write a longer description or delete this line.}
13
- spec.homepage = "https://ulysseszh.github.io/doc/alda-rb"
14
- spec.license = "MIT"
15
- spec.required_ruby_version = Gem::Requirement.new(">= 2.7.0")
16
-
17
- # spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
18
-
19
- spec.metadata["homepage_uri"] = spec.homepage
20
- spec.metadata["source_code_uri"] = "https://github.com/UlyssesZh/alda-rb"
21
- spec.metadata["changelog_uri"] = "https://ulysseszh.github.io/doc/alda-rb/CHANGELOG_md.html"
22
-
23
- # Specify which files should be added to the gem when it is released.
24
- # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
25
- spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
26
- `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
27
- end
28
- spec.bindir = "exe"
29
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
30
- spec.require_paths = ["lib"]
6
+ spec.name = "alda-rb"
7
+ spec.version = Alda::VERSION
8
+ spec.authors = ["Ulysses Zhan"]
9
+ spec.email = ["UlyssesZhan@gmail.com"]
10
+
11
+ spec.summary = %q{A Ruby library for live-coding music with Alda.}
12
+ # spec.description = %q{TODO: Write a longer description or delete this line.}
13
+ spec.homepage = "https://ulysseszh.github.io/doc/alda-rb"
14
+ spec.license = "MIT"
15
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.7.0")
16
+
17
+ # spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
18
+
19
+ spec.metadata["homepage_uri"] = spec.homepage
20
+ spec.metadata["source_code_uri"] = "https://github.com/UlyssesZh/alda-rb"
21
+ spec.metadata["changelog_uri"] = "https://ulysseszh.github.io/doc/alda-rb/CHANGELOG_md.html"
22
+
23
+ # Specify which files should be added to the gem when it is released.
24
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
25
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
26
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
27
+ end
28
+ spec.bindir = "exe"
29
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
30
+ spec.require_paths = ["lib"]
31
+
32
+ spec.add_runtime_dependency 'bencode'
33
+ spec.add_runtime_dependency 'colorize'
34
+ spec.add_development_dependency 'minitest', '~> 5.0'
35
+ spec.add_development_dependency 'rake', '~> 12.0'
31
36
  end
data/exe/alda-irb CHANGED
@@ -8,11 +8,13 @@ HOST = 'The hostname of the Alda REPL server; only useful in Alda 2; see `alda r
8
8
  PORT = 'The port of the Alda REPL server; only useful in Alda 2; see `alda repl --help`'.freeze
9
9
  NO_COLOR = 'Whether the output should not be colored'.freeze
10
10
  NO_PREVIEW = 'Whether a preview of what Alda code will not be played everytime you input ruby codes'.freeze
11
+ NO_RELINE = 'Whether to use Reline to read input'.freeze
11
12
 
12
13
  host = 'localhost'
13
14
  port = -1
14
15
  color = true
15
16
  preview = true
17
+ reline = true
16
18
 
17
19
  OptionParser.new do |opts|
18
20
  opts.banner = 'Usage: alda-irb [options]'
@@ -21,9 +23,10 @@ OptionParser.new do |opts|
21
23
  opts.on('-p', '--port int', PORT) { port = _1 }
22
24
  opts.on('-c', '--no-color', NO_COLOR) { color = false }
23
25
  opts.on('-P', '--no-preview', NO_PREVIEW) { preview = false }
26
+ opts.on('-r', '--no-reline', NO_RELINE) { reline = false }
24
27
  end.parse!
25
28
 
26
29
  Alda.deduce_generation
27
- opts = {color: color, preview: preview}
30
+ opts = { color: color, preview: preview, reline: reline }
28
31
  opts.merge! host: host, port: port unless Alda.v1?
29
32
  Alda::REPL.new(**opts).run
@@ -90,7 +90,9 @@ module Alda
90
90
  COMMANDS.each do |command, generations|
91
91
  define_method command do |*args, **opts|
92
92
  Alda::GenerationError.assert_generation generations
93
- Alda.pipe(command, *args, **opts, &:read).tap { raise CommandLineError.new $?, _1 if $?.exitstatus.nonzero? }
93
+ result = Alda.pipe command, *args, **opts, &:read
94
+ raise CommandLineError.new $?, result if $?.exitstatus.nonzero?
95
+ result
94
96
  end.tap { module_function _1 }
95
97
  end
96
98
 
@@ -154,8 +156,43 @@ module Alda
154
156
 
155
157
  @executable = 'alda'
156
158
  @options = {}
159
+ @env = {
160
+ 'ALDA_DISABLE_SPAWNING' => 'yes',
161
+ 'ALDA_DISABLE_TELEMETRY' => 'yes'
162
+ }
157
163
  v2!
158
164
 
165
+ ##
166
+ # :call-seq:
167
+ # env() -> Hash
168
+ # env(hash) -> Hash
169
+ # env(hash) { ... } -> Object
170
+ #
171
+ # When called with no arguments,
172
+ # returns the commandline environment variables (a Hash)
173
+ # used when running +alda+ on command line.
174
+ # It is <tt>{"ALDA_DISABLE_SPAWNING"=>"yes","ALDA_DISABLE_TELEMETRY"=>"yes"}</tt> by default
175
+ # (for speeding up the command line responses:
176
+ # {alda-lang/alda#368}[https://github.com/alda-lang/alda/issues/368]).
177
+ #
178
+ # When called with an argument +hash+,
179
+ # merge the old environment variables with +hash+ and set
180
+ # the merged Hash as the new environment variables.
181
+ # Returns the new environment variables (a Hash).
182
+ #
183
+ # When called with an argument +hash+ and a block,
184
+ # execute the block with the environment being set to the merge of the old environment
185
+ # and +hash+, and then restore the old environment.
186
+ # Returns the returned value of the block.
187
+ def env hash = nil, &block
188
+ if hash
189
+ @env = (old_env = @env).merge hash.map { |k, v| [k.to_s, v.to_s] }.to_h
190
+ block ? block.().tap { @env = old_env } : @env
191
+ else
192
+ @env
193
+ end
194
+ end
195
+
159
196
  ##
160
197
  # :call-seq:
161
198
  # pipe(command, *args, **opts) -> IO
@@ -165,7 +202,7 @@ module Alda
165
202
  # or pass the IO to the block.
166
203
  # See COMMANDS_FOR_VERSIONS for an explanation of +args+ and +opts+.
167
204
  def pipe command, *args, **opts, &block
168
- add_option = ->key, val do
205
+ add_option = ->((key, val)) do
169
206
  next unless val
170
207
  args.push "--#{Alda::Utils.snake_to_slug key}"
171
208
  args.push val.to_s unless val == true
@@ -180,8 +217,8 @@ module Alda
180
217
  # subcommand options
181
218
  opts.each &add_option
182
219
  # subprocess
183
- spawn_options = Alda::Utils.win_platform? ? {new_pgroup: true} : {pgroup: true}
184
- IO.popen args, **spawn_options, &block
220
+ spawn_options = Alda::Utils.win_platform? ? { new_pgroup: true } : { pgroup: true }
221
+ IO.popen Alda.env, args, **spawn_options, &block
185
222
  end
186
223
 
187
224
  ##
@@ -194,7 +231,7 @@ module Alda
194
231
  # and each Hash has the following keys:
195
232
  # - +:id+: the player-id of the process, a three-letter String.
196
233
  # - +:port+: the port number of the process, an Integer.
197
- # - +:state+: the state of the process, a Symbol (may be +nil+, +:ready+, +:active+ etc.).
234
+ # - +:state+: the state of the process, a Symbol (may be +nil+, +:ready+, +:active+, or +:starting+).
198
235
  # - +:expiry+: a human-readable description of expiry time of the process, a String (may be +nil+).
199
236
  # - +:type+: the type of the process, a Symbol (may be +:player+ or +:repl_server+).
200
237
  def processes
@@ -205,7 +242,7 @@ module Alda
205
242
  state = state == ?- ? nil : state.to_sym
206
243
  expiry = nil if expiry == ?-
207
244
  type = Alda::Utils.slug_to_snake type
208
- {id: id, port: port, state: state, expiry: expiry, type: type}
245
+ { id: id, port: port, state: state, expiry: expiry, type: type }
209
246
  end
210
247
  end
211
248
 
@@ -214,9 +251,9 @@ module Alda
214
251
  # up?() -> true or false
215
252
  #
216
253
  # Whether the alda server is up.
217
- # Always returns true if ::generation is +:v2+.
254
+ # Checks whether there are any play processes in ::processes in \Alda 2.
218
255
  def up?
219
- Alda.v2? || Alda.status.include?('up')
256
+ Alda.v1? ? Alda.status.include?('up') : Alda.processes.any? { _1[:type] == :player }
220
257
  end
221
258
 
222
259
  ##
@@ -224,9 +261,9 @@ module Alda
224
261
  # down? -> true or false
225
262
  #
226
263
  # Whether the alda server is down.
227
- # Always returns false if ::generation is +:v2+.
264
+ # Checks whether there are no play processes in ::processes in \Alda 2.
228
265
  def down?
229
- !Alda.v2? && Alda.status.include?('down')
266
+ Alda.v1? ? Alda.status.include?('down') : Alda.processes.none? { _1[:type] == :player }
230
267
  end
231
268
 
232
269
  ##
@@ -240,6 +277,6 @@ module Alda
240
277
  @generation = major == '1' ? :v1 : :v2
241
278
  end
242
279
 
243
- module_function :pipe, :processes, :up?, :down?, :deduce_generation
280
+ module_function :env, :pipe, :processes, :up?, :down?, :deduce_generation
244
281
 
245
282
  end
data/lib/alda-rb/error.rb CHANGED
@@ -58,15 +58,26 @@ class Alda::NREPLServerError < StandardError
58
58
  # This is an Array of String.
59
59
  attr_reader :problems
60
60
 
61
+ ##
62
+ # The status returned by the nREPL server.
63
+ # It is an Array of Symbol.
64
+ # Symbols must appear are +:done+, +:error+, and there may be +:unknown_op+.
65
+ attr_reader :status
66
+
61
67
  ##
62
68
  # :call-seq:
63
- # new(host, port, problems) -> Alda::NREPLServerError
69
+ # new(host, port, problems, status) -> Alda::NREPLServerError
64
70
  #
65
71
  # Creates a Alda::NREPLServerError object.
66
72
  # Raises Alda::GenerationError if the current generation is not \Alda 2.
67
- def initialize host, port, problems
73
+ def initialize host, port, problems, status
68
74
  Alda::GenerationError.assert_generation [:v2]
69
- super problems.join ?\n
75
+ @status = status.map { Alda::Utils.slug_to_snake _1 }
76
+ if @status.include? :unknown_op
77
+ super 'unknown operation'
78
+ else
79
+ super problems.join ?\n
80
+ end
70
81
  @host = host
71
82
  @port = port
72
83
  @problems = problems
data/lib/alda-rb/event.rb CHANGED
@@ -365,7 +365,7 @@ end
365
365
  # end
366
366
  #
367
367
  # You can operate a score by purely using inline lisp events.
368
- # The following example only works in Alda 1 due to breaking changes in Alda 2
368
+ # The following example only works in \Alda 1 due to breaking changes in \Alda 2
369
369
  # ({alda-lang/alda#483}[https://github.com/alda-lang/alda/issues/483],
370
370
  # {alda-lang/alda#484}[https://github.com/alda-lang/alda/issues/484]).
371
371
  #
@@ -152,8 +152,8 @@ module Alda::EventList
152
152
  #
153
153
  # Append the events of another Alda::EventList object here.
154
154
  # This method covers the disadvantage of alda's being unable to
155
- # import scores from other files.
156
- # See https://github.com/alda-lang/alda-core/issues/8.
155
+ # import scores from other files
156
+ # ({alda-lang/alda-core#8}[https://github.com/alda-lang/alda-core/issues/8]).
157
157
  def import event_list
158
158
  @events.concat event_list.events
159
159
  nil
@@ -239,7 +239,7 @@ class Alda::Score
239
239
  # Alda::Score.new { piano_; c; d; e }.play from: 1
240
240
  # # (plays only an E note)
241
241
  def play **opts
242
- Alda.play code: self, **opts
242
+ Alda.env(ALDA_DISABLE_SPAWNING: :no) { Alda.play code: self, **opts }
243
243
  end
244
244
 
245
245
  ##
data/lib/alda-rb/repl.rb CHANGED
@@ -222,6 +222,11 @@ class Alda::REPL
222
222
  # Whether a preview of what \Alda code will be played everytime you input ruby codes.
223
223
  attr_accessor :preview
224
224
 
225
+ ##
226
+ # Whether to use Reline for input.
227
+ # When it is false, the \REPL session will be less buggy but less powerful.
228
+ attr_accessor :reline
229
+
225
230
  ##
226
231
  # :call-seq:
227
232
  # new(**opts) -> Alda::REPL
@@ -230,6 +235,7 @@ class Alda::REPL
230
235
  # The parameter +color+ specifies whether the output should be colored (sets #color).
231
236
  # The parameter +preview+ specifies whether a preview of what \Alda code will be played
232
237
  # everytime you input ruby codes (sets #preview).
238
+ # The parameter +reline+ specifies whether to use Reline for input.
233
239
  #
234
240
  # The +opts+ are passed to the command line of <tt>alda repl</tt>.
235
241
  # Available options are +host+, +port+, etc.
@@ -240,12 +246,14 @@ class Alda::REPL
240
246
  # A new one will be started only if no existing server is found.
241
247
  #
242
248
  # The +opts+ are ignored in \Alda 1.
243
- def initialize color: true, preview: true, **opts
249
+ def initialize color: true, preview: true, reline: true, **opts
244
250
  @score = TempScore.new self
245
251
  @binding = @score.get_binding
246
- @lex = RubyLex.new
252
+ # IRB once changed the API of RubyLex#initialize. Take care of that.
253
+ @lex = RubyLex.new *(RubyLex.instance_method(:initialize).arity == 0 ? [] : [@binding])
247
254
  @color = color
248
255
  @preview = preview
256
+ @reline = reline
249
257
  setup_repl opts
250
258
  end
251
259
 
@@ -261,14 +269,12 @@ class Alda::REPL
261
269
  if Alda.v1?
262
270
  @history = StringIO.new
263
271
  else
264
- if opts[:port] && [nil, 'localhost', '127.0.0.1'].include?(opts[:host]) &&
265
- Alda.processes.any? { _1[:port] == opts[:port].to_i && _1[:type] == :repl_server }
266
- @port = opts[:port].to_i
267
- @host = opts[:host] || 'localhost'
268
- else
269
- @nrepl_pipe = Alda.pipe :repl, **opts, server: true
270
- /nrepl:\/\/(?<host>[a-zA-Z0-9._\-]+):(?<port>\d+)/ =~ @nrepl_pipe.gets
271
- @host = host
272
+ @port = (opts.fetch :port, -1).to_i
273
+ @host = opts.fetch :host, 'localhost'
274
+ unless @port.positive? && %w[localhost 127.0.0.1].include?(@host) &&
275
+ Alda.processes.any? { _1[:port] == @port && _1[:type] == :repl_server }
276
+ Alda.env(ALDA_DISABLE_SPAWNING: :no) { @nrepl_pipe = Alda.pipe :repl, **opts, server: true }
277
+ /nrepl:\/\/[a-zA-Z0-9._\-]+:(?<port>\d+)/ =~ @nrepl_pipe.gets
272
278
  @port = port.to_i
273
279
  Process.detach @nrepl_pipe.pid
274
280
  end
@@ -314,8 +320,8 @@ class Alda::REPL
314
320
  def message op, **params
315
321
  result = raw_message op: Alda::Utils.snake_to_slug(op), **params
316
322
  result.transform_keys! { Alda::Utils.slug_to_snake _1 }
317
- if result.delete(:status).include? 'error'
318
- raise Alda::NREPLServerError.new @host, @port, result.delete(:problems)
323
+ if (status = result.delete :status).include? 'error'
324
+ raise Alda::NREPLServerError.new @host, @port, result.delete(:problems), status
319
325
  end
320
326
  case result.size
321
327
  when 0 then nil
@@ -358,7 +364,9 @@ class Alda::REPL
358
364
  indent = 0
359
365
  begin
360
366
  result.concat readline(indent).tap { return unless _1 }, ?\n
361
- ltype, indent, continue, block_open = @lex.check_state result
367
+ # IRB once changed the API of RubyLex#check_state. Take care of that.
368
+ opts = @lex.method(:check_state).arity.positive? ? {} : { context: @binding }
369
+ ltype, indent, continue, block_open = @lex.check_state result, **opts
362
370
  rescue Interrupt
363
371
  $stdout.puts
364
372
  return ''
@@ -372,18 +380,25 @@ class Alda::REPL
372
380
  #
373
381
  # Prompts the user to input a line.
374
382
  # The parameter +indent+ is the indentation level.
375
- # Twice the number of spaces is already in the input field before the user fills in.
383
+ # Twice the number of spaces is already in the input field before the user fills in
384
+ # if #reline is true.
376
385
  # The prompt hint is different for zero +indent+ and nonzero +indent+.
377
386
  # Returns the user input.
378
387
  def readline indent = 0
379
388
  prompt = indent.nonzero? ? '. ' : '> '
380
389
  prompt = prompt.green if @color
381
- Reline.pre_input_hook = -> do
382
- Reline.insert_text ' ' * indent
383
- Reline.redisplay
384
- Reline.pre_input_hook = nil
390
+ if @reline
391
+ Reline.pre_input_hook = -> do
392
+ Reline.insert_text ' ' * indent
393
+ Reline.redisplay
394
+ Reline.pre_input_hook = nil
395
+ end
396
+ Reline.readline prompt, true
397
+ else
398
+ $stdout.print prompt
399
+ $stdout.flush
400
+ $stdin.gets chomp: true
385
401
  end
386
- Reline.readline prompt, true
387
402
  end
388
403
 
389
404
  ##
@@ -456,7 +471,9 @@ class Alda::REPL
456
471
  else
457
472
  if @nrepl_pipe
458
473
  if Alda::Utils.win_platform?
459
- system 'taskkill', '/f', '/pid', @nrepl_pipe.pid.to_s
474
+ unless IO.popen(['taskkill', '/f', '/pid', @nrepl_pipe.pid.to_s], &:read).include? 'SUCCESS'
475
+ Alda::Warning.warn 'failed to kill nREPL server; may become zombie process'
476
+ end
460
477
  else
461
478
  Process.kill :INT, @nrepl_pipe.pid
462
479
  end
@@ -7,5 +7,5 @@ module Alda
7
7
  # The version number of alda-rb.
8
8
  #
9
9
  # The same as that in alda-rb gem spec.
10
- VERSION = '0.3.0'
10
+ VERSION = '0.3.1'
11
11
  end
metadata CHANGED
@@ -1,15 +1,71 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: alda-rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ulysses Zhan
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-05-30 00:00:00.000000000 Z
12
- dependencies: []
11
+ date: 2023-06-03 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bencode
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: colorize
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '5.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '5.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '12.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '12.0'
13
69
  description:
14
70
  email:
15
71
  - UlyssesZhan@gmail.com
@@ -83,7 +139,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
83
139
  - !ruby/object:Gem::Version
84
140
  version: '0'
85
141
  requirements: []
86
- rubygems_version: 3.1.6
142
+ rubygems_version: 3.4.13
87
143
  signing_key:
88
144
  specification_version: 4
89
145
  summary: A Ruby library for live-coding music with Alda.