/*
 * $Source: /source/LocalDeveloper/Apps/Vi/RCS/Vi.m,v $
 * $Revision: 1.2 $
 * $Date: 93/09/14 19:06:53 $
 * $State: Exp $
 * $Author: pbiron $
 *------------------------------------------------------------------
 * Paul Biron (pbiron@gslis.ucla.edu)
 * Graduate School of Library and Information Science
 * GSLIS Building
 * 300 Circle Dr. North
 * University of California, Los Angeles
 * Los Angeles, Ca. 90024
 *------------------------------------------------------------------
 * Every function in this file has a function header which has the
 * following format:
 *
 *     Name             : name of function
 *     Purpose          : 1 or 2 line statement of purpose
 *     Arguments        : names and purposes of all arguments
 *     Return Value     : what the function returns
 *     Calls            : NON-library functions called by this function
 *                        The name of the function is followed
 *                        (in parens) by the name of the file in which
 *                        the function is defined
 *     Globals Accessed : NON-library global variables/macros
 *                        used and/or modified by this function
 *                        The name of the variable is followed (in parens)
 *                        by the name of the file in which the variable
 *                        is declared (with the keyword "macro" if applicable)
 *     Notes            : Longer statement of purpose, notes on the
 *                        algorithm used, and other assorted information
 *                        helpfull to someone reading/calling the
 *                        function
 *
 *------------------------------------------------------------------
 * This file was edited with tab stops set to 4, so it may look
 * like a mess if you edit it with other tab stops
 *------------------------------------------------------------------
 * This "application" allows you to open various text files with vi(1)
 * from the Browser (or from within IB, etc).  In order for this to work
 * you must have Scott Hess's Stuart terminal emulator.  Stuart is a
 * replacement for Shell, and is Shareware, available from finer ftp
 * archives everywhere.
 * 
 * Vi is a sublcass of Application, which acts as its own "delegate"
 * for handline appAcceptsAnotherFile and app:openFile:fileType:
 * messages.
 *
 * The portions of this program (very little, in fact) that I wrote are in
 * the public domain, and you may do whatever you want with them.
 *------------------------------------------------------------------
 */

#ifndef SOIL
/*
 * location of soil binary
 */
#define SOIL "/usr/local/bin/soil"
#endif
#ifndef TERMDELAY
/*
 * see Notes: section of app:openFile:fileType:
 */
#define TERMDELAY 2000
#endif

#import "Vi.h"        // for class interface

#import <sys/param.h> // for MAXPATHLEN def
#import <libc.h>      // for fork(2), exec(2), etc. decl
#import <errno.h>

@implementation Vi : Application

/*
 * Name             : appAcceptsAnotherFile:
 * Purpose          : Notify the Workspace Manager that we can open
 *                    more files
 * Arguments        : sender -- id of message sender
 * Return Value     : YES
 * Calls            : none
 * IVars Accessed   : none
 * Globals Accessed : none
 * Notes            : none
 */
- (BOOL)
appAcceptsAnotherFile:sender
{
	return (YES) ;
}

/*
 * Name             : app:openFile:type:
 * Purpose          : Notification from the Workspace Manager that
 *                    we should open another file
 * Arguments        : fileName -- name of file to open
 *                    fileType -- ext of file to open
 * Return Value     : YES if successful, NO otherwise
 * Calls            : none
 * IVars Accessed   : none
 * Globals Accessed : SOIL (macro, Vi.m)
 *                    TERMDELAY (macro, Vi.m)
 * Notes            : Builds of the vi(1) command line for fileName,
 *                    fork(2)'s and execl(2)'s soil on that command line.
 *                    Then queue's up a terminate: message.
 *
 *                    Queuing the terminate: message is really a hack,
 *                    and is done because when multiple files are
 *                    launched from the Workspace the app only knows
 *                    about the first one from the command-line, so
 *                    we just keep waiting for the Workspace to tell
 *                    us to open another file or until some timeout
 *                    period has elasped, after which we assume that
 *                    no more requests are coming and terminate.
 */
- (int)
app:sender openFile:(char *) fileName type:(char *) fileType
{
	char vicmd[MAXPATHLEN] ;
	char title[MAXPATHLEN] ;
	int pid ;

	sprintf (vicmd, "/bin/sh -c \"/usr/ucb/vi %s\"", fileName) ;
	sprintf (title, "/usr/ucb/vi   %s", fileName) ;

	if ((pid = fork ()) == 0) {
		execl (SOIL, "soil", "-Shell", vicmd, "-Title", title,
			"-Activate", NULL) ;
		fprintf (stderr, "Vi: execl failed: %s: %s\n", SOIL, strerror (errno)) ;
		exit (1) ;
		}
	else if (pid == -1)
		perror ("Vi: fork failed") ;

	[self perform:@selector (terminate:) with:self
		afterDelay:TERMDELAY cancelPrevious:YES] ;

	return (YES) ;
}

@end
