This guide is rather more technical in nature than the JOT User Guide. It goes into some details of the design and internals of the editor, it's command structure, it's primitive commands and installation. For a general user guide take a look at jot user guide, jot examples and jot quick reference. In particular, there is a special startup script qr.jot which is designed to be used thusly:
$ jot -st=qr
In jot, a text buffer is an internal data structure containing an image of some text. There are two classes of buffer - primary and secondary buffers.
Each primary buffer is identified by a single-character buffer key. The following buffers are accessible but some are used by command file scripts. Buffers may contain a file image, fragments of text or jot command strings - otherwise known as macro commands.
See A, H and basic commands.
Whereas, with primary buffers, it's easy enough to reference other buffers - the A command, for example, can move or copy text into some destination buffer by referencing it's buffer key ( a simple ASCII character identifying the destination buffer) or the Z, or OZ may be used to switch context. For secondary buffers, which must be referenced by a longer path expression that option does not exist and, short of a major redesign of the basic editor language, cannot be made to exist.
This is a particular problem for commands that access other buffers using a buffer key Z, OZ, A, B, H There are a range of extended editing commands to help with this - see %X
Another way is to temporarily clone the buffer onto the stack using the OQ or %H=GETDATA where the clone can addressed using the bufer key ( ~ ).
Secondary buffers are passed by address - this means that, although several different copies of a buffer may exist in various places, they are all just pointers and all refer to the same underlying data structure. This applies to the following commands:
We can use O# to make a copy of a secondary buffer in a more conveniently-addressable primary buffer before working on it. However the nominated primary buffer remains attached to the data object - until the link is broken. This can be done using %D with the -unlink option.
The upshot of all this is that any changes to one of these copies will be reflected in all of them.
Like most modern editors jot attaches editor functions to various function keys, escape sequences and and various combinations of the Shift, Ctrl and Alt keys with function and other keys. The key-to-function translation table is held in the text buffer ( ^ ) defined at startup time - see about startup scripts.
As a function key is pressed, signals trickle through various layers of the OS (maybe xkb followed by terminfo) until they reach the editor in the form of a keycode or an escape sequence.
The point to note about linux system-defined escape sequences is that they are liable to change from one distribution to another. It's not even guaranteed that these will yield any usable key code at all and sometimes they have been known to collide with other keycodes/escape sequences from the same system. See define_keymap.jot for details of how to redefine the jot key mapping for your system. The curses_keys_<version>.jot in the jot distribution was set up using a Fedora-27 with TERM set to xterm.
After a key event is received, jot will attempt to match the received keycode with codes in the ^ buffer (see startup.jot). Some keys return a simple numerical value, others return an escape sequence - an {Esc} character followed by a few ordinary printable characters. Alternatively, the user may type in {Esc} followed by two or more characters - essentially another form of escape sequence.
Where a parameter is required, e.g. for the <<Do>> function the script name parameter is represented in the function definition by a pair of adjacent hash characters. For in a typical linux installation this key will be defined by this entry in the ^ buffer:
X010A %r=##"Command file pathName> ";
X010A is the key code associated with the F2 key for some curses versions.
In command mode, the name of the script is typed in *before* hitting {F2}, thus the function key doubles up as a delimiter for the parameter string, saving you the bother of hitting {Return}.
In insert mode, however, it is necessary to prompt for the pathname and the prompt is, of course, the string following the double hash. If the prompt string is omitted then no prompt is issued.
The startup script builds the key translation table in buffer ( ^ ) - see startup.jot.
In the normal startup script, for example, we find this definition of the <<Remove>> function (this removes the currently-selected substring):
<<Remove>>(s/ /e-)Then, further along in the startup.jot script we see this:
<<Remove>> {Shift+F5}This says that the <<Remove>> function should be activated by pressing the F5 function key while the Shift key is held down.
In the curses_keys_xterm script we find this line:
X0119 -- {Shift+F5}
In the WindowsNT_keys script we find this line - functionally similar but a different keycode.
X374 -- {Shift+F5}
these give the specific key code for {Shift+F5}. Finally, looking in the key-translation buffer ( ^ ) of a linux session we should see this:
X0119 (s/ /e-)
The sequence of events is thus:
As we hit keys, various layers of hardware and the operating system perform a translation from electrical impulses in the keyboard to keycodes that can be understood by whatever software is reading them - in this case jot.
For windows the situation appears to be that all flavours of NT-windows running on any machine connected to any compatible keyboard will always yield the same keycodes.
For linux, the recent history of unix intrudes, as video terminals became popular a great many firms entered the market with competing and, well, incompatible devices which all had to be connected to unix servers. This was the necessity that gave birth to the invention of termcaps. Later there was terminfo - an improved version of termcaps.
With termcaps/info it became possible for many users, all connected to a unix server using a variety of terminals and for the system to communicate reliably with all of them. But only if each has properly announced which terminal type they have by setting their $TERM env.
However ... most linux installations run on PCs with only one keyboard and only one monitor but the unix distros have provided a plethora of terminal types and many distros set up the default TERM to xterm. But no! ... not all distros provide a complete description of the capabilities of an IBM-compatible keyboard and worse yet, not all agree on what keycodes result from various combinations of function and control keys.
This is resolved in the startup script (See startup.jot), which runs different keycode-setup scripts according to your curses version (see WindowsNT_keys.jot and curses_keys_<version>.jot).
The mapping of function key events to editor functions is determined in various layers of OS and, in particular your terminfo file and, finally, by the editor startup file. See also X-windows setup
The approximate sequence of events, in the startup.jot file is:
Jot is normally used to edit text files held on the filing system but it can pick up text from the stdin stream (see -) by using the usual | (pipe) and > (redirection syntax.
The P command usually prints line in the console area. When the editor is stared in stream-out mode the lines selected for printing are, instead, sent to stdout, where they can be directed to a file or piped to another process. The stream-out operation is detected automatically when stdout is set to anything except your xterm (or windows console). In the following example every 10th. line is copied to the file test.txt:
jot ${JOT_RESOURCES}/l99.t -in="(pm10)0 %a;" > test.lis
or it could be piped through to some other command:
jot ${JOT_RESOURCES}/l99.t -in="(pm10)0 %a;" | cat
The windows version of jot has a minor restriction that no jot windows may be set up, this restriction does not apply in in linuxland where target lines may be selected interactively.
The %A command has an option to specify an alternative exit message or to output a selected buffer to stdout instead of the usual exit message.
jot ${JOT_RESOURCES}/l99.t -in="(pm10)0 %a=bye now;" | cat
to suppress the exit message use -quiet:
jot ${JOT_RESOURCES}/l99.t -quiet -in="(pm10)0 %a;" | cat
Here's another example - the 99 bottles of beer demonstration. (see http://99-bottles-of-beer.net) 99 bottles of beer is a simple drinking song:
Take one down and pass it around, 98 bottles of beer on the wall.
...
Take one down and pass it around, 1 bottle of beer on the wall.
Take one down and pass it around, no more bottles of beer on the wall.
No more bottles of beer on the wall, no more bottles of beer. Go to the store and buy some more, 99 bottles of beer on the wall.
The object of the exercise is to write some code in your favourite language to generate the lyrics correctly - this is one way of doing it in jot:
$ jot -in="ol99 (o#boo/%d bottles of beer on the wall,/r0o#oo/ %d bottles of beer./b"\ "ol1o- ol-1o=\ o#oo/Take one down and pass it around, %d bottles of beer on the wall./b)0 ok"\ "(f-/1 bottles/-e-)3 m0i/Go to the store and buy some more, 99 bottles of beer on the wall./b %a='.;"
The help files are structured in a similar fashion to occam folded files.
The top help file normally contains only file folds. If, for example, the JOT_RESOURCES env is set to /home/my_home/resources, there should be a top-level helpfile help.hlp in the help subdirectory:
/home/my_home/resources/help/help.hlp
Inside that file we might find this line:
[unix]unix - Notes on a few unix commands.
When When a user queries this help entry (by moving the cursor to somewhere in the line and hitting F1) the [unix]unix element is transformed into the path:
/home/my_home/resources/help/unix/unix.hlp
Within the child help files are folded sections like this:
> {{{ Section name > Section text. > ... > }}}These help sections are nestable.
The help files can be typed in manually, but it is easy to make mistakes in the fold nesting. It is recommended that help files be prepared as plain-text documents with the section hierarchy defined by section header levels (i.e. the section levels indicated by the section numbers) - see text document preparation.
There are some text-processing scripts to help with this:
The maximum length line that can be displayed properly is limited by the display window. When the editor has to display a longer line the behaviour is as follows:
In jot documentation, a window is a viewing area of the terminal. By default, the startup script creates a single window which displays whatever happens to be the current buffer. The area at the bottom of the screen is the console area, used to display system messages etc. and prompts for your typed-in commands. In the event of a long line with the current character being off to the right of the screen then the console area is used to repeat an appropriate section of the line.
The standard startup script (see about startup scripts) will use your screen dimensions to calculate the size of a single window that will leave a one-line console area at the bottom of the screen. It also sets up the screen, using the %L command. it also uses the %s=console command so that various message can temporarialy encroach into the window area. When this happens, the window will be restored to it's full size on the next command - or by hitting {return}. If the temporary display overwrites the current line in the display window then the current line is repeated in the console area.
When the console area is set up with two or more lines, lines of text scroll up the console up to the bottom line of the last window. If the console is set up with one line but allowing it to temporarialy encroach upwards into the windows area (see %s=console for details), then the console will borrow lines up to the specified limit.
For debugging scripts, especially when using the jot debugger, it is useful to set up windows for a fairly large console window. For normal usage a one-line console area is useful since this maximizes the text view.
The size of a window can be adjusted with the WindowStretch and WindowShrink functions. The view can be adjusted left, right up or down with the functions - see ViewUp, ViewDown, ViewLeft and ViewRight respectively.
It is possible to split the viewing area between more than one window with one or more windows dedicated to displaying specified buffers. The screen may be split either vertically or horizontally - see about multi-window working and WindowOne, WindowHorizSplit and WindowVertSplit functions.
Jot supports text two types of text containing tabs - normally the ascii VT character, here referred to as tab. The first form uses tabs simply to align text into predefined columns, the second form aligns tab-delimited text cells. Cells often contain numerical data, so the text is right-justified and over-long strings are truncated to maintain the tabular structure.
See %b=tabstops, %b=tabcells and %b=tabsort. It also generates tab-separated tables (see Query dir).
When viewing tabular data it is often useful to have a header line showing the meaning of each column - the window headers provided by %b=header will follow tabstops set in the text body eg:
$ jot ${JOT_RESOURCES}/consumertrends2012q3cvmnsa_tcm77-292466.tsv \
-in="m+13 %b=header '.; %b=tabcells -1; wol12ow"
The header is also useful for wide blank-separated tables eg:
$ pmap -XX <anyValidPid> | jot -in="m %b=header '.;"
In addition to %b=tabstops and %b=tabcells, there are two more options for representing tabular text.
If the width of the table execeeds that of your window, you can set the leftoffset - see about long lines and %b=leftoffset this is all taken care of by the <<WordRight>> and <<WordLeft>> functions.
A good example is the output of the linux dumpkeys command - the keycodes section consists of 256 entries per line with 20 or more characters per entry, to view these with a header showing the modifier values try this:
$ sudo dumpkeys -f | jot -in="(f/ /s/\t/(v//e)0)0m-0 %b=tabstops -1; \
ol0z\$m-0k0(i/\t/)3 (o#oo/\t%2X/r0o~ol256o<)0 z.%b=header '$;"
You may then navigate the table using WordLeft, WordRight, WordUp and WordDown - {Shift+LeftArrow}, {Shift+RightArrow}, {Shift+UpArrow} and {Shift+DownArrow} respectively.
As with linear text, if the current character ends up outside the visible area of the screen (i.e. left of the buffers leftoffset setting, or right of the right margin), the relevant section is repeated in the console area. Also, if any part of the cell is out of the viewing area or the tabstops are set to narrow to properly display a cell, the cell text is truncated and displayed prefixed with a pling ( ! ) character. The section of text is also repeated in the console area - see about long lines.
While the %b=tabstops command affects only the way tables are represented on the screen in the current edit session, There are scripts available to permanently change the text file - see autotab.jot, autotabjust.jot, autotabdp.jot and retab.jot.
Jot offers a Text-based User Interface (TUI) which can support mouse-click and menu-driven applications. Although the plain-text menus might look quite crude and clonky by modern standards but that doesn't make them less useful than their slick counterparts. Take a look at the coding of dbg.jot, tk.jot and linkdocs.jot for examples of how this might be done.
For menus, there will be a wide range of follow-on actions, then the tag is effectively a callback selector - see dbg.jot for examples. For hypertext applications the tag simply gives the link destination - possibly in the form of a hashtable key - see linkdocs.jot.
By default, any mouse activity (movements, clicks, drags etc.) are ignored since in X the default mouse functions (selections) are reasonably useful. If however, some application needs to handle mouse events, these can be enabled. An example of a script that does this would be linkdocs.jot.
Jot is normally driven by keyboard events with mouse-button events disabled. When mouse events are enabled, these are treated as keyboard events with special mouse event codes prefixed with 'M@. In linux, it is possible to select mouse events in the %s=mousemask command, in windows this either enables or disables all mouse events.
The normal startup sequence defines four functions
M0040 <<CopyFromMouse>> -- {Button2Up} M0080 <<NoteFromMouse>> -- {Button2Down} M0200 <<FocusToMouse>> -- {Button2DoubleClick} M4000 <<InsertHereMouse>> -- {Button3Click}
these are intended to be demonstrators rather than useful functions - enable them for use with the mousemask command:
> %s=mousemask 42A0To integrate these in a useful way - e.g. for mouse clicks to perform useful processing some metadata is often required - e.g. to perform a jump to some place in another buffer on a mouse click we might need a hash-table key. This key can be associated with a launch point by adding a text tag in the launch point with the%b=addtag command using the -text=<string> modifier.
See also query getmouse, %s=mousemask, %s=setmouse and %b=addtag
Menus are normally but not exclusively driven by mouse events - normally clicks. Menu items are normally highlighted by choosing a different colour pair for them - see %b=tagtype and %b=addtag.
For menus each menu item will require a different callback - this is normally determined by tagging menu items with a text tag (see %b=addtag) that identifies the callback. Alternatively, the click-event handler might simply pick up the visible text from the menu buffer and identify the follow-on action from that.
Popup menus can be set up using popup windows - see the -popup option of the %W command and the tk.jot script..
Back in the days of teletypewriters and paper tape it was all so easy. The American Standard Code for Information Interchange (ASCII) would represent every character you could ever want with just 7 bits - so long as you weren't a mathematician, an engineer or anyone working in a non-english-speaking part of the world.
Mapping the 7-bit ASCII code to 8-track paper tape code left one extra bit which was sometimes used for checking - early modems, electro-mechanical tape punches and readers were not especially reliable. Since that time, the 8-bit unit (one byte) has become the industry-standard unit for organization of computer memory.
Modern computer hardware is much less error prone and, where error-checking schemes are employed, nowadays they are usually cyclic-redundancy systems that can detect and correct multiple errors. Also modern modern transmission protocols include error detection and correction. So the 8-th. bit is not required as a check for storage or transcription errors.
Unicode (or Universal Character Set - UCS) - an industry-standard encoding scheme for most characters in the alphabets of most written languages, including many symbols used in mathematics and engineering. The range of characters is so vast that, in practice, it is necessary to encode characters as sequences of one-byte tokens. Some tokens indicate the existence of yet more tokens to come, in UTF-8, UTF-16 and UTF-7. In common with many mail and unix systems jot uses UTF-8 to represent unicode characters.
It's important to note that whereas UCS is basically a vast character set, UTF-8, UTF-16, UTF-7 ... are coding schemes designed for efficient(ish) transmission, storage and handling of characters belonging to that set by encoding them as sequences of bytes in the range 128-255.
UTF-8 is a back-compatible expansion of the usual 8-bit, non-parity ASCII character set utilizing the, now redundant, 8th. bit and two or more bytes to yield an encoding space for many thousands of unique character codes. These can be used to represent all of the unicode characters. Both the windows and linux versions of jot support UTF-8 encoding.
UCS-2 is an early attempt at a unicode encoding scheme - unfortunately whereas UCS-2 can address a character space of 64K characters (at most, and in practice far less) the full chinese character set has in excess of 70K characters. This resulted in UTF-16 and UTF-32, UTF-32 abandons all pretence of packing efficiency and just gives each character 32 bits (a full word in most modern computers). UTF-16, like UTF-8 is a variable-length scheme which can encode all of the current unicode characters.
While UCS-2 and UTF-16, may not be actually obsolete they were never really much good. Consequently jot offers only very limited support for UCS-2, it's slightly more intelligent younger sibling UTF-16 or it's obese brother UTF-32.
Jot makes no attempt to make sense of any of these encodings. The recommended solution for UCS-2, UTF-16 and UCF-32 is to convert them using iconv (linux) or a similar windows file-format converter. The filing-system explorer get.jot automatically uses iconv to read these formats as UTF-8 but to be consistent with the jot policy of not making unrequested changes to files, the pathname is changed in the editor session.
Various earlier schemes, designed for users working in their own languages, allows an additional character space (theoretically up to a further 128 characters) by setting the parity bit. This scheme, enshrined in microsoft code pages, became popular because it allowed several sets of non-roman alphabets with the minimum of fuss and still preserves the ancient principle of one byte equals one character - very important for developers of text-handling tools. This is fine for those, like most of us, who never have to write in more than one non-roman alphabet in any one document. There are now various ISO-8859-x standards covering these character sets.
The linux version of jot of jot can read and manipulate files containing mixed UTF-8 and ISO-8859-x character encodings. For correct rendering of ISO-8859-x you must have your locale set correctly - see -locale. Any text entered will be encoded in UTF-8. Also, some care is required in the choice of terminal - a recent version of xterm is a usually a good bet.
If the locale is not set up correctly, the startup sequence may fail as it reads strings containing non-ASCII characters.
With appropriate unicode support jot should, in theory, be usable for any left-to-right written language. Support for right-to-left languages (Hebrew, Arabic etc.) may be possible later.
The windows version can properly display files containing either UTF-8 or those containing ISO-8859-x - but not both in the same document. This version requires the correct code-page setting for the file - see %b=codepage and -Codepage, by default it's set to codepage 65001 - that's UTF-8 to you and me. Again, any text entered will be encoded in UTF-8.
The linux version can only read and display UTF-8 but, if it is required to view or modify a UTF-n file there is a little script iconv.jot which, as it's name suggests, uses the unix utility iconv to transform the file to something that can be read, it will also write the file in it's original format.
In general, jot represents unicode as strings of UTF-8 bytes. The exceptions to this are:
To enter UTF-8 characters into the command line use the jot script uc_basic.jot - this recognizes sequences of keystrokes and converts them to the relevant UTF-8 byte sequence. To generate the euro symbol ( € ), for example:
> {Esc u = E}In command mode, uc_basic.jot translates this sequence on the command line, so start off by loading the basic unicode:
> uc_basic{F2}Then, for example, to search for the the string "cost €123.456", type:
> cost {Esc u = E}123.456F8The uc_basic.jot script added the u=E escape string to your key translations list and it substituted the UTF-8 encoding for € in the command line.
Many IBM-compatible keyboards supplied in non-english-speaking parts of the world, have non-roman characters. Assuming your system is set up correctly, in linux, these keystrokes are converted to the correct UTF-8 sequence by the OS. If, for whatever reason, your linux locale (or Windows codepage) does not match your keyboard, you can specify a different locale with the -locale (or -Codepage) qualifier. If you have some ISO-8859-x encoded in a different locale, you can change the locale of a buffer with the -locale CLI modifier.
To suppress conversion of unicode, turn off unicode support for that buffer with the %b=unicode [0|1] command. Turning unicode support off (%b=unicode 0;) displays each non-ASCII byte as a tilde ( ~ ), unicode support can be restored with %B=unicode 1;
Currently, the following unicode character encoding schemes are supported by jot:
Files may be read in any supported unicode encoding scheme and, typically, will be written out in their original encoding scheme.
It detects the encoding scheme by checking for a valid Byte-Order Marker (BOM) - this is a few bytes written at the very begining of the file. UTF-8 files may optionally have a BOM, jot detects this but takes no further action apart from removing the BOM from the file image, if the file is rewritten, jot will reinsert the UTF-8 BOM. Here is a list of BOMs jot can detect:
BOM bytes Unicode encoding scheme ~ EF BB BF UTF_8 ~ FF FE UTF_16, little-endian ~ FE FF UTF_16, big-endian ~ 00 00 FE FF UTF_32, big-endian ~ FF FE 00 00 UTF_32, little-endian
While the file is internally represented in UTF-8, jot maintains a tag indicating the original encoding scheme so that it can rewrite the file correctly. This tag appears in the query buffer report in the UCEncoding line. If it is desired to rewrite the file in one of the other supported unicode encodings, this tag may be changed with the %b=encoding command.
For example, the UTF-8 encoding for the euro sign ( € ) is E2, 82, AC - jot will recognize these characters as UTF-8 and store them in the same form. When jot displays these characters they must be converted from the UTF-8 internal representation to C-language "wide characters" coding for the euro symbol for display on the screen. It's left to your terminal emulator to correctly interpret the UTF-8 string to present the correct image on the screen.
Note that the R and OR commands will normally traverse the specified number of characters irrespective of how many bytes have been used to represent each character. Similarly the E command normally erases the specified number of characters irrespective of their byte count. This behaviour is modified by the %b=unicode command, which can be used to turn off all unicode support - with unicode disabled, R, OR and E commands count bytes not characters. Erasing bytes belonging to UTF-8 characters is not recommended - there is no guarantee that the line will display properly when unicode-support is turned back on.
Binary files (i.e. any non text file) are generally made that way to minimize their size and improve performance - the most important class of binary files are executables and libraries. We would need be very desperate to want to start hacking those. Also, many have some sort of file integrity checking - so your modified file may get rejected anyway.
However, there are occasions when it might be useful examine these files and, provided we understand their internal structure, it is possible to glean some useful insights by going through hex dumps of binaries.
In a *very* few instances there might even be something to be said for a facility to write a hacked dump file back in a binary form. Jot has the -binary qualifier to the %O command which does exactly this. Typically proceed as follows:
Something for you to try (unzip seems to check only the total length of the zipfile) This operation only changes the name from 'test' to 'ZZZ':
$ jot -init="%i= -binary ${JOT_RESOURCES}/test_get/test_get.zip; \
%b=unicode 0; %r=hex2ascii; f/test.zip/f-/74 65/(e3i/5A /)4 \ %o= -binary /tmp/test.zip;"
$ unzip -l ${JOT_RESOURCES}/test_get/test_get.zip
$ unzip -l /tmp/test.zip
Jot's journal files are designed to recreate a session in the event of an abnormal exit. The journal file, along with a cache of files and queries read by the original session, can be used to retrace all your activity in a recovery session so that you end up with an editing environment identical to that before the abnormal exit. In the future, journal files might provide the basis for some sort of undo function - although it would be rather slow by modern standards.
By default no journal is maintained - the editor is not particularly crashy and modern computers and power grids are generally reasonably reliable. The endurance of battery-powered devices is also quite good these days. From time to time however we are reminded that certain can't-happen events are in fact infrequent events and it's pretty distressing to see hours of work wiped out like that.
When the CLI qualifier -journal is set, jot maintains a history file and snapshots of all the files it reads - these files are normally deleted as the next session starts. Following a crash the journal files remain and the original session is re-created by reading in snapshots of the original files and re-running the interactive commands.
An empty lock file is also created in the journal directory, this is deleted when a jot session exits normally (via %C or %A). If, however, the previous session did not exit normally (or maybe it's still running in background?), the presence of LOCK will the prevent the usual destruction of the old sessions history files. The editor will inform you of the correct pathname and leave you to take appropriate action.
The process for a session editing myfile.txt is described below.
$ jot myfile.txt -journal[ -init=<initializationSequence>] [ -<any other valid args>]
As usual, the args may appear in any order. In your current working directory (cwd) jot creates a new subdirectory <fileName>.jnl - for this to happen, you clearly need write access to your cwd. At the star of the session that directory will contain three files:
More files may be added as the session continues, these are:
$ jot myfile.txt -st=recover
Where the original session read a file or launched a system query, the recovery session will read the backup copy from the journal directory.
$ jot myfile.txt -startup -init="%r= -asconsole ./recover_now.jot"
The history file contains the replacement pathnames (in the <name>.jnl area) and other bits of information from the original session like adjustments to terminal size and results of system-query reports. These raw data are munged into a personalized recovery script by the recover.jot script.
If some mismatch is found, the session is terminated immediately with a message explaining what went wrong.
See about not losing your work, %S=RecoveryMode and recover.jot for full details of the journal/recovery process.
Tags are used to mark sections of text with some special attribute. Typically, this will be display colour but tags are also used internally to identify and to protect hash-table target points or to add metadata to points in the text. They are also used to add debugging code to functions. The metadata is in the form of a text string, this is an essential ingredient in jot mouse and menu-driven interfaces where the tag metadata is used to identify a mouse-event callback.
Those familiar with vim and Emacs tags (of the sort generated by exuberant ctags), should note that jot tags are nothing to do with that. In jotspeak these are index files - see about index files.
The key feature of jot tags is they stick to the original text even as the surrounding text is altered or moved. This is what happens if the text is changed on a line containing tagged text:
Each colour tag indicates a colour pair (i.e. a foreground and a background colour) to be associated with the tag see %b=tagtype. The tags are added to text with the %b=addtag command.
The colours associated with the tags are defined in the %b=tagtype command
referenced by the %b=addtag command. The names must not exceed 12 characters.
The %b=addtag command adds a tag into the internal record data - the tag identifies the start and end points of the tagged substring.
The colour-tag definitions are associated with the buffer and are displayed by the query buffer query. The tags are associated with records and can be listed using the query tags query.
For windows there is no limit on the number of named tags you can define - although there seems little point in going beyond the 256 unique colour pair combinations that are possible with windows.
For linux, there are only 64 possible colour-pair combinations and the curses system allows only 63 user-defined colour pairs. The 63-colour-pair limit is a system limit - the total number of colour pairs in all buffers cannot exceed this.
Jot can be used to maintain a stand-alone file or, for big complicated projects, a suite of files including source, documentation and whatever other text files that might constitute a code-development project.
Project files should be placed in a dedicated directory (the project-file directory) with a startup file containing all project-specific startup commands. The actual project files are usually ignored by the editor, they may be used for storing informal project-specific notes, to-do-lists, checklists etc.
An example project directory, startup file and project files are to be found at ${JOT_RESOURCES}/ide/... this directory was set up as an example for the ide.jot script. It has the following subdirectories:
Th example projects in ${JOT_RESOURCES}/ide/projects are structured such that the work directory sits alongside the projects directory, in practice the work area can be anywhere convenient to you.
To initiate a project session, first cd to the projects directory then start the editor with the appropriate project file. The projects-directory startup.jot will set up the session using commands specified for your chosen project file. Note that the contents of the project file are usually ignored, you can use the project file for informal notes, tests, examples checklists and to-do lists.
Index files contain pointers to specific points in one or more text files and are used to facilitate rapid and convenient context changes.
Jot supports two types of index files - the native jot format which is used to drive the %I command with a seek and section-size specification and the vim-style tags file generated by the ctags unix command.
The native-jot index files are optimised for navigating *very* large files, where it would be impossible, or very inconvenient, to load and search the whole file - see about large files. The native-jot index form has also been adapted for use with large collections of files eg the source-file tree for a complicated programming project - see about large collections of files.
Jot also supports the vim-style tags files, these can be conveniently generated by generated by ctags.
The native-jot indexes supported by the jot scripts big_file.jot and multi_file.jot are significantly faster for very large files since they use a filing-system seek to access the files and only read the sections of interest. The downside is that writing modified versions of the files requires special care. Writing is supported by big_file.jot, the modified file will usually require re-indexing as the seek points will have changed.
In contrast, vim-style tags files read the entire file to a buffer making it easy to write an updated version but, because it needs to search the entire file for each new section heading, it can be slow if there are any very big files in the tree - this is most unlikely for normal source-code trees.
A working definition of a very large file is one big enough to exceed the capacity of a text editor as supported by our system. That definition takes into account various system configuration and tuning considerations like memory size swap size disc bandwidth cache size and all that sort of stuff.
The main problem with *very* large text files is not changing them but just viewing them. Although These files are generally both generated and read by machine they are presented in a text form because people need to work on them when something goes wrong.
These files are frequently used as intermediaries in CAD design flows using design systems from rival vendors. Many are based on spice netlists and a spice netlist of just a section of a modern chip is never going to be a small file.
So the way jot approaches this problem is to acknowledge that nobody, pondering the problem of "what went wrong" or "why am I seeing that error report" or "why that timing violation" is ever going to want to look at all xxxGb of a file - only the bits that an investigation leads to. So we need a method that lets us pull in the relevant bits of information. There are several qualifiers to the %I command that allow us to pull in selected parts of a big file and make it viewable - even if not editable. In any case modifying these files wouldn't do us much good - we'd be corrupting the design flow.
The %I command has a number of features designed to facilitate the reading big files. In %I, the -hold, -bytes and -block qualifiers can be used to read large files by the spoonful (or, indeed, by the bucketful) for filtering or generating an index, as in the big_file.jot script. This script gives a more-or-less normal editing environment for specified sections of large files.
Many modern editors offer methods of maintaining source-code trees using some sort of index file. In vim and Emacs thes index files are called tags files but in jotland, in order to avoid unnecessary complexity, index files are referred to as index files. Also as it happens, in jotspeak, the term "tags" refers to little bits of metadata that can be attached to text - see about tagged text.
When working on some big complicated project, involving lots of source files or maybe, after downloading some source-code, one of the first things many of us like to do is to browse the source code to get some idea of how it works.
Unfortunately, the more complicated systems consist of a large number of source files and, without some prior knowledge of how the sources are structured, it can be difficult to see what's going on. The scripts multi_file.jot and ctags.jot are designed to help with this problem.
These scripts each support a separate index-file format, multi_file.jot supports one based on an extension of the form used for large files (see about large files) and ctags.jot supports vim-style tags files which can be conveniently generated by Exuberant Ctags.
There are two clearly identifiable groups of jot commands - those text manipulation and those for interfacing with the operating system and for internal housekeeping.
In general, the basic text manipulation commands are all single characters some of these take qualifiers which may be either numerical, text strings or special characters. Most commands return a success/fail status flag - a fail will result in an interruption in the programme flow within a block.
The housekeeping commands can be for probing and setting system state or calling system services. These are generally prefixed with a percent ( % ) character. Because of th e more rigid syntax of these commands they allow more complicated expressions and pathnames for referencing buffers. e.g:
These perform essential bread-and-butter operations you would expect to find in any editor - to do with finding, substituting and inserting strings, manoeuvring, moving blocks of text etc. Some naturally take string arguments e.g: F (find in text), S (substitute) and I (insert) while others naturally take numeric arguments e.g: M (move line), R (move rightwards) and some take a buffer key to identify a destination buffer e.g.:Z (Zoom to some other buffer), A (Abstract - cut text to some other buffer).
Numeric parameters are generally specified in decimal e.g:
> m123String parameters may use any non-alphanumeric ASCII character as a delimiter provided the delimiter does not occur in the string. Note that most (see Q) of these commands will accept ISO-8859-x or UTF-8 characters in the parameter string but only ASCII characters may be used as delimiters.
If there is no further text on the command line then the string may be left unterminated. These examples all find the next instance of the string £1234:
> f/£1234/ > f/£1234 > f@£1234@ > f"£1234"Most commands that accept a string parameter will also accept a reference to a buffer by replacing the string and delimiters with '<key> in the command line (e.g. F'@ ) in this case the string used is the entire current line of the referencedy buffer. The input parameters to many of the percent commands (mainly those which take pathNames) may also be defined indirectly in this way (e.g. %ia='$; %qb=file '$ ) but the destination buffer cannot be the same as the pathName buffer. Where this type of indirection is used, there is an upper limit of 1024 on the allowable length of parameter strings.
The indirect reference can be to a buffer on the operand stack (see the stack).
In this example, the value of env FRED is used to define a search string:
> %q~=env FRED; mz. f'~Most references to numerical items on the stack cause the to item to be removed, references to buffers on the stack remove the link to the buffer and, if no other links exist, the buffer object is destroyed. In this example, the top item on the stack contains a numerical value used to set the size of a hashtable:
> %h=create '~;In jot's direct insert mode (see command-mode vs. insert mode), you cannot enter commands (but you can temporarily exit to command-mode - see TempInsertMode). You can only type text straight onto the screen or fire off the editor functions attached to hot-keys and control keys. If an editor function requires an parameter it will prompt you for it. Type it into the console area and hit {Return}. See %s=commandmode for details about jot's type-into screen mode.
The percent commands are a rag-bag things dealing with various houskeeping operations and providing an extended-syntax equivalents for some of the basic commands.
%W (Window management) and %I (Input from a file), are examples of houskeeping operations and %X=find (extended-syntax find - allows string expressions) and %X=zoom (zoom to another buffer) identified by a buffer-path expression.
The percent commands are all long-format commands that begin with a percent sign ( % ) and are terminated by a semicolon ( ; ).
In general, the percent commands all conform to the following structure:
%xy=<operation> [ -<qual1>=<qual1Arg>[ -<qual2>=...[ ...]] <mainArg>;
Both the mainArg and the qualifier args may use string expressions. These allow argument strings to be described by symbolic reference to substrings in any number of buffers, numerical values or control characters. See string expressions for more details.
Historically, percent commands that need to identify a target buffer did this by way of the buffer key part of the percent-command syntax. With secondary buffers which must be referenced by a buffer path expressions, all of these commands now have an optional argument which can be used to specify a path expression e.g %I= -buf=<pathExpression>
The basic commands allow two simple forms of string expression:
contains a quote mark. The terminating delimiter is optional when there are no further commands on the line.
The percent commands accept these two forms and another more general string expression which allows for concatination of several indirect string expressions, specification of control characters and escaping of special characters. The string passed to the percent command is the concatination of any number of subexpressions separated by ampersands. A subexpression can be:
The special characters being:
The simple commands like F, I and S all take simple string arguments, the string you give it is literally the string that gets applied (except for the special case when the arg is a single quote ( ' ) followed by a single character, which is taken to be a primary-buffer key. This is an indirect reference to the nominated buffer and the string passed to the command is the current line of the nominated buffer.
For many percent-command arguments there is the option to use a string expression. The jot string expressoion syntax was designed to minimize the number of special characters that have to be escaped if ever they are to appear in the resultant string.
A jot string expression consists of any number of simple subexpressions separated by by the string concatination character ( & ):
StringExpression = <subExpr1>&<subExpr2>&...
Where each subexpression may be any of the following forms:
For literal substrings, any leading whitespace is normally trimmed off, when this is not desired, the leadinh blank should be escaped wih a backslash ( \ ) e.g:
> %M=\ This message will be indented by three blanks.; > %M= This message will not be indented.;Note: it is not necessary to escape whitespace other than the first character.
For indirect references to either primary or secondary buffers, the subexpression is replaced with the current line of the nominated buffer.
Indirect references to buffers always have a quote at the start of the subexpression. For references to primary buffers, this is followed by the buffer key, for references to secondary buffers the remaining path expression follows the quote.
References to the stack are also allowed using the buffer key character tilde ( ~ ) at the start of a subexpression is expanded according to the type of item at the top of the stack::
To define control characters in the range 0X80 to 0XFF use the following specifications:
These are the special characters ( ' ^ \ & and ; ) - note that some are only special at the start of a subexpression:
Note that the maximum total length for percent-command string expressons is currently set at 1024 characters. However the simple commands will work for any length - in this example a string of over 2000 characters is indirectly referenced by the I command:
$ jot ${JOT_RESOURCES}/t.t -st=dbg -in="%iq=l99.t; (ji/ /)0 z.f/jon/ i'q"
This scheme applies to all percent commands except the search string of regular expressions - i.e. ( %X=find -rex ). In this case the string is passed as-is to the regular-expression processor. This exception is made because regular expressions contain many funny characters which would require escaping - where it is necessary to specify the search string indirectly it is necessary to construct a macro containing the full command string.
About the Operand Stack
The operand stack allows simple arithmetic operations and tests to be performed on objects (typically integer quantities) held in a push-down stack. It can also hold real numbers and temporary buffers created by the system query commands. The full range of operations is described in Stack Operations.
The underlying C-language type for integer values is long long, for real values it's double.
For the benefit of those not familiar with the notion of stacks in computing. Stacks are analogous to those spring-loaded plate stacks so beloved of institutional caterers. As clean plates are delivered, the stack gets pushed down, as plates are taken off the next one pops up. Note that, when plates are added individually, the last one on is the first one off - this is a key property of computer stacks - sometimes known as LIFOs (Last-In First-Out).
And so it is, with our operand stack, new values are 'pushed' onto the stack and later 'popped' off for processing. Each item on the jot stack is wrapped up in a little data structure called a stack frame, which play the part of plates in the above description. Many common arithmetic operations require two operands, for these, the top two operands are removed and the result is pushed onto the stack.
A stack frame can be detached from the stack, assigned a name and loaded into a hash table (see about hashtables), from there it can later be referenced by the same name and restored to the stack.
Essentially the stack objects can interact with the text and the system the following ways (see Stack operations for the full list):
If performing a straightforward text abstraction (e.g. A~) or maybe a query to stack with %q~=... (see %Q), a new buffer stack frame will be created at the top of the stack. If, however, you are doing a cumulative abstraction (i.e. a~+,a~- or a~. - see A) then the item at the top of the stack must be a buffer stack frame.
Jot supports the usual arithmetic and logical operations and can use values in the stack to control programme flow or values can be written to the text. Addition, for example, pops the top two values and pushes their sum back onto the stack (see O+).
All arithmetic and comparison operations will work with integer or real values, for mixed operations integers are first converted to reals and the results of such arithmetic is always real. Any attempt to perform arithmetic on a buffer-type will fail.
Each buffer can have an associated hashtable. Hashtables are referenced by keyword - the keyword can be any unique string and each hashtable entry may point to one of the following classes of data object:
Any number of these five types of entry may coexist in the same hashtable. Note also, the buffer-type data entries may each support child hashtables.
The JumpObj is essentially an index which allows fast references to indexed text. Hashtables are a useful alternative to searching with the F command when the buffer is extremely large or when a macro makes many references to moderately large buffer making the searching a significant proportion of a macros execution time (see %H=jump)
The DataObj is a stack-frame (see the stack) that has been detached from the top of the stack and can be copied back to the stack as required, this works for any stack-frame type - integer, float or buffer (see %H=data, OV and OQ commands). Data objects can be swapped between the stack and the hashtables, note that the data-object buffers can also have hashtables, leading to the possibility of unlimited hierarchies of hashtables.
For data objects assigned to one of the main buffers, the syntax is pretty simple - to extract the value of an object named "fred" hanging off the current buffer it would be:
> ov/fred/But to access an object named 'fred' hanging off data-object-buffer named 'jim', which is itself hanging off another data-object-buffer named 'brian' hanging off the buffer ( . ) - we might just plod through the hierarchy - first making the parent buffer current then descending to the child ... etc.:
> z.oq/brian/z~ oq/jim/z~ oq/fred/That's pretty painful - so there is a path-specification syntax designed for delving into buffer hierarchies without having to constantly change focus:
[<bufferKey>=][<PathElement1>[|<pathElement2>[| ... ]]]
This is how we might use this syntax to access the object "fred" in the hierarchy described above:
> oq/.=brian|jim|fred/While this syntax simplifies usage, and makes for tidy encapsulation of objects, it still requires three relatively expensive hashtable operations to locate the data. Note that that, although some path depth may be desirable - possibly essential for some recursive functions, it can get expensive and programmers are urged to keep their data structures as flat as possible.
The code repository hashtable is useful for creating data structures as the hashtable is created at startup time and this buffer should never get deleted.
The SetsectObj is intended for the handling of very large files, it defines the byte-offset and byte-count of sections of files - see %H=setsect, %H=setfsect and the -section=<hastableKey> section of the %I command.
The SetfsectObj is similar to SetsectObj except that it also includes a pathname and is intended for support of collections of files - see about large collections of files
Typically what happens is the text is first scanned to identify the target points, and create hashtable entries. When queried, the editor picks up a reference to the original target point an restores the editor focus to that at the time when the entry was created.
The ZombiObj exists because the gnu hashtables do not support removal of entries. When a %H=delete request is made, the hashtable entry is left in place but the object it points to becomes a zombie.
When a buffer object is duplicated on the stack (see O#) it is said to be cloned. The original and the clone are identical and point have pointers to the same underlying data structure.
Note that stack-based buffer that has already been used to define one data object cannot be used to define another. This restriction is, hopefully, not very onerous since the same data can be accessed via the first data object. The restriction comes about because, put simply, an object can only have one parent tree. In practice, as the hash-table trees are deleted, a data object shared between two different trees would acquire an undefined status.
When a hashtable is destroyed by %H=destroy or it's parent buffer is cleared (eg by the A, %D, %Q, %I, ... commands), then all of it's it's objects and any descendants are also destroyed. There may be clones of destroyed buffers on the stack or the current buffer may be a clone of a buffer previously dangling off a destroyed hashtable. These remain effective and usable - but their hashtable path is removed as their parent buffers no longer exist.
For more details on hashtables, take a look at Using Hashtables.
When secondary buffers are used (see about text buffers these lack a simple single-character buffer key but all secondary buffers have a parent buffer, and maybe a chain of several parent buffers leading back to a primary buffer. A path expression is just a list of parents going back to the primary buffer.
The path Q=fred|jim|jane, for example, identifes a buffer named jane with parent "jim", jim has the parent "fred" and fred is a child of the primary buffer Q.
In it's simplest valid form , a buffer-path expression could just be the primary buffer key. Also, many percent commands have default s for the primary buffer, in particular %h=call (for calling a jot function) defaults to the code-repository buffer ( * ).
Jot allows users to construct macro-commands which can apply tests make decisions and return results - they can also, of course, alter your text.
Most commands are capable of failure, by looking at the status returned by a command we can often deduce something useful about the text we're working on. If, for example, the r command fails it can only mean that the cursor is already at the end of a line, if f/<string>/ fails then it means that string does not exist. When writing a macro-command these failures are not so much disasters as potentially useful results.
Sequences of jot commands may be organized into blocks bounded by round brackets. Optionally, the sequence of commands within a block may be broken by commas, the sequence following the comma take control if a failure occurs in the sequence before the comma - giving us an if-else structure. Since the else-sequence might fail successive commas can be deployed giving us an if ... elseif ... elseif ... structure. Ultimately, if the last sequence in the block fails then the *entire* block returns a failure. Blocks may be nested to any number of levels.
Jot blocks, like most jot commands, can be given a repeat count. As with jot commands this may be infinite the repeat count for a block must be a decimal literal immediately after the end brace. As with other jot commands for an infinitely repeating block, set the repeat count to zero. In the event of an unhandled failure occurring in a repeated block, the block exits immediately even if it has not gone through all it's iterations. In these circumstances a block with a finite repeat count returns a failure, an infinitely-repeating block always returns success.
A sequence of commands can be enclosed within parenthesis (see ( and ) ), this has the following effects:
Here's a few examples:
(f/fred/s/bill/)23 - is a finite repeat block, it seeks the next 23 occurrences of fred and substitutes bill. If there are less then 23 freds in the text then the F command fails and so to does the complete block. If there are more than 23 then, on completion, there will still be some fred's left.
(f/fred/s/william/)0 - is a conditional repetitive block, the thing keeps on finding freds and substituting williams until all freds have been found, then the F command fails, the block exits but in this case the block exits successfully.
(f1/fred/s/bill/, f1/jim/s/dave/) - If the current line has a fred at or to the right of the current character, it will get changed to bill. If there is no fred then the failed f1 command leaves the current character unchanged and searches the line for jim, if found then it gets changed to dave.
Any buffer can hold sequence of commands, the commands in the buffer can be executed as a macro command. Macro commands can call other macros - but recursive macro calls (where a macro, or one of it's children, calls itself) are not allowed. For primary buffers, the command to run a macro is a single quote ( ' ) followed by the buffer key but secondary buffers may also be used in this way. For secondary buffers use the %x=macro command - this can take either a primary-buffer key or a secondary-buffer pathname.
See %x=macro for this, the path may be either a secondary buffer or a simple primary-buffer key, or ' which will run a macro in a primary buffer defined by a single-character buffer key.
JOt functions are command strings which may be activated by calling by name and passed a parameter string.
Jot offers a primitive form of subroutine support, Sequences of commands may be entered in a buffer and then referenced using the %H=call command.
Code can be designed to operate only on the stack resulting in procedure-like behaviour. There is no formally-defined parameter-passing mechanism - programmers may use the stack or global buffers. But, it should be noted, that there is no protection of stack objects - programmers must be very careful to maintain strict discipline in their stack operations. Also, the only way back to the calling macro is to reach the end of the called sequence - there is no return command.
The code repository set up by startup.jot is in the ' buffer. The first line of the code is, by convention, assumed to be the routine name and is ignored by the %h=call command.
Where there are many routines defined by the normal startup script (see startup.jot) saved in a buffer, there is no explicit mark denoting the end of each. Instead, the first line of the next routine is used as an end marker. The %h=call behaviour detects the end of a routine by checking for the existence of tags on each record. Any tag is assumed to be the hash-table target for the next routine in the repository. This very simple approach breaks if, for any reason, other tags have been added - so do not apply the jot.jot to the code repository.
Most commands set a success/failure flag. Failures are quite normal in JOT - many commands are used simply to locate structures in the text and these failures are normally handled in the command sequence. One may, for example want to test if the cursor is at the end of a record, then we might use the move right (R) command and check it's status - a failure can only happen when the cursor is at the end of a line.
Errors are more serious (typically a syntax error in your coding or an I/O operation that failed), these result in an immediate exit from the command sequence with a message in the console area. By default, errors will stop execution of the current command sequence with a message indicating what's gone wrong - these can be suppressed using %s=verbose or -quiet.
There is a message associated with failures too but these are suppressed by default. If a command sequence ends with the error flag set then the termination message "{Command-sequence failed.}" is issued with a simple diagnostic indicating which command failed.
If a command fails and no command is found to handle the failure, then the block or macro fails, if the failing command was not in a block or macro then a message like this appears at the console:
> {Command-sequence failed.}...<failingcommand>...See %s=verbose for details on controlling the level of error reporting.
Failing commands are handled as follows:
If the block was an infinite loop i.e. '( ... )0' then the loop exits without passing on the failure, all other types of blocks fail.
Hashtables offer a good way of rapidly accessing data objects scattered around in an unstructured mass. Although initially introduced to the editor as a way of finding predetermined points in a large file image (see Using Hashtables to Locate Text), their range has been expanded to calling jot functions (see calling functions by name), fast access of large files (see about large files), accessing large collections of moderately-sized files (see about large collections of files) and storage and retrieval of generic data (see using hashtable data).
All %h commands can refer to hashtables belonging to other buffers e.g. the command "%hz=jump fred;'" will search for an entry "fred" in the hashtable associated with buffer z, whereas "%h=jump fred;" will search the hashtable in the current buffer.
The %H=newjump and %H=addjump commands provide a method of indexing and rapidly returning to sections on the text image.
Internally, this works by storing internal memory addresses of text targets in the hashtable. The hashtable entry points to a record descriptor which remains constant even if text has been added or removed in the buffer and a target-point tag is inserted in the record metadata.
The target is the selected substring at the time when the hash-table entry was first created. Now future changes to the text may change the record containing the target but the target substring must match the hashtable entry. In this context there are two important classes of change to consider
delete the target string.
The %H=jump command returns to same focus point as when the entry was created with the %H=newjump and %H=addjump commands. It also maintains the original line number - this might now be wrong since changes to the target buffer may have altered the actual line number - but the linenumber entry in the hashtable is out of date. If this is a problem then use the %H=fix command to update line numbers held in hashtables.
When the context switch happens, the line number in the target buffer is set to the line number at the time when the entry was created. This may now be incorrect if records have been added or deleted between the hash-table target points.
The editor automatically adjusts hashtable entries when changes have moved the target. It offers several options for situations when the target string has been deleted.
The simplest method is to make the target buffer readonly (the buffer containing the target string - see %b=readonly). Making the buffer ReadOnly is a simple and totally effective but it is quite restrictive.
Another option is to automatically destroy the hashtable when target records are deleted - this is appropriate when the usage implies that any change requires a hashtable rebuild - see %H=create.
Another option is to protect records containing the target strings from deletion - see %H=create.
Another option is for the hashtable target points to be adjusted to point to the next available point in the text - see adjust in %H=create.
Finally, the default option, is to just remove the hash-table entries pointing to deleted targets, this is the default behaviour - see delete in %H=create.
For examples of %h=jump - look at ${JOT_HOME}/coms/qr.jot (see qr.jot).
The primary focus for arithmetic and logical operations is the stack (see the stack) - values and strings can be placed on the stack, manipulated and either written to some buffer or used to control programme flow. The %H=data command is essentially the declaration of a data object. The value of this object can be copied to and from the top of the stack.
Once defined by the hashtable data command, a value can be assigned using the OV command which pops the stack and copies the value to the data object.
Note that the hashtable data command does not require the specification of a data type - the type of data (an integer value, a real value or a string) is defined at the time when a value is assigned. In fact it is possible to change the type of a data object any number of times.
The value can be retrieved using the OQ command, essentially the reverse of OV, the value is copied to a new stack frame and pushed onto the stack.
The following metasyntax has been used in this user guide:
the letter b followed by the letter x.
The first, most obvious difference between jot and ecce is that jot is a screen editor - it maintains a window as an accurate reflection of the what the file image is currently looking like.
The next significant difference is that, whereas ecce would only use printing characters for controlling the editor, jot also utilizes function keys and, where available, the numeric and mid keypads.
Internally, the structure is quite different, ecce used the buffer-gap structure which made good use of simple memory schemes available in 1960's minicomputers. In contrast jot uses a less efficient but more flexible record-descriptor structure better suited to modern approaches to memory management.
The most recent version of ecce had 23 usable buffers designated A-W, and three macros X, Y and Z. Jot has buffers associated with all printing ASCII characters although, being case insensitive, a-z are folded into A-Z and any buffer may be used as a macro - that's about 60 fixed buffers/macros that are easily accessible with the Z command. In addition to those, however, jot also supports an unlimited number of secondary buffers, the access syntax can get a bit painful though.
Other significant new features:
Comparing the command set of ecce with jot, we see a few old favourites have been culled (D, T, U have been abolished or reassigned new meanings). However, for the percent commands, the cull is more like a total bloodbath
This section describes an approach to debugging jot code by inserting special commands (T and %S=trace) into the source code and manually monitoring the results. The dbg.jot script provides an menu-driven interactive approach which allows insertion of breakpoints into compiled code.
The editor has various features designed for the monitoring of execution flow and the location and analysis of bugs. One unfortunate aspect of the jot language is that, because failures happen all the time, it's often hard to easily identify the failures that cause problems.
There are various methods of probing the internal state of the editor and various methods for selecting break points. It supports a simple single-step debugger with various options for controlling the step range and the amount of information displayed at each step - see About jot debugging. The break point can be defined in the following ways:
The T command is easily inserted into the source code of any script, macro or command line. Where this is not selective enough, the T command can be made conditional e.g.: ... (v/fred/t, ) ... will only trigger the trap when the text at the current character matches the string "fred".
Frequently if is useful to skip over a block, macro or function call or an entire script. This can be accomplished using the DebuggerQuit function ({Esc+Q}) - which uses the %s=traceskip command. Typically this will be used when single-stepping through some code and we want to step-over, say, a macro call - see Using %s=commandcounter in debugging.
See %s=trace for details on how to set the trace vector - essentially, the trace vector controls when a trace-point occurs (every command, every new line etc.) and what trace activity is to be triggered at these points (a Breakpoint, display the source line, display of current line, stack-dump, backtrace etc.)
Another potentially-useful debugging tool is the %s=on_int command. When a function enters an endless loop a {Ctrl+C} interrupt is the only way of exiting it - but, by default it leaves no clue what was going on. This allows the specification of some commands to be executed before execution is terminated. Typically, this might be a backtrace or a trace point see Query backtrace for details on the jot backtrace reports.
The command-line option -hold is also useful in cases where a script or macro exits abruptly with a %A - it allows some diagnostic probing before the session finally terminates.
The script dbg.jot offers an interactive debugging environment.
If, shock horror, the editor should crash and the crash can be repeated under gdb, or some similar debugger, the diagnostic function diag() can be called. This does a jot backtrace a stack dump and gives brief informatoion on the followin buffers:
The command counter method is useful when a data-sensitive failure occurs deep into many re-iterations of programme loops or when a script or function fails under mysterious circumstances. In order to use this method successfully it is first necessary to identify the command count just before the point of failure. Having done that, it's possible to set a debugger trap at some point just before the failure using the %s=commandcounter command and re-spin your script or function.
Before setting the trap it is necessary to find how many commands were processed leading up to the failure but note that the command counter is reset at the start of a session and then after every interactive operation. Here are some useful ways of obtaining the the command counter:
The command counter is wrapped up in braces immediately after the message e.g: for the message
{-init sequence failed. (3097) (line 1 of buffer i)} ...
the command counter was 3097.
Note that most of the other messages do not include the command counter - to request it with these set bit 10 of the verbosity mask - see below.
The state of the command counter appears in the query system report.
$ jot ... -in="failing_script.jot;" -hold
Then make a note of the command counter (say 123456) and set the counter a few steps lower for the re-spin:
$jot ... -in="%s=cc 123450; %r=failing_script.jot;"
(%s=cc is a valid abbreviation for %s=commandcounter).
See the example at setting command-counter breakpoints
This section describe the primitive (i.e. basic built-in) commands. For details of jot functions and key sequences see JOT User Guide.
JOT has the following primitive commands, meta-commands and modifiers, most are capable of failing in some way, failures normally result in the raising of the failure flag (see success, failure and errors), this can affect execution flow:
R[n] - shift Right by n characters (bytes if unicode support is turned
off - see Unicode - the gruesome details).
Move character pointer n[1] places to the right, it fails and raises the failure flag if there is an attempt to go past the end of the line. For non-unicode characters one byte is equivalent to one character. For unicode characters, if unicode support has been turned off (see the %b=unicode command) the current-character pointer may be left pointing to a mid-unicode byte. See also OR command and about unicode.
M[[=|-]n]|[*[-]] - Move to start of specified line.
The command raises the failure flag if there is an attempt to move past the last line or before the first line of the file.
X[-][n] - eXit or re-iterate current, or selected parent block.
The X command with a +ve argument causes the selected block to exit immediately, with a negative argument it causes to selected block to repeat from the start. The numerical value specifies which of the enclosing blocks to exit or repeat. A value of 1 (or -1) specifies the current block, 2 (or -2) it's enclosing block ... etc.
The X command does not affect the current value of the block-repeat counter.
In this context a block means any code-sequence enclosed by round braces and the current macro or function call. The range of the X command is limited to the current macro-command or function. Other than returning a status value the X command cannot affect blocks in the calling code sequence.
On exit the status is usually set to success, a backslash ( \ ) can be appended to change the status to failure.
Y[[=|-]n]|[*[-]] - move in column (Y axis) by [n] lines. Y0 - Reset the column traversed by subsequent Y commands.
Similar to the M command except that it up and down in a column of text.
If it passes through a line that is too short to maintain the columnar movement, the cursor is left at the end of the line but the original column number remains stored internally. If some subsequent invocation of Y passes through lines of sufficient length, the original columnar movement is restored.
If the display is in tabular mode then the Y command operates on the table columns set up by the %b=tabcells command and Y moves to the first character of the appropriate table column.
The special case y0 will reset the internally-stored column number. It does not affect the cursor position but causes the *next* y command to redefine the column number.
E[-][<n>] - Erase n bytes to the right [ or left] of the cursor.
Erase next[previous] n[1] bytes. If n is finite and would cause the cursor to go out of bounds the failure flag is raised. With a positive arg, E deletes the bytes from the currently-selected character and characters to it's right. With a negative arg, it deletes bytes from characters to the left of the current chr.
The programmer must be aware that one byte is not necessarily a complete character - see about unicode.
P[-][<n>] - print line(s).
Prints (displays in the console area) the next[/previous] n[1] lines. If n is specified, and is greater than 1, or less than -1, then the current line is set to the last line printed. If the value of n would cause it to go outside the range of the current buffer then the failure flag is raised.
F[-][range][<delim><string><delim>|'<key>][-][rpts] - Find
Search text for specified string. If found the substring is highlighted and becomes the selected substring. - see About the current character and substrings
The F command takes parameters which specify the search string, a range and repeat count.
By default JOT starts off in it's case insensitive mode, this can be modified by the '%S=case' command.
If there is no currently-selected no substring, the search starts at the current character. If there is a substring, the search starts one characters after (or one character before, in the case of F-) the start of the current substring.
For unsuccessful forwards-looking multi-line searches the current character is left at the start of the last searched line. For unsuccessful backwards-looking searches current character is left at the end of the last-searched line.
For unsuccessful single line searches (i.e. when the range parameter is set to 1) the current character pointer is left unchanged for both forwards and backwards-looking searches.
Parameters:
f-/abc/
The second delimiter may be omitted is there are no further commands or modifiers on the command line - e.g. f/monday
Alternatively, the '<key> form will search for a match to the current line of the nominated buffer e.g. f'@ - see basic commands.
Finally, if no find string is specified, then it uses the last-used literal search string.
e.g: in the following, the first command finds the next occurrence of the string 'fred', the next find locates the string indicated by the current record of the $ buffer and, finally, it locates the next instance of the string 'fred'.
> f/fred > f/'$ > fSee also %X - search with options and %S to change case sensitivity.
T - Trace
This sets the trace vector to the value specified by the default trace vector. By default the trace vector is 0 (no tracing activity) and the default trace vector is set to Trace_Stack, Trace_Print, Trace_Break and Trace_AllCommands this means:
Alternatively, the trace vector can be set explicitly with the %s=trace command. The default trace vector can be redefined with %s=tracedefault.
See also about jot debugging and the jot debugger.
Q[-][<delim><string><delim>|'<key>] - Qualify
Tests for existence of any of a specified set of characters in substring.
The argument string can contain any ASCII and unicode characters but, for a range of character codes (see below), ASCII and unicode should not be mixed in the same range.
The character at [or before] the current character position referred to here as the "match character") is compared to the character set specified by the string parameter, if one of the specified set of characters matches then the command returns successfully, otherwise if reports a failure. The Q command is invariably case sensitive and has no effect on the text file image.
If, instead of the <delim><string><delim> syntax, the '<key> syntax is used, then the qualifying string is in the current line of the specified buffer.
The string may be a simple list of all allowable characters, or may specify a range of ASCII characters ordered by their ASCII codes, to match to the literal '-' character it should be the first or last in the string for example:- Q/0123456789/ Will match to any digit. Q/0-9/ Will do the same but saves typing. Q/0-9+-/ Will match to any digit or the '+' or '-' characters. Q/0-9A-Fa-f/ Will match to any Hex digit.
If the character set includes unicode and the match character is also unicode, then the character and the string are both converted to native UTF and the comparison is done in UTF. This is one of the few instances where jot operates on full-width unicode - see practicalities of unicode etc. and jot.
V[-][string] - Verify string.
Verify - tests text at current character position for match with string.
If the given string matches the substring to the right of the cursor then the substring is highlighted and becomes the About the current character and substrings. If not then the failure flag is raised. Correspondingly, V- verifies the text to the left of the cursor.
C[-][n] - Change case.
Change case of next [previous] n characters. If n is specified and would cause the cursor to go out of bounds the failure flag is raised.
Note that the C command has no affect on unicode characters.
I[-][string][n] - Insert substring
Inserts specified substring before current character.
The optional '-' parameter only affects the position of the substring end pointer on completion - normally the cursor is immediately after the end of the inserted substring I- causes it to be at the start.
S[-][<delim><string><delim>|'<key>] - Substitute
Replace the currently-selected string with the given string.
If a substitute string is defined then this is replaces the current substring, if no substitute string is specified then the last used substitute string is used.
When the '<key> syntax is used, the substituted string is taken from the current line of the specified buffer.
This command normally only fails when the current buffer does not currently have a valid substring About the current character and substrings (e.g. following a F, T V or a previous S command) - when it fails the failure flag is raised.
B[-][n] - Break line.
Where n is an optional (defaults to 1) repeat count, on completion the character pointer is left at the beginning of the second line (i.e. it still points to the same character), except if a negative repeat count is entered
A negative repeat count will break the line the same number of times but will leave the character pointer at the end of the first half line.
G[<n>] - Get
Read a new line(s) of text or single character from the keyboard.
Use this to key in new text above the current line, the parameter sets the number of lines to be input or you may terminate with a control+C or a colon ':' at the beginning of an otherwise empty line.
By default it prompts with "> " but you may define the prompt string using %s=prompt.
If a linecount is specified and an early exit is forced, then the failure flag is raised.
See also the %G command, which reads lines from the current script or macro and the OG command, which reads single characters to the stack.
J[-][n] - Join
Joins current line with next (or previous) line.
If join runs out of lines (because it's at the start/end of the buffer) then the failure flag is raised.
K[-][n] - Kill i.e. delete line(s).
This completely removes lines and there is no way of getting them back. If n is specified and finite and it runs out of lines to kill, then the command fails. K0 deletes the current line and all subsequent lines, K-0 deletes the current line and all previous lines.
K- deletes the current line and leaves the cursor at the begining of the line above, similarly K-n deletes the current line and up to (n-1) lines above leaving the cursor at the begining of the line above the last deleted line. If the first line was deleted, then the cursor is left at the begining of the line following the original current line.
Note that there must always be at least one line in a buffer. To maintain this situation, an instruction to kill the last record in the buffer will only erase all the text leaving an empty record - it will also fail.
N[.] Note
Note = Note line [and character] number for later abstract.
This sets the start point of one or more lines of text to be moved by a later abstract A command.
Without the ( . ) modifier, complete lines are removed by the subsequent abstraction.
With the ( . ) modifier, all lines and characters are abstracted between the current character position when the N command was given to that at the time of the A command.
A<key>[+|-|.][&] - Abstract
Abstracts (moves) text from note point to current character (see N) into the nominated buffer.
If the whole-line abstraction flag is set (see N command), then only complete lines are moved.
The optional '+' qualifier places the abstracted text after the end of any preexisting text in the destination buffer, '-' similarly places it before the start '.' places at the current character in the destination buffer. If none of these qualifiers are specified then the buffer is cleared before the new text is abstracted. The current character pointer of the buffer is always left at the beginning of the of the last line of abstracted text.
The optional & qualifier copies the text without changing the original. This is essential if abstracting from a readonly buffer - see %b=readonly.
The two valid optional qualifiers must follow the buffer key but not in any particular order.
If the abstraction fails (typically because no note-point is set) then the failure flag is raised.
Abstraction in jot is similar to ecce - by default, the n (note) and the a (abstract) commands abstract only complete lines.
By default jot abstracts complete lines - like ecce. By adding the . option to the note command it abstracts to the nearest character.
Cumulative abstraction - by default the destination buffer is first cleared of any preexisting text only the abstract appears in the buffer after abstraction.
By default, abstracted text is removed from the source buffer - similar to cut, the ( & ) qualifier preserves the original - similar to copy.
For simple abstraction it's easy enough to immediately restore the text but for cumulative abstraction (using the ( . - or + ) modifiers, this is not an option. The ( & ) qualifier also permits abstraction from protected buffers
H<key>[<count>] - copy Here
Contents of specified buffer (the source buffer) is copied to current buffer (the destination buffer) either to the current character position or above the current line. There is a status flag in the source buffer that determines which.
If the source buffer was itself defined by abstraction part lines (using N.
source buffer was defined in any other way (e.g: abstraction with N, %D, %G, %I or a %Q query) then the source text is inserted immediately above the current line.
The abstraction-status flag is invisible except in the "wholeRecords" line of a query buffer report.
The effect of the optional count is to insert the text that many times.
Z<key> - Zoom (change focus to nominated buffer)
Changes the current buffer to the one identified by the buffer key.
The the key for the current buffer is displayed in the editor prompt following the line number, it is also be displayed in the window separator lines (see %w command).
( - Block start
The block of commands must be terminated by a ')', it may contain any number of valid jot commands, including sub blocks. See also ) and block structure.
)[<n>] - Block end.
This terminates the current block, if a repeat count ( <n> ) is specified then the block is repeated that many times or until the block fails, if the repeat count is zero then the block only exits when something in the command sequence fails but, overall, a zero-repeat block never fails.
If repeat count finite or not given, then any failure in the command sequence is passed on upwards. See also ( and block structure.
(<anyNumberOfCommands>, <failureHandler>) - Failure handler.
The commands following the comma are only executed when some earlier command has failed. When a command fails, control is transferred to the code following the comma - the failure handler. A single block can containing any number of failure handlers, each picking up the failure condition from the previous - this is effectively an if, else-if, else-if ... structure.
'<bufferKey>
The nominated buffer must contain a valid jot command sequence - this is a macro command or macro. Macro may also be held by secondary buffers but, because these can not be identified by a single character, these macros are called using the %x=macro command.
The macro returns a status result in the same way as a code block - see (, ) and ,.
If the previous command failed and raised the failure flag, then this resets it, correspondingly, if the previous command did not fail then the failure flag is raised.
Note, \ only applies to the command or block *immediately* before it.
If, for example, we want to insert abc in any case except when it already exists:
(v/abc/\i/abc/,)
This is also useful for inverting the status of blocks, e.g.:
(f1/fred/\ f1/jim/ f1/bill/\)\
The block will succeed if the current line contains either if the substrings "fred", "jim" or "bill".
<
P>
<validCommand or block>? - ignore status of command or block.<
/P>
This has the effect of lowering the failure flag irrespective of the outcome of the previous command.
Note, ? only applies to the command or block *immediately* before it. Thus in the sequence m99p? the ignore-failure command applies only to the p command - not m99.
You can also follow ? with \ to ensure that a command *always* fails - this is useful when a failure handler needs to exit a repeated block.
See also \ (Reverse status command), block structure and success, failure and errors.
The editor maintains an evaluation stack used for numerical and logical operations.
A stack frame may contain one of three datatypes, an integer value, a floating-point quantity or a buffer. All buffers on the stack are tagged with the buffer key '~'), as values are retrieved, there is a simple check to ensure compatibility with the expected datatype, in the event of a mismatch, execution halts with an error message.
If a stack-based buffer is the current buffer, numeric values may be added to the stack without affecting the status of the buffer. You cannot, however, return to the buffer with a Z~ or OZ command (and, also the %H=jump command) unless the buffer is at the top of the stack. This command sequence, for example, will fail:
%q~=date; m(oidr)3 z.z~
But this one's OK:
%q~=date; m(oidr)3 z.(oo/%d:/r0)3z~
The stack size is by default limited to 100 slots (see -stacksize) any push operation will fail abruptly if there are already 100 on the stack. Similarly, any pop operation will fail if there are no values on the stack.
The arithmetic operations (O+, O-, O*, O/, O=. O< and O>) work for both integer or real (floating-point) quantities. If one item is integer and the other is real then the integer operand is first converted to real and the result, where applicable, is also real.
OL<intVal> - push an integer Literal onto stack.
or
OL<floatingPointValue> - push a floating-point Literal onto stack.
The specified value is placed on the top of the stack. e.g:
> ol123This pushes the number 123 onto the top of the stack.
The literal can be modified by prefixing with x or o to specify the integer in Hex or Octal respectively. eg:
> ol1024 > olx100 > olo400Note that the usual C-language format 0xnnn or 0onnn are not supported here as these are syntactically indistinguishable from an OL0 followed by an X or another O command.
For floating-point (real) values the only permissible syntax is <nnn>.<mmm> eg:
> ol1234.56789The OL command is sometimes followed by OV. This combination is used to set a data object to a literal value. See about hashtables and using Hashtable data
o& - bitwise AND
The top two items in the stack must be integers. These are removed and the bitwise AND of the two values is added.
o| - bitwise OR
The top two items in the stack must be integers. These are removed and the bitwise OR of the two values is added.
o! - bitwise NOT
The item at the top of the stack must be an integer. It is replaced by the bitwise NOT of the original bit pattern - i.e. 0's are changed to 1's and 1's are changed to 0's.
o. - buffer concatenation.
There must be at least two items on the stack, the top item may be of any type but the second item must be a buffer.
If there are less than two items on the stack or if the 2nd. item is not a buffer, the operation fails with no effect on the stack.
On completion, the modified buffer becomes the top item on the stack.
O? - List contents of stack.
This is useful for debugging - dumps the entire contents of the stack to the console - see also query stack.
OG - reads one character from console and pushes character onto stack.
This prompts using the prompt string defined by %s=prompt and reads one character that is pushed onto the stack as a wide-format unicode character (see about unicode).
If unicode-support is disabled (see %b=unicode) then unicode characters arrive as a series of values in the range 128-255 requiring multiple OG calls. Jot does not offer any method of determining where one unicode character ends and the next begins when a series of unicode characters are entered in this way.
OO<delim><formatString><delim> - Output using sprintf format string.
Output the value at top of stack using the format string.
If the current buffer has a substring following a command that defines a substring (eg: F, S, I, OI or a previous OO command), then the substring is replaced by the sprintf output. This sequence will first insert 999 and then immediately change it to 123:
> ol123 ol999 oo/%d/ oo/%d/this will give both numbers - the r-r removes the substring marker without affecting the cursor position:
> ol123 ol999 oo/%d/ r-r oo/%d/When writing unicode characters, the %c format string *must* have the l (long-format) modifier to convert the wide-format unicode eg:
> ol65r0boo/%c simple ASCII character/r0 > ol163r0boo/but the unicode %lc requires the l modifier with %%c/Note that the OG command can add a unicode character too the stack.
For numeric values the use of this modifier is recommended but a simple %d seems to work on most systems for integers of not more then 32 bits eg - this generally seems to work;
> ol123456789r0boo/%d/but use %ld to avoid truncation:
> ol123456789123456789r0boo/%ld/On completion, the current character points to the end of the inserted substring.
Examples:
> ol12345 oo"The number you first thought of is %-10d" > %q~=buffer; f/pathName = /-bza oo/The pathname is %s/ok > off za oo/%8f/ > oo/%lc/ - used to print a long-format unicode character.OQ<delim><key><delim> - Value, push value from hashtable onto stack.
The delimitedKey must match the key used to create a hashtable entry with the %H=data command. The OV operation pops the stack and copies the top frame value to the hash-table entry, deleting any previously-held value associated with that hashtable entry. A copy of the frame can later be returned to the top of stack with the OQ command.
In the event of an unmatched hashtable key or an empty stack, the OV command fails. Note that there is no typing in the %H=data command so OV just takes whatever datatype happens to be at the top of the stack and copies it to the data object.
If the top item on the stack is a buffer, then a complete copy of all the buffer records is made and associated with the data object, ignoring most of the other buffer attributes like PathName, header or Footer.
For example:
> %h=data fred; %%Creates the entry associated with the keyword 'fred' > ol123 > ov/fred/ %%Moves the top stack frame (integer 123) to the hashtable....> oq"fred" %%Queries (restores) the stack frame 'fred'. > ol456 > ov,fred, %%Redefines the value of the data object 'fred'.
OV<delim><key><delim> - Query - pops stack and sets value in hash-table.
The key must match one used to create a data entry with the %H=data command. The OV command copies the contents of the hashtable data entry associated with the hashtable key to the top of stack.
In the event of an unmatched hashtable key or no value associated with the entry or, less likely, a full stack, the OQ command fails.
If the data object holds a buffer, then a complete copy of all the buffer records is made and placed on the top of the stack, ignoring the other attributes like PathName, header or Footer.
O+ - Add
Replace top two values with their sum.
If either of the two values is a real number then the result is real, if one is integer then it is first converted to real.
There is no checking for arithmetic overflows.
O- - Subtract
The value at the top of the stack is subtracted from the next value, the top two items are replaced by the result.
If either of the two values is a real number then the result is real, if one is integer then it is first converted to real.
There is no checking for arithmetic overflows.
O* - Multiply
Replace top two values with their product.
If either of the two values is a real number then the result is real, if one is integer then it is first converted to real.
There is no checking for arithmetic overflows.
O/ - Divide
The top item on the stack is the denominator, the next item is the numerator, both items are removed from the stack and the result of numerator/denominator is then added to the stack.
If either of the two values is a real number then the result is real, if one is integer then it is first converted to real.
There is no checking for arithmetic overflows but this command will fail if the denominator (the 1st. item in the stack) is 0.
O% - remainder.
The top item on the stack is the denominator, the next item is the numerator, both items are removed from the stack and the remainder of numerator/denominator is then added to the stack.
If either or both items are real, the reals are first converted to integer the result is always integer.
There is no checking for arithmetic overflows but this command will fail if the denominator (the 1st. item in the stack) is 0.
O= Test for numerical equality
The top two items must be either integer or real, they are compared and the top item is removed, if they are equal the command status is Success, otherwise it's Fail.
If either item is a real number it is converted to integer before the comparison. This conversion does not apply to the value left behind on the stack.
O0 Test for value zero
The top item must be either integer or real, a real value is converted to integer. The value is compared to 0 and the top item is removed, if it is zero the command status is Success, otherwise it's Fail.
If the top item is a buffer, the command fails and the stack is left unchanged.
O1 Test for value one
The top item must be either integer or real, a real value is converted to integer. The value is compared to 1 and the top item is removed, if it's value is one the command status is Success, otherwise it's Fail.
If the top item is a buffer, the command fails and the stack is left unchanged.
O~ Increment value in top of stack.
The item at the top of the stack must be an integer, for any other type the the operation fails. If the modified value has gone to zero, the failure flag is raised.
O> - Greater than.
The top two items compared and the top item is removed, if the top item is greater than the next, then the command status is Success, otherwise it Fails.
If both of the operands are floating-point values, then a floating point comparison is used. Similarly, if both items are integer, an integer comparison is performed. If only one of the operands is floating point, then a floating-point comparison is performed, using the floating-point conversion of the integer value. This conversion does not affect the value left behind on the stack.
O< - Less than.
The top two items compared and the top item is removed, if the top item is less than the next, then the command status is Success, otherwise it's Fail.
If both of the operands are floating-point values, then a floating point comparison is used. Similarly, if both items are integer, an integer comparison is performed. If only one of the operands is floating point, then a floating-point comparison is performed, using the floating-point conversion of the integer value. This conversion does not affect the value left behind on the stack.
OB - save Buffer key
The ASCII value of the current buffer identification key is placed on the stack (see also OZ).
OX - push eXtent (length) of current substring in characters or bytes.
This command pushes the length, in characters, of the currently-selected substring onto the stack.
The result is negative if the current-character pointer follows the selected substring (as would be the case after the S command, for example). Jot has two forms of substring yielding +ve and -ve results:
If unicode support is turned off off (see %b=unicode) then it pushes the number of bytes in the currently-selected substring.
See also OU, about unicode, %b=tabstops, about tabular text, query inview and uc_basic.jot.
The substring-length calculation disregards any leftoffset setting - it always assumes all characters are fully visible. See also about long lines.
OU - set sUbstring length from stack.
The length of the currently-selected substring is set to the value currently at the top of the stack. A zero can be used to remove the substring setting in that buffer.
With unicode support turned on (see %b=unicode) this value is interpreted as a character count, otherwise 's taken as a byte count.
A negative substring indicates that the current character is immediately after the selected substring (e.g. after a f/.../- os s/.../ command, doc. Otherwise the value is positive indicating that the current character is the first character of the substring (e.g. after a F/.../ or S-/../ command).
See also OX.
OT - push lengTh of current record in characters or bytes.
This command pushes the total length, in characters of the current record onto the stack.
If unicode support is turned off off (see %b=unicode) then it pushes the number of bytes in the current record.
See also OU, about unicode, %b=tabstops, about tabular text, query inview and uc_basic.jot. See also about long lines.
OF - push line no. of First line of current buffer in window.
This command will search all currently displaying windows, from first (left/topmost) to last window (right/bottommost) until it finds one displaying the current buffer. It then calculates the line number of the topmost line displayed in the window. In most cases it's much simpler than that - usually there's only one window set up to display the current buffer but see %W for details.
This information can be used to control the view e.g. it can be used to return to a previously displayed view - see also OW.
Note that the line number returned is the line number at the time when the display was last updated. If your code contains anything that might change the display you should first refresh the display with the -refresh option to the %W command.
OZ - Zoom.
The value at the top of the stack is removed and used to specify a buffer key, this is used to specify the new current buffer (see also OB).
Unlike the Z command, oz does not transliterate to uppercase and an error will result if there happens to be a lower-case acsii alpha character at the top of the stack.
ON - save line Number
The current line number is placed on the stack (see also OM).
OE - Erase no. of characters specified by stack.
The number of characters to be erased is popped off the stack, a negative value indicates leftwards erasure, positive values indicate rightwards. If there are insufficient characters then the command fails leaving the text unchanged.
OM - Move
The value at the top of the stack is removed and used to specify a relative move forwards (+ve.) or backwards (-ve) by no. of lines.
If the move is out of bounds (i.e. before the start or after the end of the current buffer) then the cursor is left at the start of the first or last line as appropriate and the command fails.
n.b. With a zero at the top of the stack, OM just moves to the start of the current line (see also ON).
OA - rAndom
A randomly-generated number is pushed onto the top of the stack. In reality, of course, this is a pseudo-random number. That means it runs to a predictable repeatable sequence depending on how the pseudorandom number generator is seeded (see O@).
O_ - Set line number.
The value at the top of the stack is removed and used to specify the line no. of current line.
The only operations which cause the line numbers to become detached from reality are the 'hashtable jump' commands
N.B. This has no effect on the cursor, it only changes the internally-maintained line number. This is displayed in the JOT prompt, and is the line number in M+ operations and ON etc.
OC - save Chr no.
Place current character no. (i.e. number of characters from beginning of line to the current cursor position) onto the stack (see also OR).
If unicode support has been turned off (see %b=unicode) then OC counts bytes not characters, including all bytes within the UTF-8 encoding of any unicode characters.
OR - shift Right by character count (byte count if unicode support is turned
off - see Unicode - the gruesome details) shifts left for negative values.
Item at top of stack is removed and used to shift the current character pointer. Cursor moves cursor right (+ve.) or left (-ve.) by no. bytes at top of stack.
If the move is out of bounds (before the start or after the end of the current line) then the operation fails and the cursor is left at the start/end of the line as appropriate (see also OC).
OI[B|C|D|O|X|F] - formatted Input conversion (of string at current character).
OI<chr> takes the character (B, C, D, O, X or F) as a format specifier and uses it to extract a value from the string starting at the current character in the current buffer. For the numerical conversions (OID, OIO, OIX and OIF), this string may be prefixed with whitespace. The result is pushed onto the stack. As usual, the interpretation of the format-selection character (B, C, D, O, X or F) is case insensitive.
Each of these variants converts characters beginning with the current character and proceeding to the right. The current character is left pointing to the character to the right of the last converted character and all the converted characters are highlighted as a substring.
In the event of there being no valid characters the current character is left unchanged, nothing is added to the stack and the command fails.
These all skip past any leading whitespace before converting digits.
OK - Kill top item on stack
The item at the top of the stack is removed and, if it's a scalar or a locally-defined buffer, it's value is lost. If it's a pointer to hash-table buffer (see OQ) the pointer is deleted but the underlying buffer is preserved.
Note that the OK command will fail if the stack is empty or the item at the top of the stack is a buffer and this happens to be the current buffer or if it is marked as write-if-changed and needs to be written out (see %b=writeifchanged).
O@ - Reset stack
Reseeds the random number generator (see OA) and then destroys all items currently in the stack. If the item at the top of the stack is an integer type then this is is used to re-seed the generator, otherwise it's re-seeded with 1.
The O@ command will work it's way down the stack, deleting entries, starting with the top item in the stack. If it encounters a buffer, it might fail at this point if this buffer is the current buffer.
OS - Swap
The items in the top and next-but-one slots in the stack swap places.
OS will fail if there are less than two items on the stack.
O# - Duplicate
The item at the top of the stack is copied and placed above the original item.
If the top item on the stack is a buffer, the O# operation does not copy the buffer records etc. it simply constructs another pointer to the same internal data. This is in contrast to OV and OQ which do make new copies of buffer data.
O# will fail if the stack is already full.
The screen display is scrolled by the number of lines indicated by the top of stack - a positive value scrolls up the screen, negative scrolls down.
See also percent-command syntax
%A[[<status>]=<message>]
%A[[<status>]='<chr>]
This exits the editor, no files are written out.
The message defaults to "Edit abandoned", it is written to stdout after closing the screen management system.
By default, the exit status code is set to 1, any value in the range 0 to 255 can be supplied in decimal.
If a message is specified, this replaces the usual "Edit abandoned" message. There is a restriction on this, the length of the message must exceed 1 character.
If some buffer has been marked as %b=writeifchanged, and the buffer has been changed, then the editor will refuse to exit until that buffer has been written. A suitable message appears if this happens - see freeall.jot.
If the exit message begins with a reference to another buffer, then this buffer is written to stdout after closing down the display. This behaviour is important when it is required to write more than the usual single-line message on exit - see about jot streams. Note that this behaviour is anomalous - that syntax normally copies just the current line of the buffer (see percent-command syntax) whereas for %A it takes the entire buffer.
%C[=<message>] - Close = Exit writing new file.
The file spec. is initially determined by the arguments given to the editor image (see -to) and may be further redefined by the %b=pathname command. By default the file will have the same pathname as the original.
The command fails if there is an attempt to %C from any buffer other than the main buffer . - to write out some other buffer use %O.
The message defaults to "Normal exit", it is written to stdout after closing the screen management system. For %C, the exit status is always set to 0.
If some buffer (other than the main buffer) has been marked as %b=writeifchanged, and the buffer has been changed, then the editor will refuse to exit until that buffer has been written or the writeifchanged lock is removed - see freeall.jot.
%E=<CliCommand> - executes a CLI command %E<key>=[ -pipe][ -status}<CliCommand> - executes CLI command and catches the output in the specified buffer. %E<key>=[ -interactive][ -exit=<exitCommand>]<CliCommand> - interactive CLI command (see also `%P`).
If a destination buffer is specified with the optional <key> qualifier, then the stdout stream of the child process is picked up and saved in the specified buffer. If no destination buffer is specified the child's stdout goes to the screen.
The command is passed to the CLI, the return status is checked and used to set the failure flag.
The simple form of %E (with no pipe) will return a success/failure result reflecting the command's exit status - any nonzero exit code is deemed to be a failure, zero is deemed to be success.
The -status qualifier causes the child-process exit status to be placed on the stack. This also causes the child's exit status to have no effect on the %E command exit status.
If the -pipe option is given, then the contents of the current buffer is output to the stdin of the command. This feature allows users to use external co-processors for handling specific tasks. When using this option the destination buffer must not be the current buffer. The editor waits for the child process to finish before continuing.
If the subprocess is inherently interactive, communicating via it's std and stdout then it is possible to set up a persistent subprocess with the -interactive qualifier (eg: gdb or sh). jot then maintains a bidirectional connection to the process and new queries and commands can be sent to the subprocess via the %P command. The child is killed when the destination buffer is destroyed or as the session closes. The exit command allows you to define a command string that causes the process to exit tidily, this is sent to the child when the associated buffer is destroyed or as the jot session exits.
The -exit qualifier is particularly important for windows, the user requires a special privilege to kill a process - even if it's a process they've created in the same session. If the session attempts to exit with active child processes it will hang while the system waits for the child to terminate. The solution is to either explicitly send the child the correct command for it to terminate itself or, use the -exit= qualifier to the %P command.
Note that, at present, the -interactive option may not be used when the session is maintaining a journal (see -journal).
%P[<key>]=[ --Waitfor=<commandSeq>][ -Nocr][ -sleep=<pause_ms>]
[ -Timeout=<timeout_s>][ <message>];
The slave session must have been previously set up by the %E command, with the -interactive modifier to create a persistent interactive session. The message is sent to the slave process's stdin and it is also appended to the buffer text. Note that the destination buffer (identified by <key>) must be the same as that in the corresponding %E command.
Jot can support any number of simultaneous %E-%P sub processes running in parallel, provided they are all associated with different buffers.
The message would normally be a command recognized by the child process. If a reply is expected via the child's stdout channel, this will be delivered to the nominated buffer.
There is usually some delay in the slave process response. When driven interactively, this delay may be small enough to go unnoticed and, in any case, the target buffer is updated asynchronously without blocking normal console activity. When %P is being driven by a jot function or a macro it will usually be necessary to include either a -sleep a -timeout or a -waitfor sequence to synchronize further jot responses.
Note that, with the the linux version, the responses usually include a windows-style carriage-return character ( \r ) this is because jot sets up a pseudo terminal ( pty ) and the child process sends these just as it would if interfacing with a real terminal.
Messages are sent to the child process and are normally terminated by "\n"
suppresses this behaviour.
By default, jot will attempt to read a reply from the child immediately after sending the message. The -sleep qualifier causes the parent process (i.e. your jot session) to sleep for the time specified in milliseconds, giving the child a chance to do whatever it has to do.
The -timeout qualifier sets a timeout, in seconds from the time the command %P was run, if no reply was received or if the waitfor condition has not been satisfied by the end of the timeout period then the %P command exits with failure status. If a timeout was set with no -waitfor commands then the %P command fails if no reply is received within the timeout period.
The -waitfor command sequence is used to check that the child process has finished sending. If the -waitfor command sequence fails, it blocks normal jot console reads until a later reply causes the -waitfor command sequence to return a success status. For this reason it's a good plan to combine -waitfor with a -timeout specification. If both -sleep and -timeout are given then the timeout period starts from the end of the sleep period.
Extended-syntax commands. Many of these are equivalent to a short form command but, whereas short-form commands like A, will take a single-character buffer key the extended-syntax form %x=abstract will take a buffer-path expression, thus allowing access to secondary buffers.
Also, the short-form versions are restricted in the flexibility of string expressions. %he %X forms allow full jot string expressions the short-form commands can take only literal strings and simple references to primary buffers. But note, jot imposes a maximum length of 1024 charactes on string expressions but simple buffer references can handle strings of unlimited length.
Additionally, the %x=find command has many more features and options than the simple F command.
Although the syntax is more long-winded and better-suited to complicated scripts, the buffer-path expressions they are designed to support, are also only really suitable for such scripts. This leaves the short-form jot language unchanged for interactive use as well as scripting.
`%X=Abstract` [ -Preserve] <bufferPath>; %X=CUt [ -Preserve] <bufferPath>; %X=COpy <bufferPath>;
These are all forms of abstraction. %x=cut is directly equivalent to %x=abstract, %x=copy is equivalent to %x=abstract with the -Preserve qualifier.
`%X=Exit` <messageStringExpr>;
Exits all macros, functions and scripts and issues the message.
`%X=Find` ... options and qualifiers <searchString>
Finds instances of the specified substring.
`%X=Insert` [ -REVerse ] <stringExpr>;
%x=insert inserts the specified substring at the current-character position.
`%X=Substitute` [ -REVerse] <stringExpr>;
Substitutes the specified substring.
`%X=Global_substitute`
Replaces all instances of matching strings with the specified replacement.
`%X=Verify` [ -REVerse][ -Back] <stringExpr>;
Verifies the current text matches the specified substring.
`%X=Here`|Paste [ -Prepend|-Insert|-Append] <bufferPath>; %x=Paste [ -Prepend|-Insert|-Append] <bufferPath>;
These are equivalent, copies the entire contents of the specified buffer to the current focus point.
`%X=Zoom` <bufferPath>;
Changes context to the current position in the specified buffer.
`%X=PUshbuf`;
Pushes a pointer to the current buffer onto the stack.
`%X=POpbuf`;
Changes context to the buffer currently at the top of the stack.
`%x=macro`;
Runs specified macro.
%X=Abstract [ -Preserve][ -Prepend|-Insert|-Append] <bufferPath>; %X=CUt [ -Preserve][ -Prepend|-Insert|-Append] <bufferPath>; %X=COpy [ -Prepend|-Insert|-Append] <bufferPath>;
These are expended-syntax versions of the A command. whereas the A command can only take a buffer key to indicate the destination buffer, these can take buffer-path expressions.
By default, the original text will disapear (i.e. a cut operation), the -preserve qualifier changes this bevaviour so that the original remains unchanged. The -preserve qualifier is mandatory when abstracting from a readonly buffer (see %b=readonly).
%X=Here [ -instances=<n>] <bufferPath>; %x=Paste [ -instances=<n>] <bufferPath>;
These are equivalent, copies the entire contents of the specified buffer to the current focus point.
By default. this copies one instance of the buffer, the -instances qualifier can be used to insert any number of instances.
%x=find %x<key>]=Find -REX ...
[ -Back][ -REVerse] [ -STARTLine=<n>][ -STARTChr=<n>][ -ENDLine=<n>][ -ENDChr=<n>] [ -THisline] [ -Verify] [ -Case=<n>] [ -SEtaperture][ -Aperture][ -RESet] [ -BReak] [ -ALl][ -FIrst][ -ANy][ -Tab=<chr>] <string>|<string1><separator><string2><separator>...;
The %X=find command performs searches similar to the F command but with a selection of options and features. It can limit the scope of a search to a defined section of the buffer (the aperture), it can search for a list of substrings either all together or one at a time and it can also do regular expressions and go backwards and forwards. It can be used to verify that one of a selection of strings is immediately adjacent to the current character and can perform searches of a defined section of the current buffer (an aperture search) and a global or aperture-restricted search and replace.
If the optional regular string <string> is not specified, then the last-specified %X=find string is re-used.
By default the search scope extends from the current character position to the end of the buffer, where the -back qualifier is given, the search goes backwards to the beginning of the buffer.
The -startline, -startchr, -endline and -endchr arguments together specify a search aperture. Searches always start at the current character and, for forwards searches, progress towards the aperture end point. Similarly, reverse searches (when -back is given) progress back from the current character towards the aperture start. The reset qualifier has the effect of first resetting the current character to the start (or end for reversed searches) of the aperture before launching the search.
Like the F command, the default case sensitivity of %X=find is determined by the %s=case setting however the -case=<n> qualifier can be given to force case (in)sensitivity for the current %X=find operation. The -case=<n> qualifier accepts a numeric argument - a zero indicates insensitivity any other value for case sensitivity.
The search string may be either a simple string or a list of strings separated by table-entry-separator characters. The table-entry-separator character defaults to an ASCII TAB character but may have been redefined by the %s=tab command or by the %X=find -tab qualifier.
Since regular expressions use many funny characters the string is passed to the Regular-expression processor as-is: no indirection to other buffers, no data-object expansion and no substitution of control characters. If control characters are required in the search string, these must be given literally.
The start line and start character define the starting point for the search. These default to the current character position for both forwards and backwards searches. If a startline is given, but no startchr, then the starting point for the search is the first character of the given line for forward searches or the last character, for backwards searches.
For forwards searches, the end point defaults to the end of the last line in the buffer. Correspondingly, the default end point for backwards searches is the start of the first line in the buffer. When an endline is given, but no end character, the end character defaults to the end of the given line for forwards searches and the start of the given line for backwards searches.
It often happens that we want to do repeated search operations within the same aperture. Thus jot provides the -setaperture and -aperture qualifiers:
%x=global_substitute
-newstring=<expr> [ -REX] [ -STARTLine=<n>][ -STARTChr=<n>][ -ENDLine=<n>][ -ENDChr=<n>] [ -THisline] [ -Verify] [ -Case=<n>] [ -SEtaperture][ -Aperture][ -RESet] [ -BReak] [ -ALl][ -FIrst][ -ANy][ -Tab=<chr>]
<string>;
All of the global_substitute aregs listed above have the same effect as described for the %x=find variant except for tha mandatory -newstring=<expr> which is unique to global_substitute. Other valid %x=find qualifiers are accepted but silently ignored.
The mandatory -newstring arg is the replacement string to be used.
The -global_substitution and -break options are intended to improve the efficiency of global operations on very long lines, where there may be a very large number of matching instances in each line. The obvious way of doing these would be
(f/<searchString>/s/<subsString>/)0 or (f/<searchString>/-b)0
Unfortunately, if there are a large number of matching instances in a *very* long line these operations can take, er. well, not quite forever but, nonetheless an unconscionable time. This is because each substitute or break operation requires the editor to copy all of the residual text and, if there are may matching instances, it has to do that a great many times.
The underlying system call only searches forwards hence, for backwards searches, when a matching line of text is found, the system call is repeated until there are no more valid matches. Hence reverse regex searches can be quite inefficient for cases where there are many possible matches on a line.
When a match is found, the first record of the destination buffer is set to the complete matched substring. Subsequent records of the destination buffer are set to substrings matching parenthesized sub-expressions.
Briefly, %X=find -rex supports most of the usual regular-expression constructs using the GNU regex library functions. Some of the more exotic ones may be missing, for details look at the documentation of the regex library routine:
http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap09.html -
Bracketed expressions - anything in matching square brackets [ ... ]
%x=find -global_substitute=<substituteString>
[ -STARTLine=<n>][ -STARTChr=<n>][ -ENDLine=<n>][ -ENDChr=<n>] [ -Case=<n>]
<searchString>;
Searches the specfiied range in the current buffer, if no range specified then the entire buffer, replacing each instance of the searchString with the substituteString.
In almost all cases, this command sequence will do perfectly well:
> m-0(f/<searchString>/s/<substituteString>)0There is one situation where the %x=global_substitute command comes into it's own. This is when the buffer contains enormously long lines, the substituteString is longer than the searchString and there are likely to be many matching instances of the searchString on a long line.
When the S command does a substitution, if the replacement string is longer, then it allocates a new section of memory copies the first part of the original line followed by the substitute string, followed by the last part of the line.
When the line is long, there is correspondingly more shifting and copying involved. When there are many instances to be replaced the process has to be repeated many times - run times tending towards the square of the line length.
The %x=global_substitute command speeds up this procedure by checking the relative lengths of the strings and counting the number of instances in the line. It then allocates sufficent memory to accomodate all the new text works its way through the line in a single active pass the run times for this are aproximately linear with the line length..
To make a significant difference to overall run times the lines have to be in the hundreds of Mb with thousands of replacement instances.
Prints the message to the console area then immediately exits all commands, macros functions and scripts.
> %x=message File &'n& is of the wrong type.;To assist with diagnostics, the %X command can be traced as a {Ctrl+c} interrupt, set Trace_Interrupt (see %S=trace) to trap these.
%X=Insert [ -REVerse ] <stringExpr>;
%x=insert inserts the specified substring at the current-character position. The string may be specified as either:
%X=Substitute [ -REVerse] <stringExpr>;
Substitutes the currently-selected substring for specified substring. The string may be specified as either:
%X=Verify [ -REVerse][ -Back] <stringExpr>;
Verifies the current text matches the specified substring. The string may be specified as either:
%X=Zoom <bufferPath>;
Changes context to the current position in the specified buffer.
If the specified buffer does not exist but it's parant does then the buffer is created.
%x=macro <bufferPath>;
This runs the jot sequence in the specified buffer - i.e. a macro. It is an extended-syntax version of the ' command. The buffer may be either a primary buffer (then the bufferPath becomes a single character buffer key) or a secondary buffer requiring a full buffer path.
See also ' - the simple command to execute a primary-buffer macro command.
%X=PUshbuf;
Pushes a reference to the current buffer onto the stack.
This is intended to be used as a replacement for the OB command in scripts and functions likely to encounter secondary buffers. These buffers cannot be reliably refernced by a buffer key. Whereas OB places the buffers single-character key on the stack, %x=pushbuf pushes the address of the current buffer. To return to the buffer use the %x=popbuf command.
Note %x=pushbuf and %x=popbuf work equally well with either primary or secondary buffers.
See also %x=popbuf, OB and OZ commands.
%x=POpbuf;
Restores a buffer, previously saved by the %x=pushbuf command.
This is intended for use by scripts and functions that may encounter secondary buffer and have previously been saved with the %x=pushbuf command. %x=popbuf is functionally identical to the command Z~ but does some additional checking.
Note %x=pushbuf and %x=popbuf work equally well with either primary or secondary buffers.
See also %x=pushbuf, OB, OZ and Z commands.
%M[<bufferKey>]=<message> - prints Message in console area.
Prints the message in the console area and continues. If the optional bufferKey is given then the message is also appended to the specified buffer.
The message may contain an indirect reference to any buffer or the stack - see basic commands e.g:
ob %q~=date; t2/, /b %m=This is the time '~; osozok
%S=<attribute> [<value>] - set the value of a System attribute.
This group of commands control various system attributes affecting behaviour in any buffer.
Briefly, these are the valid attribute keys:
%S=case [0|1|+1] - set case sensitivity attribute.
This sets case sensitivity for the F and V commands - 1 makes them case sensitive, 0 makes them case-insensitive (e.g. f/Fred/ will match to fred, FRED or Fred equally well). If no valid value is given, it defaults to 0 (i.e. insensitive to case). The value +1 reverses the current setting.
%s=system [0|1];
Controls the way jot remembers default strings for find, qualify, substitute and insert primitives (see F, Q, S and I). When one of these is invoked with a specified string, that string becomes the default for any number of subsequent operations. F and Q have separate defaults, S and I share one default string.
These commands, however, are widely used by functions defined in the startup sequence so, to preserve the users defaults, any function that uses any of these primitives should begin with "%S=system 1;" to prevent the users defaults being overwritten and they should end with "%S=system 0;"
%s=commandmode [-Set|-Unset|-Toggle][<x>|<symbArgs>] - changes command-mode attribute.
This command is used to enter the jot insert mode and various other related command-mode options see command-mode vs. insert mode. It works by setting/resetting/modifying bits in the command-mode vector. Currently, this vector has five bits, defined below, which may be adjusted either symbolically (e.g. with symbols like -Insert and Escapeall - or numerically, with a hexadecimal value.
The optional -set or plus sign ( + ) modifier indicates that the specified bits of the existing command-mode be set, the optional -unset or minus sign ( - ) qualifiers indicates that the specified bits be unset. The -toggle or '#' modifier toggles the selected bits. If none of these are given the specified value fully specifies the new command-mode vector.
Bits are assigned as follows (Hexadecimal):
Examples of various useful combinations:
Note that command mode is set to 0 for normal command-driven editor operation. See also InsertMode and TempInsertMode
specified command count.
> %s=cc 123456789; - Functionally identical abbreviation.This command is useful for debugging. It is intended to return to the point of failure following a catastrophic failure inside a complicated script or function call.
It works by taking the number of commands that should be allowed to execute normally before a trace event is triggered - see the jot debugger. When a script, macro or function fails, there are ways of finding out how many primitive commands had been executed normally before the failure - this is used to calculate the command-count limit.
This raises the question "how am I supposed to know the command count when something interesting is about to happen?" Well "something interesting" is generally an unexplained early exit from deep down in a complicated set of code blocks and functions. Assuming the error is repeatable we can extract the command-counter value at the point of failure.
$ jot ... -in="%s=verbose 13; ... "
When it fails we see a message like this:
"{-init sequence failed. (1995529) ... """
The number in brackets is the command counter at the point of failure. We can re-spin the thing but set the command counter to trigger a trace point just before the failure:
$ jot ... -in="%s=commandcounter 1995520; ... "
So it should enter the trace loop about 9 steps before it fails.
In normal execution of functions, a counter is incremented as each primitive command is processed. This counter is normally set to 0 every time a new command line is read from the console. When the initial setting is defined with %s=CommandCounter it is instead set to run for the specified number of commands and then execution proceeds in whatever trace mode you have selected. The trace mask (see %S=tracedefault) determines the trace trigger and action.
Note that the counting only applies to the command sequence initiated by the *next* command line. For subsequent command lines, the counter is reset to zero.
In recovery mode (see about Journal Files), the behaviour is modified to exit from the debugger, when the original session used the debugger - see the jot debugger.
%s=trace [-Set|-Unset|-Toggle]{[<XXXX>] | <qual1>[ <qual2>[ ... ]]]
The optional -set modifier modifies the existing state of the trace vector by setting the specified states, similarly the optional -unset modifier unsets selected states. The optional -toggle modifier reverses the current value of all specified bits.
The screen window is only redrawn when the Trace_Break bit is set.
%S=trace sets a mask which controls the user-script debugging facility for the editor - see also %S=tracedefault and the T command.
The trace action may optionally be delayed by setting an internal counter - see %S=commandcounter.
The trace mode bitmask has the following control bits which can be ORed together.
A hexadecimal value string must begin with a digit - hence to set the trace vector to F801, use 0F801 in %s=trace and %s=tracedefault, alternatively use the symbolic syntax. e.g:
> %s=trace -break -backtrace -print -stack -allcommands;One group of bits (Trace_AllCommands, Trace_CommandLines, Trace_SubSequence, Trace_Failures, and Trace_Interrupt) define the trace points. The other group of bits (Trace_Backtrace, Trace_Stack, Trace_Print, Trace_Source, Trace_backtrace and Trace_Break) determine the action to be taken at a trace point. The other one - Trace_Recovery is used in recovery scripts only - see below and about journal files.
Trace_AllCommands, Trace_CommandLines and Trace_SubSequence perform the selected trace-point actions at every command or at the start of a new command line respectively. Trace_Failures performs the trace-point actions after a failing command.
Trace_Interrupt changes normal {Ctrl+c} behaviour - {Ctrl+c} normally drops everything and returns to the normal jot prompt. With Trace_Interrupt set it enters the interactive jot debugger - note that, by default, Trace_Int is not set up by the T command, you have to set Trace_Interrupt in your %s=tracedefault setting and your %s=trace settings - see the jot debugger and Trapping on {Ctrl+c}.
The Trace_Stack bit directs a stack dump to the console, this will not be of much help unless the console area of the screen is reasonably large or there is not much on the stack.
The Trace_Print bit prints the current line of the current buffer just before execution of the command.
The Trace_Break bit triggers a break at the trace point, it prompts for a command with 'Debug Command>' any valid JOT command string may be entered. If a hexadecimal value is entered with a leading zero, then this sets a new value for the trace mode - in particular 0 will exit trace mode. Just hitting the return key advances to the next break point.
The Trace_Recovery bit causes trace points to behave normally in recovery mode. In recovery mode, the default behaviour is to read instructions from the recovery file rather than the console. Setting this bit allow normal interactive debugging of the recovery script - when unset the debugger picks up copies of debugger commands from the original session.
In order to enter the debugger while processing a recovery file, it is necessary to edit the recovery file inserting a suitable %s=trace or %s=tracedefault command in the script. A typical useful setting might be 0F901 - see also recovery notes.
Setting the Trace_Source bit causes the source line to be displayed in the console area. For most video terminals the current command is highlighted but in -tty mode, the current command is indicated by enclosing it in square brackets ( [ ] ).
Setting the Trace_Backtrace bit causes a backtrace to be issued at each trace point - not particularly useful when combined with Trace_AllCommands and Trace_CommandLines but can be most useful when combined with Trace_Failures. Even so, it is not a good idea to run the editor with Trace_Failures turned on - it's not unusual for simple keyboard-driven functions to generate several failures - all appropriately handled but you still end up with gazillions of uninteresting messages. See query backtrace for details of jot backtrace reports.
Settin -source causes the source code to be displayed as it steps through. Typically the source will appear in the console area except when the system finds you have a window dedicated to the code repository, then this is used to display progress in the source code. There are, however, occasions when tracing progress in the source code window is not at all helpful (it changes the focus in the source) - the set -console which forces source-code tracing to the console.
If a macro buffer is redefined and reused part-way through execution, the compiled code will execute normally but the original source is no longer available to the debugger for display. When this happens, the situation is detected and instead of echoing the original source, it displays a disassembly of the compiled code. For example:
$ jot ${JOT_RESOURCES}/t.t -in="%w=clear; %w=new -height=9 -delim; %s=trace 4001; %da=zai/%ga/bi/mm-/bi/:/bi/ \\\'a/b2; 'a"
In this -init sequence the buffer ( A ) is initially defined as a macro that redefines the same macro buffer with backtrace tracing turned on. As you can see, the disassembly listings are quite a bit less easy to follow.
If no trace action is specified then, appropriately, it does nothing at each trace point.
The T command simply sets the trace value to the current default value, initially set to B001 (Trace_Stack | Trace_Print | Trace_Break | Trace_AllCommands) but can be redefined using the '%s=tracedefault' command. Another useful setting is B002 - this displays the same at each stop but only stops at the start of each new command line.
See also %s=tracedefault and about jot debugging.
The usage syntax is similar to %s=commandmode.
%S=tracedefault [+-][<hexValue>]
This defines the value to be assigned to the trace vector by the T command. By default this is:
Trace_Stack | Trace_Print | Trace_Break | Trace_AllCommands
The optional + qualifier sets the specified bits, the optional - qualifier unsets the specified bits in the mask.
In contrast to %s=trace, which sets the trace mask with immediate effect, %s=tracedefault specifies a trace mask to be applied at the next break point (breakpoints are set by the T, by the %s=commandcounter commands and bu Ctrl+C interrupts).
See also %s=trace and about jot debugging.
%s=traceskip [<RelativeLevel>];
Suppresses all tracing functions until call level (of block, macro, function or script) returns to the specified level, relative to current call level.
Each time a new block, macro, function or script is entered, the call level is incremented correspondingly, the call level is also decremented on exit from these programming structures.
To skip past one of these structures and resume tracing as it exits, specify a RelativeLevel of zero (the default). To skip tracing until the current block/macro exits specify a RelativeLevel of 1, etc. It is also possible to set negative RelativeLevels - in this case tracing resumes inside the next structure.
The function DebuggerQuit is implemented using %s=traceskip.
%s=setenv <envName> <envValue>
This sets an environmental variable in your session. It does not, of course, change the environment in your shell but only for your editor session and any child processes it might spawn.
%S=verbose [-set|-Unset|-Toggle]{<x>|<symbQual1>[ <symbQual2>[ ...]]]
The default vector is set to 3, just the -nonSilent and the -prompt bits are set. Briefly, the bits are assigned as follows:
Sets the verbosity bit mask as specified in hex or symbolic qualifiers. The optional -set or '+' modifier causes the selected bits in the existing vector to be set, similarly the -unset or '-' causes specified bits to be unset, otherwise the args fully specify the new value.
The verbosity bit mask currently has the following recognized bits:
Note that the CLI qualifier -quiet works by setting the verbosity mask but before any of the normal startup messages ensuring quiet operation right from the start.
Setting -CommandCounter will also cause user-defined messages (see %M) to be augmented with the command counter state. The command counter can be used to set a break point in some later run - see %s=commandcounter and the jot debugger).
Some examples:
> %s=ve 3; - (default state) for normal prompting and error reporting. > %s=verbose -nonsilent -prompt; - Same but symbolically > %s=ve -no -p; - Same but with abbreviated symbols > %s=verb -set -CommandCounter; - Preserves preexisting setting but with command-counter values. > %s=verb -unset -CommandCounter; - Removes command-counter from preexisting setting.%s=console <0>|<noOfLines>;
This sets an upper limit on the expansion of the console messages. By default messages are restricted to any spare terminal lines at the bottom of the display (see About the jot console and display windows), setting this limit allows messages to encroach upwards into the window area of the terminal.
If set to 0 (the default state), then the console area is fixed at the number of lines left below the windows. The startup script sets the windows to leave a 2-line console area.
If the console expansion area is set to more than the number of lines below the windows, then the console area will expand upwards to a total size limit specified in the %s=console command. The Additional console lines are erased on the next editor action (a new command string, an escape sequence or just by hitting {return}.
%S=guardband[ <n>]
Sets an n-line guardband. A band of n lines is maintained between the current line of text and the top or bottom of the display. The value may be 0 - this is also the default.
In the event of the total guardband exceeding the window size, the current line is held at the centre of the window.
With a 3-line guardband, for example, it always displays the 3 lines above and below the current record.
%s=tab [<chr>]
This defines the character to be used as a cell separator for tabular text.It is also used as the default search-string separator in the %X command. It defaults to VT (vertical Tab). This can be set to, pretty-much, any normal ASCII character but not unicode characters.
%s=commandstring <CommandString>
This inserts the specified command string back into the console command buffer. This makes it possible to modify the console input using ordinary editor commands and then execute the modified command sequence.
This is used for command-line editing (see about command editing) and systematic modification of keyboard input - take a look at uc_basic.jot this uses %s=commandstring to substitute unicode escape sequences for UTF-8 byte sequences.
%s=mousemask[ <HexValue>]
This enables the detection and handling of selected mouse events - e.g. left-button clicks etc. When enabled by %s=MouseMask, mouse events can be picked up and handled in the same way as as escape sequences. Also, mouse-click coordinates can be picked up by the query getmouse command.
By default, all mouse actions are disabled (the mouse mask is set to 0), if %s=mousemask is given with no value then all mouse events are picked up by the editor (and normal X mouse actions are disabled). If a hex value is given then that value is passed to the curses mousemask() function. For full details refer to curses.h and the mousemask (3NCURSES) man page.
The problem with enabling all mouse events is that it replaces the really useful X-windows selection actions - so only set the mouse mask when you really need to define mouse functions. The standard setup defines a few mouse-action functions. This problem is not so acute for windows users since windows offers virtually no worthwhile mouse functions for console terminals.
In any case, normal service can be restored by resetting the mousemask to 0:
> %s=mousemask 0;See also About mouse events, query getmouse and %b=addtag
%s=recoverymode <value>
Used when recovering a session from journal files. In order to prevent corruption of existing files %O operations are disabled and %I and %E operations read from the journal area - see about journal files
In recovery mode I/O operations and some system interaction are restricted, writes are disabled and reads are redirected to an appropriate file in the journal directory. Several system queries (e.g. %q=dir;, %q=date;) read from logfiles or the history file in order to provide the same results in the original session.
The debugger behaviour is also modified - any debugging activity in the original session is reproduced in full using interactive responses saved in the history file. If it is required to debug the recovery process then start the debugger with the -recovery bit set (see %s=trace). If the debugger is on as it enters recovery mode then this is set automatically.
%s=copy
Copies text into the system paste buffer. The start point is set by the 'N' (Note) command, the end point is set by the current character position at the time when the %s=copy command is invoked. As with the 'A' (Abstract) command, the start and end point must be in the same buffer and, if the end point is before the start point the start and end points are automatically reversed.
In windows, the system buffer used is the 'clipboard', in linux %s=copy and %s=paste both use the X paste buffer N.B. not the selections buffer.
In order to minimize the number of statically-linked libraries in the linux version, this command is not available in the linux executables supplied in the download - see Unix and linux setup.
%s=paste
Copies the contents of the system paste buffer into the current buffer at the current-character position.
In order to minimize the number of statically-linked libraries in the linux version, this command is not available in the linux executables supplied in the download - see Unix and linux setup.
%s=prompt[ <promptString>]; - set prompt string.
Sets the prompt for the G command.
If the prompt string is not given, then the G-command prompt reverts to it's default "> ".
%s=ON_Key[ -after][ <JotCommandSequence>]
Defines a Jot command sequence to be performed before any normal interactive command. The -after qualifier says to run the command after the users command. You may define commands to be run both before and after the user command sequence - but you will need two %s=On_Key commands to define them.
The WindowWithLineNumbers function provides a good example of the use of this command.
%s=ON_Int <jotCommandSequence>;
This defines a command sequence to be obeyed in response to a {Ctrl+C} interrupt before it commences to unwind the call stack. It could, for example, be set up to backtrace. This could be useful in the diagnosis of some errors.
> %s=on_int %q=backtrace;%s=setmouse
Sets the mouse-click position to the current character in the current buffer these value will then be picked up by the next %q=getmouse command - see query getmouse, Query tags and query screen.
This is useful for emulating mouse clicks for applications designed as mouse/touch-pad interfaces in non-mouse environments (see qr.jot) and for testing scripts using the %q=getmouse command for the window query.
%s=sleep <n>;
Suspends activity for a period of n milliseconds.
%b=<attributeName>[ <value>] - set some attribute of the current buffer.
%b=UNRestricted - sets the buffer write-access attribute.
This returns the readonly and writeifchanged status of the buffer (see %b=readonly and %b=writeifchanged) to their default settings.
%b=REadonly[ 0|1] - sets the buffer write-access attribute.
The default state for buffers is that they may be modified. If this command is applied with no value specified or is specified as 1 then the current buffer is set to a readonly state. It can be viewed but not altered, sections of text may be abstracted provided the & qualifier is given (see the A command).
Text may be copied from readonly buffers using the abstract (A) by using the the ( & ) modifier or the %x=here command..
See also the %B=unrestricted command.
%b=WRiteifchanged[ 0|1] - sets the buffer write-access attribute.
The default state for buffers is: any changes are lost if the session is terminated without explicitly saving (see the %O command). In other words you lose some of your work. If this command is applied with no value or the value is specified as 1 and the buffer has been modified, the session cannot be terminated normally (by %C or %A) until the buffer has been be saved. If you set writeifchanged and then decide to discard your changes, you can unset this flag with %b=unrestricted.
In this state the buffer may be modified but if there is an attempt to overwrite or to exit the editor without first saving. Then a warning is issued and the editor session remains live. It is , of course, possible to reset this lock and exit normally to discard changes.
The motivation for this one is that jot encourages users to edit multiple files in one session - it's just a bit too easy to forget and exit without saving something important.
If, after you've checked the locked buffers, you still want to exit the session anyway, the exit.jot script might help.
See also the %B=unrestricted command.
%b=LEftoffset <n> - sets the buffers left-offset attribute.
Sets the text column to appear in the leftmost column of the window when displaying this buffer.
By default, the left offset is 0. This may be increased to display records longer than the width of the current window. See about long lines. If the given value is negative, this is silently ignored and the leftoffset is set to 0.
See also about long lines and query inview - this verifies that the current character is visible with the current leftoffset setting.
%b=TABStops[ -cellwidths][ <n1>[ <n2>[ <n3>[ ...]]]]
This command specifies the tab spacing to be adopted and that the tabs are to be displayed as simple tabstops - see about tabular text.
By default, tabs and other control characters are rendered as a tilde '~' on the screen - see about tabular text. If tabStops have been defined for a buffer containing tabular text then each tab is replaced by one or more blanks in the display. When correctly set up, the tabular text is neatly aligned with that of other records in the buffer.
Each entry in the %b=tabStops command is a number indicating the absolute column number to be assigned to the following text - hence tabStops should always be an ascending sequence of column numbers. If a tab is encountered that is already beyond (i.e. to the right of) it's assigned column then the tab character is simply rendered as a single blank.
Use %b=tabcells for buffers containing simple tabular text - indented source code, simple tables, formatted letter headings etc. For tables with wildly-varying cell lengths use %b=tabcells which will truncate overlong cells to maintain the columns.
The %b=tabstops command will delete any preexisting tabstops or tabcells settings, if no tabstops are given, then the buffer reverts to displaying tabs as tildes ( ~ ).
If the first tabstop is any negative number, then this is taken as a request for automatically-assigned tabstops - any other values in the command line are ignored. With automatically assigned tabstops the window manager analyses the position of all tab characters currently in view and assigns the smallest tabstops compatible with displaying tabular data in neat columns. Currently, the maximum number of of automatically-assigned tabstops is limited to 100.
The tabstops are displayed in the query buffer report.
%b=TABCells[ -cellwidths][ <n1>[ <n2>[ <n3>[ ...]]]]
This command specifies the tab spacing to be adopted and that the tabs are to be displayed as data cells (as per spreadsheets) - see about tabular text.
This command specifies the tab spacing to be adopted and that the tabs are Each tab-delimited item of text is said to be a cell. If the manually-defined tabcell is insufficient to display all of a cell, then the cell text is truncated and an exclamation point ( ! ) is added to the righthand end of the truncated text.
The %b=tabcells command will delete any preexisting tabstops or tabcells settings, if no tabcells are given, then the buffer reverts to displaying tabs as tildes ( ~ ).
In the event of there being a record with more then the number of predefined tabcells, then additional tabcells inherit the tab spacing of the last-specified tabcell entry.
If the first tabcell is any negative number, then this is taken as a request for automatically-assigned tabcells - any other values in the command line are ignored. With automatically assigned tabcells the window manager analyses the position of all tab characters currently in view and assigns the smallest tabcells compatible with displaying tabular data in neat columns. Currently, the maximum number of of automatically-assigned tabcells is limited to 100.
The tabcells are displayed in the query buffer report.
%b=HEader[ <headerText>] - defines or removes a static header line.
If the headerText string is given, this is displayed in reverse video at the top of any window displaying the current buffer. The header is static in the sense that it is fixed to the top line of the window and text scrolls past it. When you define a buffer string it occupies one of the lines requested in the %W command, leaving you with one less line for viewing buffer images. If no headerText string is given then any previously defined header line is removed. By default, buffers have no header line.
If the buffer has TabStops set (see %b=tabstops) then any tabs in the header text will be treated in the same way as those in the main body of the buffer. The upshot of this is that the text can contain column headings for buffers containing tabular entries (e.g. images of spreadsheets etc.).
%b=FOoter some text;
By default, the reverse-video separator at the end of a window contains the current buffer's pathname (if defined) and the buffer key. This command replaces the pathname with some text of your own choosing.
As with long pathnames, the text may be truncated to fit.
%b=UNicode {0|1}
This controls unicode support for the current buffer.
Any value other than 0 restores the default mode of operation - unicode characters are rendered normally.
The value 0 turns off unicode support, in this state each byte of UTF-8 is represented on the screen by a tilde ( ~ ).
Disabling unicode support affects the rendering of characters on the screen any non-ASCII or ASCII control characters bytes are displayed as a tilde and also affects several commands:
The editor should always navigate and display the UTF-8 correctly but UTF-8 is a variable-length encoding scheme. Now jot maintains a pointer to the first byte of the current character, if that pointer should end up pointing to some other byte the character will not be displayed correctly. This situation should not occur normally but it can happen when switching back to unicode support with %b=unicode.
%b=PAthname <pathName> - (re)defines pathname.
This sets the default pathname to be used when this buffer is later written to the filing system.
%b=SAmeflag1 - sets the user change-control flag.
Sets the user flag SameFlag1 - this remains true until there is some change to the buffer text. This flag can be tested if ever a macro needs to detect changes that have occurred since the flag was set - see also Query sameflag1.
%b=TAGtype -Colour=<foregroundColourNo>:<backgroundColourNo> <tagName>
or, according to upbringing:
%b=TAGtype -Color=<foregroundColourNo>:<backgroundColourNo> <tagName>
Currently the only tag types allowed are colour tags but it is envisaged that this might be extended in the future.
This either defines a new colour pair or redefines one. Colour pairs are defined in terms of the foreground and background colour and are referenced by the pair number.
The tag name can then be used to tag text with colour using the %b=addtag command - see also about tagged text.
Colours may be identified by number in the range 0-to-7 - or by name, in linux these are:
in windows - the I_ prefix denotes a more intense colour:
e.g. To define a colour tag "fred" as yellow forground on a blue background in linux:
> %s=tagtype -colourpair=3:4 fred;or, equivalently:
> %s=tagtype -colourpair=yellow:blue fred;In windows
%s=tagtype -colourpair=6:1 fred;
or, for a brighter yellow:
%s=tagtype -colourpair=14:1 fred;
There are three valid forms:
%b=ADdtag -text=<textString>; %b=ADdtag -Code=<bufferPath>; %b=ADdtag <tagName>;
The tag type is always colour (more accurately a colour pair), the TagName must match a previously defined tag type (see %b=tagtype) or the command fails.
Applies the named tag to the currently-selected substring in text. The named tag type and it's colour pairs must first be defined with the %b=tagtype command - see also about tagged text.
If, at "addtag" time, there is a selected substring, two tags are applied - one at the start of the currently-selected substring and one at it's end. If there is no selected substring then no tag is added.
The current focus must be some point in a functions source code - typically in the code repository buffer ( * ) or a macro. The specified command string will be compiled and inserted into the code for the function or macro at the appropriate point. The code tag is also added to the source code and will be visible to the compiler when the -tag qualifier is given - see %h=recompile and about tagged text for details. This feature is intended to support a debugging environment for jot code. In this usage the inserted commands would be breakpoints etc.
The text string, which may be of any length, is added to the tag descriptor. This string can be used for any purpose but is primarily intended for use as a hashtable key. The string is visible in the query tags report.
Tags persist until removed with the removed with the %b=remove_tag command or the text is deleted.
See also About mouse events, %b=remove_tag, %s=mousemask and query getmouse
There are several valid forms:
%b=REmove_tag -TArget=<keyName>;
The current character must match the tag point, this form removes the destination tag for %H=JUMP and %H=CODE operations.
%b=REmove_tag -Colour=<colourTagName>;
The currently-selected substring must match the extent of the tag to be removed, this form removes the selected instance of the colour type.
%b=REmove_tag -TExt=<textString>;
The currently-selected substring must match the extent of the tag to be removed, this removes the selected text tag matching the text string.
%b=REmove_tag -CODe=<bufferPath>;
The bufferPath arg indicates the buffer holding the code to be removed, the current record pointer for that buffer must point to the correct command string for the selected tag.
%b=REmove_tag -all[ -TArget][ -Colour][ -TExt][ -CODe];
The -all qualifier must be before the tag-type qualifier, this removes all tags of the specified type. If no type is specified then it removes all tags from the buffer. When -all is given, the tag-identification parameter must not be given (i.e. the keyName, colourTagName, testString or bufferPath).
The current character must be at the start-point of the tag to be deleted, except when -all is given.
This command uses the details given and the current-character position to uniquely identify one tag and then removes it from the internal record data structure. In the event of there being two or more identical tags matching the description, it randomly selects one of the matching tags and deletes only that one.
The tags were originally created by the %b=addtag, %H=newjump and %H=addjump commands - see about tagged text.
Where precise details of the tag is not known, use the query tags to extract the necessary information from the internal data set.
In the event of there being no tag exactly matching the details given then the command fails without affecting any tags.
%b[<destBuf>]=SOrt [<sliceColumn1>][ <sliceColumn2>[ <sliceColumn3> ...]]]
Performs an alphabetical sort of all records in the buffer, by default the records are sorted by the strings starting at the first character (column 0). For tabular text, other columns (slices) may be specified, to sort tab-separated tabular text use %B=tabsort
Each parameter is taken as a slice definition (i.e. a vertical slice down the tabulated text), the following forms are supported:
The sort function (a version of quicksort) compares pairs of records, initially from slice slice1. If they are found to be identical, it tries a comparison from slice slice2, then slice3 etc... If no slices are specified it performs just one comparison on each complete record.
Note that left to the user to ensure that each record has at least the number of columns specified - otherwise results are unpredictable.
The sort function modifies the current buffer and writes a sort summary into the nominated destination buffer.
See also sort.jot, this script offers a few options for tweaking the sort order.
%b=TAbsort <tab1>[ <tab2> [<tab3> ...]]] - sort buffer holding tabular text.
Each tab entry is an integer in the range 0 to n-1 where n is the number of columns in the table (counting from 0).
Similar to the %b=sort command, tabsort sorts records by values of unaligned tab-separated fields, the delimiter character defaults to an ascii VT ( 0xB ) character but can be redefined to any valid ASCII character with the %s=tab command.
Shorter fields always rank higher in a strcmp string comparison so some additional whitespace padding may be required.
%b=encoding <UTF-encodeing> - set output UTF encoding scheme for this buffer.
This sets the UTF encoding scheme to be used if ever the buffer is written out to a file. By default the encoding matches that of the original file, if it's a new file then the default is UTF-8/ASCII.
When reading a file to a jot buffer, it is not necessary to define the encoding scheme - jot recognizes the BOM tag (see Unicode - the gruesome details). Intenally, jot uses UTF-8 so other formats are converted as they are read in the reverse conversion is normally applied when they are written back.
Supported encoding schemes:
%b=COdepage <codepage>
This modifier is only available in the windows version. By default jot uses the 65001 (UTF-8).
This sets the codepage which is only relevant to unicode - see about unicode, Practicalities of unicode etc. and jot
%Q[<bufferKey>]=<query>[ -to=<destBuf>][ -append]
The various flavours of the query command offers a few selected peepholes into selected internal editor states and the system environment.
Some of these send a wordy report to a specified target buffer, the target buffer is defined either by the bufferKey (a single character identifying a primary buffer) or a buffer-path expression.
All report-generating queries may be give the optional qualifiers -to=<destBuf> and -append. The -to qualifier specifies a desitination buffer to receive the report, if a bufferKey is also specified, the bufferKey is silently ignored. The -append qualifier appends the report to the end of any preexisting content in the specified buffer. f not specified then any original content of the buffer is first cleared.
Some queries only return a success/failure status, others place values on the stack. Some will (e.g. backtrace and version) will generate a report in a specified buffer or, if no destination buffer is specified, send the report to the console area. Some (e.g. dir and file, will generate a report if a destination buffer is given or a status value if the file or directory does not exist.
Valid queries are:
%q<key>=[ -Append ]SYstem
Reports current state of system settings to nominated buffer followed by a list of primary buffers i.e. not stack-based or data-object buffers.
Trace vector = <hex value> - of trace vector - (see `%S=trace`) Case sensitivity = <hex value> - case sensitivity vector - (see `%S=case`) Command mode = <hex value> - the command-mode vector (see `%S=commandMode`) Table-entry separator = <hex value> - the character used to separate entries
in tabular text (see %S=tab).
Hold screen on exit = {On|Off} - Set by `-hold` CLI qualifier. Buffers: buffer <key1> - First in list of defined buffers. buffer <key2> ... Data-object buffers: data obj <path> ...
The list of buffers contains all primary buffers that have been created thus-far in the session, including some with lower-case alpha keys (i, t and p) - these are set up and used internally and are not accessible to the user.
%q=Linux
Used to test the underlying OS, this one fails for anything other than linux.
%q=WINDOWS
A simple test the underlying OS, this one fails for anything other than some flavour of NT-windows.
Note - this has nothing to do with the query screen command, which generates a window-assignments report.
%q<key>=[ -Append ]WD
N.B: Not available in windows.
Returns the users current working directory or fails and returns <undefined> if, for whatever reason, the PWD cannot be determined. The windows version *always* fails and returns <undefined>.
%q<key>=[ -Append ][ -Protected ]SCreen - reports screens window assignments.
Lists screen size, details of currently allocated windows and number of unallocated lines on the screen.
By default protected windows are not listed (see %W for details of protected windows) and the height they occupy is silently subtracted from the screen-height section of the report but their presence may be inferred from the window numbers and the line numbers both starting at more than 0. The -protect qualifier causes protected windows to appear in the list and the screen height to report the full height.
Then after the window-configuration section of the report follows a screen dump - the current contents of the screen is copied to the end of the report. Note that the screen dump does not show any highlights, reverse video, colour tags or the cursor position.
%q=TIme - pushes time, in milliseconds, since beginning of unix epoch onto stack.
This uses the system clock to calculate how many seconds have elapsed since the begining of unix time (zero o'clock on the first of January 1970). See also query cputime.
%q=CPutime - pushes the time elapsed since last query cputime.
N.B: Not available in the windows version.
This uses the system clock to measure the time interval between calls, it pushes a real number (cpu seconds) onto the stack. The value returned by the first call should be discarded.
It calculates gives a floating-point value calculated from the system seconds and nanoseconds elapsed-time counters. Each time it's called it subtracts the previous values of these counters from their current values and converts the difference to a floating-point number, which is pushed onto the stack. It is envisaged that this may be useful for some future profiling tool. See also query time.
In the windows version it always returns the value 0.0
%q<key>=[ -Append ]DAte - reports date and time.
Returns the current date and time in the form dd/mm/yy, hh:mm:ss
%q<key>=[ -Append ]Env <envName> - reports value of nominated env variable.
Returns the current value of the specified variable in the users env.
%q<key>=[ -Append ]Pid - Query the ID of the ediors process.
This reports just the process-ID number of the editor process.
%q<key>=[ -Append ]STack
Returns the current state of the stack in decimal hex and character format - see also O?.
%q=TABStops
This is a quick test to identify buffers which have been set up for simple tabular text. The command succeeds if tabstops are set in the current buffer, otherwise it fails - see %b=tabstops.
%q=TABCells
This is a quick test to identify buffers which have been set up for tabular text. The command succeeds if tabcells are set in the current buffer, otherwise it fails - see %b=tabcells.
%q[<key>]=[ -Append ]BAcktrace
Lists macros, functions and scripts in the active call stack - only useful for debugging but an essential troubleshooting feature. If no destination buffer key is given, the report is sent to the console area.
Each line of the backtrace report shows one level in the call stack, it shows linenumbers relative to the beginning of macros, functions and scripts and also, for macros and functions, linenumbers. relative to the begining of the defining script as these are almost invariably defined by scripts.
The backtrace system does not keep the names of the scripts used to define macros and functions but it can calculate the original line number of the commands in each backtrace frame and these are given in the backtrace report. Hence you might see entries like this:
Line 94 of function <<name>> (line 1234 of source file): <sourceCode>
It's giving the exact line number, even though it no longer has the name of the script. So it's up to the intrepid user to work out which scripts they are referring to - in practice this is easy since the culprit will generally turn out to be the script under development.
When called from a normal interactive command line it, unsurprisingly, doesn't report very much. When called from a debugger breakpoint prompt, it shows all the call frames that led to the breakpoint. It also dutifully reports the debugger as a frame in the call stack.
In addition to the various scripts, macros and function calls you may notice a few lower-case alpha macros you don't recognize:
See also bt.jot
%q<key>=[ -Append ]Buffer[ <path>]
Returns the state of the a buffer, if a path is given then it reports the state of the nominated buffer, otherwise it reports on the current buffer..
buffer key = . The key for the buffer. Parent path = ".=a" This line only appears for secondary buffers - see `about hashtables` pathName = t.t The pathname of the file read into the buffer. currentDatestamp = 2011/10/04, 16:27:16 The file's datestamp at the time of the query. SameSinceIO = TRUE This flag is set true when the file was originally read and reset by a change to any text in the buffer. SameSinceIndexed = FALSE This flag is set true by adding some hashtable entries and reset by a change to any text in the buffer. SameSinceCompiled = FALSE This flag is set TRUE when a new hash-table entry is added. SameFlag1 = FALSE This flag is set by the `%b=sameflag1` command and reset by a change to any text in the buffer. NoUnicode = FALSE Unicode support is enabled (controlled by `%b=unicode` command) MacroRun = FALSE Indicates that the buffer has been used as a macro. NoUnicode = FALSE Indicates that the buffer is UTF-8 ready - see `%b=unicode`. lineNumber = 1 The normal line number of the record. CurrentByte = 0 The current byte position, in this case it is the leftmost character of the record. SubstringLength = 0 The length, in bytes, of the currently-selected substring. wholeRecords = TRUE Indicates that, if inserted into text it will not break lines. predecessor = When called as a macro, this indicates the parent macro. editLock = Unrestricted See `%b=WriteIfChanged` and `%b=ReadOnly`. LeftOffset = 0 See `%b=leftoffset` CurrentRec max length = 209 Indicates size (in bytes) allocated for the storage of this record. protected = 0 Indicates that the current record of the buffer is a hash-table target and has been protected. ProtectedRecords = 0 Indicates that the buffer contains at least one protected record. Header = "A"~"B"~"C" ... See `%b=header` Footer = "A"~"B"~"C" ... See `%b=footer` UCEncoding = Invalid text-encoding key - the unicode encoding scheme of the original file, it is also re-written in this form. FileType = text Currently the only valid entries are text or binary. No tag types If the buffer had tag types defined then these would be listed here (see `About Tagged text`). HashTableMode = 0 Valid modes are 0 (No hashtable), 1 (ProtectEntries), TabStops = 17 41 62 89 172 ... Indicates columns in tabular text - see `about tabular text`. htab = No hashtable Indicates that there is no hash table associated with this buffer. IoFd = 0 The file descriptor used by the -hold option of the `%I` command. ChildPid = 0 The process-id of a child launched by the -interactive option of the `%E` command Buffer ( . ) has finished reading Indicates that there are no pending I/O transactions (`%I` -interactive again).
If a hashtable is present, the report gives three additional values:
Note that, in the presence of unicode characters, the CurrentByte field may give a different result to that given by the OC command, which counts characters, not bytes.
%q=SAMESINCEIO
Use this command to test for changes to the buffer since it was last read or written back to the filing system.
Command exits with failure if the buffer has been changed in any way compared to the version on the filing system, exits with success if unchanged.
Text buffers which are not images of files are always created with samesinceio set false.
%q=SAMESINCECompiled;
This command is used to determine if the current buffer has been changed since the code it contains last compiled. It is therefore only relevant to macro-command buffers.
%q=SAMESINCEINdexed
Use this command to test for changes to the the buffer since making the last hash table entry.
Command exits with failure if the buffer has been changed in any way since it was indexed with the %H commands, exits with success if unchanged. Note that text buffers which have not been indexed are always created with samesinceindexed set false.
%q=SAMEFlag1
Use this command to test for changes to the buffer since the flag was set.
Command exits with failure if the buffer has been changed in any way since the SameFlag1 was set (see %b=sameflag1), exits with success if unchanged. Note that text buffers are initially created with samesinceindexed set false.
%q=Case
This simply sets the failure flag - it fails if case sensitivity is off.
%q=Inview
Verifies that current character is visible with the current setting of leftoffset - see %b=leftoffset and about long lines. This query works independently of the display management, the consequence of this is that it is not necessary to update the display (see %W=refresh) before launching the query.
This query always pushes three values onto the stack:
For a tabcells buffer (see about tabular text) the query fails when the current character is in a truncated cell - even if the current character falls somewhere between the screen margins.
This command fails if the current character is outside the visible area. i.e if the current character is off to the right of the screen when leftoffset has been set too low or left of the left margin when the leftoffset has been set to high.
The values placed on the stack are designed to be a useful starting point for calculation of a revised leftoffset - for an example look at the definition of WordLeft and WordRight in the standard startup script.
%q=commandmode
This does not affect any buffers or the stack - it just returns a status result - Success indicates that the editor is indeed in command mode, fail indicates that it is in insert mode.
%q[<key>]=Version
If the optional key character is not given, then the report is directed to the console area.
This delivers a brief informational message about the editor version build date and host system. If the buffer key is given this message goes to that buffer otherwise it goes to the console area of the screen. A typical report looks like this:
version jot for chrome v2.0, built 27/12/16 16:59:42 using crouton ncurses 6.0.20150808
The majority of the reply is defined by the compile-time string VERSION_STRING. This is typically defined with using the output of the uname command.
The final section is obtained by calling the curses function curses_version().
%q[<key>]=DIr [<fmt1> [<fmt2> [ <fmt3> ...]]] <path>
If the specified pathname does not exit or does not point to a directory, then the command fails. If no destination buffer is specified then the dir query will only verify the path.
If the destination buffer is specified (i.e. if the optional buffer key is given) then the dir query lists the contents of the nominated directory to the nominated buffer. Note that the order is just as returned by the filing system - you will need to use %b=sort to get them in order. This command will always check that the path exists and destination node really is a directory and will fail if this is not so. If no destination buffer is specified this query will only check that the given path exists and is a directory.
If any format specifiers are included then the relevant information is added to the file entries. The following format specifiers are currently supported:
In the report sent to the specified destination buffer, the optional data fields are separated from the file names by a tab (VT) character. To make this a bit easier on the eye run the autotab.jot script.
%q[<key>]=File[ -Nofollowlinks][<pathName>]
The file query will always check that the pathName exists and will fail if this is not the case. If no destination buffer is specified, this check is all it does.
It normally follows symbolic links but If the -nofollowlinks qualifier is given this behaviour is suppressed.
If no file name is specified then the pathName of the current buffer is used. If no pathname is specified and the destination buffer is the same as the current buffer then this command fails without completing the report.
When the destination buffer is specified, the file query lists various bits of system information about the specified file. Note that there is no stripping of additional whitespace following the delimiter blank after the file keyword.
The following report is written to the destination buffer:
file <pathName> Name = "<pathName>" inode = <inodeNumber> Mode = <modeInOctal> uid = <userID> gid = <groupID> size = <fileSizeInBytes> writable by this UID = <yes|no> directory = <1_IfDirectory_0_IfNot> Access time = <fileAccessTime> Modify time = <fileModifyTime> Creation time = <fileCreationTime>
All datestamps are in the following format: YYYY/MM/DD, HH:MM:SS
%q<bufferKey>=KEYS[ -To=<destBuf>][ -Append][ -Key=<name>][ -From=<sourceBuf>];
This dumps all the keys associated with the specified buffer to a report in the nominated destination buffer it fails if there is no hash table associated with the current buffer. If no destination buffer is specified then it simply returns the status result. In addition to listing each key in full, it also the first 30 characters of the text associated with the key for data types holding secondary buffers.
The optional -to qualifier specifies a buffer to receive the report.
By default, the destination buffer is cleared of any preexisting text, if The optional -append qualifier causes the report to be appended to whatever text is already in the destination buffer.
If the optional -key=<name> argument is given, this reports on the specified hash-table entry the report is sent to the specified buffer. If the key has not been set up in that hash table then the command fails. Use %h=testkey to test for the existance of a particular key.
By default it lists keys in the current buffer, if the optional -from=<bufferPath> qualifier is given, this specifies the buffer to be the subject of the report.
The report shows the key string and relevant data for hashtable objects:
%q<destinationBuffer>=[ -Append ][ -Here] TAgs[ <path>]
In the internal data structure, each record has any number of tags associated with it. These tags are used to maintain hashtables, optional text colours and user-specified metadata in the form of text strings. This query lists the tags (hash-table target points, colour tags and text tags) in current buffer the report goes to a nominated destination buffer.
By default this reports tags in the current buffer, if the optional path was given, it reports on the specified buffer.
The optional qualifier -here will return only those tags active at the current character. Currently, this is the only mechanism for extraction of user-specified metadata from the record. One useful application for this is storage of hash-table keys associated with the text - especially when combined with a mouse-event handler. The linkdocs.jot and bookings.jot scripts are examples of this.
%q=HEap
Reports raw data from the mallinfo routine (see the mallinfo man page).
%q<buf>=[ -Append ]History
Reports all entries in the history buffer in chronological order - the report is directed to the nominated buffer. The size of the history buffer is limited but can be changed with the -history cli qualifier. This report is used in the command-edit screen - see about command editing.
N.B. The history maintained for the history query is entirety independent of the history file in the journal area - see about journal files.
%q=getmouse[ -key];
This places details of the last-detected mouse-click onto the stack. Mouse activity must be enabled by the %s=MouseMask command.
On completion, the top of the stack holds the following:
To focus to the buffer referenced by address use the %x=popbuf command, if the -key qualifier was given use the OZ command.
If the last-clicked mouse event has not been enabled (see %s=MouseMask) then %q=getmouse places three zeros on the stack.
See also About mouse events, %s=mousemask, %s=setmouse and %b=addtag
%q<buf>=VERIfy
This command performs a few simple checks aimed at detection of errors in the internal record structures. The main test is to ensure that the string length of each record is never longer than the allocated string size. This situation should *never* occur, if it were to, the editor would crash before long as other internal data gets corrupted.
If the verbosity level is more than 1 (See %S=verbose) then the contents of the buffer are echoed to the console area.
The %H commands provide the main interface for hashtables - see about hashtables. In most cases these the syntax of these commands is
%h[<bufferKey>]=<commandName> ...
where the bufferKey is an optional single-character buffer identifier and, if omitted, the current buffer is the target of the command.
Note that any buffer may hold a hashtable and any hashtable may hold any number of sub-buffers. Root buffers are those with a single-character identifier key (A-Z, 0-9 and most of the ASCII punctuation characters. In contrast, secondary buffers are either on the stack or a child of some other buffer. A buffer at the top of the stack may be referenced with the buffer key ( ~ ).
In the context of hahstables, the term path usually refers to a hashtable path, where one or more hashtables are children of the hashtable in a primary buffer. In some cases this terminology comes into conflict with the more general understanding of path - a filing-system path. In particular in the discussion of %h=setfsect and to a lesser extent %H=setsect as these interface with the filing system.
For example, the primary buffer ( Q ) has a hashtable containing a sub-buffer below the key Fred, it's hashtable has a further sub-buffer below the key Jim - to reference an item named thingie in Jim the following path expression would be used:
> q:=Fred|Jim|thingieSee about hashtables for details.
Many of these commands also support a -buffer=<path> qualifier which permits the specification of non-root buffers i.e. buffers which are sub-buffers of some other buffers hashtable see below and about hashtables.
See also Query keys - this command reports the keys associated with a specified hashtable.
%H=create {-delete|-destroy|-protect|-adjust} <n>[ <path>];
%H=addjump <path> - Create a hashtable for jumping back to
current focus point. See %h=addjump
%H=newjump <path> - Create a new hashtable jump entry, fails if
path does not define a unique name. See %h=newjump
%H=jump <path>
%H=data <path> - creates a hashtable object which can hold a
stack frame - see %h=data.
%H=setdata [ -new] <path> - Sets specified data object to the
value at the top of the stack - see %h=setdata.
%H=getdata <path> - Copies the specified data object's value
to the stack - see %h=getdata.
%H=setsect <path> - creates a hashtable object for use in a
%i=<pathName> ... -section; command - see %h=setsect
%H=setfsect <path> - creates a hashtable object for use in a
%i= ... -fsection; command - see %h=setfsect
%H=delete <path> - Removes specified hash-table entry.
See %h=delete
%H=code <path> - Enter a function startpoint
See %h=code
%H=call <path>[ <Args>] - Search for the function and compile it.
See %h=call
%H=recompile <path> - Search for routine then run it.
See %h=recompile
%H=fix - resets line numbers for referencing hashtables.
See %h=fix
%H=destroy[ <path>]; - Destroys the hashtable, see `%h=destroy`
%H=testkey [<path>] - Verifies the hashtable entry exists.
See %h=testkey
%H=CReate [ -parent][-delete|-destroy|-protect|-adjust] <size>[ <path>]; - Create a new hashtable.
Create a hashtable in specified buffer, or the current buffer, if none specified. The size parameter specifies the size of the table. Take care to not underestimate the required size. The value can be specified on the command line or picked up from the top of the stack. If the specified buffer already has a hashtable then this command will replace the existing hashtable with a new one, copying the existing entries into the new table. If the specified size is nonzero but less than the current number of entries then the command will fail, leaving the hashtable unchanged. If the specified size is zero then any preexisting hashtable is destroyed and no new table is created.
If the buffer already has a hashtable and the new size is sufficient, then this is destroyed and it's mode and entries are copied to the new hashtable, if the new size is insufficient then the command fails. As the hashtable is copied over, any zombies are removed (zombies are entries that have been deleted with the %h=delete command). This behaviour is intended to allow purging and re-sizing while preserving existing entries.
The -parent modifier creates the parent object and buffer, the created buffer is initialized with the string "Created by %H=create".
A hashtable can be deleted with the %h=destroy command.
The optional path parameter defines the hashtable pathname (see about Hashtables), by default, the hashtable is create in the current buffer. When a valid path is set the hashtable is created in the specified buffer or sub-buffer, sub-sub-buffer ... etc. to any depth.
The hashtable contains pointers to various classes of object (see about hashtables):
There are several options regarding behaviour when the targeted strings are to be deleted (see about hashtables). Essentially these are:
%H=Newjump <pathname>; - adds a new jump-point hashtable key.
Adds a new named jump-destination at the current cursor position. The name must be unique in the deleted hashtable, if - if a name collision occurs, the command fails. The number of allowable jump-points is limited only by the hashtable size (see %H=create).
Jump-destination points are used for rapid navigation around any number of buffers the hashtable of a buffer may contain jump entries for any number of buffers.
The hash table entry will store the exact location of the current character in the current buffer. In the event of a collision (i.e. the key already exists in the hashtable) the original value is silently replaced by the new value. See about hashtables.
%H=Addjump <pathname>; - adds a jump-point hashtable key.
Adds a new jump entry (see %h=jump) to the hash table for the buffer specified in the path expression, current buffer, if none is specified.
Similar to newjump (above) except that, in the event of a name collision, the original entry is replaced and the command does not fail. See about hashtables.
%H=Jump <path>; - performs a hashtable lookup and jump.
The hash table in the specified buffer (or the current buffer, if none specified) is searched. If the key exists then the focus is restored to the point at which the key was entered by %h=addjump or %H=newjump. If the key is not found, then the command fails - see about hashtables.
Not that this command causes linenumbers to become detached from reality. This is not normally a problem for very bug files - these are the files that the jumps were intended for and are not even noticeable until, after M-0, we would normally expect the line number to be 1. This can be fixed using the O_ command.
%h[<bufferKsy>]=DAta <path>; - creates a hashtable entry for storage of generic data.
If no path is specified, this creates an entry in the current buffer's hashtable, when path is specified the entry is created in the hashtable specified by the path.
This creates a hashtable entry which can be used for storage of a stack frame. The command creates a blank entry and does not affect the state of the stack. The data value can be refined with the OV command and later retrieved using the OQ commands.
Note the absence of any typing with this command, any of the three valid stack datatypes (integer value, floating-point value or buffer) may be used with any data object and the datatype is allowed to change. In this example, the data object fred is first set to an integer, then a float and, finally, a buffer - it's all allowed.
> %h=create 100; > %h=data fred; >ol123456789 ov/fred/ > ol123.456 ov/fred/ > %d~=Hello world; ov/fred/See also %h=setdata, OQ and OV.
%H=SETData[ -New] <path>
This sets the specified data object to the value at the top of the stack - this duplicates the function of the OV command.
If the -new option is given the data object is created (otherwise this must be created beforehand with the %h=data command) - see percent-command syntax.
If -new is not given the specified object must have been previously defined with a %h=data command or the command fails.The command will similarly fail if -new is given and the data object does already exist.
%H=Getdata <path> %H=Getdata [<path>]
The value of integer and floating-point objects is copied to the stack, buffers are cloned to the stack.
While the oq command has a simpler and an, arguably, less clonky syntax; this command allows string expressions in references to data objects. See percent-command syntax and string Expressions.
%H=SETSEct <path>; - creates a hashtable entry for use in %i;
This takes the top two items on the stack and creates a hashtable entry for use by the -section=<key> qualifier of the %I command.
This is a rare example of a magic command in jot - it is designed for use by scripts reading index tables for large files and probably only useful for this purpose (see about large files).
Another unusual feature of this command - although it uses two values at the top of the stack, it does not remove them. This feature is designed for the benefit of scripts which re-use each startpoint and length to calculate the startpoint of the next section.
%H=SETFsect <path>; - creates a hashtable entry for use in %i;
This takes the top three items on the stack and creates a hashtable entry for use by the -fsection=<key> qualifier of the %I command. It is designed for use by scripts reading index tables for large numbers of files and is probably only useful for this purpose. (see about large collections of files).
The top three items on the stack must be:
Another unusual feature of this command, similar to %h=setsect, although it uses three values at the top of the stack, it does not remove them. This feature is designed for the computational convenience of scripts calculating section byte counts by subtracting the previous-section seek point from the current-section seek point.
Note that consecutive setfsect calls referring to the same pathname will all share the same internally-held copy of the pathname. This behaviour is designed to minimize memory usage by the internal data structures. Fortunately most practical indexation methods will generate index file structured in this way.
%H=Delete[ <path>];
This changes the state of the selected key to a sort of half-dead zombie state. Unfortunately it is not possible to delete keys from hashtables built using the gnu-library hashtables. So we do the next-best thing.
The hash key can be re-assigned - this, for example, will work:
> %h=addjump fred; > %h=delete fred; > %h=data fred;The zombies are removed if the hashtable is rebuilt - see %H=create.
%H=COde <functionName>;
Creates an entry point for the specified function at the start of the current line. The function may then invoked with the %h=call command.
%H=CAll[ -Oneline] <functionName>[ <Args>]
The buffer indicated by the key is a code repository and defaults to ( ' ) -see calling functions by name, the entry point must have been previously defined using the %h=code command. The startup.jot script, for example, defines and creates hash-table entries for a number of routines in the ' buffer.
Parameters follow tha function name, they are copied into the ( $ ) buffer by the system. If, however, no parameters are given then the ( $ ) buffer is left unchanged so, in some instances, to indicate the absence of parameters it will be necessary to first clear the ( $ ) buffer.
The -oneline qualifier causes the compiler to stop at the end of the specified line. By default, the compiler continues to read code until it reaches either the end of the buffer, or at the start of the next function header. This behaviour is designed to allow functions to be called directly from the keystroke-translation buffer ( ^ ) e.g. in fake_vim.jot, fake_emacs.jot and fake_nano.jot. See translation of keyboard events to actions
%h<bufferKey>=REcompile[ -Tags] <functionPathName>;
Compilation is done automatically the first time a function is called (see %h=call), the code is then preserved and subsequent calls of the function will run the compiled code.
If, however, the source code has been subsequently modified, these changes will not be reflected in the compiled code and jot has no way of reliably detecting changes to individual functions. This command deletes the original code and recompiles using the updated source.
The optional -tags qualifier causes the compiler to insert code from any code tags. Code tags are mainly used for implementing debugging functions without changing the repository source - see about tagged text for details.
%H=Fix[ <path>]
This corrects the linenumbers held in any hashtable it also resets the linenumber of the first line to 1 and returns to the first line.
If records are added or removed after the buffer has been indexed in a hashtable, the linenumbers held in the hashtable may be incorrect. This can result in errors when using these linenumbers to calculate offsets between indexed records. The fix operation assigns the new, correct, linenumbers in the referencing hashtables and resets the buffer so that any errors in the line numbering are resolved.
%H=Destroy[ <path>]
This removes the entire hashtable, destroying all entries.
%H=Testkey[ -type=<type>][ -gettype]][ <path>];
The %h=testkey command verifies the hashtable contains the key matching the given buffer path. This is used to find out if an entry of the right type exists. If no secondary-buffer path is given, it simply tests for the existance of the primary-buffer hashtable.
if -gettype is given and the specified object exists then it pushes the found objects type code (see below) onto the stack, if the object does not exist then it pushes a zero.
With no type specifed this simply verifies the existance of the specified object in the given path. With a type specified, it verifies that the specified object is of that type.
If the -gettype or -type= qualifier is given, the type codes used are given by the following table:
the hashtable.
This command does not write any report, it simply returns a Success or Fail status and optionally adds an item to the stack.
%D<key>=[ -Append][ -Break] <string>;
and
%D<bufferKey>=[ -Append][ -Break] <string>; %D= -buf=<bufferPath>[ -Append][ -Break] <string>;
%D<key>= -LITERAL_DEFINITION <string> -BUFFERDEFINITIONENDSHERE;
Defines the specified buffer directly. If -append is given then the new string is added to the end of the last line of the buffer.
Whereas %D will define a single-line buffer %G is useful for defining any-number of lines.
By default this defines a primary buffer identified by the given key, if -path=<bufferPath> is given then the key is silently ignored and a secondary buffer is defined. In either case, if the buffer did not previously exist then it will be created.
The first parameter is the buffer identifier key - a single character which identifies the buffer to be defined.
The -append qualifier, instead of replacing any previous contents of the buffer, appends the sting to the end of the last line of the buffer.
The -break qualifier inserts a line break immediately after the new string.
One particularly important variant is %d~=...; - this creates a one-line buffer on the top of the stack and is often followed by the OV command. This combination is used to set a data object to a string value. See about hashtables and using Hashtable data
Special care shoud be taken when the string contains any of the percent-command special characters For a detailed description of these and string expressions see percent-command syntax.
One particular case is when %D is used to pick up search-string parameters etc. for function keys and escape sequences. Users would generally prefer to avoid having to fuss over special characters and just type in stings they want. The special terminator string " -bufferDefinitionEndsHere;" was designed for this situation. When this terminator is given, the string is taken as-is, ignoring any special characters.
For most purposes, the -bufferDefinitionEndsHere; option is entirely useless - just a long-winded way of avoiding having to escape a few semicolons when a simple backslash is easier and simpler. It is, however, very useful for picking up and processing user keyboard replies - users will appreciate not having to escape semicolons as they are typed in, so you will find them in the hot-key translation table - the ( ^ ) buffer.
%G<key>=[ -Append][ <label>][;]<line1> <line2>
...<lastLine> [<label>]:
Reads a buffer from current command stream or macro, the single character key specifies which buffer. If -append is given then the lines are appended to any preexisting text in the buffer. By default the list of lines is terminated by a line containing colon ( : ) in the first character and no other characters. If a label is specified then the list of lines is terminated by a line containing that label followed by a colon ( : ) and no other characters (including whitespace).
The equals sign may be omitted if no label is specified.
This is similar to the G command, except that whereas G always takes input from the console, %G will take from whatever command input currently active - typically a script. Thus %G is a handy way for scripts to define multi-line macros.
Buffer specifications are nestable (provided the end-point labels are chosen correctly) i.e: a %G can define a macro and the macro may defines other buffers when active.
Whereas %G defines any number of records %D is a convenient way of defining a single-line macro.
%I[<bufferKey>]=[ -buf=<bufferPath>]
[ -Seek=<ByteNo>][ -Bytes=<bytes>|-BLock=<bytes>|-Records=<n>]| [ -Overlap=<n>] [ -SECtion=<name>|-Fsection=<name>][ -Insert | -Append][ -Hold] [ -BInary[=<recordSize>]]
[<pathName>]
This loads the file to buffer specified by the -buf=<bufferPath> qualifier, if not specified then the buffer indicated by the buffer key, if neither the buffer key or bufferPath is specifed then it reads to the current buffer.
It can return a failure under the following circumstances:
The pathname defaults to the pathname of the currently-edited file. If the new filename is incompletely specified then the missing fields are filled in using the current-buffer's pathname. Note that this behaviour can cause difficulties. If the new file is in your pwd and the current file is in some other directory, you must prefix the name with the path "./". If the target file has no name extension and the current file does, you must change focus to a buffer with no pathname set.
Files may be plain ASCII or unicode encoded in UTF-8 or UTF-16LE (see Unicode - the gruesome details)
Briefly %I has the following optional qualifiers several dedicated in some way to the loading of sections of large files - see about large files:
The -hold qualifier causes the file handle associated with the buffer and to be left open, this is to facilitate reading of files in blocks. Subsequent reads to the same buffer, using the -hold qualifier can index more efficiently, starting from where the previous read ended. The actual file handle is associated with the buffer and therefore cannot be used to read into other buffers. This option is intended to be used in conjunction with the -section option, on very large files. The pathname is optional after the first such read to a buffer and is ignored. If it is required to read with -hold from a different file the old filehandle must first be reset by reading zero bytes from somewhere - maybe /dev/null.
The -bytes qualifier gives it an end count which restricts the read to that many bytes. Similarly, the -records=<n> qualifier sets an upper limit on the number of records to be read. If neither -bytes nor -records is specified, it reads to the end of the file. Similarly, if -seek is not specified it starts reading at the beginning of the file. The -seek qualifier defines a starting point, as a byte offset from the start of the file. It is designed to be used with -bytes to read selected bits from large pre-indexed files.
The -block and -overlap qualifiers are designed to facilitate the sifting and shifting of large amounts of data in the shortest possible time using the least memory. Essentially -block bypasses the usual buffering and record-forming activity and reads any amount of data into a block of memory which has been set up as a jot record. Most pattern-matching require a finite aperture to properly match various elements but, when working with with fixed-length blocks, the block boundaries can disrupt this pattern matching. The -overlap qualifier aims to avoid this by copying the last few characters of the previous block to the start of the current block.
The -block qualifier is similar to -bytes in that it specifies a limit on the number of bytes but, with -block, blocks of data are read into one record of the specified size. The block of memory it uses is overwritten by each successive read so, from the user standpoint, it appears as an exceptionally long line of text. Although there is only ever one record in the buffer, the linenumber is incremented at each read to make it easier to keep track and calculate seek offsets when using these to make index files. The -seek qualifier is unnecessary but it can be combined with the -block qualifier to override the normal sequence. The -block qualifier must be used with -hold.
The -overlap qualifier is intended for pattern matching in large files. It copies the last few bytes of one block to the start of the next block. The overlap size is small - typically less than 1Kb, determined by the required pattern-matching aperture. This allows long blocks of text to be read and scanned using normal jot commands so that some inner meaning may be extracted from the file.
The -section qualifier sets the seek and limit from the top two items on the stack. This is designed to be used in conjunction with the %h=setsect command. Unlike the -fsection variant, -section assumes that the pathname is known and constant. It is therefore more suitable for situations where only one file is used - a very large file with many sections.
The -fsection qualifier is very similar to -section, except that the hashtable object it accepts is the form created by the %h=setfsect command. These objects are created by the %h=setfsect command. Like the setsect object, this contains a seek-offset byte count and a section-length bytecount but it also contains the pathname of the file to be read. This makes the -fsection variant suitable for situations where sections are distributed over a number of files. If a pathname is also specified in the command line, this is silently ignored.
The -binary option reads the file and displays it in the form of a hex dump. The optional recordSize value, which specifies how many Hex pairs to place in each line, defaults to 16. To view ascii characters use the script hex2ascii.jot, this annotates each line of hex dump with the ascii translation. The hex dump can then be written back as binary - see the -binary qualifier to the %O command but note, for %O the optional parameter to -binary is the conversion radix.
The -insert qualifier causes the file text to be inserted into the current-character position of the buffer, the current character is left pointing to the start of the inserted text.. The -append qualifier is similar except that the new records are delivered to the end of the current buffer and the current character is left unchanged. By default (i.e. no -insert or -append) the buffer is first cleared and the new file completely defines the buffer text and the current character is left pointing to the start of the first line of the file.
If the buffer has already been reading a file with -hold, the new pathname is ignored and the old file handle is reused. To prevent this happening it is necessary to perform a read without the -hold qualifier - something like this should do the trick:
> %iz=/dev/null -append;%L=[<width>[ <height>]] - Sets the terminal line length and number of lines.
This is a throwback to the days of VT200-series terminals, the DECCOLM function allowed 80/132 switches.
In a modern windowing environment the terminal size is changed by, say, dragging the window boundaries. After this, %l can be used without the terminal-size parameter. It reads back the new screen height and width henceforth these new values are used in internal calculations involving screen dimensions. Note that adjusting the window size has no effect on jot until the new screen size is read back by the %L command.
If a terminal size is specified, each of the given dimensions should be less that the than or equal to the corresponding dimensions of the actual terminal you are using - if not then %L fails and both are set to the actual screen size.
If The width is specified without the height, the height is set by the actual terminal height.
The allowable width must not exceed the actual terminal width and the allowable height is constrained by both the actual terminal height and the current window configuration - the specified height must be sufficient to accommodate all the currently-defined windows and at least one console line. An easy way of avoiding this second constraint is to only apply the %L command after deleting all windows (see the %W command).
If the size is specified, the command may fail if either
This command also completely redraws all windows on the screen, hence it is useful if, for whatever reason (but typically because of a %E operation), the screen happens to get messed up.
The screen size can also be set at the start of day by the -screensize CLI qualifier
%O[<bufferKey>]=[ -Append][ -binary[=<radix>]][<pathName>]
The specified buffer is written out using the given pathname, defaults to the current buffer when the buffer key is not specified.
The -Append qualifier adds the contents of the buffer to the end of the file. Whether or not the -append qualifier is given, if the file does not exist, then a new one is created.
The -binary qualifier is designed for use with hex dumps of binary files (see the -binary section of %I). It translates the hex dump back to binary for writing. Octal and binary dumps are also supported by setting the radix modifier to either 8 or 2, respectively. As implied above, it defaults to 16 for hex dumps.
Note: the -binary qualifier is ignored if the buffer encoding is set to anything other than 'Plain' (see %B=encoding).
The hex (or octal/binary) dump must be formatted as follows:
The pathName defaults to the pathname of the current buffer. If the new file name is incompletely specified then the missing fields are filled in using the current pathname.
%R=[ -asConsole] [pathname][ <ArgList>] - Run a command file.
If no path is explicitly specified, then JOT first searches your PWD, if it's not found there, it searches the directory ${JOT_HOME}/coms - see installation.
The ArgList is a list of whitespace-separated parameters that are copied into the ( $ ) buffer to be picked up by your script.
The file contains editor commands, these are all executed in the same way as with console input, the default file name is startup.jot.
In the event of an un-trapped error (i.e. a command failed and no else clause applies), then execution of the script is normally terminated. The -asConsole qualifier changes this behaviour.
When the -asConsole qualifier is given, the behaviour is more like an interactive session, this feature is used in session recovery (see recover.jot) and also in the construction of test scripts, in particular test_all.jot and monkey_test.jot.
Command files may be nested to a depth of 20.
%U - Undo = Undo last substitution.
The current substring (irrespective of whether selected by F, V, I or S) is replaced by the last specified search string. Normally, of course, this would have been set as a result of a S (substitute) command, following a F (Find) command, hence the substitution is undone.
If the original find substring had a different case pattern to the replaced substring (i.e. the find was done in case-insensitive mode) then the undo will not reflect the original case pattern.
%W[<key>]={new|modify=<winNo>}
[ -height=<height>][ -width=<width>[+<guard>]]]] [ -popup[=<xOffset>[,<yOffset>]]][ -delim][ -key=<bufferKey>][ -path=<bufferPath>] [ -delete][ -insert=<winNo>][ -freeze=[0|1]] [ -protected] or
%W=update[ -RESet];
or
%W=refresh;
or
%W=clear;
The %W command controls how the the screen is divided up into viewing windows, typically just one window but the viewing screen can be partitioned both vertically and horizontally. Briefly:
The normal startup script sets up a basic window configuration - a single window displaying whatever buffer is the current focus, occupying the full width of the terminal and all lines except the last. Should the window get messed up the default configuration can be restored by invoking the WindowOne function.
In allow secondary buffer to be displayed, these may be referenced using the -path=<bufferPath> option see about text buffers. %W will fail if it is given both the -key= and a -path= qualifiers.
If a single-character key is specified in <key>, this identifies a buffer to be displayed in the window, if -key=<bufferKey> is also specified the buffer identified by newKey overrides the key. If no key is specified anywhere the window will display the current buffer.
In the event that the current buffer is displayed in some other window, maybe because of there being more than one floating window, or, one floating window, Then the floating window is left displaying whatever buffer it is currently displaying or, at the start of day, it displays blank lines.
Windows may be defined as a number of screen lines or may be vertical slices of <height> lines and <width> columns. Windows may be assigned to specific buffers or can be left unassigned - in which case they display the current buffer.
The %W command indirectly defines the height of the console area, the window size and the total height of all the windows together define the console area height. The console area can be set to temporarily expand upwards by borrowing lines from the bottom of the display window - see the %s=console command. The console normally displays a command prompt but, in the event of errors or other messages, these are displayed in the borrowed console area.
An existing window configuration may be changed with the %w=modify=<winNo> command the winNo parameter specifies a particular window . Any other valid %W modifier may be included to change the selected properties of the selected window. The window number (winNo) is assigned by the system and is given in the query screen report.
New windows, or vertical slices of windows, are added in sequence by a series of %W commands - each adding just one new window to the screen. Before adding a new window, the %W command checks that there is sufficient window height and width to accommodate the requested window if this is not the case then the %W command fails.
When it is required to change the height of an existing group of slices, this can only be accomplished by changing only the height of the first (leftmost) slice in the group. Any attempt to change the height of other members of the group will fail.
By default, the left margin of the second and subsequent slices will abut the right margin of the predecessor slice. The +<guard> modifier (where <guard> is a small integer) will insert that many blank columns between the slice and it's predecessor slice.
Although the -key option may appear redundant, the window key can be specified as the <key> - the syntax does not permit indirect expressions there. Also when used in the modify command, an unspecified key has no effect - any previous buffer assignment for that window will persist after modification. However an unspecified newKey will cause the window to display the current buffer, even if it was previously fixed to a buffer.
Note that jot does not maintain a record of the state of frozen windows. It simply avoids updating them as the state of the underlying buffer changes. Any subsequent %W=clear; or %L command will clear the window. This might be required after a %E command caused the display to scroll and replace the original view.
These are activated for display only when the associated buffer has a non-empty first line - this is a feature intended to make them easily disappear from the screen, whilst preserving their content.
Popups overwrite rectangular sections of the display but windows are redrawen in the order in which they are defined, so to ensure that the popup becomes visible the popup window should be defined after the definition of the underlying windows.
There is no limit to the number of popups but since each requires a dedicated buffer and it is quite easy to share them between a number of activities it is recommended practice to use as few as possible.
Note that the actual position of the popup is calculated as the %W command is processed. If the screen width is reduced (see the %L command) then the popup will remain at the same position on the physical screen.
For -popup windows, the height and -width dimensions specify the maximum size that the window can be allowed to grow to - if unspecified the popup may grow to fill the entire terminal screen. By default, the top-left character of the popup is normally aligned to the top left character position of the screen but this can be changed by specifying an optional xOffset and yOffset.
A positive xOffset will push the popup leftwards by <xOffset> characters, a negative offset positions relative to the terminal's right margin. Similarly, the popup's y-coordinate may be set by specifying a yOffset, in this case a positive yOffset specifies the position relative to the terminal's top margin and a negative yOffset specifies the popup's position relative to the terminal's bottom margin.
Note that, by default, the popup appears in the same colour pair and font as the surrounding text with no delimiter markers. It is left to the programmer to make suitable colour-pair arrangements for the popup stand out from the surrounding text.
The idea is that a debugging environment can set up it's own window(s) which will be ignored by the script or function being debugged. Then the debugger window does not affect the script's own window-size and placement calculations.
The main restriction is that protected windows must be at the top of the screen - so they are normally declared first although they can be added later using the -insert option, provided there are no unprotected windows above.
The %w=update forces a normal screen update. In normal interactive usage, these updates are usually performed immediately before the command prompt is issued. However some applications, although not interactive, might use the screen to display internal state, so they will use %w=update or %w=refresh as and when. The %w=refresh also updates the screen but it first clears all windows and resets lots of internal data forcing all lines to be rewritten. n.b Frozen windows are redrawen by %w=refresh.
The optional -reset qualifier (only available with %w=update) resets a borrowed-lines counter. These are lines borrowed from the bottommost windows for the console to display messages etc. and is normally reset when a command prompt is issued. The following screen update (which is just before the next command prompt) can update these lines. Now, in test, and some other scripts, the normal command prompting never happens and so we use this feature to clear away any text in these borrowed lines.
See also %S=guardband %S=console.
A JOT comment.
The command scanner ignores all text to the right of the %%.
%~ - Display character in hex.
or
%~=<hexDigits> - Insert a character at the current cursor position.
This operation is only useful for dealing with incomplete or invalid unicode characters.
The preferred method of investigating funny characters is to use OC and check the top of stack. The preferred method of specifying control or unicode character in hex is OL followed by OO.
All nonprinting characters (i.e. characters having an ASCII code of less than 0x20 and invalid unicode characters) are represented on the screen as a '~'. To investigate such a character, the %~ command returns the ASCII code, in hex, for the character at the cursor position. This command has an optional hex-value parameter, if given then the command will instead insert a control character of the specified value, at the cursor position.
With unicode support turned on (see %b=unicode) in the current buffer, the command prevents insertion of characters with bit 8 set (negative signed characters) as these may be interpreted as unicode and partly-formed unicode can lead to unpredictable results as the editor attempts to display them. To insert unicode in this way it is first necessary to turn off unicode support before entering the complete unicode multi-byte character and then re-enabling unicode support - see Unicode - the gruesome details.
This section attempts to reveal some insights into JOT usage.
Simply typing a number at the console will repeat the last command that many times. This is how the <<Again>> function works. Typically you will want to do this when you've typed in a short command string and want to interactively control how many times it gets repeated.
e.g. The following command removes any indentation from the current line and replaces it with two blanks:
> (v/ /e)0i/ /mTo repeat the treatment on subsequent lines just keep on pumping the <<Again>> key.
A block can have any number of failure handlers, thus each case becomes the failure handler for the previous one e.g. (v/fred/..., v/jim/..., ...)
A block without a failure handler will pass it's status up to the parent block, so if there are a list of conditions, any of which may be met we could write something like this:
( ... (v/fred/\v/jim/\v/bill/\) abc, def )
If the cursor is at the start of any of those names, then the command string abc is executed, otherwise it's command def.
Several scripts are available for handling tabulated text. These apply to the entire buffer. To limit the scope of these scripts, abstract the section containing the tabular data into a temporary buffer and apply the scripts in there.
By default, the tab character is the ASCII HT (Horizontal Tab 0x0B), this can be redefined with the %s=tab command.
The scripts are all based on the tab character indicating the alignment points.
The following command-line qualifiers are allowed, the keywords are case insensitive, the upper-case alphas indicate the minimum requirement - briefly:
$ <cmd> | jot - ...
The shell command <cmd> generates a text stream which is picked up by jot and loaded into the primary buffer ( . ) - this is only necessary in the windows version.
$ jot -new <pathName> ...
Either the file does not exist or, if it does it will be ignored. The editor starts with an empty buffer but with with the specified pathname and the file will be created by a %o or %c command.
$ jot <origPathName -to=<toPathName> ...
Sets the %o and %c destination file name.
$ jot <pathName> -startup=[<startupPathName>] ...
A pathName to a special startup sequence. If specified, this takes precedence over the other possible startup-file locations - see startup.jot.
If -startup is specified with no pathName argument then no startup is run.
$ jot <pathName> -init=<jotCommandString> ...
The jotCommandString commands are processed after running the normal startup sequence - this can be used to initialize the editor in some special way or for stream editing. This qualifier is also useful when jot is being driven by a shell script.
When a very long initialization sequence is required, this may be broken up and applied over any number of -init commands, in order to avoid exceptional long command lines and complicated escaping of special characters in scripts the commands are concatenated into one long command sequence in the correct order e.g:
$ jot someFile -in="i/This was set by the first line of initialization commands./b" \
-in="i/This was set by the second line of initialization commands./b" \ -in="...
$ jot <pathName> -tty ...
Teletype mode, for use in environments where the normal screen-control operations won't work or, when jot is driven by a script.
With -tty any window setup in the startup file has no effect, on completion of each command line, the current line is displayed, the position of the current character is indicated by a carat ( ^ ) in the following line and the current substring by a string of tildes ( ~ ).
$ jot <pathName> -codepage <value> ...
This qualifier is available only in the windows version, in linux the -locale qualifier performs a similar function. This qualifier sets codepage to specified value, by default codepage is set to 65001 - UTF8 - see Practicalities of unicode etc. and jot
$ jot <pathName> -locale=<locale> ...
This qualifier is available only in the linux version, in windows the -Codepage qualifier performs a similar function.
This sets the default locale for all buffers. Locale currently only affects the rendering of unicode characters. e.g:
$jot ${JOT_RESOURCES}/t.t -locale=en_US.utf-8
For linux the default locale is inherited from the shell env XTERM_LOCALE - see Things that might go wrong
$ jot pathName -obey << EndOfCommands ... cmd1 cmd2 cmd3 EndOfCommands
By default, when jot detects that stdin is not a keyboard, it is assumed to be a text stream to be picked up and processed in the primary buffer ( . ). In this case, however, it's a series of commands. The -obey qualifier identifies these as such
To push short sequences of in from the command line, the -init=<...> method is generally preferable.
Note that the last command in the -obey sequence *must* be %c or %a to terminate the editor session.
This option is really only useful in shell scripts in order to make the jot commands visible and accessible in the same context as the shell commands it interacts with. For an example look at Test 8 in ${JOT_HOME}/test.sh.
$ jot ... -journal ...
This creates a directory to hold the journal files. The journal files are used to recover your work following a crash. See About Journal Files and recover.jot for details.
$ jot ... -quiet ...
Suppresses all prompts and messages except for P commands. In -tty mode it also suppresses any indication of substrings and the current character.
It achieves this by initializing the verbosity bit mask (see %s=verbose) to zero at the start of day. This ensures that any messages, normally delivered at initialization time, are also suppressed.
$ jot ... -screensize=<width>x<height> ...
Sets the screen dimension as specified. The width is denominated in characters the height in lines.
The screen dimensions can also be specified by the %L command.
$ jot ... -stacksize=<n> ...
Sets the size of the operand stack to n. By default it is 100, if you need more then there's probably something gone badly wrong with your scripts.
$ jot ... -hold ...
Following a %A this displays the following prompt in the console area:
Exiting now (123456) hit C to continue or any other key to exit now
This allows you to see any recent messages and offers a chance to hold the session open typing the letter C or c will return a fail but keep the session open allow in you to do a bit of diagnostic investigation - any other character will exit the session..
The number in brackets is the number of commands processed since the start of day or the most recent interactive input (the command counter) - this behaviour makes the -hold option important for debugging scripts and functions - see using %s=commandcounter in debugging.
$ jot ... -History=<n> ...
Sets the size of the internal command-history buffer, by default it's set to to 20 lines. The first element of the history array is the current command, which must always exist. Hence you must specify a value in of 1 or more for this.
This buffer holds the last few typed-in commands. You cannot, at present, edit history directly but you can only view the contents of the history buffer with the %q<buf>=history command - see query history.
This internal command-history buffer is used in the jot command-editing interface - see CmdEditStart and CmdEditGo.
N.B. The size of this history buffer has no effect on the operation of the journal history - see about journal files.
$ jot -help
Displays a brief description of the jot CLI qualifiers and exits.
The jot installation process is pretty simple. For details see the installation guide at ${JOT_HOME}/docs/INSTALL There are some notes covering the environment setup at Environment
For those that like to get their hands dirty, these notes describe the basic installation structure, compilation procedure and trouble shooting.
Start by downloading either jot_v<version>.tz or jot_v<version>.zip, whichever you fancy - both archives contain exactly the same files.
Before you can run the editor a certain amount of system-dependent setup may be necessary - see either unix and linux setup or ms-windows setup.
These envs are referenced by either the main editor programme or the scripts:
Of these, the only essential one, for a working installation, is JOT_HOME, it uses this to locate the coms subdirectory (where it picks up scripts, including the all-important startup scripts). When JOT_RESOURCES is not defined, the startup script defaults it to ${JOT_HOME}/resources - the resources directory from the archive contains test, demonstration and training samples.
Typically jot will be started from the command line from an xterm (or a windows console) with a pathName argument, the editor takes over the screen and displays an image of the specified file. It also reads a setup script, by default ${JOT_HOME}/coms/startup.jot, this defines functions and the mapping of keyboard events to functions. To do this the JOT_HOME env must point to the correct point in the installation tree.
Also, if you have a shared jot installation then you may prefer to maintain your own ${JOT_RESOURCES} files. This is a collection of bits and pieces used by some jot scripts.
JOT_HOME should point here --> v<version> | --------------------------------------------- | | | | | bin coms releasenote.txt resources source | | | | ... ... ... ...
In addition to files in the jot archives you may feel the need for one or more of the following:
Although not always available by default, xsel is available as a download from your linux disto provider.
Windows users need not fret about xsel, windows does not support selections so you will have to use cut and paste instead.
Wherever you decide to unpack the archive, JOT_HOME should be set to point at the v<version> directory. You will also need to set search path. In linux/bourne-shell:
$ export JOT_HOME=/<path>/v<version> $ export PATH=${JOT_HOME}/bin/<arch>/;${PATH}
In order to minimize the number of statically-linked libraries in the linux version, the %s=copy and %s=pastecommands are not available with the linux executables supplied in the download. This deficiency can be corrected by recompiling with X11 enabled and, if necessary, installation of the X11 libs and header files.
If you have to recompile the jot executable, these commands should work, there may be a few _devl and sharable libraries to be installed:
$ versionString="jot <version>, built `\date +%d/%m/%y\ %H:%M:%S` `\uname -nspr` " $ cc -D LINUX -g -Wall ${JOT_HOME}/source/jot.c -D_FILE_OFFSET_BITS=64 -D VERSION_STRING="\"${versionString}\"" \
-lncursesw -lX11 -lXt -o ${JOT_HOME}/bin/<arch>/jot
$ gcc -g source/jot.c -D VERSION_STRING="${versionString}" -lncursesw -o bin/<arch>/jot
The linux executables supplied in the tarball were statically linked to the curses library, with cut and paste disabled by the noX11 flag, using a command similar to this:
$ gcc -DLINUX -DnoX11 $debug -g -Wall source/jot.c \
-D_FILE_OFFSET_BITS=64 -D VERSION_STRING="\"${versionString}\"" \ -Xlinker -dn -lncursesw -lncurses -Xlinker -dy -lgcc_s -o ed/bin/jot
See also X-windows setup.
To use the spelling checker functions (see text document preparation), you will need aspell on your search path.
Check your search path like this:
$ echo $PATH
You should see the path to the bin subdir in the colon-separated list it returns - if not check the following:
If the path is correct then check the binary is giving you execute permission:
$ ls -l <binPath>/jot
you should see something like this "-rwxr-xr-x" if you don't see the x characters then make it executable - like this:
$ chmod ugo+x <binPath>/jot
This is probably because you are using an old linux distribution. Try installing a newer glibc - either glibc.x86_64 or glibc.i686 for older 32-bit machines. Another approach would be to try recompiling the source, you will need various libraries including some _dev libs and a gcc - see the previous section for details of the gcc command.
Check your TERM env:
$ echo $TERM
Most distributions default it to "xterm" if it's something different, then try setting it to xterm like this:
$ export TERM=xterm
If that works out, and you have no reason to want it to be different, put that export line into ~/.bashrc so you don't have to keep on setting it in every new shell.
If, however, your TERM is set to xterm, then you've got a problem. Check your terminfos:
$ ls -l /usr/share/terminfo/x/xterm*
or, maybe:
$ ls -l /lib/terminfo/x/xterm*
There will probably be several flavours of xterm to chose from - pick a likely looking one and export that one.
The Ubuntu crouton system (and perhaps other Ubuntu systems - possibly also Debian) it may be necessary to install xterm:
$ sudo apt-get install xterm
and/or set your TERM env to xterm1:
$ export TERM=xterm1
export XTERM_LOCALE=C.UTF-8
The mapping of keyboard function keys is dependent on various elements of operating system and it's setup. This is done in several stages, ultimately, JOT picks up text characters, control codes and VT100-like escape sequences.
Jot is implemented using functions from the curses library - these provide a consistent mapping of most function keys to control codes which jot can map to your selected actions at setup time.
In addition to function keys and other keys supported by curses, jot will recognize vt220-like escape sequences generated in response to numeric-keypad actions. The mapping of these is not consistent and different installations may give different results. Use xev and xmodmap to define these mappings. See also functions defined at startup and key bindings
The jot setup assumes unique keycodes from the numeric keyboard, unfortunately, in the linux-curses environment, the numeric keypad keystrokes are indistinguishable from their twins in other sections of the keyboard. The windows version does not use curses and does not suffer from this problem. The solution for linux users, wanting to use their bean-counters keypad, is to redefine the numeric keyboard keys with xmodmap. e.g:
$ xmodmap ${JOT_RESOURCES}/my_xmodmap
This version of my_xmodmap works for PC keyboards:
!! Make the numeric keypad keys unique. keycode 63 = KP_Multiply keycode 82 = KP_Subtract keycode 86 = KP_Add keycode 91 = KP_Decimal keycode 108 = KP_Enter keycode 79 = KP_7 keycode 80 = KP_8 keycode 81 = KP_9 keycode 83 = KP_4 keycode 84 = KP_5 keycode 85 = KP_6 keycode 87 = KP_1 keycode 88 = KP_2 keycode 89 = KP_3 keycode 90 = KP_0
Wherever you unpack the archive, JOT_HOME should be set to point at the v<version> directory. You will also need to set search path. System registry entries are the recommended method but, hey, life is short maybe this will be good enough for now:
$ setx JOT_HOME=C:\<unpackPath>\v<version>\ $ set PATH=C:\<unpackPath>\v<version>n.m\bin\win32;%PATH%
In windowsland it is most unlikely you will need to recompile, which is just as well since compiling just about anything in windowsland is going to be painful. If you have a working cl installation and libgcc and libgw32c gnu libraries (try sourceforge) then something like this might work:
$ cl /c /DVC /D__value=_value /Zi /D_DEBUG /DVERSION_STRING="jot for WindowsNT v<version>" %JOT_HOME%\jot.c /Fojot.obj $ link /debug /out:%JOT_HOME%/bin/jot.exe jot.obj ^
<MSDKsPath>\v7.1\Lib\*.Lib ^ <gnuLibPath>\libgw32c-0.4\lib\libgw32c.a ^ <gnuLibPath>\libgcc\lib\libgcc.lib