home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Monster Media 1994 #1
/
monster.zip
/
monster
/
WP
/
M10.ZIP
/
M.TUT
< prev
Wrap
Text File
|
1994-01-31
|
45KB
|
868 lines
The M Tutorial File
You may ask why this editor is called M... It is called M because it is My
editor... the editor I wrote, Mine. It can be your editor too.
In this file I will walk you through the features of M. To walk around in
this text, use the arrow keys, [pageUp], and [pageDown]. They behave like
you would expect them to... As a preliminary, I'll explain notation.
Characters in square brackets are M commands... (This is to set them off
from the rest of the text.) The Alternate and Control keys are used like
the shift key. In this tutorial I'll abreviate Control by a caret "^" and
Alternate by "Alt".
For example:
[^X] is Control_X
[Alt G 2] is Alt_G and then 2.
[^X ^F] is Control_X Control_F
[Alt ^M] is Alt_Control_M
In the event you want to EXIT right away... there are two principal ways to
exit M... The first is the exit without saving [^X ^C], if there are no
modified files you will be out. If there are modified files you will be
told of that fact and asked if you want to save them. If yes, you will be
asked about each file on your way out. ([Escape] and [^G] will abort the
exit.) The second exit method is the save all files and exit [Alt Z].
(The mnemonic is that Z is the last letter in the alphabet, [Alt Z] is the
last thing you type before leaving.)
I begin with an introductory note on the general theory of M. In M
there are windows and buffers (buffers = files). A window is a view into a
buffer and is only loosely connected to a buffer. You can switch the
buffer a window is connected to very easily. You can have many more
buffers open than you have windows to view them. You can also have many
windows open on the same buffer. All combinations are possible. Every
window has a StatusLine with sundry information about the current buffer.
Every window has a current cursor position (although only the active window
has a visible cursor). Every window has a mark. The mark is an old cursor
position used in block delete and block copys. (Occasionally I may refer
to the cursor as the point, I use the terms point and cursor
interchangeably.) The actual location of the cursor is between letters...
The cursor visible on the screen is underneath a letter, the real cursor
location is just in front of that character.
The [Escape] is not treated like other keys in M, typing an
[Escape] prior to another key is equivalent to holding down Alt while
typing that key. You can think of the letters you type as a stream of
characters coming to the program. When you type an [Alt Z] for example I
stick into the character stream first an [Escape] and then a [Z]... You
can just as easily type an [Escape] and then a [Z] yourself... (In some
contexts I peek if there is a character behind the [Escape]... If there
isn't one I know that you have typed a lone [Escape] and not a Alt key
combination. In some situations I interpret a lone [Escape] as an
abort...)
When a new command is described in this text, try it! If that command is
destructive add some garbage text to play with...
For those who are familiar with emacs, M's command structure is very
similar to that. Most common emacs commands are supported with the key
strokes you are used to.
Cursor Motion:
The arrow keys, [pageUp] and [pageDown] keys move like you expect
them... The analogous emacs move cursor commands [^F] forward, [^B]
backward, [^P] up, [^N] down, [Alt V] pageUp and [^V] pageDown keys are
supported. The [Home] and [End] keys work slightly differently than
expected... When you first type [Home] the cursor moves to the front of
the line, the second time it moves to the top of the page, the third time
to the top of the file. The [End] key works similarly.
The emacs commands [^A] front of line, [^E] end of line [Alt <] top of
file, [Alt >] end of file also work.
[^RightArrow] moves right by one word (same as [Alt F]).
[^LeftArrow] moves left by one word (save as [Alt B]).
[^UpArrow] moves up by paragraphs (in Cmode a paragragh is a curly brace).
[^DownArrow] moves down by paragraphs (in Cmode a paragragh is a curly brace).
Notice as you move the cursor the 2 numbers on the StatusLine followin the
buffer name change... they are the line number and the column number. You
can move to a particular line using the goto command [Alt G (number)
Enter]. (You can abort this dialog with an [Escape] or a [^G]; [^G] is
the all purpose abort.)
The last of the simple cursor movement commands is the exchange cursor and
mark command [^X .]. Prior to executing this it is useful to set a mark to
a particular location. Both [Alt Spacebar] and [^Spacebar] set the mark
to the current cursor position. Try setting a mark and switching the mark
and the cursor.
As a final suggestion, I like it better when the cursor moves quickly... I
use the dos mode command in my autoexec.bat to do this for me. In my
autoexec I have:
mode con rate=32, delay=1
Deleting and Copying:
M has a killBuffer that it stores things in. It uses the
killBuffer as a clipboard for block copys and pastes. There are a number
of ways to put text into the killBuffer. The first way is to copy a block
into it. Set a mark [Alt Spacebar] (or [^Spacebar]), move the cursor to a
new position, and do an alt wipe [Alt W]. The text between the mark and
the cursor has been copied into the killBuffer. Next move the cursor to an
empty line and do a Yank [^Y]. Do another Yank, and another... You now
have multiple copies of the text.
Another way to get text into the killBuffer is to do a control
wipe. Like the last time, set a mark [Alt Spacebar] or [^Spacebar], move
the cursor, and Wipe [^W]. This Wipe deletes the text while moving it into
the killBuffer. The deleted text can now be yanked anywhere you want it.
There are more methods of putting text into the killBuffer. You
can kill individual lines with [Alt K] and [^K]. [^K] kills from the
cursor to the end of the line. [Alt K] kills the whole line irrespective
of where the cursor is in the line. If one kill command directly follows
another, instead of throwing out the old killBuffer and replacing it with
the new kill, the killBuffer appends the new kill to the existing
killBuffer. Try killing a whole bunch of lines in a row and yanking them
all back in one yank.
There are a few more ways to wipe text into the killBuffer, you can
kill by words. The [^Backspace] and the [^Delete] are word delete left and
word delete right. Again multiple consecutive kills append into the
killBuffer.
Finally there are some word copys into the killBuffer, [Alt
Backspace] and [Alt Delete]. Multiple consecutive copys append into the
killBuffer. Notice the control commands [^W] [^Backspace] and [^Delete]
are kills while the alt commands [Alt W] [Alt Backspace] and [Alt Delete]
are copys.
There is one more yank feature, the yankPop [Alt Y]. It is easiest
to describe what it does by actually doing it. Move to the line of 1's and
do an [Alt K] immediately followed by a [^Y], do the same thing on the line
of 2's, next on the 3's, and finally on the 4's. Now we are in a position
to show off the yankPop. Move the cursor to a blank line and yankPop [Alt
Y]. And [Alt Y] again and again and again... There is really a ring of 4
different killBuffers. When you kill something it is put into the next
killBuffer so that the last 4 kills are always available. The [^Y]'s yank
the current killBuffer again and again and again. The [Alt Y]'s pivot the
last yank with previous yanks in the killBuffer ring.
11111111111111111111111111
222222222222222222222222222222222222
3333333333333
444444444444444444444
The simple one character [Delete] and [Backspace] do not go into
the killBuffer. (The word deletes do.) (The emacs commands [^D] delete
right and [Alt D] delete word right are also supported.)
There are 2 special White Space deletes, the [Alt ,] which deletes
whitespace right, and the [Alt .] which deletes right and left whitespace.
Try putting your cursor in the middle of the line 5 lines down (between the
ABC and the DEF), and type [Alt ,]. Then move your cursor left a little
bit and [Alt .]. These white space deletes are particularly useful in
macros...
ABC DEF
There are a five other commands that I am listing under the
category of Deletes and Copys... they are:
[^T] transpose characters
[Alt L] lowercase word [Alt U] uppercase word
[Alt C] capitalize word [^C] uncapitalize work
Try them out! Notice for example that the transpose command transposes the
letter the cursor is on with the letter before the cursor except at the end
of line... (there is no character past the end of line)
Undo and Redo:
One of the most useful (important) features in M is the [^-] undo
and the [Alt -] redo. If you hold the [^-] key down, you will undo all the
editing of this file this session. If you hold the [Alt -] key down, you
will see that editing redone. The undo/redo history is essentially
infinite, you are limited by your disk space. Only commands that change
the content of the file are recorded in the undo file. (cursor motion,
searches, etc. are not recorded)
M supports only one undoFuture per file, I'll elaborate. Suppose
you have made 5 changes to a file and you undo the last two of them. At
this point there are still three changes in your history and now a future
of two changes. If you type a letter (make any change to the file) you
will cutoff your old future and begin a new one. You will still have your
history, it will be your old history of three changes plus your newest
insertion. But you will not be able to undo to the earlier state of 5
changes to the file. Hence, be very careful of what you type when you do a
large undo and you plan on redoing...
One of the most common things I do with undo/redo (other than
undoing some command I don't like) is to recover a piece of code that I
deleted very early in the current M edit session... I undo to when the
code block existed. I set a mark [Alt space] and do an [Alt W] copy into
the killbuf. (the copying does not change the file hence has no effect on
the undo/redo history) Immediately I return to the future with [Alt -],
then yank [^Y] the desired block. Now, try undoing back to the beginning
of these instructions...
In the rest of this tutorial you can recover from any command by
[^-] undoing.
Window Control:
The primary window manipulation commands are
[^X 1] make one fullsized window [^X 0] remove this window
[^X 2] split window horizontally [^X 5] split window vertically
[^L] center the cursorline
Try typing [^X 2] [^X 1] and then [^X 5] [^X 1].
(both [^X 2] and [^X 5] gives you two windows... the 5 stands for .5)
The normal window splitting commands keep your screen windows
tiled... M actually supports messy screens of overlapping windows. You
can rearrange and resize your windows to your hearts content with the
following commands. I use these commands only occasionally, they are less
useful...
[Alt endkey] grow window right [Alt homekey] shrink window left
[Alt pagedownkey] grow window down [Alt pageupkey] shrink window up
[Alt (arrow key)] move window
After rearranging the window layout on the screen, the next thing
to do is to put a variety of files in those screens. To open a file type
[^X ^F] and then a filename. If the file does not exist, it will open a
new file. Type [^X 2] and then [^X ^F] [\autoexec.bat]. The [Insert]
pivots through the open files. The [Shift Insert] pivots the other
direction. [^Insert] moves from window to window. (The emacs commands
[^X X] next buffer and the [^X O] other window are supported.) You can
also go to a buffer by name by using the [^X B <bufferName> ] command or
the [^X ^F <fileName>] command.
There is one more major item under window control. They are screen
bookMarks. The current screen configuration can be stored on a stack. You
can push a screen configuration on to the stack with the [Alt +] command
and pop it off with the [Alt =]... When it is popped off that screen is
restored. The [Alt J] command can also be used push or pop screens... You
can go to a particular pushed screen using the [Alt J <digit>] command.
Try doing a push, ([Alt J P] notice a 1 appears between the mode
parenthesis of the StatusLine. Now go to the top of the file with
[Home][Home][Home] and then type [Alt J 1]. You returned to the screen
that was pushed. Unload the the pushed screen with an [Alt =]. Screen
pushes are done automatically when using a tags file [Alt T]. I will
discuss the use of a Tags file in the search and replace section.
File Control:
The next topic is File Control. We have already used the command
to open a file [^X ^F].
The "save file" commands are:
[^X ^S] save this file [^X S] save all modified files
[^X ^W] rename and write this file
[^X ^C] exit querying changed files [Alt Z] exit saving changed files
The "don't save file" commands are:
[^X R] revert to save [^X ^C] exit querying changed files
[^X K] kill this file (get rid of this buffer, doesn't touch the disk copy)
You can also insert a file at the cursor...
[^X I] insert a file at the cursor
In the a number of the above commands, the user is prompted for a
filename. In these prompt windows there are a number of special
commands... I will discuss the filePrompt dialogs in more detail later.
Searching and Replacing:
There are a number of useful parenthesis matching routines:
[Alt ^B] backward to matching {[( [Alt ^F] forward to matching )]}
Try them out!
Next there are the incremental searches...
[^S] isearch forward [^R] reverse isearch
[Alt S] repeat last search [Alt R] repeat last reverse search
In Exact Mode searches are case sensitive otherwise searches are lower case
insensitive, upper case sensitive. This means that lower case matches both
upper and lower case while upper case only matches uppercase. During an
isearch [bacspace] and [^-] are an undo, [^S] causes a search again
forward, [^R] causes a search again reverse, [^G] and [ESCAPE] exit, [^Y]
yanks the first line of the killBuf into the search window, and [Alt /]
does wordContinuation. In regular expression mode, regular expressions can
be entered into the incremental search prompt.
In addition to the incremental searches there are jumbo
search/searchAndReplace dialogs:
[Alt ^R] jumbo replace dialog [Alt ^S] jumbo search dialog
When you type either [Alt ^S] or [Alt ^R] you enter a
search/searchMode prompt. Type an [Alt ^S] and then an [Escape]. You will
have seen a prompt window querying:
!! search for: ? eXact=^X Local=^L Reverse=^R Token=^T regexP=^P liNes=^N
[^G] aborts the search.
[^X] toggles the case sensitivity.
[^L] toggles the search to local or global... if the L flag is not
set, you will be prompted for the directory/filenames (with * and **
wildcards) to search through. (it's a grep) If the L flag is set, the
search will be in the current buffer. If the L flag is not set, (you are
doing a global search) after the search is done the screen will be split
with the lower window containing a list of all the files and lines where
the search string was found... Use [Alt N] to go to the next one. (This
works the same as in the compile command. Search for "[Alt N]" and you
will find a larger discussion of the [Alt N] command later in this text.)
[^R] toggles a reverse search... it forces a Local search.
[^T] toggles token searches... the search pattern is considered a
single token, there must be non-word characters around it. (For example:
suppose you were searching for "the", with token searches turned on the
search would skip the "the" in "other" because of the "o" and "r" around it.
[^P] toggles regular expression mode, regular expressions can be
used in your search string. At this point I will give a very short
discussion of regurlar expressions:
(NOTE: fill this in later!!!!)
During an iSearch [bacspace] and [^-] are and undo, [^S] causes a
search again forward, [^R] causes a search again reverse, [^G] and
[ESCAPE] exit, [^Y] yanks the first line of the killBuf into the search
window, and [Alt /] does wordContinuation. In regular expression mode,
regular expressions can be entered into the incremental search prompt. In
an iSearch typing the enterKey is the way you search for a newline. In a
jumbo search/replace dialog the enterKey must be entered using a [^Q].
(See the "Quoted Insert" section.)
I include word continuation with search and replace.
Word Continuation:
Word Coninuation [Alt /] is a very handy command, I use it all the
time. After you have typed a few letters and then typed [Alt /] M attempts
to guess the word you have started typing. I do this by looking at the
letters you have typed, do a reverse search for a word with starting with
the letters you have typed and if I find it, I extend the word you are
typing by the word found. If I search all the way to the top of the
document and find no match I do a forward search. This feature is a
solution to the problem that I like to have long expressive variable names
but I hate to type them out. This way I have to type them once when I
declare them and after that I only have to type a few letters and then
extend the name. It is great for #defines where I can't remember where I
put underscores. I don't have to remember, I just type a few letters and
continue the word.
Tag Files:
I am currently not satisfied with my C/C++ tagging facilities... I
have turned off this feature and I will be reimplementing something I like
better soon. If it bothers you that this feature doesn't currently work,
yell! The squeaky wheel gets the grease...
The [Alt Q] function search has not been turned off, but I don't like it
much either... (It isn't fast and it isn't pretty.) Currently it builds a
list of the subroutines in a file and lets you move around in it like an
[Alt ^S] search.
Diffs:
[^X E] compares 2 windows (equal)... If you split the screen [^X E]
will compare the two windows starting from the current locations of the
cursors. If the characters are the same, both cursors are moved
forward... The cursors will stop at the first differences... After
finding the first difference. To find the next difference, we must
reposition the cursors to equivalent places past the first difference and
do another [^X E]. eXact Mode affects the [^X E] command... When eXact
case is off, the diffs are white space independent... that all strings of
white space are treated as if there are a single space character. Then
difference that are only white space differences are ignored... When eXact
Mode is on, the comparisons must be exact, white space matters.
[^X D] diffs directories. You will be prompted for the directories
you want to compare. The diff happens in 2 passes. The first pass goes
through the two directories and builds a list of the files that occur in
only one place and the files that occur both places but are not the same.
After compiling the list the screen is split and the first pair of files
that occurred in both directories but have a difference are opened and a
[^X E] diff is started... After walking through that file (with multiple
{^X E] diffs) the next pair is called up with an [Alt N] (next)... After
the last pair, the diff compile buffer is brought up.
Line Wrapping/Reformatting:
There are two principle reformatting commands, they are the [Alt P]
reformat the current paragraph command and the [^TAB] retab the line
command. The [Alt P] command reformats a the current Paragraph. It uses
the wrapColumn (settable with the [Alt TAB] command or the M environment
variable) as the target line length. The top of a paragraph is a line with
leading white space or a first character in the first column that is a '.'
or a '\'. The end of a paragraph is a line with leading whitespace or a '.'
or a '\'. In Cmode the [Alt P] only affects comments, it reformats them.
When WrapMode (or Cmode) is on, the spacebar not only inserts a
space it also tests the current line length, and if it is longer than the
wrapColumn it causes a paragraph reformat. (In Cmode only comments are
affected.)
[Alt TAB] is used to set both the wrapColumn and tabStops. You
will first be prompted for a wrapColumn. Only numbers between 0 and 512
are legal answers. Answers outside this range are ignored. Next, you will
be prompted with the current tabStop sequence, for example if the sequence
were: tabs=2 8 4 the first tabStop is in the 2nd column, the second is
in the 10th column, the third is in the 14th column, the fourth is in the
18th column, the fifth is in the 22nd column... (it repeats tabStop every 4
columns because of the terminal 4)
As an aside, M supports two tabbing conventions. The tab
convention I like the best is that where a tabStop and a tab are the same.
That is when you hit the tab key, one tab character is inserted into the
text and in the screen drawing I interpret the width of the white space to
be whatever it needs to be to fill to the next tabStop. Then with the
example tab setting tab=2 8 4, after a newLine, when you first hit a tab,
one tab character is inserted into the file and the cursor moves to column
2. When the tab key is hit again a second tab character is put into the
text and the cursor moves to the 10th column. On the third tab key, a
third tab character is inserted into the file, the cursor is moved to the
14th column. This is the default tabbing convention.
I had a number of users who complained bitterly about this
convention. They complained that the dumbest printer programs wouldn't
print their files properly. The convention they wanted was one where
tabStops were disconnected from the tab character. The tab character
always took you to a column that is a multiple of 8 irrespective of the
tabStops. The editor uses a combination of tab characters and spaces to
move to a tabStop. Then in our example (tab=2 8 4) the first time the
person types a tab 2 spaces are inserted, The second time, the two spaces
are removed and a tab character is inserted (taking you to column 8) and
then two more spaces are inserted after the tab character... In the second
mode, M inserts the most efficient combination of spaces and tabs when a
tab is typed. You can toggle between the two different tabbing conventions
using the [^X M T] command. You can also toggle the convention by setting
the M environment variable with the -h (hard tabs) option.
The [^TAB] command reindents a line. It is most useful in Cmode
where it does a very "smart" C indentation... In text mode it just
reindents the same as the first non-blank line it.
This brings up the topic of edit Modes... All Modes are toggles,
Changing Edit Modes:
[^X M] followed by one of [C] [O] [W] [X] [S] [I] [T] [P] or [B]
Toggle the particular edit modes:
C) Cmode: toggles smart indenting, parenthesis matching, C programming mode
O) Overwrite: toggles between overwriting and inserting
W) Wrap: toggles on/off automatic line wrapping (usually for a text mode)
X) eXact: toggles search case sensitivity
S) Scroll: toggles the vertical scrolling method
I) cIndent: toggles the C indentation method
T) Tab: toggles the use of hard tabs
P) regular exPressions: searches use regular expressions
B) Binary: toggles displaying as a binary
Notes about the modes...
Toggling eXact Mode on causes searches to be case sensitive
otherwise searches are lower case insensitive, upper case sensitive. This
means that lower case matches both upper and lower case while upper case
only matches uppercase. eXact Mode also affects the [^X E] diffs.
The Cmode toggle [^X M C] turns on/off the "smart" C indenting,
color comments, comment wrapping, the [^upArrow] [^downArrow] (up/down
paragraph in text mode, up/down to matching '{' or '}' in C mode), etc...
The Binary mode toggle [^X M B] just displays the text in a hex mode
with 16 characters/line.
The cIndent toggle [^X M I] toggles between two indenting styles of
Cmode. The default mode is pretty, the alternate style is gross but I had
a number of people demanding it so I support it. I don't want to encourage
the use of that style so I won't discuss exactly what it is. If you must
you can experiment with it. (It is also setable through the M variable.)
Now that I have mentioned all the Mode flags, it is appropriate to I should
redescribe the StatusLine. The StatusLine I currently have on this file
looks like this:
** m.tut 434 16 (W) c:/work/m/m.tut #B = 32
m.tut is the buffer name.
434 is the line number the cursor is on.
16 is the index in the line.
(W) means WrapMode is on. (all Modes would appear here)
c:/work/m/m.tut is the absolute path name
#B = 32 tells me the number of pages of memory I am currently using
(See Known Ways to Kill M at the bottom of this file for a further
discussion of this variable)
When you first start M the StatusLine has == instead of ** at the beginning
of the StatusLine. This signifies the file is identical to what is out on
the disk (unchanged). When I change it the == turns into **. Some files
come up as %% instead of ==. This means they are read only. When you type
a [^X] the second character temporarily becomes a ^. When you type
an [Escape] the second character temporarily becomes a &.
Macros:
M supports keystroke macros. Type [Alt M] to begin recording a
macro. You will be prompted for the key to bind the macro too, you can
bind it to any unbound key (any key that beeps when you type it, I usually
use a function key). Then type the characters/commands you want to
execute. When you are done type [Alt M] again to end the recording. Now
when you type the key you bound the macro to, the macro will be played.
Your current set of macros can be saved by typeing [Alt ^M] (save all
current macros). Whenever you load m you get all your current macros
loaded by default (the live in a file called macrofil.$m$ in your home
directory (the directory specified by the environment variable HOME) (if
you have not set a HOME variable I fall back to using the TMP then TEMP
variables directory.) There is currently a limitation on the macros, you
can not call another macro from inside of a macro. (this prevents
recursion) I will probably lift this restriction sometime. When an
operation fails, I generally abort the macro... (for example if a search
fails I will not continue the macro...) Also if you want to stop a macro,
generally [^G] (the all purpose abort) aborts the macro...
There is another simple macro facility, a repeat execute commmand
[ESCAPE (number) (key)] execute (key) the given (number) of times. For
example if you type [ESCAPE 27 *] you will get a line of stars 27 long.
You can invoke a macro with this command. Suppose you have bound a macro
to F1, you could execute that macro 10 times by typeing [ESCAPE 10 F1].
The [^G] abort will abort this type of macro too... I should mention the
abort key.
Abort:
[^G] is the all purpose abort. It aborts most things... (not
all) If you notice some operation that you think it should abort and it
doesn't, complain and I'll fix it. It aborts most searches, macro
executions, etc... (The reason ^G is the abort key is historical. ^G
(hex 0x07) was the teletype symbol for the bell... Typing ^G rings the
bell.)
Inserting Literals, the Quoted Insert:
[^Q (any key)] is the quoted insert. We use this to insert keys as
iterals into text... For example you can insert a into the code by
typing a [^Q ^B]. You can alway insert decimal values of ascii codes
by using the numeric keypad keys while holding the Alt key down.
In a search prompt and any file that is in Binary Mode you can insert hex
directly by typing [^Q] and a two digit hex number e.g. [^Q 9 F].
Information:
There are a few miscellaneous data that you might want to insert
into your text. By typing [Alt I] and then one of [D], [T], [P], [A], [+],
[-], [=], or a digit string, the following data can be entered into your
text:
[Alt I] information, [D]-Date, [T]-Time, [P]-Pathname, [A]-Absolutepath
Entering a digit string sets a static counter...
[Alt I +] outputs the counter and then increments it.
[Alt I -] outputs the counter and then decrements it.
[Alt I =] outputs the counter and leaves the counter unchanged.
I find these most useful for use in macros. For example to document
changes to code I have macros that insert a bunch of boiler plate including
the current date. The [Alt I] command works correctly in prompt windows.
Shells:
You begin a dos shell with [^Z]. Do not confuse this with the exit
saving all changed files command [Alt Z]. When you shell out to dos, you
do not really leave M, you suspend M... If while out in dos you somehow
crash your machine you will not be able to resume that edit session...
That means that if have not saved the file you will have lost work. There
are some very confusing scenarios that can happen for example, suppose you
shell out and forget that your are in a shell and start a new M session on
top of the old one... (I currently don't catch this...) Then you open a
file and don't see changes you know you made... (they are in the suspended
M session and haven't been saved yet...) you reimplement those changes, do
even more things finally exit that session, realize you're in a shell,
resume the suspended M session, and find your files translated back to that
earlier state (I don't currently detect that the files changed on
me...)... Its a bad situation... If you ever find yourself in this
situation the safest things you can do are a revert to saved (return to the
disk image of the file) or exit without saving anything. An unsafe thing
that you might try is to save your changed files to a different name...
Whatever you do it is a bad business. It can be confusing and frustrating
when you start having multiple M sessions suspended... I recommend you
don't do it. I use dos shells to go do something, and then I return
immediately to the M session. (To resume an M session type "exit" at the
dos prompt. Exit is a normal dos command.) When I shell out I copy most
of the memory image of M to your "TMP" directory, (I look at the TMP
environment variable, see care and feeding section...) leaving only a small
loader to resume executing later... You regain most of your ram for the
spawned dos session.
If you want to execute one dos command and capture the output I use
the [^X N] command. The default command is make. I use the [^X N] command
to do compiles. I attempt to parse the output after the dos command has
run. I recognize most compiler error messages and I will open the file and
take you to the line number of the error... I split the screen and put up
the file where the error occurred in the top window and in the bottom
window I put the compile output with the top line showing the current
error. You can move the cursor to the *compile* buffer and you will notice
the cursor is on the line of the current error... When [Alt N] is typed
the cursor in the compile buffer is moved down one line and I attempt
parsing from there. While you are in the *compile* buffer you can position
the cursor one above an error message you are interested in, then typeing
[Alt N] will take you to it.
Next, I will discuss a topic I have been postponing, the file/buffer dialog
prompts.
File/Buffer Dialog Prompts:
In most file prompting dialogs and in the buffer prompt dialog ([^X
B]) there is a subdialog accessible by typing a space... When a space is
typed in one of these file/buffer prompts I attempt name completion... If
there is only one file/buffer with the letters already typed I finish the
typing for you. If there is more than one name that matches I continue the
typeing up to the point where the names differ and I pop down a subwindow
with a list of the possible matches. You can move the cursor down with the
arrow keys and select the file you are interested in. One way to select it
is by moving the cursor to it and hitting the enter key. For example try
typing [^X B] then a space. Move the cursor to m.tut and hit [Enter], you
are there. Try a different buffer... The same type of thing can be done
after [^X ^F]. Sometimes I use wild cards and the space (for filename
continuation). I type [^X ^F] and then *.cpp and then finally a [Space], I
get a directory listing of all my .cpp files. I select more than one file
by moving my cursor to a particular file, hit the spacebar, move to another
hit the spacebar, etc... (hitting the spacebar is a toggle, hitting it a
second time unselects a file.) After I have selected all the files I am
interested in I hit [Enter], and they are all loaded. Just like in the
grep I can use the * in directory names and the ** (the wildcard directory
name that matches the "." and all subdirectories) in the filenames.
Sometimes I use the [^X ^F] dialog to do a file find for me... For example
I can search from the root for m.tut by typing in the [^X ^F] prompt:
/**/m.tut and then a spacebar... M will show you where all the "m.tut"
files live and give you the opportunity to open the ones you are interested
in.
There are a few other "special" commands active in the [^X ^F]
prompt, the [:] key is special, if you are any where in the prompt and you
type a "c:", when I see the colon I realize you must have just typed a
drive letter and I clean up the prompt and show you the default directory
on the appropriate drive...
The [/] and [\] keys are also "special". (In a filename prompt M
considers all types of slashes to be directory seperators...) If you type
a slash following another slash, I realize two slashes in a row makes no
sense as a directory name... I consider that to be a wild card for the root
directory, I make the prompt be the root directory.
Another "feature" true in general for all prompt dialogs is that if
the cursor is in the first column and you type a "normal" character, I
empty the prompt first before I insert your character. Sometimes you don't
want this "feature" to happen, you can turn this behavior off in the
current particular instance by typing an [Insert].
One last note while I am on the topic of prompting dialogs... The
prompt windows are not that different from most other windows... I do
yanks and [Alt W] copys all the time in them... For example sometimes in
making a batch file I want a list of files in a directory. I start a [^X
^F] dialog, hit a spacebar, enter the file list window, set the mark at the
top, go to the bottom, and do an [Alt W] to copy it into the killBuffer. I
[Escape] out of that dialog and yank the killbuffer into my batch file.
Then I make up a macro that does something to each file name.
Help:
The documentation and online help is sparse... This tutorial is
the most extensive help discussion I have. It will not be a static
document, I will be enlarging it with more general discussions about the
internal operations of M. There are presently 3 online help options, all
of them accessed through a [^H]. They are:
[^H H] bring up the m.hlp file [^H B] describe keyBindings
[^H F] describe Functions
I think the [^H H] is the most useful. The m.hlp contains a
complete but extremely terse description of all commands. It is arranged
by topic with some miscellaneii at the end. As a note, put the m.hlp file
in the same directory as the m.exe executable.
The [^H B] command gives a list of active keys and the subroutines
currently bound to them.
The [^H B] command is currently only partially implemented. The
descriptions of the commands are not tabulated, there are only question
marks where descriptions should be.
Execute By Name:
Commands in M can executed by name. The names are the actual
subroutine names of my code. You begin the execution by typeing [Alt X]
and then in the prompt dialog you type the subroutine name... The [Space]
does name continuation... If you type a space at the very beginning you
will get a list of commands (very much like the buffer name list). You can
continue typing the name or you can move your cursor to the command (using
the arrow keys) and execute the command by typing [Enter]. If you want to
get a copy of this list just set a mark and do an [Alt W] to copy the list
into the killBuf then open a writable file and yank it in.
Care and Feeding of M:
1) Put M.EXE and M.HLP in the same directory somewhere on your path
2) Set a TMP environment variable to a directory for temp files (for
example, make a directery off the root called c:\temp and in your autoexec.bat
use a set command to point to it... put the following line in your
autoexec:
set TMP=c:\temp
M will put its temporary files here... periodically delete the contents of
this directory... M usually cleans up after itself but if you exit M
ungracefully, (for example you shell out and crash or reboot before
returning to M) I will have left some garbage in TMP. (If there is no TMP
variable M will look next for a TEMP variable. M will complain if it can not
find either of these...)
3) Set a HOME environment variable to a home directory... The macrofil.$m$
and the startup.$m$ files live here. If you do not set a HOME variable m
will use the TMP variable. The downside of not setting a HOME variable is
that if you then delete everything in c:\temp, you will lose the macros you
had saved... As an example, make a directery off the root called c:\home and
in your autoexec.bat use a set command to point to it... put the following
line in your autoexec:
set HOME=c:\home
4) Optionally set SWAPDIRS as a path variable to use for swap files:
set SWAPDIRS=d:\temp;c:\temp;j:\temp
m will swap to d:\temp until it is full than to c:\temp etc.
5) Optionally set the environment variable M (in the autoexec). With the M
environment variable you can customize many of the default behaviors of M.
An example set command might be of the form:
set M= -cXXXXXX -i -p -s -t4 -wDDD
There are many different M options, I will list them:
-a1,a2 set alphabets, a1=wordChars, default is A-Za-z0-9_
a2=symbolChars, no default
The alphabets are used to determine beginning/end of words.
-cXXXXXX is a 6-digit hex number specifying colors, each digit
specifies a color
X1 is the StatusLine backGround color
X2 is the StatusLine foreground color
X3 is the text backGround color
X4 is the text foreground color
X5 is the Cmode text comment backGround color
X6 is the Cmode text comment foreground color
The Colors are:
BLACK = 0
BLUE = 1
GREEN = 2
CYAN = 3
RED = 4
MAGENTA = 5
BROWN = 6
LIGHTGRAY = 7
DARKGRAY = 8
LIGHTBLUE = 9
LIGHTGREEN = A
LIGHTCYAN = B
LIGHTRED = C
LIGHTMAGENTA = D
YELLOW = E
WHITE = F
The default color choices are -c9f8f8b
-h hard tabs, (indentation is a mix of spaces and tab chars)
See the discussion in the Line Wrapping/Reformatting section
-i toggle cIndent Mode, same as [^X M I]
See the discussion in the Edit Modes section
-l load file lines as text always... (don't auto sense binary)
-p paid your money, (don't show startup message)
-s toggle the Scroll Mode, see [^X M S] in the Edit Modes section
-t,-tc set the tabs... -t and -tc refer to tab settings for
normal file and Cmode files... You can set both, one or
neither of them. Here are some examlpes:
set M= -t4 -tc4
// sets both normal and cmode tabs to 4
set M= -t8 4 -tc2
// sets normal tabs to 8, 12, 16, 20, ... cmode tabs to 2
defaults are -t8 -tc4
-v attempt checkout of read only files
-wDDD set wrap column, DDD is a decimal number for example:
set M= -w78
// sets the wrap column to be 78
default is -w76
6) Optionally set up an M.CFG file. M.CFG files are my response to user
demands to set more options than can be comfortably set in an environment
variable. There are three statement types, they are:
set X=YYYY
include FILEXXXX
bindKey KEY_TO_BIND FUNCTION_NAME
The set command sets environment variables... (you could set the M varaiable)
The include command allows you to include files into the M.CFG file
The bindKey command allows you to change the default key bindings... You
can move commands to keys that you like... To get the complete list of
commands see the [Alt X] discussion. To get correct names for the keys see
the [^H B] command... I don't recommend you change the bindings because
when someone else uses your machine or you use someone elses, you will
become frustrated, you will not get the bindings you've grown to know and
love. ;-)
M.CFG files are searched for in the following way... I first search in the
directory you were in when you started M. I search in that directory's
parent. I search in your HOME directory. The first place I find an M.CFG
file I stop and do not look further. I look up the M environment only
after looking up M.CFG files. (That way you can set it in your M.CFG file.)
I look up the TMP and HOME variables when I need them.
Known Ways To Kill M:
1) M uses a paged memory scheme for the contents of your files.
When you first open a file if you are only looking at the beginning of the
file I don't get anything except the beginning of it... As you try to look
at other parts of the file I bring more of the file into memory. I bring
it in 2K at a time, 2K buffers. The number on the StatusLine #B = 39 for
example means I am currently using 39 2K buffers. If you bring in a really
big file and page through it you will see this number climb and climb and
eventually stop climbing... Now as you continue looking at new pages old
pages are being swapped out... (into swap filees in your TMP directory if
they are changed) At this point I have used up all the system memory and I
must relinquish a page of memory if I need it somewhere else. (Now we are
getting closer to how to kill M) Only file contents can be paged out, I
have other memory requirements that can not be paged. I do not virtualize
the data structures describing the files. If you open another file I must
relinquish memory for the file descriptors that can not be paged out... If
you open many files you will see the number of buffers start dropping...
If you open enough file so that the number of buffers gets to 0, M
crashes. Don't do this! If you try to do really big things like open all
the files on your hard disk, M will crash... I don't have a good bail out
method yet. That will come in later editions... If you know you are going
to do something really big, save your files first. (This whole situation
is rarely a problem, I have had 500 files open at once, I estimate that M
dies on my pc (with my memory configurateion) at ~700 open files. File
sizes are not an issue at all, only the sheer number of files.)
2) If you run out of disk space while M is saveing a file... M can
crash in a variety of ways. M does not cope well with these type of system
errors... Always maintain some free disk space.
If you find more ways to kill M, I am interested, especially if it is
reproducible... You can send mail to me at:
Greg Gadbois
18 Hillside Ave
Amesbury Mass 01913
My current email address is
greg@dragonsys.com
P.S. I am adding a final note just as I release M Version 1.0... The 1.0
version number denotes the first open release I have had. That does not
mean that M is a new and buggy product... M has existed and has been
evolving since 1988 as my personal editor. I have frozen the current
release as the entry-level shareware version of M. I continue to evolve M
and I have a "premium" version that has a number of additional features.
Among them is journal files (a continuous backup method so that even if the
power goes out while editing, no work is lost). I am charging $25 for the
frozen shareware version of M and $35 for the premium version. A native
windows version of M also exists but is not yet ready for prime time. It
will be ready soon.
P.P.S. Keep those checks rolling in! ;-)