[comp.os.vms] How to get multi-level command history to work?

stevesu@copper.TEK.COM (Steve Summit) (06/20/87)

Here's a new question, which I'm surprised hasn't been discussed
here already.  The version 4 terminal driver provides for recall
of the previous command line, and DCL somehow extends this to the
last 20 lines.  More recently, DEBUG and CMS (and probably
others) have also acquired the same functionality.

The obvious question is, how can I make my own interactive
applications interact with the terminal driver to provide deeper
command history?  I am sure that there are undocumented terminal
driver qio's which implement this, and I could go off and wade
through the fiche, but surely someone out there knows, and I'm
sure many people would be interested to hear how.

                                           Steve Summit
                                           stevesu@copper.tek.com

gwalker@SPCA.BBN.COM (Gail Rubin Walker) (06/24/87)

It probably hasn't been discussed before because it IS documented and
has been from the start. See the Terminal Drivers chapter of the
I/O Manual. I implemented 20 line recall in a program myself a few years
ago using only that documentation - no fiche reading. You get
to use a new (in VMS 4.0) form of $QIO read called an itemlist read and
you specify that you don't want the driver to do command line recall. Then
your program gets control when the user types up-arrow or ctrl-B (the terminator
returned to your program is ctrl-B whether they typed that or the up-arrow).
There is also a way to pre-fill the input (with a recalled line, for example).

The one thing I would caution you on - if you are modifying the input done
by existing programs, note that itemlist $QIOs have a different form of
I/O status block (IOSB) and the form IS also documented so be sure to check
your code if you use the IOSB.

-- Gail Walker, BBN

klb@philabs.Philips.Com (Ken Bourque) (06/24/87)

The screen management stuff now gives you 20 lines (I think) of command
recall.  Using it is probably the simplest way to get more than 1 line.  My
understanding is that the terminal driver gives you one line, DCL gives you 20
lines (using its own implementation) and SMG gives you 20 lines.  The VMS
utilities which acquired 20 line recall got it by using SMG.

klb@philabs.philips.com  -or-  seismo!philabs!klb  

"James_A._Gray.OsbuSouth"@XEROX.COM (06/25/87)

Here's a new question, which I'm surprised hasn't been discussed
here already.  The version 4 terminal driver provides for recall
of the previous command line, and DCL somehow extends this to the
last 20 lines.  More recently, DEBUG and CMS (and probably
others) have also acquired the same functionality.

The obvious question is, how can I make my own interactive
applications interact with the terminal driver to provide deeper
command history?  I am sure that there are undocumented terminal
driver qio's which implement this, and I could go off and wade
through the fiche, but surely someone out there knows, and I'm
sure many people would be interested to hear how.

	The answer to this question is to use SMG$READ_COMPOSED_LINE.
	The following sample program (FORTRAN) shows what needs to
	be done to use this feature in a program which does not use the
	SMG routines for screen I/O.  Note that it defines a 30 line recall
	buffer.

		Jim

	PROGRAM SMG
C
	PARAMETER
	1	RECALL_SIZE	= 30
C
	CHARACTER
	1	RECEIVED_TEXT*132
C
	INTEGER
	1	KEYBOARD_ID,
	1	KEY_TABLE_ID,
	1	RECEIVED_STRING_LENGTH,
	1	SMG$CREATE_KEY_TABLE,
	1	SMG$CREATE_VIRTUAL_KEYBOARD,
	1	SMG$DELETE_VIRTUAL_KEYBOARD,
	1	SMG$READ_COMPOSED_LINE,
	1	STATUS
C
	EXTERNAL
	1	SMG$_EOF
C
10	FORMAT (' Echo input: ',A)
C
	STATUS = SMG$CREATE_VIRTUAL_KEYBOARD (KEYBOARD_ID, , , , RECALL_SIZE)
	IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS))
	STATUS = SMG$CREATE_KEY_TABLE (KEY_TABLE_ID)
	IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS))
