Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make the up and down arrow keys show history entries in a script using zsh?

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.

like image 908
nachocab Avatar asked Sep 02 '15 15:09

nachocab


1 Answers

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

like image 60
Francisco Avatar answered Nov 04 '22 22:11

Francisco