Class: Fusion::CLI::Repl
- Inherits:
-
Object
- Object
- Fusion::CLI::Repl
- Defined in:
- lib/fusion/cli/repl.rb
Constant Summary collapse
- RESET =
"\e[0m"- LIGHT_BLUE =
"\e[94m"- GREEN =
"\e[32m"- RED =
"\e[31m"- PROMPT =
"#{LIGHT_BLUE}fsn> #{RESET}"- CONTINUATION_PROMPT =
"#{LIGHT_BLUE}...> #{RESET}"- VALUE_MARKER =
"#{GREEN}✔ #{RESET}"- ERROR_MARKER =
"#{RED}✗ #{RESET}"- SITE =
REPL entries report errors with the same site as inline (
-e) code. { origin: "code", file: "<inline>" }.freeze
Instance Method Summary collapse
-
#complete?(buffer) ⇒ Boolean
String -> yes/no.
-
#handle(buffer, environment) ⇒ Object
String (+ Env) -> String.
-
#initialize(root_env:) ⇒ Repl
constructor
A new instance of Repl.
- #run ⇒ Object
Constructor Details
#initialize(root_env:) ⇒ Repl
Returns a new instance of Repl.
25 26 27 |
# File 'lib/fusion/cli/repl.rb', line 25 def initialize(root_env:) @root_env = root_env end |
Instance Method Details
#complete?(buffer) ⇒ Boolean
String -> yes/no
62 63 64 65 66 67 |
# File 'lib/fusion/cli/repl.rb', line 62 def complete?(buffer) return true if buffer.strip.empty? ast = Fusion::Parser.parse_repl(buffer, site: SITE) ast.is_a?(AST::Expression) || ast.is_a?(AST::Statement::Assignment) end |
#handle(buffer, environment) ⇒ Object
String (+ Env) -> String
70 71 72 73 74 75 |
# File 'lib/fusion/cli/repl.rb', line 70 def handle(buffer, environment) ast = Fusion::Parser.parse_repl(buffer, site: SITE) runtime_value = CLI.evaluate(ast, environment) wire_pair = Serializer.serialize(runtime_value, lenient: true) Encoder.encode(wire_pair, mode: :bang) end |
#run ⇒ Object
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/fusion/cli/repl.rb', line 29 def run CLI.prepare! require "reline" Reline.output = $stderr Reline.prompt_proc = proc do |lines| lines.each_index.map { |i| i.zero? ? PROMPT : CONTINUATION_PROMPT } end # The session env is a child of the run's root, so it carries the jail; # bindings accumulate here while loaded files stay isolated at the root. environment = @root_env.child.set_context(:dir, Dir.pwd) loop do buffer = begin Reline.readmultiline(PROMPT, true) { complete?(_1) } rescue Interrupt $stderr.puts("^C") # discard the half-typed entry and re-prompt next end break if buffer.nil? # Ctrl-D on an empty line ends the session next if buffer.strip.empty? output = handle(buffer, environment) marker = output.start_with?("!") ? ERROR_MARKER : VALUE_MARKER $stderr.print(marker) # decoration on stderr $stdout.puts(output) # the clean value on stdout end end |