==== An SDF sam tutorial ====
===Basic Editing===
When you run sam newfile you only see the command window (blue area) on top
but the actual file contents window has not opened.
Right click on the white area and you will see the filename listed.
Selecting it and noticing that the cursor changed you can then click and the contents
will appear. If the file didn't exist there will be no contents.
After that you can start typing on the text edit window. With your mouse
you can either select the text edit window or the command window using
the left mouse button. In the following document commands will appear in bold font.
The most basic commands to interact with the editor are **q** to quit,
**w [filename]** to write the file to disk and **u [times]** to undo.
If we have currently selected a filename and issue the **w** command sam will
tell us the total amount of characters it wrote. It also might warn us
if the file does not end with a newline.
By issuing the **n** command we see the file menu list.
when the text window has changes of a file
that haven't been written yet to disk the file line
in the menu list starts with the ' character.
To quote //The text editor sam// paper by Rob Pike a file consists of
* it's contents, which are an array of characters
* the name of the associated disk file
* the modified bit that states whether the contents match those of the disk file
* a substring of the contents called the "current text" or "dot".
* the value of dot is the location of the current text
* the contents of dot are the character it contains
Since edit operations apply on selections we must learn ways to control the value of dot.
The easiest way is to highlight some text. This action sets dot to that range.
By the command **p** we print the contents of dot and by the command **=** we see the range
on the file it maps to.
By issuing ranges on the editor we will see the text they specify getting highlighted.
Some example ranges would be
^Range ^Decription ^
|0,$ |from line zero till the end of the file which can also be expressed as ,|
|3 |the third line|
|#30,#50|character 30 till character 50|
|2,#100 |line 2 till character 100|
To operate on text in or around dot we can use commands like append, change, insert etc.
For example to delete the text in dot we just press **d** , and to insert sometext before dot
we would issue **i/sometext/** , or to append it after dot **a/sometext/** . **m** followed by an
address moves the text in dot after that address. **t** followed by an address just copies
the text to that address without deleting from the original location.
=== Editing more than one file ===
By right clicking and selecting new we can create a new text editing window to work
on another file. If we have more than one files open we notice that in the file menu
list we see more lines. The file we are currently working on is marked by a .
symbol.
By issuing the **b** command we can set our current file to other files. For example if we have
2 files open, named file1 and file2 and we issue b file2 and then n we see that
file2 will be selected. If we try to open a completely new file that isn't in the
file menu list, the **b** command will fail. That is why the **B** command exists which
can be used to create a new entry. Note that if the file didn't exist in the disk
a write still needs to happen for it's data to be persisted.
Other basic file menu commands are **D** (to delete an entry) **f** (to rename a file entry)
**e** (to replace current with file) and **r** (replace dot by the contents of file). Here we
notice that if we rename an entry that doesn't rename the file on disk. Instead if we
issue **w** on the renamed entry it will create a new file on disk.
=== Examples for sam regex ===
The benefit of sam is that it allows for regex tasks to be chained and also debugged
easily from within the editor. We will consider a toy example to indent properly some
code of the form
if foo {
bar
}
We would like bar to be indented at 8 spaces in, one more level than //if// is.
We can start with a regex to detect the opening brace
, x/{$/
should detect, in the whole file (,) these braces.
Now we can match backwards to find the prepending white space in that line we matched
by just chaining the next regex.
, x/{$/ -/^[ ]*/
now that matches the white space before.
We would like to add at least as much white space to the line below and
then some (4 spaces for example).
But for that to work the line below must be free of leading white space.
Therefore we will remove it from any line that is below an opening brace. The search is
, x/{\n[ ]*/
and to remove the white space between the start of line and the first character we chain it like
, x/{\n[ ]*/ s/^[ ]*/ /
The final form of our regex chain is
, x/{\n[ ]*/ s/^[ ]*/ /
, x/{$/ -/^[ ]*/ t .+0
=== Interacting with external commands ===
Of course creating a indentation program with just regexp would be duplication of work.
For most languages pretty printers exist like gofmt and cb (C beautifier) let' try
to run cb on some ugly-fied C.
if (foo
To pass all this code through cb we can just select it and then
issue the command |cb . that would replace the dot by
if (foo
similarly we can read input from a command
using < and write to a command using > if we want to count all the
characters in a selection for example we can highlight it and issue >wc
, observe that this doesn't changes our current text
We could also imagine a command where it replaces every
occurrence of //{DATE}// with the current system date in the whole document
, x/{DATE}/
would find any occurrence of the string //{DATE}// and then replace that
dot with the output of the date command.
=== Self guided discoveries ===
* create two files (file1 and file2) add text to both, use **n** and **b** to control which file has the focus.
* on file2 for example issue continuously
r file2
0
and repeat. What is happening? why? what if we only issue **r file2** without the 0 afterwards?
* can you specify a reverse range like #10,#5 ?
* highlight a word. then issue **m+0**. why is this happening? what is **t+0** doing? what if you keep issuing **t+0**?
* Improve the toy indent example by
* making lines align when no opening brace is detected in the end of line
* remove 4 leading spaces if the line has a closing brace
=== Documentation and more ===
*[[http://man.cat-v.org/9front/1/sam|man sam(1)]]
*[[http://doc.cat-v.org/plan_9/4th_edition/papers/sam/|The Text Editor Sam (Rob Pike)]]
*[[http://doc.cat-v.org/bell_labs/sam_lang_tutorial/sam_tut.pdf|A Tutorial For The Sam Command Language (Rob Pike)]]
*[[http://sam.cat-v.org/cheatsheet/sam-refcard.pdf|Sam Cheatsheet (PDF) (Steve Simon)]]
*[[https://www.youtube.com/watch?v=JbWdS7isUiI|A Sam Session youtube video (Pilgon Sesh60)]]
*[[https://plan9docs.wordpress.com/2012/05/07/using-the-sam-editor/|Using The Sam Editor from plan9docs (iainws)]]