class

Reply::ExpressionEditor

Inherits Reference < Object

The ExpressionEditor allows to edit and display an expression.

Its main task is to provide the display of the prompt and a multiline expression within the term bounds, and ensure the correspondence between the cursor on screen and the cursor on the expression.

Usage example:

# new editor:
@editor = ExpressionEditor.new(
  prompt: ->(expr_line_number : Int32) { "prompt>" }
)

# edit some code:
@editor.update do
  @editor << %(puts "World")

  insert_new_line(indent: 1)
  @editor << %(puts "!")
end

# move cursor:
@editor.move_cursor_up
4.times { @editor.move_cursor_left }

# edit:
@editor.update do
  @editor << "Hello "
end

@editor.end_editing

@editor.expression # => %(puts "Hello World"\n  puts "!")
puts "=> ok"

# clear and restart edition:
@editor.prompt_next

The above displays:

prompt>puts "Hello World"
prompt>  puts "!"
=> ok
prompt>

Methods that modify the expression should be placed inside an update so the screen can be refreshed taking in account the adding or removing of lines, and doesn't boilerplate the display.

Constructors

new

Creates a new ExpressionEditor with the given prompt.

Source

Class methods

parts_from_colorized(line, width, prompt_size = 0)

Splits the given line (colorized) into parts delimited by wrapping.

Because line is colorized, it's hard to know when it's wrap based on its size (colors sequence might appear anywhere in the string) Here we does the following:

  • Create a String::Builder for the first part (part_builder)
  • Iterate over the line, parsing the color sequence
  • Count cursor x for each char unless color sequences
  • If count goes over term width: reset x to 0, and create a new String::Builder for next part.
Source

Instance methods

<<(char : Char) : self

Should be called inside an update.

If char is \n or \r, inserts a new line with indent 0. Does nothing if the char is an ascii_control?.

Source
<<(str : String) : self

Should be called inside an update.

Source
back

Should be called inside an update.

Source
clear_expression

Should be called inside an update.

Source
color=(color : Bool)
Source
color?
Source
current_line
Source
current_line=(line)

Should be called inside an update.

Source
current_word

Returns the word under the cursor following word_delimiters.

Source
current_word=(replacement)

Replaces the word under the cursor by replacement, then moves cursor at the end of replacement. Should be called inside an update.

Source
current_word_begin_end

Returns begin and end position of current_word.

Source
cursor_on_last_line?
Source
delete

Should be called inside an update.

Source
delete_after_cursor

Should be called inside an update.

Source
delete_before_cursor

Should be called inside an update.

Source
delete_line(y)

Should be called inside an update.

Source
delete_word

Should be called inside an update.

Source
empty?
Source
end_editing(replacement : Array(String) | Nil = nil)

Prints the full expression (without view bounds), and eventually replace it by replacement.

Source
expression
Source
expression_before_cursor(x = @x, y = @y)
Source
expression_height
Source
height

The editor height, if not set (nil), equal to term height.

Source
height=(height : Int32 | Nil)

The editor height, if not set (nil), equal to term height.

Source
insert_new_line(indent)

Should be called inside an update.

Source
lines
Source
move_cursor_down(allow_scrolling = true)
Source
move_cursor_left(allow_scrolling = true)
Source
move_cursor_right(allow_scrolling = true)
Source
move_cursor_to(x, y, allow_scrolling = true)
Source
move_cursor_to_begin(allow_scrolling = true)
Source
move_cursor_to_end(allow_scrolling = true)
Source
move_cursor_to_end_of_line(y = @y, allow_scrolling = true)
Source
move_cursor_up(allow_scrolling = true)
Source
move_word_backward
Source
move_word_forward
Source
next_line=(line)

Should be called inside an update.

Source
next_line?
Source
output
Source
output=(output : IO)
Source
previous_line=(line)

Should be called inside an update.

Source
previous_line?
Source
prompt_next

Clears the expression and start a new prompt on a next line.

Source
replace(lines : Array(String))
Source
scroll_down
Source
scroll_up
Source
set_header

Sets a Proc allowing to display a header above the prompt. (used by auto-completion)

io: The IO in which the header should be displayed. previous_height: Previous header height, useful to keep a header size constant. Should returns the exact height printed in the io.

Source
set_highlight

Sets the Proc to highlight the expression.

Source
update(force_full_view = false, &)

Refresh the screen.

It clears the display of the current expression, then yields for modifications, and displays the new expression.

if force_full_view is true, whole expression is displayed, even if it overflow the term width, otherwise the expression is bound and can be scrolled.

Source
update(force_full_view = false)
Source
width

The editor width, if not set (nil), equal to term width.

Source
width=(width : Int32 | Nil)

The editor width, if not set (nil), equal to term width.

Source
word_back

Should be called inside an update.

Source
word_delimiters

The list of characters delimiting words.

default: \n\t+-*/,;@&%<>"'^\\[](){}|.~:=!?

Source
word_delimiters=(word_delimiters : Array(Char))

The list of characters delimiting words.

default: \n\t+-*/,;@&%<>"'^\\[](){}|.~:=!?

Source
x

Tracks the cursor position relatively to the expression's lines, (y=0 corresponds to the first line and x=0 the first char) This position is independent of text wrapping so its position will not match to real cursor on screen.

| : cursor position

prompt>def very_looo
ooo|ng_name            <= wrapping
prompt>  bar
prompt>end

For example here the cursor position is x=16, y=0, but real cursor is at x=3,y=1 from the beginning of expression.

Source