Loading a customisation file such as LIB VEDEMACS produces a complete change in the behaviour of Ved. We can change particular aspects of Ved's behaviour using single POP-11 commands. For example, to change the size of the indentation step produced by the tab key we assign an integer to `vedindentstep'; e.g.,
3 -> vedindentstep;If we want output generated a `lmr' command to always come out in the current file we can do
true -> vedlmr_print_in_file;If we want POP-11 mishaps to come out in the current file we can do
true -> vedlmr_errs_in_file;In fact the Ved command `output' can be used to achieve the same effect. If you give the command `output .' (i.e., `output' with a full-stop as argument) then the `** 4', and any other POP-11 printing, will come out in the current file. To get back to the original arrangement, do `output output.p'.
To see what other customisation variables and procedures there are, look at REF VEDVARS and REF VEDPROCS.
File structures are stored in a list called `vedbufferlist'. The file structure for the file currently being edited is also stored in the variable vedcurrentfile. Within the file structure, the main component is the representation of the text itself. This is stored in a vector called `vedbuffer'. The `vedbuffer' structure contains the lines of the file represented in the form of strings. Thus
vedbuffer(2) ==> ** - TEACH POPCOURSE10 - Programming the Poplog editorThe main procedure in the editor program is called `vedprocesschar'. This procedure reads in a key press from the keyboard and updates the current file structure accordingly. If the user has pressed an ordinary character key, then the procedure inserts the corresponding character into the string representing the current line, at the appropriate position (possibly pushing the rest of the text one position to the right). If the user has pressed some sort of function key (e.g. ENTER) then actions are performed to implement the relevant function.
To illustrate the way in which one can exploit the program interface to Ved, we will look at the implementation of a command that tests for the presence of duplicated words (such as `the the') in the current file. To create a new Ved command we simply define a procedure whose name begins with ved_. For example, if we want to implement a command called `silly' we define a procedure called `ved_silly'. Once we have done this, giving the command `silly' will execute the procedure. You can test this out by loading the following definition and then giving the command `silly'.
define ved_silly; 'A very silly command' ==> enddefine;Note how the output does not come out in the usual place. This is because the print command was executed from the command line, i.e., outside a Ved file.
Ved commands are just procedures and can therefore perform any action you like. To work gradually towards the definition of the command that tests for duplicate words, let us first write a command that counts the number of words in a file. This can be done by writing a procedure that moves the cursor to the top of the file and then keeps advancing it forwards, word by word, until the end of the file is reached. The number of cursor moves is then the number of words in the file. The command might be defined like this.
define ved_count; vars n = 0; vedtopfile(); until vedatend() do vedwordright(); n + 1-> n; enduntil; vedputmessage('There are '><n><' words in the file'); enddefine;The header of the definition is self-explanatory. We want a command called `count'; we therefore define a procedure called `ved_count'. The second line contains a `vars' command that sets up and initializes to 0 a variable called `n'. In the third line we see a call on a procedure called `vedtopfile'. This procedure is the Ved procedure that causes the cursor to jump to the very top of the file. We then see an `until' loop. This continues executing until such time as the Ved procedure `vedatend' returns a non-false result. This only occurs when the cursor is at the very end of the file. Thus the loop will continue to execute until such time as the cursor has reached the end of the file.
Within the body of the loop we see a call on the procedure `vedwordright' followed by a `+' command that increments the variable `n' by 1. The `vedwordright' procedure moves the cursor one word to the right or onto the next line if there is no word to the right. Thus, the loop will continue to execute until successive calls on `vedwordright' have brought the cursor all the way to the end of the file. By incrementing `n' each time we go around the loop we end up with a count of the number of words in the file.
In the final line of the procedure we see a call on the procedure `vedputmessage'. This is the Ved procedure that displays messages on the command line. It takes a string as argument. In the present call the string is constructed by joining together two strings (`There are ' and ` words in the file') and the value of `n'.
This procedure advances the cursor to the right until the current character (the value produced by `vedcurrentchar') is not an alphabetical character, or the current position is off the end of the line (the value of `vvedlinesize'). In most circumstances this will ensure that the cursor moves to a position immediately after the current word. Once the end of the current word has been found, the procedure uses the built-in procedure `substring' to derive the substring between the original position and the word-end position. This is then returned in the output variable `word'.
define vednextword -> word; vars i = vedcolumn,; until not(isalphacode(vedcurrentchar())) or vedcolumn > vvedlinesize do vedcharright() enduntil; substring(i, vedcolumn-i,vedthisline()) -> word; if length(word) < 1 then false -> word endif; enddefine;The `vednextword' procedure is used repeatedly by the `ved_nextdups' procedure. This is the procedure that actually implements the command. It works forwards from the current position in the file to the end, at each point picking up the current word and comparing it against the previous word (stored in the local variable `last_word'). If it discovers a duplication, the procedure puts up an explanatory message and returns. At the end of the loop the procedure assigns the value of `word' to be the new value of `last_word'.
define ved_nextdups; vars last_word = false, word; until vedatend() do vednextword() -> word; if isstring(word) and word = last_word then vedputmessage('Multiple occurrence of '><word); return; endif; word -> last_word; vedwordright(); enduntil; enddefine;
The command is a useful aid when one wishes to convert an expression with a very large value into a power of 10. In order to obtain the value of the expression provided as argument, the procedure has to evaluate it as POP-11 code. This can be done quite conveniently by calling the built-in procedure `compile' giving it the result of applying `stringin' to `vedargument'. The call on stringin converts the string into what is known as a a `character repeater'. In this form the `compile' procedure can effectively implement the POP-11 code contained in the string. If the code comprises a single expression this will produce a value on the stack. Thus the whole call produces the value of the expression.
define ved_log; vars i, n = compile(stringin(vedargument)); for i from 1 to 1000 do if 10 ** i > n then return(i-1) endif; endfor; enddefine;Within the body of the procedure a `for' loop is used to gradually increase the value of the local variable `i' until such time as the value of
10 ** iexceeds the value of the specified expression. At this point the procedure simply returns the value of `i' (using an explicit `return' command with arguments). Thanks to the convention that any value left on the stack at the end of a command execution gets displayed on the command line, the returning of this value causes it to be displayed to the user.
define ved_subtract; dlocal vedcolumn vedline vvedlinesize; vars n1 n2; vedcurrentitem() -> n1; vedchardown(); vedcurrentitem() -> n2; vedchardown(); vedinsertstring(n1-n2 >< nullstring); enddefine;It uses a fairly straightforward sequence of commands. It uses the procedure `vedcurrentitem' to read in the numbers under the cursor position and it uses `vedchardown' to descend to the line below. Finally it applies `vedinsertstring' to the string produced by joining the resulting value to an empty string (contained in the built-in variable `nullstring'). This inserts the appropriate value into the file. Note also the use of the `dlocal' command here to localize the changes made to the position-defining variables `vedline', `vedcolumn', and `vvedlinesize'.
You can test the command out by executing it with the cursor over the initial `2' of `23456'.
23456 721
REF VEDCOMMS REF VEDPROCS REF VEDVARSIf you have plenty of time on your hands you might want to look at
DOC VEDMANUAL DOC VEDUSERGUIDE