1000	STATUS = SMG$READ_COMPOSED_LINE (KEYBOARD_ID, KEY_TABLE_ID,
	1	RECEIVED_TEXT, 'SMG Demo> ', RECEIVED_STRING_LENGTH)
	IF (STATUS .EQ. %LOC(SMG$_EOF)) GOTO 9000
	IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS))
	WRITE (UNIT=*, FMT=10) RECEIVED_TEXT(1:RECEIVED_STRING_LENGTH)
	GOTO 1000
C
9000	STATUS = SMG$DELETE_VIRTUAL_KEYBOARD (KEYBOARD_ID)
	IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS))
	CALL EXIT
C
	END

jimp@cognos.uucp (Jim Patterson) (06/29/87)

In article <1150@copper.TEK.COM> stevesu@copper.UUCP (Steve Summit) writes:
>Here's a new question, which I'm surprised hasn't been discussed
>here already.  The version 4 terminal driver provides for recall
>of the previous command line, and DCL somehow extends this to the
>last 20 lines.
>
>The obvious question is, how can I make my own interactive
>applications interact with the terminal driver to provide deeper
>command history?  I am sure that there are undocumented terminal
>driver qio's which implement this,  someone out there knows, and I'm
>sure many people would be interested to hear how.

It's all documented in the I/O user's guide.  If you want to do this
at the QIO level, then you need to first disable automatic recall
using the option TRM$M_TM_NORECALL, and trap the recall sequence yourself.
A new terminal driver option called TRM$_INISTRNG allows you to
place your own initialization string into the buffer prior to
a terminal read; by keeping your own command history you can
remember which string to put into the buffer at which time.

However, SMG (DEC's SCREEN MANAGEMENT GRAPHICS) has already done all
of this, and DEBUG and CMS just use SMG.  By using the routine
SMG$READ_COMPOSED_LINE instead of whatever read routine you have been
using, you will automatically get 20-line recall.  You have to use the
associated routines for defining a virtual keyboard, etc, but it's all
described in the RTL manual.  As an added bonus you can set up your
own version of DEFINE/KEY to map the keyboard for your program.



-- 

Jim Patterson          decvax!utzoo!dciem!nrcaer!cognos!jimp
Cognos Incorporated    

healy@canisius.UUCP (Patrick Healy) (07/01/87)

In article <1292@briar.Philips.Com>, klb@philabs.Philips.Com (Ken Bourque) writes:
> The screen management stuff now gives you 20 lines (I think) of command
> recall.  Using it is probably the simplest way to get more than 1 line.  My
> understanding is that the terminal driver gives you one line, DCL gives you 20
> lines (using its own implementation) and SMG gives you 20 lines.  The VMS
> utilities which acquired 20 line recall got it by using SMG.
> 
> klb@philabs.philips.com  -or-  seismo!philabs!klb  

Ken,  this is undeniably correct other than the 20 lines that $SMG is merely
a default.  You can set an alternate value when you use the SMG$CREATE_
_VIRTUAL_KEYBOARD. The $SMG documentation gives a better description.

I also have a related question.  To use the SMG$RECALL_INPUT_LINE you must 
you must first have the Screen Management stuff running (ie. create a virtual
keyboard, save the physical screen etc.).  I'm trying to write a vms 'finger'
and would like to get the person's last command instead of using $GETJPI to 
find their image.  Is there a way to recall the last line of another process 
without using Screen Management utilities?  Possibly through IO$ calls? Any
chance of it being accessible through the device driver stuff?


Thanks!


-----------------------------------------------------------------------------
USMAIL:	Patrick Healy / Canisius College / 2001 Main St. / Buffalo, NY 14208
OFFICE: 42 55m 32s N / 78 51m 10s W / basement
VOICE:	(716) 883-7000 Extensions 440, 441, 446, 447 Eastern Time 
UUCP:	...!{decvax|watmath|allegra|rocksvax}!sunybcs!canisius!healy
 "					     ...!ames!canisius!healy
BITNET: HEALY@CANISIUS
CSNET:	healy%canisius@CSNET-relay
-----------------------------------------------------------------------------