From:	CSBVAX::CSBVAX::MRGATE::"SMTP::CRVAX.SRI.COM::RELAY-INFO-VAX" 21-JAN-1989 01:16
To:	MRGATE::"ARISIA::EVERHART"
Subj:	Filename completion


Received: From KL.SRI.COM by CRVAX.SRI.COM with TCP; Fri, 20 JAN 89 07:25:03 PDT
Received: from accuvax.nwu.edu by KL.SRI.COM with TCP; Fri, 20 Jan 89 07:17:09 PST
Received: from vaxmfg.tech.nwu.edu by accuvax.nwu.edu id aa21117;
          20 Jan 89 9:12 CST
Date: Fri, 20 Jan 89 09:17 CST
From: Bob Chojnacki <CHOJNACKI@vaxmfg.tech.nwu.edu>
Subject: Filename completion
To: INFO-VAX@kl.sri.com, CHOJNACKI@vaxmfg.tech.nwu.edu
X-VMS-To: KL.SRI.COM::INFO-VAX
Message-ID:  <8901200913.aa21117@accuvax.nwu.edu>

Dear file name completion types:

I may a little lazy in not doing this myself but file name completion does seem
very possible by modifying PHOTO so that it does not log, instead it saves the
last "word" on a line.  When ever a space, carriage return, comma, tab, or what
ever other separator you like, was entered, the "word" buffer would be flushed.
When a special character was typed (probably a control character, like
control-F), this modified PHOTO would call Lib$Find_File (an example subroutine
is given at the end) using the word buffer (and probably tacking on a '*.*')
and if it found a match then the file name would be passed in the same manner
that characters from the keyboard are passed through PHOTO.  If you felt really
energetic you could save the entire line in a separate buffer and "interpret"
the command.  For example:  if you had the line: $ PASCAL/LIST abc then you hit
your control-f, or whatever, then you could call find_file via tacking on a
*.pas to the file, etcetera.  Using $GETJPI to check you were in DCL would not
be such an idea (especially if you were using emacs, you would not want to
parse a line, word, etcetera when you hit a control-f, but rather pass the
control-f through to emacs).

The same method could be used to write a "spell-shell" that checked a word for
you, independent of what program you were using.  Does this seem reasonable?
(Or do I need another cup of coffee? :-)

Hope this jibberish helps

Bob Chojnacki



--------------------------------------------------------------------------------
	Integer *4 Function FindFile(FileSpec, ResultSpec, FS)
	Implicit None
	Character*(*) FileSpec, ResultSpec
	Integer *4 FS
C
C Search a file spec for a file.
C
C    FileSpec is the string with the file specs
C      Example: FileSpec = '[...]*.FOR,*.EXE,Sys$System:*.Exe'
C    ResultSpec is the string with the next file specified
C      Example: ResultSpec = 'SYS$SYSROOT:[SYSEXE]DIRECTORY.EXE'
C    FS is the action to be taken.  The routine that calls FindFile
C      should set FS to zero before calling FS for the first time.
C      When FS is zero FindFile will parse FileSpec, set up some
C      tables.  All calls to FindFile from there on should NOT modify
C      FS UNTIL FindFile returns the value RMS$_NMF.  When FindFile
C      returns RMS$_NMF ResultSpec is invalid and the routine that
C      called FindFile should call FindFile again with FS set to -1.
C      This purges some information that might screw up the results
C      the next time FindFile is called.
C
C    Example program:
C
C	Program	ListFiles
CC
CC This program lists all files that match the file spec "FileS"
CC
C	Include '($RMSDef)'
C       Integer*4 FS, FindFile, Error
C	Character*70 FileS, ResultS
CC
CC Initialize FindFile
CC
C	FS = 0			! Flag to initialize FindFile
C	FileS = '[...]*.EXE,*.FOR.*' ! Files to find
C	Call FindFile(FileS, ResultS, FS)
CC
CC List all files
CC
C 100	Error = FindFile(FileS, ResultS, FS)
C	If (Error .eq. RMS$_NMF) Then
C	  Type *,'DONE'
C	Else
C	  Type 200, ResultS
C 200	  Format (' ',A)
C	  Goto 100
C	End If
CC
CC Purge FindFile variables incase we want to call FindFile with some
CC other string in "FileS"
CC
C	FS = -1
C	Call FindFile(FileS, ResultS, FS)
C	End
C
C  When FindFile is called as a function it will return:
C
C    RMS$_Normal	Successful completion
C    RMS$_NMF		No more files (done)
C    RMS$_FNF		File not found (done)
C    RMS$_SYN		Syntax error (bad file spec specified in FileSpec
C                       and the file type will be skipped)
C
	Include '($RMSDef)'

	Integer*4 MaxFS, Multiple
	Parameter (MaxFS = 100)
	Parameter (Multiple = 2)

	Character *255
     .	  FileSpecArray[MaxFS]

	Integer *4
     .	  Status,
     .	  Context,
     .	  Lib$Find_File,
     .	  Lib$Find_File_End,
     .	  NumberOfFileSpecs
