Skip to content

Commit

Permalink
New version 0.1.4
Browse files Browse the repository at this point in the history
Added Kernel#alda.
Now use Alda::[] to specify command options (not subcommand options)
  Alda[quiet: true].play code: 'piano: c d e f' # => ""
REPL is now colorful.
Added clear_history function in REPL.
Added CommandLineError#port.
Fixed the bug: raising CommandLineError or OrderError causes exiting REPL.
  • Loading branch information
UlyssesZh committed Apr 24, 2020
1 parent 2a72300 commit 2e97de8
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 18 deletions.
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
source "https://rubygems.org"

# Specify your gem's dependencies in alda-rb-rb.gemspec
gemspec

gem "rake", "~> 12.0"
gem "minitest", "~> 5.0"
gem "colorize"
4 changes: 2 additions & 2 deletions alda-rb.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Gem::Specification.new do |spec|
spec.name = "alda-rb"
spec.version = Alda::VERSION
spec.authors = ["Ulysses Zhan"]
spec.email = ["2938747508@qq.com"]
spec.email = ["UlyssesZhan@gmail.com"]

spec.summary = %q{A Ruby library for live-coding music with Alda.}
# spec.description = %q{TODO: Write a longer description or delete this line.}
Expand All @@ -18,7 +18,7 @@ Gem::Specification.new do |spec|

spec.metadata["homepage_uri"] = spec.homepage
spec.metadata["source_code_uri"] = spec.homepage
# spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
spec.metadata["changelog_uri"] = "https://github.com/UlyssesZh/alda-rb/releases"

# Specify which files should be added to the gem when it is released.
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
Expand Down
87 changes: 72 additions & 15 deletions lib/alda-rb.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
require 'stringio'
require 'irb/ruby-lex'
require 'alda-rb/version'
require 'colorize'

{
Array => -> { "[#{map(&:to_alda_code).join ' '}]" },
Expand Down Expand Up @@ -34,6 +35,18 @@ def to_s
end
end

module Kernel
# Runs the alda command.
# Does not capture output.
# @example
# alda 'version'
# alda 'play', '-c', 'piano: a'
# alda 'repl'
def alda *args
system Alda.executable, *args
end
end

# The module serving as a namespace.
module Alda

Expand All @@ -60,15 +73,25 @@ module Alda
].freeze

COMMANDS.each do |command|
define_method command do |options = {}, **command_options|
args = []
block = ->key, val { args.push "--#{key.to_s.tr ?_, ?-}", val.to_s }
options.each &block
define_method command do |*args, **opts|
block = ->key, val do
next unless val
args.push "--#{key.to_s.tr ?_, ?-}"
args.push val.to_s unless val == true
end
# executable
args.unshift Alda.executable
args.map! &:to_s
# options
Alda.options.each &block
# subcommand
args.push command.to_s
command_options.each &block
output = IO.popen [Alda.executable, *args], &:read
raise CommandLineError.new $?, output if $?.exitstatus.nonzero?
output
# subcommand options
opts.each &block
# subprocess
IO.popen(args, &:read).tap do
raise CommandLineError.new $?, _1 if $?.exitstatus.nonzero?
end
end
end

Expand All @@ -79,6 +102,9 @@ module Alda
singleton_class.attr_accessor :executable
@executable = 'alda'

singleton_class.attr_reader :options
@options = {}

# @return Whether the alda server is up.
def up?
status.include? 'up'
Expand All @@ -96,6 +122,18 @@ def self.repl
REPL.new.run
end

# Sets the options of alda command.
# Not the subcommand options.
def self.[] **opts
@options.merge! opts
self
end

# Clears the command line options.
def self.clear_options
@options.clear
end

# Including this module can make your class have the ability
# to have an event list.
# See docs below to get an overview of its functions.
Expand Down Expand Up @@ -348,6 +386,10 @@ def history
@session.history.to_s
end

def clear_history
@session.clear_history
end

def get_binding
binding
end
Expand Down Expand Up @@ -384,7 +426,7 @@ def start
def rb_code
result = ''
begin
buf = Readline.readline '> ', true
buf = Readline.readline '> '.green, true
return unless buf
result.concat buf, ?\n
ltype, indent, continue, block_open = @lex.check_state result
Expand Down Expand Up @@ -412,7 +454,7 @@ def process_rb_code code
end
code = @score.events_alda_codes
unless code.empty?
$stdout.puts code
$stdout.puts code.yellow
play_score code
end
true
Expand All @@ -423,7 +465,7 @@ def try_command # :block:
begin
yield
rescue CommandLineError => e
puts e
puts e.message.red
end
end

Expand All @@ -448,17 +490,32 @@ def clear_history

# The error is raised when one tries to
# run a non-existing subcommand of +alda+.
class CommandLineError < Exception
class CommandLineError < StandardError

# The <tt>Process::Status</tt> object representing the status of
# the process that runs +alda+ command.
attr_reader :status

# The port on which the problematic Alda server runs.
# @example
# begin
# Alda.play({port: 1108}, code: "y")
# rescue CommandLineError => e
# e.port # => 1108
# end
attr_reader :port

# Create a CommandLineError# object.
# @param status The status of the process running +alda+ command.
# @param msg The exception message.
def initialize status, msg = nil
super /ERROR\s*(?<message>.*)$/ =~ msg ? message : msg&.lines(chomp: true).first
if match = msg&.match(/^\[(?<port>\d+)\]\sERROR\s(?<message>.*)$/)
super match[:message]
@port = match[:port].to_i
else
super msg
@port = nil
end
@status = status
end
end
Expand All @@ -469,9 +526,9 @@ def initialize status, msg = nil
# Alda::Score.new do
# motif = f4 f e e d d c2
# g4 f e d c2 # It commented out, error will not occur
# c4 c g g a a g2 motif # OrderError
# c4 c g g a a g2 motif # (OrderError)
# end
class OrderError < Exception
class OrderError < StandardError

# The expected element gotten if it is of the correct order.
# @see #got
Expand Down
File renamed without changes.

0 comments on commit 2e97de8

Please sign in to comment.