Commit e0eee5b
Changed files (1)
lib
elelem
builtins
lib/elelem/builtins/terminal.rb
@@ -2,7 +2,50 @@
module Elelem
module Builtins
- class Terminal < Elelem::Terminal
+ class Terminal
+ def initialize(stream: $stdout, **)
+ @stream = stream
+ @dots_thread = nil
+ @at_line_start = true
+ end
+
+ def say(text, as: nil)
+ stop_dots
+ return if blank?(text)
+
+ text = render(text, as) if as
+ write "#{text}\n"
+ @at_line_start = true
+ end
+
+ def print(text)
+ stop_dots
+ return if blank?(text)
+
+ write text
+ @at_line_start = false
+ end
+
+ def thinking(text)
+ print("\e[2;3m#{text}\e[0m") unless blank?(text)
+ end
+
+ def doing(name, args, state: "+")
+ gap
+ say "#{state} \e[36m#{name}\e[0m(#{args})"
+ end
+
+ def waiting
+ stop_dots
+ @dots_thread = Thread.new do
+ loop do
+ @stream.print "."
+ @stream.flush
+ sleep 0.1
+ end
+ end
+ end
+
def display_file(path, fallback: nil)
system("bat", "--paging=never", path) || say(fallback || path)
end
@@ -10,7 +53,8 @@ module Elelem
private
def render(text, as)
- return super unless as == :markdown
+ return "\n ✗ #{text}" if as == :error
+ return text unless as == :markdown
gap
width = @stream.winsize[1] rescue 80
@@ -23,8 +67,23 @@ module Elelem
text
end
+ def gap
+ stop_dots
+ write("\n") unless @at_line_start
+ @at_line_start = true
+ end
+
+ def stop_dots
+ return unless @dots_thread
+
+ @dots_thread.kill
+ @dots_thread = nil
+ write("\n")
+ @at_line_start = true
+ end
+
def write(text)
- super
+ @stream.print text
(@transcript ||= open_transcript).print text
end
@@ -34,6 +93,10 @@ module Elelem
session_id = "#{Time.now.utc.strftime("%Y%m%dT%H%M%SZ")}-#{Process.pid}"
File.open(File.join(state_dir, "#{session_id}.transcript"), "a").tap { |f| f.sync = true }
end
+
+ def blank?(text)
+ text.nil? || text.to_s.strip.empty?
+ end
end
end
end