Hello Crystalists, Crystalers, Crystalizers! (or any other name!)
I just released REPLy, a shard that provide a REPL’s reader. It’s something similar to readline or fancyline, which supports multiline input, history, input coloration, auto-completion and more. It was extracted from IC which is a repo that surround the crystal interpreter, and use the full potential of REPLy.
Here a minimal example:
require "reply"
reader = Reply::Reader.new
reader.read_loop do |expression|
# Eval expression here
puts " => #{expression}"
end
And how to customize the reader:
require "reply"
class MyReader < Reply::Reader
def prompt(io : IO, line_number : Int32, color? : Bool) : Nil
# Display a custom prompt
end
def highlight(expression : String) : String
# Highlight the expression
end
def continue?(expression : String) : Bool
# Return whether the interface should continue on multiline, depending of the expression
end
def format(expression : String) : String?
# Reformat when expression is submitted
end
def indentation_level(expression_before_cursor : String) : Int32?
# Compute the indentation from the expression
end
def word_delimiters : Regex
# Return the word delimiters used for pick the word for auto-completion
end
def save_in_history?(expression : String) : Bool
# Return whether the expression is saved in history
end
def auto_complete(name_filter : String, expression : String) : {String, Array(String)}
# Return the auto-completion result from expression
end
end
I would be very happy to hear feedback, and I am open to collaboration to improve the project!
I think as a shard is fine, the usage is not enough frequent for me to be in the sdt-lib, that would not prevent to be used for crystal-i as a shard though.
I consider support visit history is really useful for a REPL.
I have to add a alias to crystal as cr like this to use ic instead of crystal i
#!/bin/bash
case $(basename $0) in
cr)
case "$1" in
i)
if which ic &>/dev/null; then
ic "${@:2}"
else
crystal "$@"
fi
exit
;;
*)
command=crystal
esac
# ...
esac
;;
BTW: how to set C-n -> Down, C-p -> Up for ic as the binding used by linux shell?
I doesn’t yet implemented a way to customize hotkeys, all hotkeys are hard coded in REPLy. But, in a first time I could hard code these hotkeys as they seem to be common.
In fact, there still missing others quite common(useful) keybinding: (C is Ctrl, A is Alt)
C-f → forward char
A-f → forward word
C-b → back forward char
A-b → back forward word
C-d → delete after char on cursor. (exit to REPL only no char in current line)
A-d → delete after word on cursor.
A-Backspace → delete before word on cursor.
C-k → delete to end of line
C-u → delete to beginning of line.
You can reproduce those keybinding in any linux/mac shell or ruby IRB/Pry, as long as it is readline compatible.
But before implementing the keybinding, we should implementing the feature behind (forward word, delete after char on cursor, etc…). It would be not hard to do though.