[comp.os.misc] Wanted: thoughts about history mechanisms.

dfenyes@thesis1.med.uth.tmc.edu (David Fenyes) (04/24/91)

Hello,

I'm working on a small shell and I'd like it to have much of the 
functionality of ksh and bash without taking up as much space.
If I want the code itself to fit in 64K, I've got about 8K code space
to implement a history mechanism.  I figure the approach would be
to have the shell simply store the lines, and offer access to them
in a meaningful way.  All processing & re-execution, etc. can then
be done with shell funcs.  (The shell is based on Kenneth Almquist's ash)

What is the best way to approach a history mechanism?

Since the way we think of commands typed into a shell is in 'blocks'
of one 'major' prompt (PS1) and the subsequent continuations (PS2's),
This might be one way for the shell to think about chunks of history.

Here are my thoughts for a low-level shell history support:

- implement history as a dynamically resizable list.

- Mark each line as major or minor prompt (ps1 or ps2)

- history command is basically a lister.

- A load command (which is already implemented in the shell) allows
  a line to be pre-fed to the editor, so a line is already in the
  buffer when the editor is invoked.  If 'load' is invoked with
  a line already in the buffer, the previous line is saved in the
  history and the new line is stored in the buffer.

- `load' command would contain an option to load as minor prompt line,
  loading as a major prompt line as default.

- The history command contains options to list from <line> to <line>,
  where <line> could be relative or absolute, or can list 'blocks'
  from the nth back major prompt to the n+1st, etc.  History options
  would allow lines to be listed either plain, or with appropriate
  prefixed option to the 'load' command to allow it to read in the
  line as either a major or minor prompt line.


Using these tools, history can be saved in a file either wholesale
with a trap 0, or the most recent chunk before each prompt via the
EVERY variable, which is executed before a PS1.  At logout, the
file can be truncated to HISTSIZE with /bin/tail, and at login,
the file can be read in with a function that precedes each line
with the word 'load' and executes the result.

Re-executing a command or block could be accomplished via something
like :
eval $(history options args...)
(done in a shell function.)

substitution could be done with something like
eval $(subst $1 $2 "$(history opts args)"), where subst() is a
shell function using builtin expr.

These are just some rough thoughts, so I thought I'd ask this group
for input, since most of us do some thinking about shells.

Thanks,

David.
----
David Fenyes                                 dfenyes@thesis1.hsch.utexas.edu
University of Texas Medical School           Houston, Texas