#!/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;;'
