#!/bin/sh # # @(#) /u/des/src/duf/vip 1.10 97/11/13 13:45:25 # # vip: 'vi' a pipe # # Description: # 'vip' lets you use 'vi' (or the editor of your choice) # within a pileline. # # Usage: # vip [-no] [command] # # -n close stdin; # -o do not send output; # If command is not specified, stdin is used. # # Copyright (c) 1997 by Daniel E. Singer. All rights reserved. # Permission is granted to reproduce and distribute this program # with the following conditions: # 1) This copyright notice and the author identification below # must be left intact in the program and in any copies. # 2) Any modifications to the program must be clearly identified # in the source file. # # Written by Daniel E. Singer, Duke Univ. Dept of Computer Science, 5/30/95 # # Modifications: # # 12/06/96, D.Singer # added -o; # added use of VISUAL and EDITOR environment variables; # # 7/14/97, D.Singer # added -n; # reversed meaning of -o; # other cosmetic changes; # # 8/1/97, D.Singer # changed name from pvi to vip; # # 8/13/97, D.Singer # changed option processing to 'getopts'; # added use of TMPDIR environment variable; # # 8/21/97, D.Singer # oops!, 'getopts' doesn't seem to be universally available, # so some home-grown code has been added; # # 11/13/97, D.Singer # added some additional signal processing so can kill the pipeline # during the edit; #PATH='/bin:/usr/bin:/usr/ucb' #export PATH PROG=`basename $0` USAGE=" Usage: $PROG [ -no ] [ command ] Edit interactively in a pipeline. -n close stdin, if from the keyboard; -o do not send edited text to stdout; command command to run to produce initial text for editing, otherwise stdin is used; " : ${TMPDIR:="/usr/tmp"} # where temp. files go TEMP_FILE="$TMPDIR/$PROG.$$" # temp. file to hold data to edit COMMAND="cat" # default command to produce input DFLT_ED="vi" # default editor ED="$DFLT_ED" # editor AWK=nawk # system annoyances SYS=`uname -sr` case "$SYS" in "Linux "*) AWK=awk ;; "HP-UX "*) AWK=awk esac # # get editor from the environment, if possible # if [ -n "$VISUAL" ]; then ED="$VISUAL" elif [ -n "$EDITOR" ]; then ED="$EDITOR" fi # # access to user only for temp. files # umask 077 # # clean up if certain signals caught; # see below for additional signal handling; # # the symbolic signals do not work on SunOS 4 #trap 'rm -f "$TEMP_FILE"; exit' HUP INT QUIT TERM #trap 'rm -f "$TEMP_FILE"; exit' 1 2 3 15 trap 'rm -f "$TEMP_FILE"; exit' 0 1 2 3 15 IN_OPT=0 # close input option OUT_OPT=0 # no output option COMMAND_OPT=0 # if command args given SYNTAX="$PROG: option syntax error." # # process command line options # while [ "$#" -gt 0 ]; do OPT="$1" case "$OPT" in -n) IN_OPT=1 ;; -o) OUT_OPT=1 ;; --) shift break ;; # unknown option -?) echo "$SYNTAX" >&2 echo "$USAGE" >&2 exit 1 ;; # compound option, break it up -??*) NEW_OPTS=`$AWK 'BEGIN { OPT_STR = "'"$OPT"'"; LEN = length(OPT_STR); NEW_OPTS = ""; STATUS = 0; for (POS=2; POS+0 <= LEN; ++POS) { OPT = substr(OPT_STR,POS,1); if (OPT !~ /[a-zA-Z0-9]/) STATUS = 1; NEW_OPTS = NEW_OPTS " -" OPT; } print NEW_OPTS; exit STATUS; }' <&-` || { echo "$SYNTAX" >&2 echo "$USAGE" >&2 exit 1 } shift if [ "$#" -gt 0 ]; then set -- $NEW_OPTS "$@" else set -- $NEW_OPTS fi continue ;; # end of options, just command arguments left *) break esac shift done # # if there are still arguments on the command line, # use them as a command to produce input; # if [ "$#" != '0' ]; then COMMAND="$*" COMMAND_OPT=1 fi # # dump input to a temp file, which will be edited and later deleted # if [ "$IN_OPT" = 1 -a -t 0 ]; then # # close stdin # exec <&- # # still try to run any specified command, hopefully # it doesn't need stdin # if [ "$COMMAND_OPT" = 1 ]; then eval "$COMMAND" > "$TEMP_FILE" else > "$TEMP_FILE" fi else eval "$COMMAND" > "$TEMP_FILE" fi # # change input to the keyboard for the edit # exec &1 exec >/dev/tty # # need a way to kill the edit session without having the pipeline continue; # if one of these signals is caught, send TERM to the process group; # trap 'clear; kill -15 0' 1 2 3 # # edit the temp file, might want to save it elsewhere... # $ED "$TEMP_FILE" STATUS="$?" # # deal appropriately with stdout, # then get rid of the temp file # if [ "$OUT_OPT" = 0 -a -f "$TEMP_FILE" ]; then cat "$TEMP_FILE" >&3 fi exec 3>&- exec >&- # this should happen on exit via the trap #rm -f "$TEMP_FILE" exit $STATUS