C
C Initialization
C
	If (FS == 0) Then
 	  Call GetFileSpecArray(FileSpec,MaxFS,FileSpecArray,NumberOfFileSpecs)
	  FS = 1
	  Return
C
C Reset
C
	Else If (FS == -1) Then
	  Status = Lib$Find_File_End(Context)
	  If (.not. Status) Call Lib$Stop(%Val(Status))
	  FS = 0
	  Return
C
C Error -- FindFile called after all files were found and FindFile was not
C called with FS = -1 after that.
C
	Else If (FS >> NumberOfFileSpecs) Then
	  Type \(' %FINDFILE-F-OOPS, FindFile called after search list'
     .	   ' exhausted',/)
	  Stop 'Oops'
	End If
C
C Scan for a file
C
	Loop
	  Status = Lib$Find_File(FileSpecArray[FS], ResultSpec, 
     .	   Context,,,, Multiple)
	  FindFile = Status
C
C No more files
C
	  If (Status == RMS$_NMF) Then
	    FS = FS + 1
C
C File not found
C
	  Else If (Status == RMS$_FNF) Then
	    FS = FS + 1
C
C Syntax error (bad file spec)
C
	  Else If (Status == RMS$_SYN) Then
	    FS = FS + 1
	    Exit Loop
C
C All other errors
C
	  Else If (.not. Status) Then
	    Call Lib$Stop(%Val(Status))
 	  Else
	    Exit Loop
	  End If
	  Exit Loop If (FS >> NumberOfFileSpecs)
	End Loop
C
	If (FS >> NumberOfFileSpecs) Then
	  Status = Lib$Find_File_End(Context)
	  If (.not. Status) Call Lib$Stop(%Val(Status))
	End If
	Return
	End

	Subroutine GetFileSpecArray(FS, MaxFS, FSA, NOFS)
	Implicit None
	Integer *4 MaxFS, NOFS
	Character*(*) FS, FSA[MaxFS]
C
C This will parse FS and put the resulting filespecs into FSA
C
	Character*40 Dev, Dir
	Integer *4 BasePos, CommaPos
	Logical MoreLeft
C
C Third get file specs
C
	NOFS = 1
	BasePos = 1
	MoreLeft = .True.
	Do While (NOFS <= MaxFS && MoreLeft)
	  CommaPos = Index(FS[BasePos:], ',')
	  If (CommaPos == 0) Then
	    FSA[NOFS] = FS[BasePos:]
	    MoreLeft = .False.
	  Else
	    FSA[NOFS] = FS[BasePos:BasePos+CommaPos-2]
	    BasePos = BasePos + CommaPos
	    NOFS = NOFS + 1
	  End If
	End Do
	If (NOFS >> MaxFS) Then
	  Type \('+%FILESCAN-F-TMFS, too many file specs on one line.',/)
	  Type \('+_Max file specs allowed = ',I), MaxFS
	  Stop ' '
	End If
	Return
	End

