2

I'm using RLWrap to "tame" a really good REPL, Dyalog APL, that unfortunately had its origins in Windows land and therefore does not comply with UNIX conventions. Moreover, being a closed source product, it cannot be modified to do so.

I managed to achieve most of my goals, but Ctrl-D still causes it to barf an error and keep running, while I would like it to cause a graceful exit, like any other REPL.

I looked into rlwrap options, as well as its filter API, for a way to intercept EOF coming from the user and translate it into a custom exit command, which would be )off in my case, but I couldn't find a way to do it.

My current alias:

alias dyalog='rlwrap -a -H ~/.dyalog_history /opt/mdyalog/17.0/64/unicode/dyalog -b -s'

Relevant options are:

  • -s tells Dyalog to start in a simple REPL mode, without taking control of the screen;
  • -a tells RLWrap to always remain in readline mode, ignoring Dyalog's attempts to read the input character by character.
Tobia
  • 17,856
  • 6
  • 74
  • 93

2 Answers2

0

The trick is to catch the return code from the read. Given how nested it is, I find it easiest to do this in a hidden file in the home directory.

To see how it works fully, I include a larger code block, but the core is on that line with the 'read' in it.

sCommand=""
while [ ! "$sCommand" == "exit" ]
do

    sHistory=~/.promptHistory
    sCommand=$(rlwrap -H $sHistory sh -c 'read -p "> " REPLY && echo $REPLY'; echo $? > ~/.hold)

    if [[ "$(cat ~/.hold)" -eq 1 ]]; then sCommand="exit"; fi

    if [ "$sCommand" == "exit" ]; then return; fi # Bail out if the user asked for exit.

    case $sCommand in

        # All useful commands intercepted here.  Let 'exit' flow through.

    esac

done

The magic is in getting the return code with $? and getting it into ~/.hold for safe keeping. From there, the rest is just code.

James Madison
  • 845
  • 1
  • 7
  • 18
0

Assuming that a "naked" dyalog responds to CTRL+D by exiting gracefully, you can make rlwrap pass this key directly to dyalog by adding the next few lines to your ~/.inputrc:

$if dyalog 
 "\C-d": rlwrap-direct-keypress
$endif

You may (or may not) have to issue

 $ stty eof undef

beforehand in the terminal you're using (to prevent CTRL+D from closing your stdin)

Hans Lub
  • 5,513
  • 1
  • 23
  • 43