1

I am using an enhanced kotlin REPL and have entered a multi-line code snippet:

$rlwrap bin/ki.sh
ki-shell 0.3/1.4.21
type :h for help
[0] fun reformat(
    str: String,
    normalizeCase: Boolean = true,
    upperCaseFirstLetter: Boolean = true,
    divideByCamelHumps: Boolean = false,
    wordSeparator: Char = ' ',
)
 {
  println("In reformat")
}

If you were observant you may have noticed that the kotlin shell had been "wrapped" with rlwrap. I had hoped that would provide a single keystroke to scroll past that multi-line command. However as can be seen in the following screenshot the up-arrow key (and likewise shift- or option- or command- or control- up-arrow) only moves up a single line at a time

enter image description here

So is there any such wrapper for REPL-like utilities that will enable multi-line scrolling?

Note that the scala REPL does have the multi-line scrolling as does ipython under certain circumstances (in my case only under iTerm but not under Terminal).

I am on macOS Catalina but expect the answer would apply equally to most *NIX variants.

WestCoastProjects
  • 58,982
  • 91
  • 316
  • 560

1 Answers1

1

From the rlwrap manual:

-m, --multi-line [newline_substitute]
  Enable  multi-line input using a "newline substitute" character
  sequence (" \ ", [space-backslash-space] by default). Newline sub‐
  stitutes are translated to newlines before sending the input to 
  command.  With this option, you can call an external  editor  
  $RLWRAP_EDITOR  on  the  (expanded)  current  input  with the    
  rlwrap_call_editor key (CTRL-^ by default)

When using rlwrap -m, pressing CTRL+^ will drop you into an editor where you can edit your multi-line snippet. Upon exiting the editor, the snippet will be sent to the rlwrapped command, and also be put into the rlwrap history as one single line (with newlines replaced by the "newline substitute") Moving through history with and will still show those snippets as one single line, but you can expand them at any moment into multi-line text within your editor by pressing CTRL+^ again

Not exactly what you're looking for, but it does scroll entire multiline commands at a time, which I like better than e.g. ipython where you still (at least with the terminals I use) have to press a couple times to move past a large function definition.

Of course, as with any readline wrapper, there are donwsides: you will lose any context-sensitive completion your CLI might have had, and even the paltry rlwrap completion mechanism will not work within the multi-line-editor.

Setup:

It should work "out of the box" by just issuing

$ rlwrap -m -a <my_cli_command> # -a because your cli probably 
                                # does some line editing already

Some tweaks:

  • If you prefer a diffferent editor, add a line
    export RLWRAP_EDITOR='<my_editor_of_choice>[-opts] in your .bashrc. The default is vi +%L. %F, %L and %C in RLWRAP_EDITOR will be replaced by filename, line and column, respectively, in order to drop you into the editor at the very spot where the cursor was in rlwrap
  • To use a different editing hotkey, add a line like "\C-b":rlwrap-call-editor to ~/.inputrc (CTRL+^ is the default)
  • To use a different "newline substitute" (e.g. "||") , add an argument to -m like in rlwrap -m'||' (the default is ' \ ')
  • if your editor_of_choice does syntax colouring based on filename extensions, add an argument -M.ext (default: no extension)

For example:

export RLWRAP_EDITOR='my_edit --auto-save-on-exit %F:%L'
# ... or put the above in .bashrc
rlwrap -a -m': ' -M_bas QLSuperBasic # ... those were the days
Hans Lub
  • 5,513
  • 1
  • 23
  • 43
  • This looks v promising. I guess it would be necessary to find a `.kt` syntax file? I'm looking into that – WestCoastProjects Jan 19 '21 at 14:12
  • That depends on your editor. I'm an `emacs` guy, and for that there certainly exists a kotlin-"mode" . If you specify that the `.kt` file extension needs kotlin-mode Bob's your uncle.. – Hans Lub Jan 19 '21 at 14:21
  • Would you be able to piece together what the command line would be here? This seems to be heading towards/contain the correct answer but getting to a functioning result is quite challenging . I'm considering to ask a separate question about using `rlwrap` with kotlin – WestCoastProjects Jan 19 '21 at 14:31
  • I didn't have much luck with installing the kotlin shell, so I'll try to give a general roadmap. Be aware that with any readline wrapper you'll also _lose_ some functionality, like context-aware completion. – Hans Lub Jan 19 '21 at 22:51