Enough theory: let's type. UniVerse has its own command line editor which allows you to view and change records. As everything in UniVerse takes the form of records in files (programs, commands and keywords from the UniVerse command language, field descriptions in dictionaries, and, of course, traditional data records), the editor has very wide application, allowing you to do everything from changing data to writing programs.
To invoke the editor, the command is:
ED filename recordkey
(This, incidentally, is the form taken by many UniVerse commands, as most of them operate in various ways on records in files.)
As mentioned above (see Universe and UNIX), each UniVerse command takes the form of a record in the VOC file. As we earlier entered the command SH
to invoke a Unix shell, it follows that there must be a record corresponding to this command in the VOC. To find out, enter:
ED VOC SH
You should see the following message:
4 lines long.
And the UniVerse editor's prompt:
----:
Now enter the command P to display a 'pageful' of the record,:
0001: V
0002: /bin/sh
0003: U
0004: TICRG
----:
This record only has four fields, so no more can be displayed. However, if the record had many fields, P
would only display as many as would fit on your display. By repeatedly enter P
therefore, you can read your record a page at a time.
Notice the message 4 lines long
which appeared when you edited this record. While the editor thinks in terms of 'lines', each line is actually a field. That is to say, the editor shows one field on each line. What you are looking at here is, in a sense, 'raw' data. Using a SQL based database like Oracle, your only access to data in columns in via the SQL language, and you cannot change the values in columns in ways which are inconsistent with the column definitions. UniVerse, on the other hand, allows you to look at and even change the raw data, not constrained by the field definitions, or, indeed, anything.
Depending on the nature of the change, changing this record would probably have the effective of disabling the SH command, and so we shan't do it. Instead, enter the Q
command to
exit the record. If you had changed the record before exiting, you would see the prompt:
***** Record changed. OK to quit (Y) ?
You would then have to enter a Y
before you were returned to the UniVerse prompt.
When back at the UniVerse prompt, enter the command:
>ED VOC FLUFFY
You will be amazed to discover that there is no UniVerse FLUFFY
command or keyword, so there is no record on the VOC file corresponding to this key. Instead you will see:
New Record.
----:
The command to put the editor into 'insert mode' is I
. Enter it and you will see:
0001=
This prompt is telling you that whatever you type in will become line 1 (and thus field 1) of the new record 'FLUFFY'. In the case of VOC
records, every record represents a command or other keyword in the UniVerse command language, and field 1 of each record determines whether the keyword in question is a command, a filename, a command parameter, or has some other meaning. We shall set up a 'paragraph' (a little like a Unix command script) to be run whenever someone enters the command 'FLUFFY', so enter PA
. Your record will now look like this:
0001= PA
0002=
You are now being invited to enter a value for the second field of the record FLUFFY
. Each line after the first in a UniVerse paragraph is a command, so try the following:
0001= PA
0002= DISPLAY You have just entered the command 'FLUFFY'.
0003= DISPLAY This is not a terribly useful command.
0004= DISPLAY All it does is display this message.
0005=
(Do not be concerned if you have made any mistakes in entering these lines: we shall be looking at the commands you'll need to change things, and so correct any mistakes, below.)
To indicate that you do not wish to enter any more fields, simply hit ENTER instead of entering another field. You will be returned from the =
'input' prompt to the :
'command' prompt:
0005=
(press ENTER)
----:
At any given time your record will have a 'current line'. This is the line which will be changed by any commands you might enter. You can make any line current just by typing in its number. Enter 2
to make line 2 active:
----: 2
0002: DISPLAY You have just entered the command 'FLUFFY'.
----:
You can also move a certain number of lines relative to your current line by entering +n
or -n
where n
is the number of lines you want to move. For instance:
----: +1
0003: DISPLAY This is not a terribly useful command.
----: -2
0001: PA
----:
Just hitting ENTER on its own is the equivalent of entering +1
to move to the next line:
----:
(press ENTER)
0002: DISPLAY You have just entered the command 'FLUFFY'.
----:
You can jump straight to the 'top' of your record with the command T
, or straight to the bottom with B
, like this:
----: T
Top.
----: B
0004: DISPLAY All it does is display this message.
Bottom at line 4.
----:
A subtlety here is that the top of the record is not line 1, but line 0. This is because (a) new records and completely empty records (which UniVerse allows) don't have a line 1, and (b) by going to line 0 and using the I
command, you can insert lines before line 1 of your current record.
Let us now assume that you wanted to replace the word entered
with the word typed
. To do this, you would use the C
or 'change' command thus:
----: 2
0002: DISPLAY You have just entered the command 'FLUFFY'.
----: C/entered/typed
0002: DISPLAY You have just typed the command 'FLUFFY'.
----:
(In fact, the character you used to separate entered
and typed
need not be /
: it could be any of the following: !"#$%&()*+,-.:=@[\]_`{|}
or '
. This is useful when the thing you want to change, or the thing you want to change it to, actually contains a /
.)
You can also use the C
command to change every occurence of one string to another by adding a /G
parameter. The G
stands for 'global'. For instance, to change every space to an asterisk on this line, try:
----: C/ /*/G
0002: DISPLAY*You*have*just*typed*the*command*'FLUFFY'.
----:
Our command now looks a little odd. To change it back:
----: C/*/ /G
0002: DISPLAY You have just typed the command 'FLUFFY'.
----:
To apply the same change to more than one line, simply add the number of lines you wish to change to the end of the command. For instance, to change the word DISPLAY
to IGNORE
on the current line and the one after it (two lines altogether), add /2
:
----: C/DISPLAY/IGNORE/2
0002: IGNORE You have just typed the command 'FLUFFY'.
0003: IGNORE This is not a terribly useful command.
At line 3
----:
The editor will display any lines which are actually changed. Note the At line 3
message at the end of the change. If you change more than one line in this way, the editor will make the last line examined the current line: even if the string you wanted to change did not appear in it and the line was therefore not changed. For instance, if you had entered the command C/typed/used/2
, then lines 2 and 3 would have been searched for the string typed
. Only line 2 contains it, so only line 2 would have been changed, but line 3 was the last line examined, and so line 3 becomes your current line. The message is just a reminder of this.
You can even apply a 'global' change across more than one line, by adding /Gn
to you command where n is the number of lines you wish to change. One of the most common used of C
is to do a complete search and replace by first entering the command 1
to move to the first line, and then entering the command C/something/something else/G99999
. C
doesn't get upset if you try to change more lines than there are in the file: it'll just change as many lines as it can find, and leave the last line as the current line.
Changing DISPLAY
to IGNORE
has left our paragraph looking a little odd. To reverse (or in Windows parlance 'undo') a change, you can use the quaint command OOPS
:
----: OOPS
Record restored to condition prior to command "C/DISPLAY/IGNORE/2".
0002: DISPLAY You have just typed the command 'FLUFFY'.
----:
Note that note only have the lines been put back the way they were before the C
command, but even your current line has been set back to 2: where you were before you made your change.
OOPS
only reverses commands which change the content of the record. For instance, if you enter C/A/B
to change an 'A' to a 'B', you can reverse the change with OOPS
, however: if you enter the command +2
to move your current line 2 lines down, OOPS
will ignore this. Neither can OOPS
reverse any changes before the last.
While you can make almost any change to a line using C
, some changes are so common that they have commands of their own. For instance, to add or 'append' something to a line, enter the command A newbit
, where newbit
is the bit you want to add. For instance:
0002: DISPLAY You have just typed the command 'FLUFFY'.
----: A That's silly.
0002: DISPLAY You have just typed the command 'FLUFFY'.That's silly.
Note that there is no space between the full stop at the end of the original line and the word 'That'. To append a space, you must remember to leave two spaces between the A
and the newbit
.
If you've made this change, OOPS
it back.
You can break a line into two using the command B endofline1
, where endofline1
is the sequence of characters you want at the end of the first line. Everything after these characters is broken into a new line underneath. This sounds worse than it is: and an example is clearer:
0002: DISPLAY You have just typed the command 'FLUFFY'.
----: B typed
0002: DISPLAY You have just typed
----: +1
0003: the command 'FLUFFY'
----:
Note that while B
broke the line in two, it didn't change the current line. You had to type +1
(or you could just have pressed ENTER) to move the current line down one and see the new line created.
If you haven't made this change, do, because it's handy to demonstrate the next editor command, which is:
To join your current line to the one below it, enter the command CAT
. To repair the break you inserted above, therefore:
----: 2
0002: DISPLAY You have just typed
----: CAT
0002: DISPLAY You have just typed the command 'FLUFFY'.
----:
To delete a line, enter the command D
. To delete n
lines, enter the command Dn
. This is simply enough: the only bewildering thing is that unlike most commands, D
does not redisplay the (new) current line once it has finished. For instance, if you are only line 2 and enter the command D
, line 2 disappears, and line 3 becomes the new line 2, (and line 4 the new line 3, and so on). However, the editor does not display the new line 2 to let you know where you are. To get round this, a trick is to enter the command +0
, which moves your current line zero lines down (ie. not at all) and forces the redisplay of your current line:
----: 2
0002: DISPLAY You have just typed the command 'FLUFFY'.
----: D
----: +0
0002: DISPLAY This is not a terribly useful command.
----:
Try this, but then OOPS
the deleted line back.
To duplicate the current line, use DUP
:
----: 2
0002: DISPLAY You have just typed the command 'FLUFFY'.
----: DUP
0003: DISPLAY This is not a terribly useful command.
----:
Note that a copy of line 2 now appears on line 3, and line 3 is now the current line. Enter OOPS
to reverse this.
To locate or search for something, enter L something
:
----: T
Top.
----: L sef
0003: DISPLAY This is not a terribly useful command
----:
Though it may not be immediately obvious, the string sef
appears in the word useful
. As you see, L
will find your string wherever it appears, and whether it appears as a separate word or within a string.
The F
or 'find' command is slightly different. F something
will only find lines which begin with something
. This is in fact a particular case of a more general form of the command: where Fn something
will find the first line in which something
appears in column position n
. The plan F something
command is therefore equivalent to F1 something
. This is, as it seems, a very specific command, and perhaps not as well used as L
: but when it is useful, it is very useful. Any kind of positionally formatted text, such as the fixed width columns in a report saved to disk, or even the indented statements of a UniVerse Basic program, are easier to manage using this command.
The commands L
and F
on their own (ie. without a something
to search for) will simply repeat the last locate or the last find respectively.
To define a block, first go to the first line of the block and enter the command <
, then go to the last line and enter >
:
----: 2
0002: DISPLAY You have just typed the command 'FLUFFY'.
----: <
Block FROM set to line 4.
----: 3
0003: DISPLAY This is not a terribly useful command.
----: >
Block THROUGH set to line 4.
If you want to define just one line as a block, you can enter the command <>
Having defined your block, you can COPY
it, MOVE
it, or DROP
(delete) it. To copy or move it, simply go it the location you would like the block to be inserted, and enter the appropriate command:
----: T
Top.
----: COPY
BLOCK from 4 through 4. OK (Y) Y
0001: DISPLAY You have just typed the command 'FLUFFY'.
----:
COPY
will make a copy of the lines in the new location (leaving the original lines alone). MOVE
will delete the original lines. DROP
will simply delete the original lines.
Note that before the COPY
was allowed, a 'confirmation' message appeared, and you had to enter a 'Y' to proceed. You can toggle these confirmation messages on and off using the BLOCK
command:
----: BLOCK
BLOCK operation verification = disabled.
----: BLOCK
BLOCK operation verification = enabled.
You can go to the beginning of your block using the command G<
, and then end with G>
, and you can 'clear' your block (which is to say remove the block definition, without deleting any lines) by using the <, > or <> commands on line 0. Use the T
(top) command to get to line 0.
A number of the commands already explained above can be combined with blocks. For instance:
C/oldstring/newstring/B
applies the change command to every line in the block,
C/oldstring/newstring/GB
applies the change command globally to every line in the block,
PB
displays the contents of the block a page at a time.
You may enter a UniVerse command without leaving the editor by using the PERFORM
command:
----: XEQ DISPLAY Do something!
Do something!
----------------- Returned to the EDITOR from the XEQ command.
This command can be tremendously useful, as it allows you to consult UniVerse for information without leaving the record you are editing. For instance, if you are editing a UniVerse Basic program and you need to consult one of your earlier programs to see how you achieved a particular end, you can use XEQ to invoke the editor from within the editor and look at your other program. The record you were editing originally is not saved, but not lost, merely 'suspended' until you return to it.
The commands FILE
and SAVE
will both write your record back to its file, complete with any changes you have made to it. The only difference between them is that SAVE
will allow you to carry on editing (and so is most useful for making periodic 'safe copies' of your work - a very good idea incidentally), while FILE
leaves the editor and returns you to the UniVerse prompt (and so you would generally used once you had finished editing your record: for the time being at least),
You can optionally specify a new record key, or even a new filename and record key, by entering SAVE/FILE newkey
or SAVE/FILE filename newkey
. In this way, you can edit a record, and then leave it unchanged while creating or overwriting another record - possibly in another file.
Bear in mind that UniVerse is a multiuser system and operates a system of 'record locks' to prevent two or more users simultaneously modifying a record and thus nullifying each others work. While you are editing a record, your editor will apply a lock to it, and noone else will be able to access it: through the editor or through any application. If you enter the command RELEASE
, you can release this lock and continue editing the record: though naturally you risk either overwriting someone elses work, or allowing them to overwrite your work, by doing so.
The UniVerse editor supports a command history and command stack almost identical to that available from the UniVerse command prompt. .L
can be used to list commands, .X
to reexecute them, and so on. Rather than describe these stack commands in full here, I would refer the reader back to The Command Stack above.
The commands I have listed above are only a subset of those available within the UniVerse editor, and even some of those I have listed are capable of greater refinement than I've described here. While the information on this page should be sufficient to get you started, as you become more fluent you will doubtless wish to learn more about the editor's command set. UniVerse's own manual is very thorough, but perhaps the best source of information is the editor's own HELP
command:
----: HELP
You may type one character, a keyword, or just <RETURN> for more information.
If you press ENTER, you will be shown a list of all the editor commands. By entering a single letter, you can reduce this list to those commands which begin with your chosen letter. For instance, if you enter B
you will see:
B - Set the current line pointer to the BOTTOM line. B any - BREAK the current line after 'any' into two lines. BLOCK - Toggle BLOCK operation verification between ON and OFF.
If you enter a 'keyword', which can be any word or phrase longer than a single letter, you will see a list of all the editor commands which mention that keyword in their help listing. For instance, entering the keyword BLOCK
shows you all the editor commands which are somehow block related:
BLOCK - Toggle BLOCK operation verification between ON and OFF. C/// - CHANGE one or more lines. formats permitted are: C/from/to C/from/to/# C/from/to/G C/from/to/#G C/from/to/G# C/from/to/B C/from/to/BG C/from/to/GB where / - is any delimiter character. from - is the character string to be replaced. to - is the character string to substitute. # - is the number of lines to CHANGE. (The default is one) G - is the letter 'G' (global) CHANGE all instances in line. B - is the letter 'B', CHANGE all lines in the defined BLOCK. COPY - COPY a BLOCK (see '<' and '>' ), source block is unchanged. DROP - DROP (DELETE) all lines in the defined BLOCK (see '<' and '>' ). G< - GO TO line defined by the beginning of the current BLOCK. G> - GO TO line defined by the end of the current BLOCK. MOVE - MOVE a BLOCK (see '<' and '>' ); source block is deleted. PB - PRINT on CRT all lines in the defined BLOCK (see '<' and '>' ). SEQ/// - Generate SEQUENTIAL numbers. Formats permitted are: SEQ/from/start/# SEQ/from/start/#/inc where / - is any delimiter character. from - is the optional character string to replace. start - is the starting sequential number.
ED
is the standard editor for PICK derived systems. It would be familiar to a user of Prime INFORMATION, COSMOS Revelation, or VMark UniVerse.
The other editor supported by UniVerse is UV.VI
, which is simply a link to the famous UNIX editor vi
. This is unique to UniVerse, simply because UniVerse is the only PICK derived system to run over UNIX.
If you are familiar with vi
, it is possible to go through life without ever learning ED
: and if you are coming to UniVerse from UNIX you may be tempted to do this.
The choice of editor is, in many ways, somewhat personal, and people are often quite partisan in singing the praises of their favourite editor. A direct comparison of ED
and vi
would therefore be contentious and unlikely to be useful. To a greater extent than perhaps we realise, we all tend to rationalise a defence of that which we are used to: and to believe that an editor feels natural because of the intuitiveness of its design, when in fact it feels natural through long habit and acclimatisation.
I would, however, recommend that any UniVerse developer becomes familiar with ED
, even if it is not his first choice for his day to day work. The reasons follow:
1. ED
is available on all PICK derived platforms. Many UniVerse systems must be ported from or communicate with other PICK systems on other platforms: these all provide ED
but not vi
.
2. Most UniVerse records attach particular meanings to particular field numbers: ED
numbers the lines it is editing in recognition of this. The UV.VI
interface to vi
switches vi
's line numbering on, but it is clumsier than ED
's, and most vi
programmers are not used to it, as vi
is primarily a code and script editor, not a data editor.
3. ED
provides ready access to the UniVerse command language through the XEQ
command.
4. The command stack in ED
is similar to that available from the main UniVerse command prompt: its use promotes consistency and fluency. Furthermore, the 'stack commands' used to manipulate commands both in ED
and from the UniVerse command prompt are based on the commands used to change text in the editor itself.
5. As explained earlier in this course, UNIX does not understand UniVerse file internals. In order for UV.VI
to work, therefore, a special linking program must first make a copy of a record's contents as a UNIX temporary file for vi
to work on, and copy this back to the UniVerse file once vi
has finished. This is clearly less efficient and elegant than ED
, which is written in UniVerse Basic and can thus access the records directly. Furthermore, the name of the temporary file created to allow vi
to work is unrelated to the name and location of the original record, and can thus be misleading.
6. ED
understands UniVerse Basic, which will be covered later in this course. It can therefore automatically indent it to show it's structure: and this is a tremendously useful facility.
In short, ED
was designed for use with UniVerse, and vi
wasn't. I doubt I will have reached the die-hard vi
enthusiast, but I hope I will have encouraged others to at least become familiar with UniVerse's own editor.