Skip to content

Instantly share code, notes, and snippets.

@tompng
Created August 5, 2024 09:35
Show Gist options
  • Save tompng/594c53af2b2b4be5091a846f425b563d to your computer and use it in GitHub Desktop.
Save tompng/594c53af2b2b4be5091a846f425b563d to your computer and use it in GitHub Desktop.
Text editor using reline
require 'irb'
require 'reline'
$status = nil
Reline::Face.config(:editor_status) do |face|
face.define :default, foreground: :white, background: :blue
end
Reline.add_dialog_proc :editor_status, ->(*) do
if (message = $status)
$status = nil
pos = Reline::CursorPos.new(cursor_pos.x, -1)
Reline::DialogRenderInfo.new(pos: pos, contents: message.lines, face: :editor_status)
end
end
def edit(file)
Reline.prompt_proc = ->(lines) do
n = [(lines.size + 1).to_s.size, 3].max
format = "%0#{n}d> "
(1..lines.size).map { format % _1 }
end
Reline::LineEditor.define_method(:_editor_save) do |_key|
begin
File.write(file, whole_buffer)
$status = "Saved to #{file}"
rescue => e
$status = "Failed to save to #{file}\n#{e.message}"
end
end
Reline.pre_input_hook = -> do
Reline.core.config.instance_eval do
emacs = @additional_key_bindings[:emacs]
emacs.add("\C-s".bytes, :_editor_save)
emacs.add("\r".bytes, :key_newline)
end
if File.exist?(file)
code = File.read(file)
Reline.line_editor.instance_variable_set(:@buffer_of_lines, code.split("\n"))
end
end
if file =~ /\.rb$/
Reline.output_modifier_proc = ->(output, complete:) do
IRB::Color.colorize_code(output, complete: complete, local_variables: [])
end
Reline.auto_indent_proc = ->(lines, line_index, byte_pointer, is_newline) do
return nil if lines == [nil] # Workaround for exit IRB with CTRL+d
return nil if !is_newline && lines[line_index]&.byteslice(0, byte_pointer)&.match?(/\A\s*\z/)
code = lines[0..line_index].map { |l| "#{l}\n" }.join
tokens = RubyLex.ripper_lex_without_warning(code, local_variables: [])
RubyLex.new.process_indent_level(tokens, lines, line_index, is_newline)
end
end
begin
Reline.readmultiline { false }
rescue Interrupt
end
end
file = ARGV[0]
unless file
puts 'file=ARGV[0] missing'
exit
end
puts "Editing file #{file}"
puts 'Save: C-s'
puts 'Exit: C-c'
puts
edit file
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment