11

As shown in this answer, it's possible to use read with Readline (-e) in bash to return previous history items by using the up and down keys:

#! /usr/bin/env bash

while IFS="" read -p "input> " -e line; do 
    history -s "$line" # append $line to local history
done

What is the right way to do this in zsh? (getting user input on a loop and allowing for up/down key history completion). This doesn't work:

#! /usr/bin/env zsh

while IFS="" vared -p "input> " -c line; do 

done

I think history completion is disabled by default on scripts in zsh. Also, I don't want the history to come from the shell, but from the input that is entered in the script.

Community
  • 1
  • 1
nachocab
  • 13,328
  • 21
  • 91
  • 149

1 Answers1

2

I think you're asking for something along these lines... untested

#! /bin/zsh -i

local HISTFILE
# -p push history list into a stack, and create a new list
# -a automatically pop the history list when exiting this scope...
HISTFILE=$HOME/.someOtherZshHistoryFile
fc -ap # read 'man zshbuiltins' entry for 'fc'

while IFS="" vared -p "input> " -c line; do 
   print -S $line # places $line (split by spaces) into the history list...
done

[EDIT] Notice I added -i to the first line (#!). It is merely a way to indicate that the shell must be running in interactive mode. The best way to achieve this is to simply execute the script with zsh -i my-script.zsh, because passing arguments to #! commands differs between Linux and OSX, so it is in principle something one should not rely on.

Honestly, why don't you just start a new interactive shell using some custom configuration and (should it be necessary) hooks between commands? The best way to achieve this is likely to just start a new shell using different config files a new history.

This is a much better way to do this:

 mkdir ~/abc
 echo "export HISTFILE=$HOME/.someOtherZshHistoryFile;autoload -U compinit; compinit" >! ~/abc/.zshrc
 ZDOTDIR=~/abc/ zsh -i

you can then change the script's config file to perform any other customisation you need (different color prompt, no history saving etc).

To actually do things with the user input, you should use one of the many hooks handled by add-zsh-hook

Francisco
  • 3,980
  • 1
  • 23
  • 27
  • Thanks for the answer! `setopt interactive` doesn't work though. – nachocab Sep 08 '15 at 12:43
  • indeed that doesn't work. That flag can't be set once the shell is up and running. I made a slight edit to the script. In any case, you really should just be using a normal interactive shell, no config files – Francisco Sep 09 '15 at 08:14
  • Hmm, it still doesn't work (I'm on OSX, and I get a beep when I use the arrow keys). The reason why I'm not running it as a new shell is because this is just a toy example. The actual script does other things with the user inputs. – nachocab Sep 09 '15 at 08:49
  • Add a hook with `add-zsh-hook` and have that append a function call to commands, or just execute something when adding to the history. – Francisco Sep 09 '15 at 09:32