BSD new tty driver: ^W (werase)

Jonathan Payne jpayne at cs.rochester.edu
Wed Apr 13 09:53:34 AEST 1988


In article <1051 at mcgill-vision.UUCP> mouse at mcgill-vision.UUCP (der Mouse) writes:

>Actually, this is an argument for putting full-fledged line editing
>into the tty driver (because people don't make mistakes only when
>typing to the shell).  But given the current architecture of the
>kernel, this is difficult to do right.  I guess it's time to redo the
>kernel.  Hmm, this project is getting bigger!
>
>					der Mouse
>
>			uucp: mouse at mcgill-vision.uucp
>			arpa: mouse at larry.mcrcim.mcgill.edu


It's not hard to implement a full-fledged line editor into the kernel.
Dave Corley and I did it for an Operating Systems class project last
spring.  Here's a description of the line editor we implemented in
Berkeley 4.3 Unix.

The line editor is a new line discipline for Berkeley 4.3BSD UNIX operating
system.  The reason for building the editor into the kernel is to provide
more than just the basic editing commands available with vanilla UNIX.
With the line editor enabled, users can do simple, but very useful,
intraline editing, without having to invoke an expensive text editor to do
so.  Because the line editor is built into the kernel, it is available to
all programs.  So when you're typing in your mail, for example, you can fix
simple typos quickly.

To enable the line editor, you type:

	stty led [tty-type]

The line editor uses several advanced features of terminal to position the
cursor and to clear the screen, etc.  Stty(1) uses termcap to get the
escape sequences the line editor uses, and then uses a new ioctl to copy
them into the kernel data structures.  By default stty uses the environment
variable TERM as the terminal type name, but if the optional argument
[tty-type] is specified, that name will be used instead.  The line editor
takes advantage of the following capabilities:

	ce	*			clear to end of line
	cl	*			clear screen
	ho	*			home cursor
	le	*			cursor left
	LE				multiple cursor left
	nd	*			NonDestructive space (cursor right)
	ND				multiple cursor right
	up	*			cursor up

Capabilities with '*' are ones which must exist in order for the line
editor to work correctly.  If your terminal can back space (^H) then "le"
is not required.  If your terminal has LE or ND capabilities then it would
definitely be worth defining them.  They must be in the form of a printf
format string, e.g., "\E[%dC".  If any of the *'d capabilites are missing,
stty will print an error message.  The line editor ignores padding
information.

If you specify "stty tabs" then the line editor will try to use tabs to
position the cursor (if it's the most optimal way to position the cursor).
For terminals with no ND or LE, this makes a big difference.

In conjunction with the line editor modification, changes to the C Shell
have been made to exploit the line editor.  In particular, there is a new
history/substitution '!' modifier, 'i', similar to 'p', which tells csh to
insert the text into the line editor rather than just print it to the
screen.  This is much better than trying to remember the rather obscure
"edit" commands built into CSH.  Now all you need to know are the ways to
select different commands from the history list (which is trivial), and use
the line editor to do the rest.

The line editor has the following commands defined (they are your basic
EMACS commands):

	CTRL(A)			beginning of line
	CTRL(B)			backward character
	CTRL(D)			delete character forward
	CTRL(E)			end of line
	CTRL(F)			forward character
	CTRL(G)			reset numeric argument count
	CTRL(H)/BS		delete character backward
	CTRL(K)			kill to end of line
	CTRL(L)			clear screen and redraw input
	CTRL(P)			reinsert previous typed line
	CTRL(R)			redraw input line
	CTRL(T)			transpose characters
	CTRL(U)			quadruple numeric argument
	CTRL(W)			delete word backwards
	CTRL(X)			kill to beginning of line
	META(B)			backward word
	META(D)			delete word forward
	META(F)			forward word
	META(Rubout)		delete word backward
	META(0-9)		specify numeric argument
	META(ESC)		insert ESC character

Anything else you type gets inserted into the line editor buffer at point,
and point is moved forward one.  In other words, this is just like EMACS on
one line.

All the normal interrupt characters, and other special characters (e.g.,
lnextc, rprntc, etc.)  work the same was as before.  If you change one of
those characters to one of the built in editor commands, you will lose the
use of that editor command.

CTRL(P) is special.  If you type Return and there's an error, you can type
CTRL(P) and the last line will be reinserted into the editor buffer.  So
it's a fast way to correct mistakes like that.  The alternative would be to
do "!!:i" if you're running the modified csh, and then edit, which is
substantially more than just type CTRL(P).  The alternative to the line
editor would be to come up with an efficient way to do the magic csh
substitution on the line.  The alternative to that would be to retype the
whole line, which is what we all did in the old days.

There is one new character you can define, called the daemon prefix
character, which lets you do a bunch of things you normally can't do unless
you are talking to a shell.  For instance, there is a daemon command to
print the processes running on your terminal via the ps command.  The way
this works is by having the kernel communicate directly with a special
program called the ttdaemon.  All the user has to do is turn on this
feature using stty, like this:

	stty dnext <chr>

Pick a character, any character, which you don't often use.  The
recommended character is ^_, typed ^/ on many terminals.  The following
commands are current defined:

	^_ k			kill current process group (KILL)
	^_ c			kill current process group (TERM)
	^_ t			execute "ps lt" on tty
	^_ p			execute "ps t" on tty
	^_ i			reinitialize tty settings
	^_ u			print a list of users
	^_ l			print load average via uptime(1)
	^_ ^_			insert ^_ into line editor

If a ^_ k or ^_ c is provided a numeric argument argument, then that signal
will be sent instead of KILL or TERM.  What's nice about this special
character is that it works even when the terminal is in RAW mode.  So once
you've enabled this character you can always know what's happening on your
terminal, or you can reset your modes if a program dies at a bad time.
Once you get used to a feature like this, it's very hard to live without it.

Because the line editor gives you the capability to move around on the line
and insert/delete text in arbitrary places on the line, we needed to teach
the line editor how to wrap lines.  In the other line disciplines when
lines get too long, either they wrap because the terminal wrapped, or the
characters are lost past the end of the screen.  If we let the line editor
do that, though, the screen would get totally messed up (you just wouldn't
believe it!).  So, when a line gets too long, a '!' is placed at the end of
the line and the line is continued on the next terminal line.  If the
enough characters are erased so that they all fits on one line, the '!'
goes away.  This is much better than the other line disciplines, which just
mess up completely in situations like that.

So, what do you get with the new line discipline.  You get an editor.  And
not just any editor, either - an EMACS, which is the best.  If you don't
like editors, you at least get wrapped lines.  Editors aside, you also get
the ttdaemon, which lets you do all sorts of useful things.  If you don't
like the ttdaemon either, then you don't like computers and should change
professions (or majors, whichever is appropriate).



More information about the Comp.unix.questions mailing list