New shard REPLy : A Reader for your REPL

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 =
reader.read_loop do |expression|
  # Eval expression here
  puts " => #{expression}"

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

  def highlight(expression : String) : String
    # Highlight the expression

  def continue?(expression : String) : Bool
    # Return whether the interface should continue on multiline, depending of the expression

  def format(expression : String) : String?
    # Reformat when expression is submitted

  def indentation_level(expression_before_cursor : String) : Int32?
    # Compute the indentation from the expression

  def word_delimiters : Regex
    # Return the word delimiters used for pick the word for auto-completion

  def save_in_history?(expression : String) : Bool
    # Return whether the expression is saved in history

  def auto_complete(name_filter : String, expression : String) : {String, Array(String)}
    # Return the auto-completion result from expression

I would be very happy to hear feedback, and I am open to collaboration to improve the project!


When this shards can be included with Crystal std-lib? as IRB with readline or reline.

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


case $(basename $0) in
        case "$1" in
                if which ic &>/dev/null; then
                    ic "${@:2}"
                    crystal "$@"
	# ...		

BTW: how to set C-n -> Down, C-p -> Up for ic as the binding used by linux shell?

1 Like

I think we could vendor this shard inside the compiler, to be used by the interpreter. I’ll play with it when I have some time.


Good the alias :slight_smile:

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.

It would be directly integrated in src/compiler/interpreter, or somewhere in the stdlib, like the highlighter? :slight_smile:

Yes, C-n/C-p quite common AFAIK.

could you please add it same as up/down arrow?

I do a little hack on my local, it works, such a surprise!

Following is PR, feel free to change or merge it.

BTW: we probably want to mention the keybinding of Up/Down/C-p/C-n in ic’s README.

1 Like

I was implementing on my side too, did exactly the same thing :sweat_smile:, I was just adding some spec for it.


Cool! i closed my PR, thank you very much.

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.

anyway, we can add those feature smoothly.

I will create a feature request there.

1 Like

Yes, great!

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.

Probably just for the interpreter for now.

1 Like

Is there exists other cases for use this?

Thanks @I3oris , all above feature works now!