I sent this to pop-forum, but maybe it would be of interest or use to
some news readers who don't get pop-forum mail.
From Aaron Sloman Mon Mar 1 19:47:14 GMT 1993
To: pop-forum@hplb.hpl.hp.com
Subject: ved_browse (A new browsing utility)
I've been finding it difficult to find things in the Poplog system
because of the proliferation of different directory trees (including
local directories, X stuff, and the possibility of additional
libraries, such as objectclass, etc.)
It used to be possible to get by with "index" files (e.g. HELP INDEX,
HELP XVEDINDEX HELP XPOPINDEX) but it is hard to remember these names,
and in some cases (e.g. HELP PLOGINDEX) you have to have the language
subsystem loaded for the index file and the corresponding documentation
files to be accessible. (In V14.2, lib make_indexes is a heroic attempt
to get round this.)
I now think that in effect the old Poplog indexing mechanisms have
broken down because there are too many categories all with their own
help, teach, ref, lib, etc. files, and remembering about all the
different names imposes an intolerable cognitive requirement on users.
So I've tried to produce a better solution, and ved_browse is a first
attempt.
LIB VED_BROWSE described in HELP VED_BROWSE helps you find out which
files are actually available in various POPLOG library categories, e.g.
pop11 help files
prolog teach files
pop11 autolodable files
pop11 lib files (including autoloadable files)
prolog src files
ml lib files
lisp ref files
To run the program (after installing it in an autoloadable library) do
ENTER browse
You first get a menu (on the command line) of languages to choose from
(i.e. all the four poplog languages) and then a menu of types of file
(e.g. teach, help, ref, lib, etc.) In both case select by typing the
appropriate number key (without RETURN).
Then, to look at a particular file listed in the browse index file, put
the cursor on or to the left of its name, and press the REDO key (or
again do ENTER browse).
The HELP file and the LIB file follow, separated by a row of "="
signs.
This version works on Unix Poplog only. I leave it to someone else
to convert it to VMS.
Aaron
Help file follows, then LIB file.
=======================================================================
[help file to go in $poplocal/local/help/ved_browse or in main system]
DRAFT HELP VED_BROWSE (Unix Poplog only) Aaron Sloman, Feb 1993
LIB VED_BROWSE
This utility provides an extension to the Poplog Ved-based mechanisms
for browsing online documentation and libraries. The library makes
available the command "ENTER browse", which makes it easy to browse
online documentation and libraries in Poplog.
CONTENTS - (Use <ENTER> g to access required sections)
-- Introduction
-- (a) ENTER browse (Building an index)
-- (b) ENTER browse (Selecting from a browse index)
-- How an index is built
-- The structure of the browse index files
-- WARNINGS
-- Changing search lists: the browse_search_lists property
-- SEE ALSO
-- Introduction -------------------------------------------------------
The procedure ved_browse has two forms of behaviour, depending on whether
the current file is already a browse index file created by a previous
call of ved_browse. In that case the name where the cursor is, is used
to read the relevant file into the editor. If the current file is not a
browse index file, then ved_browse will create one.
In order to do this it first asks you to select the language, and then
it asks you which type of file is required, For both of these it
provides a simple menu on the VED status line. More detailed
explanations follow.
-- (a) ENTER browse (Selecting from a browse index) -------------------
If invoked in an index of files previously created as described below by
"ENTER browse", the command fetches the file whose name the cursor is
above or to the left of.
(See the WARNING below)
-- (b) ENTER browse (Building an index) -------------------------------
If the command is not invoked in a browse-produced index of available
files, it gets you an index of available files in a category, using the
name of the category and the directory searchlist for the category.
When you give the command "ENTER browse" it first asks you which
language subsystem, by presenting the following menu:
0:current 1:pop11 2:prolog 3:lisp 4:ml
Select the language by typing the appropriate key. Pressing "0" implies
that you want the language that is currently the default. (There's no
need to press RETURN after making your selection.)
It then prompts you on the status line to specify which category of
files to look at. You select from the following menu, by typing a
number:
1:help 2:teach 3:ref 4:doc 5:lib 6:auto 7:src 8:include
Select the category by pressing the appropriate number key.
When the language is Pop11, the 8 category options correspond to
searching through directories in
vedhelplist
vedteachlist
vedreflist
veddoclist
popuseslist
popautolist
popsrclist
popincludelist
except that overlaps between help, teach, ref, and doc lists are
eliminated. (By default they have a lot of overlap, for convenience.)
For other languages only a subset of categories may have corresponding
directories. (It would be possible, but a bit tedious to have the
program automatically modify the second menu depending on which language
you have chosen. I may do that later.)
Ideally documentation and libraries associated with VED should be dealt
with separately from Pop-11 information, but that would require major
reorganisation of the Pop-11 directory structure. So information
about VED is obtained by selecting the Pop-11 option first, and then
teach, help, ref, or lib second.
-- How an index is built ----------------------------------------------
Once you have selected a category and a language, ved_browse traverses
directories in that category and lists their contents in a VED buffer,
grouped by directory. It does this by spawning a sub-shell with a
command of one of the following forms, depending on the operating system
SunOS
/usr/5bin/ls -xL dir1 dir2 dir3 ....
HP-UX
/bin/ls -xL dir1 dir2 dir3 ....
Others
/bin/ls -CL dir1 dir2 dir3 ....
where the directory names come from the appropriate search list.
If you prefer to vary the format of the index you can alter the string
browse_ls_command, defined in LIB VED_BROWSE. E.g. to have single column
output try
'ls -L' -> browse_ls_command;
You can keep the index and at any time later on move the VED cursor to
the name of the desired file and again give the command
ENTER browse
in order to read that file. Alternatively, simply press the REDO key if
that command is still on the command line.
NOTE: it should be possible to tailor this program to work on VMS, but
I am not sufficiently familiar with VMS or VMS Poplog.
-- The structure of the browse index files -----------------------------
A different index file is created for each combination of language and
file category.
The top two lines in the file are used by subsequent calls of ved_browse
to recognise that this is a browse index file, and to determine the
language and category, so they should not be edited after creation.
The first line is an instruction to the user and also identifies the
file as a browse index file. The second line gives language name and
index category. The third line is a reminder not to edit the first two.
After that a table of contents is provided listing the directories
found, in the standard format of Poplog online documentation files so
that you can select a group using the normal "ENTER g" command, as
described in HELP * VED_INDEXIFY
Files in a directory are grouped together.
-- WARNINGS -----------------------------------------------------------
1. SUBDIRECTORIES
If there are any sub-directories in the directories included in
search lists they will be listed as ordinary files, and attepts to
access them in mode (b) may produce mysterious failure messages.
Some of those sub-directories will in any case be included in search
lists (e.g. $popvedlib and $popvedlib/term are both in popautolist
and popuseslist), but not all sub-directories are.
If you wish to have sub-directories indicated as directories in the
browse index add the "F" flag to browse_ls_command (See MAN * LS).
However, this will slow down creation of indexes considerably.
2. UNREADABLE FILES
In "src" directories some unreadable binary files will be listed, in
particular files called safepop11 or files with the suffixes
.o .obj .olb .wlb
3. CATEGORIES NOT INCLUDED
There are some X source files provided with Poplog that are not in
any standard search list. These will not be found by ved_browse, but
can be explored (e.g. using ved_dired -- see HELP * DIRED) in the
following directory
$usepop/pop/x/Xpw
There are also some useful command files in $popcom, and possibly
$poplocal/local/com $popsys/popenv which are not included. There
should be something like a vedcomlist category.
Also $popcontrib is not included at present (unless you add some
$popcontrib directories to your search lists). That should be remedied,
though ved_dired can easily be used to browse $popcontrib.
4. USER-DEFINED CATEGORIES
HELP * VEDGETSYSFILE and REF * VEDGETSYSFILEPDR describe mechanisms by
which users can define new browseable file categories that can then be
integrated with the standard Poplog cross reference (hypertext)
mechanism. At present ved_browse does not cope with these, but it is
easy to extend, by modifying the values of the following global
variables from LIB VED_BROWSE
browse_type_menu browse_types
browse_subsystem_menu browse_subsystems
and then adding extra keys to the property described below, where
a key is a word composed of a subsystem (language) name and a type
name.
-- Changing search lists: the browse_search_lists property ------------
The search lists are stored in a pop-11 property (see * newproperty)
called browse_search_lists. The lists are accessed and updated via
keys that are words composed from the language name and the file
category. The following keys are used:
For Lisp: lisphelp lisplib lispref lispsrc lispteach
For Poplog ML: mlhelp mllib mlsrc mlteach
For Pop11: pop11auto pop11doc pop11help pop11include pop11lib
pop11ref pop11src pop11teach
(This includes all the main X documentation and libraries)
For Prolog: prologhelp prologlib prologsrc prologteach
The value associated with each key can either be a word whose valof
normally holds the search lists, or a list in the standard form of
Poplog search lists. (See HELP * SEARCH_LISTS). The procedure
flatten_searchlist is used to remove extraneous information before the
list is used by ved_browse.
Examples:
browse_search_lists("lisplib") =>
** [$poplocal/local/lisp/modules/ $usepop/pop/lisp/modules/]
browse_search_lists("pop11help") =>
** vedhelplist
Note however, that the default vedhelplist will include "ref" "doc" and
"teach" directories, whereas ved_browse will ignore those if the
category chosen is "help".
You can modify a search list for a particular category by associating a
new variable name, or a list with the key. e.g.
"prologliblist" -> browse_search_lists("prologlib");
[...some list ...] -> browse_search_lists("lisplib");
NOTE: this mechanism should be better integrated with LIB SUBSYSTEM.
However, it was intended that ved_browse should be usable to look
at documentation and programme libraries for a poplog language that
is not included in the current process, and LIB SUBSYSTEM does not
yet provide an appropriate mechanism.
-- SEE ALSO -----------------------------------------------------------
The following additional files may be relevant.
HELP * DOCUMENTATION
HELP * SHOWLIB
HELP * VEDSYSFILE
HELP * VEDGETSYSFILE
HELP * DIRED
DOC * SYSSPEC
HELP * SUBSYSTEMS
REF * SUBSYSTEM
(including entries for
* ved_lisp * ved_pml * ved_pop11 * ved_prolog)
LIB * VED_BROWSE
--- $poplocal/local/help/ved_browse
--- NO COPYRIGHT. USE AS DESIRED FOR ANY PURPOSE -------
=======================================================================
End of HELP file. LIB file follows.
=======================================================================
/* --- NO COPYRIGHT. COPY AND REUSE AS REQUIRED ----------
> File: $poplocal/local/auto/ved_browse.p
> Purpose: Get an index to online files, or access a file
> Author: Aaron Sloman, Feb 26 1993
> Documentation: HELP * VED_BROWSE
> Related Files: See cross references in HELP VED_BROWSE
*/
section;
;;; Global constants used below
;;; Standard directories for PML documentation and libraries
lconstant dir_lists =
[
;;; ML
[mlhelp [ '$poplocal/local/pml/help/' '$usepop/pop/pml/help/' ]]
[mlteach [ '$poplocal/local/pml/teach/' '$usepop/pop/pml/teach/']]
[mllib ['$poplocal/local/pml/lib/' '$usepop/pop/pml/lib/']]
[mlsrc [ '$usepop/pop/pml/src/' ]]
;;; LISP
[lisphelp
['$poplocal/local/lisp/help/' '$usepop/pop/lisp/help/' ]]
[lispref ['$usepop/pop/lisp/ref/' ]]
[lispsrc [ '$usepop/pop/lisp/src/' ]]
[lispteach ['$poplocal/local/lisp/teach/']]
[lisplib
['$poplocal/local/lisp/modules/' '$usepop/pop/lisp/modules/']]
;;; PROLOG
[prologhelp
['$poplocal/local/plog/help/' '$usepop/pop/plog/help/' ]]
[prologteach
['$poplocal/local/plog/teach/' '$usepop/pop/plog/teach/' ]]
[prologlib
[ '$poplocal/local/plog/lib/'
'$poplocal/local/plog/auto/'
'$usepop/pop/plog/lib/'
'$usepop/pop/plog/auto/' ]]
[prologsrc
['$usepop/pop/plog/src/']]
;;; POP11
[pop11teach vedteachlist]
[pop11help vedhelplist]
[pop11ref vedreflist]
[pop11doc veddoclist]
[pop11src vedsrclist]
[pop11teach vedteachlist]
[pop11auto popautolist]
[pop11lib popuseslist]
[pop11include popincludelist]
]
;
;;; Define a property mapping combination of language and category onto
;;; search list, or its name.
global constant browse_search_lists =
newproperty(dir_lists, length(dir_lists), [], "perm");
;;; Some useful strings
lconstant
browse_index_message =
'BROWSE INDEX: put cursor on desired file name then press REDO',
name_terminators = '\s\t';
;;; Menu strings, and corresonding vectors of names of languages or
;;; file categories
global vars
browse_subsystem_menu =
'0:current 1:pop11 2:prolog 3:lisp 4:ml',
browse_subsystems =
{current pop11 prolog lisp ml},
browse_type_menu =
'1:help 2:teach 3:ref 4:doc 5:lib 6:auto 7:src 8:include :',
browse_types =
{'help' 'teach' 'ref' 'doc' 'lib' 'auto' 'src' 'include'},
;
;;; Nex procedure should be part of poplog
define sys_file_exists() with_nargs 1;
;;; check for existence of a file. Faster than -readable-
sys_file_stat(nullvector)
enddefine;
;;; get default command for running "ls" on library directories
#_IF sys_file_exists('/usr/5bin/ls')
;;; Probably SunOS !
global vars browse_ls_command = '/usr/5bin/ls -xL';
#_ELSEIF issubstring('hp', hd(sys_machine_type))
;;; Running HP-UX
global vars browse_ls_command = '/bin/ls -xL';
#_ELSE
;;; Default for Unix systems
global vars browse_ls_command = '/bin/ls -CL';
#_ENDIF
define lconstant getoption(menu_string, vector) -> char;
;;; displayse menu options and returns the selection, based on
;;; character typed by user.
lvars char, menu_string, vector, len = datalength(vector);
;;; show menu and wait for response
repeat
vedsetstatus(menu_string, false, true);
vedwiggle(0,vedscreenwidth);
vedscr_read_input() -> char;
if isnumbercode(char) and (char - `0`) <= len then
quitloop
else
vedscreenbell()
endif
endrepeat;
enddefine;
define lconstant thisname() -> name;
;;; return file name under or to right of VED cursor
;;; also move VED cursor to right of the name
lvars char, name, startcol,
col = vedcolumn,
line = vedthisline();
min(col, vvedlinesize) -> col; ;;; in case to right of text
;;; find beginning of name by moving left to space or tab
until col == 1
or strmember(subscrs(col, line), name_terminators)
do
col - 1 -> col;
enduntil;
;;; now get name to right of cursor
;;; Move right past spaces and tabs to start of name
until col > vvedlinesize
or not(strmember(subscrs(col, line), name_terminators))
do
col + 1 -> col;
enduntil;
;;; record beginning of name
col -> startcol;
;;; find next space or tab character, ending file name
until col > vvedlinesize
or strmember(subscrs(col, line), name_terminators)
do
col + 1 -> col;
enduntil;
;;; now extract the name
substring(startcol, col - startcol, line) -> name;
;;; move cursor to end of name
col -> vedcolumn;
enddefine;
define lconstant prune_dirs(doc_type, doc_dirs) -> doc_dirs;
;;; return doc_dirs, minus those that don't include doc_type
lvars dir, doc_type, doc_dirs, dirs;
flatten_searchlist(recursive_valof(doc_dirs)) -> doc_dirs;
unless member(doc_type, ['lib', 'auto']) then
;;; remove dirs of different type, e.g. remove ref dirs
;;; from help list
[%
for dir in doc_dirs do
if issubstring(doc_type, dir) then dir endif
endfor
%] -> doc_dirs
endunless;
;;; now remove redundancies
[%
for dirs on doc_dirs do
front(dirs) -> dir;
unless member(dir, back(dirs)) then dir endunless
endfor
%] -> doc_dirs
enddefine;
define lconstant browse_get_file();
;;; get file name that cursor is on or to left of in browse index file
lvars filename, language_and_type;
vedbuffer(2) -> language_and_type;
thisname() -> filename;
;;; Now build up the help, teach, showlib or whatever command
veddo(language_and_type sys_>< space sys_>< filename)
enddefine;
define lconstant browse_make_index();
lvars
char, dir, command, doc_type, subsystem_name,
searchlist, doc_dirs,
oldfile = vedcurrentfile;
getoption(browse_subsystem_menu, browse_subsystems) -> char;
subscrv(char - `0` + 1, browse_subsystems) -> subsystem_name;
;;; deal with option 0
if subsystem_name = "current" then subsystem -> subsystem_name endif;
;;; in case current subsystem is prolog "top" level.
if subsystem_name = "top" then "prolog" -> subsystem_name endif;
;;; find documentation type
getoption(browse_type_menu, browse_types) -> char;
subscrv(char - `0`, browse_types) -> doc_type;
;;; create the key for accessing the table - a compound word
;;; and use it to access the property
browse_search_lists(consword(subsystem_name sys_>< doc_type)) -> doc_dirs;
;;; flatten the list, get rid of duplicates, and remove extras
prune_dirs(doc_type, doc_dirs) -> doc_dirs;
if doc_dirs == [] then
vederror('NO SEARCH LIST FOR ' >< subsystem_name >< space >< doc_type)
endif;
;;; build up a string to form the argument for veddo, of the form
;;; sh <ls command> dir1 dir2 dir3 ... | expand -8
;;; where expand is used to remove tabs.
consstring
(#| explode('sh '), ;;; for ENTER sh, to invoke vedgenshell
explode(browse_ls_command),
`\s`,
for dir in doc_dirs do
if sys_file_exists(dir) then explode(dir), `\s` endif
endfor,
explode(' | expand -8')
|#) -> command;
veddo(command);
;;; That should have created lists of relevant files, in a
;;; new VED buffer. Check.
if oldfile == vedcurrentfile then vederror('NO FILES FOUND') endif;
;;; suppress screen output till call of vedrefresh, below
dlocal vedediting = false;
vedtopfile();
vedlineabove();
0 -> vedlineoffset;
;;; Insert instructions at top of file. (Also used to identify this
;;; later as a browse index file)
vedinsertstring(browse_index_message);
;;; now record the language and documentation type
vedlinebelow();
vedinsertstring(
if subsystem_name = "ml" then 'pml' else subsystem_name endif
sys_>< space sys_><
if member(doc_type, ['lib' 'auto']) then 'showlib' else doc_type
endif);
vedlinebelow();
vedinsertstring('NB:- Do not alter previous two lines -:NB');
;;; Now remove the line produced by vedgenshell, starting "sh"
vednextline();
if isstartstring('sh ', vedthisline()) then
nullstring -> vedthisline()
else
vedlineabove();
endif;
if length(doc_dirs) > 1 then
;;; Now prepare an index to directories, using ved_indexify
veddo('gs;@a/;-- /;');
veddo('indexify');
else
vedlinebelow();
vedinsertstring(hd(doc_dirs))
endif;
vedtopfile(); vedtextright();
vedputcommand('browse');
chain(vedrefresh);
enddefine;
;;; Now the top level procedure
define global ved_browse();
if vvedbuffersize > 2 and vedbuffer(1) = browse_index_message then
;;; inside a "browse" index file. Get the name and find the file.
browse_get_file();
else
;;; create a new index
browse_make_index()
endif
enddefine;
endsection;
--
Aaron Sloman,
School of Computer Science, The University of Birmingham, B15 2TT, England
EMAIL A.Sloman@cs.bham.ac.uk OR A.Sloman@bham.ac.uk
Phone: +44-(0)21-414-3711 Fax: +44-(0)21-414-4281
|