caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Aaron Bohannon <bohannon@seas.upenn.edu>
To: OCaml List <caml-list@inria.fr>
Subject: [Caml-list] ocaml top-level line editing script
Date: Wed, 4 Jul 2012 13:06:15 -0400	[thread overview]
Message-ID: <CANghcebYMmAMwvooRAPm2QONn2pCBEzwUgF29K5PN+3cWr1Y6Q@mail.gmail.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 914 bytes --]

Hi,

One thing that is missing from the OCaml top level loop is line
editing features.  I used to use a wrapper program called "ledit" that
added readline support, but I never seem to have it installed on my
machine when I need it, and moreover, I have started to get used to
the more flexible line editing of zsh.

After some poking around, I found that it's fairly straightforward to
wrap any REPL with a zsh script and get zsh line editing capabilities,
which includes multi-line support (e.g., so you can fix a typo you
made three lines back).

I'm attaching the script I hacked together, in case it is useful to
anyone else.  It works great for me, but it was not written to be
generic and robust, so YMMV.  You must use ctrl-D to exit cleanly -- I
didn't bother adding support for "#quit".  I'm sure someone could make
many improvements to it if they had more patience for zsh scripting
than I do.

 - Aaron

[-- Attachment #2: zcaml --]
[-- Type: application/octet-stream, Size: 1173 bytes --]

#!/usr/bin/env zsh

# Simple wrapper function for "ocaml" that adds zsh line editing capabilities.
# Based on the "nslookup" example distributed with zsh.

setopt localoptions localtraps

local input output

zmodload -e zsh/zpty || zmodload -i zsh/zpty

trap 'return 130' INT
trap 'zpty -d ocaml' EXIT

zpty ocaml command ocaml

zpty -r ocaml output '*
# '
printf "%s" "$output"

bindkey -N viins-copy viins
bindkey -N vicmd-copy vicmd

# some mappings that I like
bindkey -M viins-copy "^A" vi-beginning-of-line
bindkey -M viins-copy "^E" vi-end-of-line
bindkey -M viins-copy "^P" history-beginning-search-backward
bindkey -M viins-copy "^N" history-beginning-search-forward

# use ctrl-\ to enter a newline -- afterward, you can still edit previous lines
bindkey -M viins-copy -s "^\\" "^V^J"

while input=''; vared -he -p '# ' -M viins-copy -m vicmd-copy input; do
  # add line to zsh history
  print -s "$input"
  # break on ctrl-D (I think?)
  [[ "$input" = EXIT ]] && break
  # ";;" is added because this loop will hang if we don't get back to a prompt
  zpty -w ocaml "$input;;"
  zpty -r ocaml output '(|*
)# '
  printf "%s" "$output"
done

zpty -w ocaml '#quit;;'

             reply	other threads:[~2012-07-04 17:06 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-07-04 17:06 Aaron Bohannon [this message]
2012-07-04 17:56 ` "Markus W. Weißmann"
2012-07-05  1:46   ` Aaron Bohannon
2012-07-05  4:25     ` Aaron Bohannon
2012-07-04 18:24 ` rixed
2012-07-04 21:19   ` Anthony Tavener

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CANghcebYMmAMwvooRAPm2QONn2pCBEzwUgF29K5PN+3cWr1Y6Q@mail.gmail.com \
    --to=bohannon@seas.upenn.edu \
    --cc=caml-list@inria.fr \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).