@node Interpreter, Variables, Description, Top @chapter Facilities within the Command Interpreter This is a guide to the use of SM variables, the macro processor, the help command, and the history facilities. The vector arithmetic and plotting facilities are described below. Various examples are scattered throughout the text, to give some guidance on the use of SM's capabilities. @findex quit Perhaps the most important thing to know is how to escape from SM. If you have a prompt, simply type @code{QUIT}@footnote{or @code{q} which is a macro defined as @code{DELETE HISTORY QUIT}. This will exit SM just the same, but the @code{ quit} won't appear on your history list, waiting to be playedback accidently. Actually, @code{q} will query you before quitting}. If you are running some command, try @ctrl{C} to get a prompt. Most commands will eventually return control to the keyboard following a @ctrl{C}. In addition, the parser is reset, and the input buffer cleared. Sometimes @ctrl{C} leaves a @} on the buffer if it thinks that it'll help get back to the prompt, which can generate an irrelevant syntax error. Occasionally it can still be confused -- try typing a few characters and maybe a @}. @findex weird, can't get prompt When you have interrupted SM with a @ctrl{C}, a macro called @code{error_handler} is executed, if it is defined. The one that we provide does things like setting the expansion back to 1, and resetting any window commands that you might have issued, and then prints a message @code{handler...} to tell you that it's done its work. If you don't like this, see `private initialisation' in the index for how to get your own handler loaded automatically. @findex errors, handler for @findex macros, error_handler @findex handler, see errors If you make a mistake, and SM notices a syntax error, it'll print a message indicating where you were and which macro you were running. It is possible for the wrong macro to be reported (if SM has finished reading the macro before detecting the error), in which case you'll be told that the error occurred in a macro that called the offender. Setting @code{VERBOSE} (@pxref{Verbose}) to 3 or 4 provides a more direct way of finding the true location of the error. @findex syntax error @findex weird, wrong macro in message If you define the variable @code{traceback} to be 1 (maybe with the line @code{traceback 1} in your @file{.sm} file) @findex .sm, traceback @findex macros, traceback @findex traceback on error you'll get a traceback of what macros were active when the error occurred; the same caveats about the wrong macro being reported apply. In addition, the usual interrupt capabilities of your operating system will work under SM, with a couple of quirks. @findex interrupts Under Unix, in case of emergency, type @ctrl{\}, and SM will ask you if you want to return to the prompt, and if you don't it'll offer a core dump, and then exit. As usual, typing @ctrl{Z} (from the C-shell) will interrupt the process, which may be restarted later. Under VMS, @ctrl{Z} will interrupt SM, and return you to the command interpreter (DCL). Typing @code{CONTINUE} will then allow you to restart SM@footnote{If you are using VMS, you may prefer to use @ctrl{Y} as your interrupt character. A suitable set of key definitions is in a file called @code{maps_vms.dat} in the top SM directory. It may be read with the @code{READ EDIT} command (@pxref{Key Bindings}), and this may be done automatically in your @code{startup} macro by the variable @code{edit} in your @file{.sm} file.}. @findex VMS, keybindings @findex VMS, spawned processes If SM is running in a SPAWNed sub-process, then @ctrl{Z} will reATTACH you to its parent. To continue SM, use the DCL ATTACH command. We strongly suggest that you learn how to do this, it makes life much easier -- all you have to do is SPAWN a process from DCL and start SM from there. Do check with your VMS system manager to ensure that you have the right quotas for SPAWNing (Process limit must be at least 3, because SM will use one for itself and one for hardcopies). An especially simple way to do all this is is to use the command file @file{kept_SM.com} in the main SM directory. It'll handle the spawning and attaching for you. @findex VMS, quotas Another fact to bear in mind is that the characters @key{^}, @key{$}, and @key{#} are special, as @key{^} is used by the history system, @findex special characters, $ @findex special characters, # @findex special characters, ^ @findex special characters, \ @findex continuing long lines @findex long lines, continuing @key{$} introduces a variable, and @key{#} starts a comment. The special meanings of all of these characters except ^ can be turned off by preceding them with a \. To type a ^, use the quote_next character (initially @ctrl{Q} or ESC-q) to quote the ^; i.e. type @code{ESC-q}.@footnote{In fact you can rebind any character to replace @key{^}, @pxref{History Editor}} A @code{\n} is interpreted as a carriage return, and a @key{\} as the last character on a line escapes the newline, so that the line and the one following it are treated as one long line. A @key{\} preceding any other character (except a @key{"}; see next paragraph) is simply a @key{\}. This character is used to set font types in the @code{LABEL} commands, so it has no special meaning to the command interpreter, which simplifies the entering of strings for @code{LABEL} commands. @findex special characters, arithmetic A further problem is that symbols such as @key{+}, @key{-}, @key{*}, and @key{/} are used to separate words, which is what you want for mathematics, but maybe not what you had in mind for filenames. @findex double quote @findex special characters, " @findex single quote @findex special characters, ' Enclosing a word in double quotes turns off all special meanings except @key{^}; an embedded @key{"} may be escaped with a @key{\}. Single quotes are used quite differently; enclosing a word in 'single quotes' makes it into a string so @code{'12'} is a two-character string and not an integer at all. There are times when this is important; for example @code{if(y == 'yes')} tests if the vector @code{y} is equal to the string `yes', whereas @code{if('yes' == 'yes')} asks whether two identical strings are equal (they are). When you remember that I can legally say @code{set yes='no'} you'll appreciate the distinction. @findex quoting, 'single quotes' @findex quoting, "double quotes" The characters @code{@{@}} also perform quoting, turning off the special meanings of all characters (including single and double quotes, but not @code{^}). The difference between double quotes and braces is that the latter have grammatical value; they are part of the syntax that SM understands. In most cases you can use angle brackets instead of curly ones if the grammar needs the brackets but you don't want to turn off expansions (@pxref{Variables}). @findex quoting, @findex quoting, @{curly brackets@} SM is case-sensitive. It will accept keywords in either upper or lower case, but this is a special dispensation on its part. If you insist on typing in uppercase say @code{load uppercase} when you first start SM, or put the line @code{uppercase 1} in your @file{.sm} file. @findex uppercase, making SM understand Furthermore keywords may not be abbreviated. This is not a great hardship as it is easy to define macros which make the minimum abbreviation a synonym for the full command. Many such macros are predefined for you when you first use SM; see @ref{Libraries} for details. In particular, certain common abbreviations of commands have been predefined by the SM startup file. @findex case sensitivity @findex .sm @findex environment file, see .sm Every time that SM is started, it looks for an environment file called @file{.sm} which consists of names of variables and their values. From # to the end of a line is taken to be a comment. A list of directories to be searched in order for @file{.sm} files is compiled into SM, it usually consists of the current directory, then your home directory, and then some system directory. The system default can be over-ridden by defining the environment variable @code{SMPATH} which is a list of directories separated by single spaces. Each directory on the search path is tried in turn until a file is found containing the desired variable, which allows your choices to take preference over those of the system administrator. In the list of directories @code{.} is taken to be the current directory, and @code{~} is your home directory unless you specified a command line @code{-u name} option, in which case it is taken to be name's home directory instead. This means that @code{sm -u name} will usually run SM as if you were @code{name}. If @code{name} is @code{null}, then SM won't look for a @file{.sm} file in anyones home directory. @findex command line, other user @findex .sm using someone else's @findex .sm omitting your ~/.sm The default path is equivalent to an @code{SMPATH} of @example export SMPATH=". ~ /u/sm/lib/" @end example @noindent (or an equivalent incantation). Note that the directory @code{/u/sm/lib/} ends in a @code{/} so that a filename can be directly appended (on a VMS system it would probably end in a @code{:} or @code{]}). @findex .sm search path @findex SMPATH variable An example file would be (the filenames are written in Unix) @example # I'm a comment line fonts /users/sm/fonts.bin graphcap /users/sm/graphcap help /users/sm/help/ macro /users/sm/macros/ name Robert # Or alternatively `Dr._Lupton' @end example @findex .sm, fonts @findex fonts, .sm The @code{fonts} file contains the SM fonts (in a binary form), @findex .sm, graphcap @findex graphcap, .sm the @code{graphcap} entry is used to define the file used to describe graphics terminals (@pxref{Graphcap}), @findex help, .sm @findex .sm, help @code{help} is the directory used by the help command, @findex .sm, macros @findex macros, .sm @code{macro} is the default directory where macros reside, @findex .sm, name and @code{name} is what SM will call you (you can put spaces into your name by using underscores, e.g. @code{My_Lord} will be referred to as @code{My Lord}). You can access entries in the environment file yourself, as described in the section on variables. See the section @ref{Libraries} to see how entries in the @file{.sm} file are used to influence the behaviour of SM, or consult your local expert. You might want to borrow someones @file{.sm} file when you first use SM, although you should do fine without one. For more detail, and further special entries, see @ref{Environment Variables}. @findex command line, environment file @findex .sm, specified on command line The name of the @file{.sm} file can be specified on the command line as ``@code{-f name}'' or you can ask to use @code{name}'s .sm file with @code{-u name}. VMS users should ensure that SM has been installed as a foreign command to take advantage of these capabilities. @findex command line, specifying .sm file @findex initialisation, see startup @findex startup, @code{default} macro @findex startup, macros SM then tries to read in any macros in the file @file{default} in the directory @file{macro} and attempts to execute the macro @code{startup} if it exists. @findex startup, command line @findex command line, macro files If @code{-m filename} appears on the command line, this is taken to be the name of another file of macros and these are read, and the eponymous macro is executed (after any pre- or suf- fix has been removed. For instance if you start SM with the command @code{sm -m /home/tst.m}, it will first read the file @code{/home/tst.m}, and then attempt to execute the macro @code{tst}).@footnote{Under VMS, SM must have been installed as a foreign command for this to work, and it must @emph{not} have been linked with the debugger} @findex VMS, foreign command @findex command line, commands Anything left on the command line is treated as if it had been typed at the prompt, for example @code{sm restore vital.save} will start by @code{RESTOR}ing from the file @code{vital.save} (see @code{RESTORE} if you want to know what this means). The @code{-m} option is not really a good way to personalise SM. The @code{startup} macro discussed under `useful macros', which is run every time that you start SM, looks for a directory @code{macro2} in your @file{.sm} file, and if it is there reads a file @file{default} from it, and executes the macro @code{startup2} which it expects to find there. On case-insensitive operating systems, such as VMS, you may need to quote the command line to prevent it being translated to upper case. SM then @findex startup, history file attempts to read a set of history commands from a file in the current working directory, passes control to the input routine and issues a prompt. The file is given by the entry @code{hist_file} in your @file{.sm} file, and if it isn't present then no history will be remembered. @findex .sm, history file You are then able to type commands, as many as will fit on one line@footnote{Occasionally a is required by SM, so putting two commands on one line will give a syntax error. The cause is the way that the grammar is written (@pxref{Command Internals}), the fix is either to use two lines, or else to put an explicit carriage return at the appropriate point with a \n}, and use the features described below. You can use a combination of these features to run SM in `batch' mode. If you had a history file that you just wanted to run, then you could start SM, say @code{playback}, and quit. You could have a macro called @code{batch} in @code{batch.m} that did just that, and say @code{sm -m batch.m} to execute it. In fact, you don't even need your own macro as one is pre-defined for you so @code{sm batch} is sufficient. You could write your own macros along this lines to do more complex tasks. @findex batch, running SM in A more convenient alternative (under unix) would be @code{sm -S < history_file} where the @code{-S} is explained in the next paragraph. For completeness, we should mention the other command line flags, @code{-h}, @code{-l logfile}, @code{-n}, @code{-q}, @code{-s}, @code{-S}, @code{-v#}, and @code{-V}. @findex command line, logfile @findex command line, quiet @findex command line, no startup macro @findex command line, stupid @findex command line, verbose @findex command line, version number The @code{-h} prints a summary of command line options, if you specify a logfile with @code{-l} everything that you type at the keyboard is copied into the logfile (except editing commands). When you start SM it usually runs a macro @code{startup}; @code{-n} prevents this. The @code{-s} (for `stupid', or `silent' or `suppress') flag disables the command line editor (although the history list is still saved, so commands like @code{playback} will work), @code{-q} suppresses the initial `Hello' message, and @code{-S} is like @code{-s} but it also suppresses the prompt and stops SM from intercepting @ctrl{c}. You can get the same effect as @code{-s} from inside SM with the command @code{TERMTYPE none}. If you are reading from a file or pipe SM behaves as if you had invoked it with the @code{-S} flag. @findex prompt, suppressing This is useful if SM is being run from inside another programme, via a pipe (VMS: mailbox), or on a @emph{very} stupid terminal. @findex command line, suppress echo If you want to set a particular value of verbose, use @code{-v} for example @code{-v-3} is equivalent to the @code{VERBOSE -3} command given interactively. If you want to know SM's version string without starting SM, you can use the @code{-V} flag. @node Variables, History Editor, Interpreter, Top @chapter String Variables @findex variables, introduction @findex variables, syntax Some SM users seem to be confused by variables and vectors; if you are one of these, the section on quoting (@pxref{Quoting}) might help. SM maintains a set of variables which are defined with one of the statements @example DEFINE name value @end example @noindent @tex \vskip-20pt @end tex or @tex \vskip-40pt @end tex @example DEFINE name @{ value_list @} @end example @noindent @tex \vskip-20pt @end tex or @tex \vskip-40pt @end tex @example DEFINE name ( expression ) @end example @noindent where @code{name} must consist of digits, letters and `_' (but must not start with a digit), and may be a keyword. @findex variables from keyboard @code{Value} may be a word or a number. @code{Value_list} has no such restrictions and may contain many words. Note that due to the presence of the @{@}, variables are not expanded (i.e. replaced by their value) in @code{value_list}, whereas they are in @code{value}. In fact, the list can be delimited by @code{<>} rather than @code{@{@}}; see @code{DEFINE} for details. The expression in @code{DEFINE variable ( expr )} should be a scalar; if it is not, the first element of the vector will be used and you will be warned, if @code{VERBOSE} (@pxref{Verbose}) is one or greater. @findex verbose, variables Sometimes you just want to evaluate an expression and treat the answer as a string; in this case use the special vector form @code{$(expr)} which is replaced by the value of the expression --- for example @code{echo e is $(exp(1))}. Expressions are further discussed under `Vectors and Arithmetic'. There are a number of special variables whose value is always the current value of some internal SM variable such as the current position or the point type. The variable ``date'' is also special and expands to give the current time and date, --- try typing @code{echo $date}. You can freeze these variables at their current value by saying @code{define name |} (see below). @findex variables, use @findex grammar, variables Each time SM reads @code{$name} it replaces it by its value, considered as a character string. For example, @example DEFINE hi hello WRITE STANDARD $hi @end example @noindent will print @code{hello}. This expansion is done before even the lowest level of lex analysis, so if a command is attempting to read a value it is possible to give it the name of a SM variable. An example would be the @code{XLABEL} command, which writes a string as the x-axis label of a graph, @example DEFINE name Aelfred @end example @example XLABEL My name is $name @end example @noindent will invoke the @code{XLABEL} command, and write @code{My name is Aelfred} below the x-axis. (Incidentally, @code{DEFINE Aelfred Aethelstan YLABEL $$name} will write @code{Aethelstan} as the y-axis label, which can be handy in macros. The use of the double $$ indicates to SM to do a double translation, as it first expands to @code{$Aelfred} which then expands to @code{Aethelstan}). @findex variables, deletion A variable can be deleted by @code{DEFINE name DELETE} so for example the macro @example MACRO undef 1 @{ DEFINE $1 DELETE @} @end example invoked as @example undef name @end example @noindent will undefine the variable @code{name} (see the section on macros if you are confused). @findex variables, special values @findex .sm, defining variables @findex variables, from .sm @findex variables, accessing internal There are also three special @code{values}, @code{:}, @code{|}, and @code{?}. The command @code{define name :} means `get the value of name from the environment file'. If this fails, and if the variable is all uppercase, SM will then try to use the value of an environment (VMS: logical) variable of the same name. Using @code{define name ?} means `read the value of name from the keyboard'. You can specify a prompt to be used, see @code{DEFINE} for details. The form with @code{|} has changed a little with version 2.1.1. The variables that you can use with @code{|} have not changed, but their usage has slightly. They are all defined for you when SM starts and each is always correct, tracking the current value of the corresponding internal variable. For example, try @code{echo $angle angle 45 echo $angle}. If you now say @code{define angle |}, @code{$angle} will cease to track the internal value and will remain fixed (the same effect can be achieved with @code{define angle 45}). When you say @code{define angle delete} it will once more track the internal value. Your old code will continue to work, but in many cases it is possible to remove the explicit definition with @code{|}. This special sort of variable will not be @code{SAVE}d, and will not show up if you list the currently defined variables. A list of the @code{|} variables is given in the section on @code{DEFINE}. So using the example @file{.sm} environment file listed in the previous section of the manual, @code{DEFINE name :} will define @code{name} to be @code{Robert}, @code{DEFINE angle |} will give the last value set by the @code{ANGLE} command, and @code{DEFINE datafile ?} will ask you for the value of `datafile', which can be useful in macros. For example, @example DEFINE noise ? @{ Ring bell? @} IF('$noise' != 'n') @{ bell @} @end example @noindent will execute the macro @code{bell} if you type anything but n in reply to the question `Ring bell?'. @findex variables, testing if defined @findex variables, from internal values When writing macros, it is also sometimes useful to know if a variable has been defined. The variable @code{$?name} has the value 1 if @code{name} is defined, otherwise it is 0. For instance, there is a line @example define term : if($?term) @{ termtype $term @} @end example in the startup file, to set a termtype if present in the environment file. @findex variables, from data files There are also commands to read the values of variables from data files defined with the @code{DATA} command. @table @code @item DEFINE name READ i or @item DEFINE name READ i j @end table will set @code{name} to be the i'th line of the file (or the j'th word of the i'th line). An example is given in the section on `useful macros'. You can read variables from the headers of binary files (specified with the @code{IMAGE} command) using @code{DEFINE name IMAGE}, although this is only supported for a limited class of @code{file_type}'s (@pxref{2-D Graphics}). All currently defined variables may be listed with @findex variables, listing @findex listing variables @example LIST DEFINE [ begin end ] @end example @noindent where the optional @code{begin} and @code{end} define the range of variables (alphabetically) to be listed. You might prefer to use the macro @code{lsv} which won't appear on your history list. @findex variables, within double quotes Variables are usually not expanded within double quotes or @{ @}. If for some reason you need to force expansion within double quotes, it can be done with @code{$!name}. @findex variables, forcing expansion The macro `load' discussed under useful macros gives an example of this mechanism. If you need to expand a variable, with no questions asked (and even within @{@}), use @code{$!!name}. @findex variables, concatenation Sometimes you may want to terminate a variable name where SM doesn't want to, and this can be done with a trick involving double quotes. Say you are writing a macro to find all the stars redder than B-V = 1.0 in a set of data vectors, and you want to rename them with a trailing ``_red'', so @code{star} goes to @code{star_red}. So you write a foreach loop, @example FOREACH x ( U B V R I J K ) @{ SET $x_red = $x IF(B-V >1)@} @end example @noindent Well, that won't work because SM thinks that you are referring to a previously defined variable named @code{x_red}, so it will complain that @code{x_red} is not defined. But if you write it as @code{$x""_red} the @code{""} separate the @code{x} from the @code{_red} until @code{$x} is expanded, and then disappear, and all is well. When a variable is read, SM skips over all whitespace before the definition, and this can cause problems if you hit @ctrl{C} in the middle, as the rest of the command will be thrown away. If you ever hit a @ctrl{C}, and can't get a prompt, try typing any non-whitespace character. @findex weird, can't get prompt @findex variables, are not vectors @findex vectors, are not variables Variables are @emph{string}-variables, and are not primarily designed for doing arithmetic (that's what vectors are for). This is a common source of confusion so let's consider some examples (at the risk of anticipating some later sections of the manual). @example DEFINE a 12 @end example @noindent defines a variable @code{a} which consists of the two characters `1' and `2', and which can be used @emph{anywhere} --- for example @code{xlabel $a}. What about vectors? Consider @example SET x=10 @end example @noindent which defines a single-element vector whose value is ten, ready to be used in expressions such as @example SET y=$a + x*12 @end example @noindent Note that the @code{$a} is @emph{still} just the two characters `1' and `0', but in this context that is interpreted as the number ten. So what does @example DEFINE y $a+x*12 @end example @noindent do? Well, actually it results in a syntax error (the `+' ends a word), so try @example DEFINE y <$a+x*12> @end example @noindent This defines the variable @code{y} as the string `10+x*12', it doesn't evaluate the expression. You can evaluate the expression if you want with @example DEFINE y ( $a+x*12 ) @end example @noindent which defines @code{y} as the string `130'. Incidently, you can sometimes get away without an explicit variable with the syntax @code{$($a+x*12)} which also expands to the string `130'. The fact that variables are simply strings can be used to build complex commands; consider for example the macro @example readem # read multiple lines columns with names in row 1 READ ROW names 1.s DEFINE rc <$(names[(0)]) 1> DO i=2,DIMEN(names) @{ DEFINE rc <$rc $(names[($i - 1)]) $i> @} LINES 2 0 READ < $rc > @end example @noindent @findex reading named vectors which reads the names of a set of columns from line 1, builds a command to read the data in the variable @code{rc}, and then reads all the data in one command. You could of course loop through @code{names} reading each column in turn, but this should be a good deal faster. By default variables are global, so if you have a variable @code{$i}, and a macro that you call also uses a variable @code{$i}, the macro will change the value that you so carefully defined. To avoid this, it is possible to force variables (and also vectors) to be local, using a command like @code{DEFINE i LOCAL}; in this case the variable @code{$i} will softly and suddenly disappear when you leave the current macro (and therefore you cannot make variables local at the topmost level, i.e. at the command prompt). In fact, such variables aren't strictly local, they have what's called nested scope, as they are visible from any macros that you may call --- they simply do not propagate backwards up the call stack. You are free to make a variable local in any (or all) macros, there's no restriction on how deep such local declarations may be nested. @findex variables, local @node History Editor, Key Bindings, Variables, Top @chapter Command History @findex history, introduction It is often very useful to be able to repeat a command, or perhaps correct a mistake in what you have just typed. Ways of doing this are usually referred to as `history', and SM has two distinct mechanisms. One is very similar to that of the Unix C-Shell, and the other allows you to edit commands using a syntax similar to the popular editor `emacs', or a generalisation of the DCL history under VMS. If you are not familiar with Unix, emacs, or VMS don't despair; a description of the commands and how to invoke them follows in this document. Both of these mechanisms are implemented by the routine which reads input lines. As each line is sent to the parser, it is copied onto a history list. This list may be printed with @code{HISTORY}, and the commands may be @findex history, listing @findex history, re-using commands re-used by referring to them by number, as @code{^nn}, or by a unique abbreviation, as @code{^abbrev}. In addition, the last command may be repeated by using @code{^^} and the last word of the last command by @code{^$}.@footnote{ @code{^^} and @code{^$} really do get back the last command typed, even if it isn't on the history list. If you want the last remembered command, use up-arrow or @code{^P}} These symbols are expanded as soon as they are recognised (see examples, or experiment), and are then available for modification by the editor. Sometimes a @code{^string} will retrieve a command beginning @code{string}, but not the one that you want. Version 2.1.1 no longer supports the use of @code{^TAB} to search for the next-most-recent command beginning @code{string}, but you can use the search commands (@ctrl{R} and @ctrl{S}) instead. Some people really don't want @code{^} to be their history character, either because they're used to something else (such as !), or because they want to type lots of real @code{^}s (e.g. you are using @TeX{}-style strings); if this describes you, rebind them -- see the next section. If you are considering the history list as a sort of programme to be repeated you may think that @code{HISTORY} lists the commands in the wrong order; if so use @code{HISTORY -}. @findex history, listing backwards For example, if I type: @example PROMPT @@ echo I like SM HISTORY @end example @noindent SM will set the prompt to be @code{@@}, replace the macro @code{echo} by its value @code{WRITE STANDARD} and print @example I like SM @end example and then @example 3 HISTORY 2 echo I like SM 1 PROMPT @@ @end example @noindent (The actual numbers will be different, depending on what other commands you have executed, and also because SM may have read a history file. In that case there'll be many more commands on the list, but no matter.) If I then type @example ^2 @end example @noindent (that is ^2 not control-2) the screen will look like @example @@ echo I like SM I like SM @end example @noindent as if I had just typed it in (@code{@@} is the prompt) . Typing @example ^^ (Yes, ^$ ) @end example @noindent will now result in SM printing (truthfully) @example I like SM (Yes, SM ) @end example @findex history, deleting commands It is possible to delete commands from the history buffer with the @code{DELETE} command. If the command is given with zero, one, or two arguments, then the specified range is deleted (but their numbers are not re-used). If no arguments are given, the last command on the buffer is deleted, and its number is released to be re-used. In other words, the command @code{DELETE} will delete first itself, and then the previous command from the history list. The command @code{DELETE HISTORY} only removes itself from the history list, and several of the common commands are defined as macros which use it, for instance @code{dev} is defined as @code{DELETE HISTORY DEVICE}. This means that the command will not appear on the history list, to confuse you when you do a playback. But if you now innocently use @code{dev} in a macro, that macro won't appear on the list either. Still worse, if you use @code{dev} twice in one macro, the previous command will be deleted as well which could be quite confusing. @findex weird, lost commands @findex lost commands You can also delete lines of history using @code{ESC-@ctrl{D}} as described shortly. The numbering is consecutive, starting at zero. Each command retains its number until you use a @code{HISTORY} command to list the remembered commands, in which case they are all renumbered, and it is these new numbers that are listed. By default only 80 lines are remembered, and as you continue typing earlier ones fall off the list. @findex history, number remembered Because the history buffer is also used to compose complex commands, this limit can be aggravating. You may be able to defeat this by putting many commands on each line (you may have to use @code{\n} to terminate label commands explicitly) or by writing macros. Alternatively you can define a longer history buffer when you start SM by including an entry @code{history} in your environment file @findex .sm, history which gives the number of commands to be remembered. If you set @code{history} to be @code{0} the history list is made infinitely long. Incidently, it is the total number of commands that matters, not the range of history numbers present. This limit on the number of history lines isn't enforced while writing a macro onto the history list (using @code{WRITE HISTORY}). You can use this fact to write a sneaky macro that extends your history; type @code{HELP extend_history} if you are interested. @findex extending history buffer @findex history, extending buffer Some people seem to like their history editors to remember where they were, so that after they retrieve and execute a command the next @ctrl{P} or @tex $\uparrow$ @end tex @ifinfo up-arrow @end ifinfo will retrieve the command one further back on the history list (that is, if you have just retrieved command number 123 and executed it as command number 234, then @ctrl{P} will get you command number 124; you can execute it as command number 235). If this describes you, define the variable @code{remember_history_line}, which you can either do directly, or by putting a line @code{remember_history_line 1} in your @file{.sm} file. @findex .sm, remember_history_line @findex history, editor @findex edit, history The editor allows you to modify commands, either as you type them or as you retrieve them from the history list. The various editing commands may be bound to keys of your choosing, but the default bindings are given in this list of possible commands: @findex edit, commands @findex edit, bindings @table @code @item @ctrl{A} Go to start of line. @item @ctrl{B} Go back one character. (Equivalent to @tex $\leftarrow$ @end tex @ifinfo left-arrow @end ifinfo ). @item @ctrl{C} Interrupt (as usual). @item @ctrl{D} Delete character under cursor. @item @ctrl{E} Go to end of line. @item @ctrl{F} Go forward one character. (Equivalent to @tex $\rightarrow$ @end tex @ifinfo right-arrow @end ifinfo ). @item @ctrl{H} Identical to @ctrl{?} (DEL). Delete character to left of cursor. @item @ctrl{I} (TAB) Insert spaces up to the next tab stop. By default a tab is taken to be 8 characters wide, but this may be changed by specifying @code{tabsize} in your @file{.sm} file. @findex .sm, tabsize @item @ctrl{J} (LF) Equivalent to @ctrl{M}. @item @ctrl{K} Delete to end of line. The deleted string is stored, and may be restored using @ctrl{Y}, repeatedly if so desired. @item @ctrl{L} Redraw the current line. @item @ctrl{M} (CR) Send line to be executed. Some terminals seem to replace @ctrl{M} with a linefeed (@ctrl{J}), thereby making it impossible to make SM obey you. We therefore make @ctrl{@@} equivalent to @ctrl{M} for emergency use. (This is control-space on many terminals). @findex weird, behaviour of keys @item @ctrl{N} Get the next command on the history list, if it exists (see @ctrl{P}). (Equivalent to @tex $\downarrow$ @end tex @ifinfo down-arrow @end ifinfo ). @item @ctrl{O} Execute the previous command on the history list. Equivalent to @ctrl{P}@ctrl{E}@ctrl{M}. @item @ctrl{P} Get the previous command on the history list, if it exists (see @ctrl{N}).(Equivalent to @tex $\uparrow$ @end tex @ifinfo up-arrow @end ifinfo ). @item @ctrl{Q} Quote next character; Turn off any special significance to the editor. @ctrl{Q} is often used by the terminal, so we have defined @ctrl{[}-q (that is escape followed by q) as an alternative. @item @ctrl{R} Search backwards (reversed) for a string; the opposite of @ctrl{S}. The `string' can actually be any regular expression (see the manual entry for @code{APROPOS}). If you specify a zero-length string (i.e. simply hit carriage return) the previous search string will be reused. @item @ctrl{S} Search forward for a string; the opposite of @ctrl{R}. @ctrl{S} is often used by the terminal, so we have defined @ctrl{[}-s (that is escape followed by s) as an alternative. @item @ctrl{T} Toggle insert/overwrite. By default, characters are inserted before the cursor. If overwrite is set, they replace the character under the cursor. Note that ESC-u will not correctly restore words deleted with ESC-d in overwrite mode. @item @ctrl{U} Delete from the cursor to the start of the line. @item @ctrl{V} Go forward 5 lines. @item @ctrl{W} Delete the previous word. Identical to ESC-h @item @ctrl{Y} Insert the string most recently deleted with @ctrl{K} after the cursor. @item @ctrl{Z} Return to the operating system, without killing SM. (Under VMS, if you are running SM in a spawned subprocess @ctrl{Z} will attach you to DCL. Otherwise, SM returns you to DCL.) @item @ctrl{?} (DEL) Equivalent to @ctrl{H}. @item ESC-@ctrl{D} Delete this line and remove it from the history list. Note that this is different from just clearing a line with (e.g.) @ctrl{U}, which only erases a @emph{copy} of the line. @item ESC-< Go to the first line of a macro, or the oldest history command. @item ESC-> Go to the last line of a macro, or the most recent history command. @item ESC-g Go to a given line of a macro, or a given history command. You'll be prompted for the line number, if you change your mind you can get out with DEL or @ctrl{H}. @item ESC-q Quote the next character, turning off any special significance to the editor. Identical to @ctrl{Q}. @item ESC-s Search forward for a string. Identical to @ctrl{S}. @item ESC-v The opposite of @ctrl{V}, go back 5 lines. @item ESC-y Like @ctrl{Y}, except that it gets older deletions, cycling back through a collection of (currently 5) deleted lines. @end table Some ESC-letter combinations are available which operate upon complete words. A word is defined as a whitespace delimited string, so 2.998e8 is a perfectly good word. In addition, it is possible to undelete words that have been deleted with an ESC-d or ESC-h. @table @code @item ESC-b Go to the start of the previous word. @item ESC-d Delete to the beginning of the next word. @item ESC-f Go to the beginning of the next word. @item ESC-h Delete back to the beginning of the current word. The same as @ctrl{W}. @item ESC-u Restore the last word deleted, putting it before the cursor. Further @code{ESC-u}'s will restore more words. When no more are available, the bell is rung. @end table Any printing character is inserted before the cursor (unless overwrite has been set with @ctrl{T} ). Illegal characters ring the terminal bell. If you insert a non-printing character on a line, the cursor may get confused. @findex edit, escaping If ever you are stuck at the command interpreter, and you want to send a signal to the operating system (e.g. a @ctrl{Y} to DCL), but SM is catching the key and using it for its own purposes, the easiest thing to do is to define a macro such as @code{MACRO aa @{aa@} }, and then run it. While it is running (i.e. until you type @ctrl{C}) keys should have their usual functions. @node Key Bindings, Operating System, History Editor, Top @chapter Changing Key-Bindings @findex edit, bindings As mentioned above, it is possible to redefine the meanings of keys to the history (and macro) editor. The command @code{EDIT keyword key-sequence} will make typing that sequence of keys correspond to the command @code{keyword}. For example, to make @ctrl{R} redraw the current line, you could say @code{EDIT refresh @ctrl{R}}. @findex changing key bindings @findex key bindings, changing The keyword can be any in the list below, or any single character. Each character in the key-sequence can be a single character, @ctrl{c}, or @code{\nnn} where @code{nnn} is an octal number. Alternatively, @code{READ EDIT filename} will read a file specifying the new bindings which has two lines of header, followed by pairs of @code{keyword key-sequence}. Lines starting with a # are comments. An example is the file for VMS users given below. A problem can come up with multiple-key sequences. Imagine that you have bound some function to @ctrl{X}@ctrl{A}, for example @example EDIT end_of_line ^X^A @end example @noindent then what happens when you try it? SM sees the @ctrl{X} and uses its default binding, @code{exit_editor}, and then sees a @ctrl{A} and goes to the start of the line, which wasn't the desired effect. The solution is to tell SM that @ctrl{X} is not a legal key, in which case it will either ring the terminal bell (if there are no key-sequences starting with an @ctrl{X}), or wait for the next key. In short, @example EDIT illegal ^X EDIT end_of_line ^X^A @end example @noindent should work. On a somewhat similar topic, the @code{KEY} (@pxref{Key}) command may be used to define a key to generate a string. See the end of the section on macros for how this works. All the current key definitions may be listed using @code{LIST EDIT}, including the @code{KEY} definitions. @findex listing, key bindings The names of operators, and their default bindings, are given in the following table: @findex bindings, names of operators @findex edit, names of operators @table @code @item @ctrl{A} start_of_line @item @ctrl{B} previous_char @item @ctrl{C} @item @ctrl{D} delete_char @item @ctrl{E} end_of_line @item @ctrl{F} next_char @item @ctrl{G} illegal @item @ctrl{H}, DEL delete_previous_char @item @ctrl{I} tab @item @ctrl{J} carriage_return @item @ctrl{K} kill_to_end @item @ctrl{L} refresh @item @ctrl{M}, @ctrl{@@} carriage_return @item @ctrl{N} next_line @item @ctrl{O} insert_line_above @item @ctrl{P} previous_line @item @ctrl{Q}, ESC-q quote_next @item @ctrl{R} search_reverse @item @ctrl{S} search_forward @item @ctrl{T} toggle_overwrite @item @ctrl{U} delete_to_start @item @ctrl{V} scroll_forward @item @ctrl{W}, ESC-h delete_previous_word @item @ctrl{X} exit_editor @item @ctrl{Y} yank_buffer @item @ctrl{Z} attach_to_shell @item ESC-< first_line @item ESC-> last_line @item \034 escape @item ESC-b previous_word @item ESC-d delete_next_word @item ESC-f next_word @item ESC-g goto_line @item ESC-u undelete_word @item ESC-v scroll_back @item ESC-y yank_previous_buffer @item ESC-@ctrl{D} delete_from_history @item ^ history_char @end table @findex VMS, keybindings A simple example of a bindings file for a hardened VMS user might be @example # This is a set of DCL-ish key maps for SM # name key toggle_overwrite ^A start_of_line ^H delete_previous_word ^J yank_buffer ^R search_reverse ^[r attach_to_shell ^Y @end example @noindent Note that that's the two characters @code{^} and @code{A} not control-A. It could just as well have been written @code{\001}. We need a new character for @code{yank_buffer} now that @ctrl{Y} is otherwise engaged, and I have chosen @ctrl{R} (which means that I can't use @ctrl{R} to search backwards, so I chose @code{ESC-r} for @emph{that}). You should be warned that some terminal protocols map @ctrl{M} to @ctrl{J}, so this use of @ctrl{J} could render you unable to issue commands. As mentioned above, in an emergency @ctrl{@@} can be used instead of @ctrl{M}. When SM is started, or whenever the @code{TERMTYPE} command is used to change terminals, the arrow keys are bound to the commands @code{previous_line}, @code{ext_line}, @code{previous_char}, and @code{ext_char}. For terminals such as a Televideo-912, which uses characters such as @ctrl{K} for arrow motion, these can supersede the previous meanings (in this case @code{kill_to_end}); The only fix is to use the @code{EDIT} or @code{READ EDIT} command to get what you want, probably within a macro. @findex weird, behaviour of keys @findex edit, bindings If you want to use @code{'} as your history character instead of @code{^} you need to say @code{edit history_char ` edit ^ ^}. If you try to use a character special to SM such as ! this won't work (you'll get a syntax error) and you'll have to use the next alternative, namely put the commands into a file and say @code{read edit filename}, for example: @example # Change the history character # name key history_char ! ^ ^ @end example @noindent Because this particular change is so common, it's possible to specify that @code{`} be your history character simply by including a line @code{history_char `} in your @file{.sm} file (or you can choose your own character. Choosing 0 has the effect of using the default, @code{^}). @findex .sm, history_char @findex history, changing character @findex edit, termtype @findex termtype @findex alphanumeric, see terminal @findex screen, see terminal SM needs to know something about the terminal that you are using, so as to run the history/macro editor. This is entirely separate from the problem of describing the terminal's graphics. It will try to discover what sort of terminal you're on by using the value of @code{term} from your @file{.sm} file, @findex .sm, term or failing that the value of the environment variable @code{TERM} (Unix) or the logical variable @code{TERM} (VMS). A @code{term} entry of @code{selanar -21} is equivalent to a @code{TERMTYPE selanar -21} command. You can also use the @code{TERMTYPE} command directly. SM then uses the terminal type specified to look up its properties in the termcap database (@pxref{Termcap}). You can also use @code{TERMTYPE} to specify the size of the screen, or to turn off SM's idea of where the cursor is. On some terminals, you can only send a cursor to an absolute position and this is chosen to be the bottom of the screen. This is not what you want for, e.g., a VT240 as it will lead to your graph scrolling off the screen. The use of a negative screen size to @code{TERMTYPE} will disable this cursor motion, but will also make editing lines slower. If a line of your graph is being deleted when the SM prompt appears, you may need to use @code{TERMTYPE dumb} or @code{TERMTYPE none}. @findex terminals, specifying screen size @findex terminals, graph scrolling off screen @findex weird, behaviour of alpha cursor @node Operating System, Macros, Key Bindings, Top @chapter Talking to the Operating System @findex VMS, DCL escape @findex shell escape Any line from ! to the newline is passed to your shell (DCL under VMS, the Bourne shell under unix. If you set the variable @code{SHELL} in either your @file{.sm} file or the environment it will be used instead; the former takes priority).@footnote{The first of these commands in a SM session may be rather slow under VMS, as we have to spawn a subprocess.} @findex .sm, SHELL For example, @code{!ls} or @code{!directory} will list the current directory. The return code from the command is available in the variable @code{$exit_status}, on unix systems it will be 0 for success, for weirder systems you should look in the system manual for the return value of the C function @code{system}. @code{$exit_status} is one of the variables that can be set with @code{DEFINE exit_status |}. @findex internal variables, exit_status It is also possible to change the directory that SM uses to look for data or macro files with the @code{CHDIR} command - for instance @code{CHDIR "../more_data"}@footnote{Unfortunately, this is currently not available to VMS users}. If a directory name starts with `~', @code{CHDIR} replaces the `~' with your home directory. This is the only place that `~' is treated specially, for instance it is not interpreted by the @code{DATA} command. Because directory names often contain mathematical characters such as @code{[} or @code{/}, it is wise to quote the directory, or use the macro @code{cd} which quotes it for you. @findex changing directory @findex current directory