class Reply::ExpressionEditor

Overview

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.

Defined in:

expression_editor.cr

Constructors

Instance Method Summary

Constructor Detail

def self.new(&prompt : Int32, Bool -> String) #

Creates a new ExpressionEditor with the given prompt.


[View source]

Instance Method Detail

def <<(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?.


[View source]
def <<(str : String) : self #

Should be called inside an #update.


[View source]
def back #

Should be called inside an #update.


[View source]
def clear_expression #

Should be called inside an #update.


[View source]
def color=(color : Bool) #

[View source]
def color? : Bool #

[View source]
def current_line #

[View source]
def current_line=(line) #

Should be called inside an #update.


[View source]
def current_word #

Returns the word under the cursor following #word_delimiters.


[View source]
def 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.


[View source]
def current_word_begin_end #

Returns begin and end position of #current_word.


[View source]
def cursor_on_last_line? #

[View source]
def delete #

Should be called inside an #update.


[View source]
def delete_after_cursor #

Should be called inside an #update.


[View source]
def delete_before_cursor #

Should be called inside an #update.


[View source]
def delete_line(y) #

Should be called inside an #update.


[View source]
def delete_word #

Should be called inside an #update.


[View source]
def empty? #

[View source]
def end_editing(replacement : Array(String) | Nil = nil) #

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


[View source]
def expression : String | Nil #

[View source]
def expression_before_cursor(x = @x, y = @y) #

[View source]
def expression_height : Int32 | Nil #

[View source]
def height #

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


[View source]
def height=(height : Int32 | Nil) #

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


[View source]
def insert_new_line(indent) #

Should be called inside an #update.


[View source]
def lines : Array(String) #

[View source]
def move_cursor_down(allow_scrolling = true) #

[View source]
def move_cursor_left(allow_scrolling = true) #

[View source]
def move_cursor_right(allow_scrolling = true) #

[View source]
def move_cursor_to(x, y, allow_scrolling = true) #

[View source]
def move_cursor_to_begin(allow_scrolling = true) #

[View source]
def move_cursor_to_end(allow_scrolling = true) #

[View source]
def move_cursor_to_end_of_line(y = @y, allow_scrolling = true) #

[View source]
def move_cursor_up(allow_scrolling = true) #

[View source]
def move_word_backward #

[View source]
def move_word_forward #

[View source]
def next_line=(line) #

Should be called inside an #update.


[View source]
def next_line? #

[View source]
def output : IO #

[View source]
def output=(output : IO) #

[View source]
def previous_line=(line) #

Should be called inside an #update.


[View source]
def previous_line? #

[View source]
def prompt_next #

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


[View source]
def replace(lines : Array(String)) #

[View source]
def scroll_down #

[View source]
def scroll_up #

[View source]
def set_header(&header : IO, Int32 -> Int32) #

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_hight: Previous header height, useful to keep a header size constant. Should returns the exact height printed in the io.


[View source]
def set_highlight(&highlight : String -> String) #

Sets the Proc to highlight the expression.


[View source]
def 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.


[View source]
def update(force_full_view = false) #

[View source]
def width #

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


[View source]
def width=(width : Int32 | Nil) #

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


[View source]
def word_back #

Should be called inside an #update.


[View source]
def word_delimiters : Array(Char) #

The list of characters delimiting words.

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


[View source]
def word_delimiters=(word_delimiters : Array(Char)) #

The list of characters delimiting words.

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


[View source]
def x : Int32 #

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.


[View source]
def y : Int32 #

[View source]