Command file library

The scripts

There are a number of predefined JOT command file in the ${JOT_HOME}/coms area - see installation. In general these have a one-line description at the start of the command file. The most useful ones are described below

These are run by first typing the name of the script, followed by any arguments and then pressing the 'F2' button i.e:

> <scriptName>[ <arg1>[ <arg2>[ ...]]]{F2}

If the <<Do>> function has not been mapped to the F2 button then, as a temporary workaround you can type in the command %r=<scriptName>. If the script happens to be one that takes arguments then you must manually define the arguments in the $ buffer - this is always used to define script and macro arguments. Then run the script with %r=<scriptName> like this:

> %r=<scriptName>[ <arg1>[ <arg2> ...]]

In addition to Do there are two script-search functions ScriptByName and ScriptByFunc. ScriptByName searches for scripts in ${JOT_HOME}/coms and your PWD for those with the '.jot' name extension whose names match the given string (if no string given then it just lists all scripts in the searched areas e.g:

> mc{Shift+F2}

To apply the script on your buffer, move the cursor to the line with your script name and run macro 0 (normally {KP_0}.

By convention, all jot scripts should have a one-line comment in the first line. This should briefly describe what the script is intended to do. If it's a complicated script then detailed instructions should be left in the ? buffer.

ScriptByFunc searches these first-line comments in the search areas and returns a list of those matching the string e.g:

> multicolumn{Ctrl+F2}

To apply a script on your buffer, first select one by moving the cursor to the line with your script name and run macro 0 (normally {KP_0}.

startup.jot

The script ${JOT_HOME}/coms/startup.jot is normally run by the editor as it starts up but if some other startup-script has been specified (see notes on the -startup section of command-line qualifiers) then that script can call this startup script normally (e.g: %r=startup; ) or if it is necessary to defer finalisation of the keymap setup, it can be called with the -nofinalize option (e.g: %r=startup -nofinalize; ) - see below for usage notes on the -nofinalize option.

It's principal functions are:

This script creates a mapping of xterm escape sequences to code calls. It's first requirement is to have a map detailing the translation of key codes the to key names that appear in all the documentation.

The mapping of key names to function calls is entirely for the the convenience of the user and can be changed to suit user requirements.

In linux, the mapping of keys to actual key codes is a two stage process, firstly the physical signals received from the keyboard must be identified, then they are translated to a set of hardware-independent keycodes. Many, but not all, modern linux distributions use X Keyboard Extension (XKB). Followed by terminfo/termcap database identified by your TERM variable. For most linux distributions this seems to default to "xterm". If you are interested in that sort of thing, there's a compiled terminfo database file below /usr/share/terminfo/... - if your $TERM is set to xterm, for example, you will pick up the file /usr/share/terminfo/x/xterm.

Although there seems to be pretty broad agreement on what the default setting for $TERM should be, there is no standardisation on what it's capabilities should be and, in particular, what keycodes should be returned for some of the Shift - Ctrl - Alt combinations (see translation of keyboard events to actions).

If the current directory contains a startup.jot file then jot picks up this in preference to the ${JOT_HOME}/coms version.

If the optional CLI arg -startup is specified (see command-line qualifiers), then this overrides any startup path from ${JOT_HOME}/coms or the current directory. if the qualifier is given without the '=<pathName>' value, this is equivalent to -startup=/dev/null i.e. no startup script.

In summary, the startup-file selection is, in order of precedence:

There are two mapping tables used to fully define the finished key translations table in the ( ^ ) buffer:

The startup script will finalize initialization of the editor by merging thes two tables into the key-to-function translation table in buffer ( ^ ) - see translation of keyboard events to actions. It is this last step that is suppressed by the -nofinalize option.

If the -nofinalize option is given, the macro to do the finalisation is defined in buffer ( # ) as the startup script exits, this allows your startup script to modify the final setup in some way before invoking this macro or maybe some different macro to setup the functions and keymap buffers.

The startup script also defines the following dats objects in the code-repository ( * ) hashtable:

nomod.jot

$ jot <pathName> -st=nomod

This is an alternative startup script which modifies the key mapping to transform the standard {Ctrl|Shift|Alt+Fn} to a prefix style for those experiencing difficulty or discomfort reaching combinations of the Shift, Ctrl and Alt keys. In fact nomod.jot calls the normal startup script and modifies the keycodes data before finalising the key mapping.

Instead, a two-key prefix is typed in before hitting the function key - in this context Fn should be taken to mean any top-row function key, any mid, or numeric-keypad key or any arrow key:

The transformation assigns a weight of 1 to Shift, 2 to Ctrl and 4 to Alt. No prefix is required for the unmodified function keys.

In addition, qr.jot also accepts the qualifier -nomod, which causes it to display the prefix key sequence instead of modifiers.

curses_keys_<version>.jot

Theses scripts are run by the standard startup.jot script, they define mapping of keys to whatever key codes are generated by your terminfo, these are then assigned functions by the startup.jot script. Currently there is a keymap file for the following:

These script only work when called by startup.jot this then attaches functions to the key definitions in these scripts. If run directly, it's only effect of these scripts is to load buffer @ with the key-names to key-codes map.

In addition to providing the all-important mapping of editing functions to keystrokes these files also map the unassigned and unassignable key combinations. Some key combinations are unassignable because they collide with other keys or because they've been hijacked by the operating system for some system shortcuts. Feel free to add your own functions or rearrange the or redefine the assignments as in whatever way seems appropriate.

The key mappings tend to vary significantly, so a utility is provided to assist with redefining and checking the key-map script - see define_keymap.jot and verify_keys.jot respectively.

WindowsNT_keys.jot

The function of this is identical to the various flavours of curses_keys (see curses_keys_<version>.jot) in that it associates functions with their respective keycodes - i.e it defines key bindings.

uc_basic.jot

> uc_basic{F2}

This script defines a small number of basic unicode characters that may then be entered using a four-key sequence beginning {Esc}, {u}, {c1>} and {<c2>} where the characters c1 and c2 uniquely define a character in the supported unicode subset. The uc_basic script performs this substitution on the command line using %s=commandstring. See also about unicode.

These are the escape sequences and characters supported by uc_basic.jot:

- {Esc u ' a} á {Esc u ' A} Á {Esc u " a} ä {Esc u " A} Ä - {Esc u > a} à {Esc u > A} À {Esc u ~ a} ã {Esc u ~ A} Ã - {Esc u ^ a} â {Esc u ^ A} Â {Esc u c a} ǎ {Esc u c A} Ǎ - {Esc u o a} å {Esc u o A} Å {Esc u _ a} ā {Esc u _ A} Ā - {Esc u ; a} ą {Esc u ; A} Ą {Esc u b a} ă {Esc u b A} Ă - {Esc u , c} ç {Esc u , C} Ç {Esc u O R} ® {Esc u O C} © - {Esc u t m} ™ {Esc u < <} « {Esc u > >} » {Esc u " <} “ - {Esc u " >} ” {Esc u ' <} ‘ {Esc u ' >} ’ {Esc u . .} … - {Esc u . ^} · {Esc u x x} × {Esc u - :} ÷ {Esc u ^ 0} ⁰ - {Esc u ^ 1} ¹ {Esc u ^ 2} ² {Esc u ^ 3} ³ {Esc u 1 2} ½ - {Esc u 1 4} ¼ {Esc u 3 4} ¾ {Esc u s s} ß {Esc u s o} § - {Esc u / o} ø {Esc u / O} Ø {Esc u - d} đ {Esc u - D} Đ - {Esc u d h} ð {Esc u D H} Ð {Esc u ~ n} ñ {Esc u t h} þ - {Esc u T H} Þ {Esc u a e} æ {Esc u A E} Æ {Esc u ! !} ¡ - {Esc u ? ?} ¿ {Esc u = L} £ {Esc u = E} € {Esc u = Y} ¥ - {Esc u / C} ₡ {Esc u | c} ¢ {Esc u o x} ¤ {Esc u / /} \ - {Esc u o o} °

uc_math.jot

>uc_math{F2}

This script sets up some characters used in maths and engineering, essentially it is used in the same way as uc_basic.jot. It follows the vim digraph scheme.

define_keymap.jot

$  jot ${JOT_HOME}/coms/curses_keys_Vn.jot -in="%r=define_keymap[ -init]"

This script is used to map actual keycodes received from a real keyboard. It works by prompting for each of the various keystrokes in the nominated keys file and replacing the key code with whatever it picks up from your typing.

Be aware though, that certain keys are hardwired as system shortcuts. These can cause evil or, at least, bizarre unhelpful, things to happen. Alt+F12 on some systems, for example, closes the current window. Now why we should need a shortcut to close a window when there must be at least half a dozen other ways of doing it is a question beyond the scope of this user guide. But that's what it does, it's very annoying, and there seems to be no way of turning it off - not without re-coding and recompiling slabs of kernel. See also Translation of keyboard events to actions

The define_keymap script sniffs through the key map file you give it and wherever it finds "????????" in the escape-sequence field, it prompts you to hit the specified modifier and function-key combination. So first launch an ordinary editing session to reset the dodgy keys to "????????" before launching define_keymap:

$  jot new_keys.jot -in="%r=define_keymap"

It recognizes the special escape sequence {Esc s k} as an instruction to skip the current keycode. This causes the current line of the keycode file to be left unchanged.

If you've made a mistake or just want to take a break, you can interrupt with {Ctrl+c} and manually change the incorrect keycode back to "????????" then save your work, exit and restart.

In the unlikely event of you needing to redefine all keys codes, use define_keymap.jot with the -init qualifier:

$  jot new_keys.jot -in="%r=define_keymap -init"

The -init qualifier tells it to begin by scrubbing all keycodes in the file, replacing each with the string "????????". The main section of the script then searches these reset keycodes, prompts you to prod that combination of keys and picks up the keycode which then replaces the reset keycode. This process is repeated until all missing keycodes have been filled in.

verify_keys.jot

$ jot -in=%r=verify_keys

This is a simple script that allows the user to verify the keyboard mappings. It simply prints the keycode and name of the function key to the console area as they are struck. Function-key names are assumed to be in a comment field of the keyboard map file e.g. ${JOT_HOME}/coms/curses_Vn.jot

tk.jot

This is normally invoked by a client-application script:

> %r=tk;

It defines some functions used to create simple menu-driven interfaces.

Some important function it defines are:

Menus are defined in a tabular form - see below

dbg.jot

A toolbox containing a bunch of features offered in support of the development of jot code.

$ jot -st="dbg[ -nostartup][ -testtree]
$ jot -st="dbg[ -ide

At it's simplest, it just starts up with a much smaller main window (20 lines), which allows for a much bigger console area and better visibility of system messages:

$ jot -st=dbg ...

dbg shortcuts

The dbg script supports a number of, mainly navigational, utility escape sequences.

> <objName>{Esc d q}

Displays the value of the named object.

> {Esc d l}

Runs your specified launch commands.

> {Esc d d}

Takes you to the diagnostic screen.

> {Esc d t}

Takes you to the menu definition table.

> {Esc d u}

Takes you to the monitor/button-box buffer.

> {Esc d m}

Takes you to the monitor buffer.

> {Esc d b}

Adds a breakpoint to selected point in code - see dbg_addBreakpoint entry in dbg Breakpoints.

> <commandString>{Esc d c}

Sets condition on the seleced breakpoint. - see dbg_setBreakCondition in dbg Breakpoints.

> <commandString>{Esc d a}

Sets an action to be performed on entry to breakpoint - see dbg_setBreakAction in dbg Breakpoints.

> {Esc d v}

Disables code tracing in the code window.

To trace code in the source-code window (the default) the system must refocus the source-code fiew to the step currently being executed. This is usually helpful but less so when some other function is being operated upon, then we want to remain focused on the target code.

Housekeeping menu

The options here are to do with setting up the debugging environment.

  • "Disable mouse" doesn't actually stop the mouse working altogether, this sets the mouse mask to zero so that normal X-windows mouse behaviour is restored (see %s=mousemask. To re-activate mouse activity type the command "%s=mousemask 4."

  • Run menu

    These menu items ar used to launch a new run and stepping from breakpoints.

    The Breakpoint menu

    The dbg.jot script inserts breakpoints into the compiled code for the function under investigation. Breakpoints are a form of jot trace points (see the jot debugger) - essentially a trace point is created by inserting either a T or a %s=trace command into the code.

    Ideally, one would set a breakpoint just ahead of a troublesome section of code then single-step through the code noting values on the stack and in relevant buffers and data objects to identify the problem. In reality it's not always quite as easy as that. One common difficulty is the breakpoint may be inside one or more loops and we are only interested in a specific pass. To do this we set a condition on the breakpoint.

    The dbg script defines the following functions and associated menu items for breakpoints:

    The Monitor menu

    When stepping from a breakpoint it is frequently helpful to follow the state of various verious data objects and buffers as the code progresses. The dbg.jot monitor window is designed to faciitate that. Objects and buffers may be added to a list in the monitor buffer and the displayed values are updated at every breakpoint or at specified points.

    The list of values and the distribution of monitor-update pints is controlled by the "Monitor" submenu:

    The Command Counter menu

    One unfortunate aspect of jot langusge is the way command failures are handled - it sometimes happens that an unexpected failure burried deep an a stack of loops, function or macro calls can cause the entire ediface to mysteriously fail.

    The command counter is an important element in the jot debugging toolbox (see using %s=commandcounter in debugging). Briefly, it is used in two ways:

    dbg Traps

    showline.jot

    > %r=showline [-x|-o|-utf-8]

    qr.jot

    $ jot -st=qr
    

    or for users of nomod.jot (an alternative startup for CTS/RSI sufferers):

    $ jot -st="qr -nomod"
    

    qr.jot reads the main jot user documentation in their raw ( .txt ) form to provide a useful quick-reference entry point to the words, using the linkdocs.jot script insert the link metadata. Valid links are highlighted in green.

    A left-button click on a link will follow the link. A left-button click in any other part of the window will return to the previous view.

    If you are in a non-mouse environment, macro_1 is set up to emulate mouse clicks - move the cursor to a link and {Esc 1} emulates a mouse click.

    The -nomod qualifier changes toe {Ctrl|Shift|Alt+Fn} modified keystrokes in the documentation, to the prefix form defined by nomod.jot.

    ide.jot

    $ cd <projectDir>; jot <projectName>
    

    e.g:

    $ cd work ; jot ide_hello
    

    or

    $ cd work ; jot ide_jot
    

    This is a very simple Integrated code Development Environment (IDE). It is set up to work in linux and wine with any command-driven compilers and gdb-like debuggers - typically gcc, cl, gdb and winedbg.

    There is an internal switch to focus on either linux or windows versions of the executables.

    Your projects directory should have it's own startup file which loads files and assigns buffers to the source files. (for examples, see ${JOT_RESOURCES}/ide/projects/startup.jot ). This local startup will normally call the main jot startup file at ${JOT_HOME/coms/startup.jot to give you all the usual jot functions.

    On startup ide.jot splits the screen into the following fields:

    The menu line offers the following items: _ - File - launches a submenu - see below.

    The script operates by setting up a window on buffer ( L ) and associating it with an interactive command pipe (see %E), any suitable compilers can be used - typically gcc (linux) and cl (windows). The script runs windows programmes with wine and the winedbg debugger and gdb for linux.

    The script defines the following data objects and default values as follows, these may be redefined in your startup script - for examples see ${JOT_RESOURCES}/ide/projects/startup.jot:

    A typical session might begin with a bit of editing of the source in the main window, then either hit the "Save" button or manually type in the usual file-write command (%O) to save the source-file image, then press the "Compile" button to run your specified compile command. The script will refuse the compile request if the source has not yet been saved.

    One might then hit "Run", which will run your compiled programme either in your default shell (linux) or in wine, if you have selected windows.

    If you have bugs to diagnose, you might then invoke the debugger - gdb or, if you have selected windows, winedbg.

    The selection of Linux (the default state) or windows is set by the "Linuxland" or "Windowsland" buttons below the "File" menu item.

    For examples see working with ide.jot.

    fake_nano, fake_vim and fake_emacs

    fake_nano.jot, fake_vim.jot and fake_emacs.jot are attempts at emulating the behaviour of these editors in jot.

    A good question, at this point, would be "why bother with a nano/vim/emacs emulator when there are perfectly good versions available for free anyway?" Well, it would be true to say it's a good demonstration of the power and flexibility of jot that it can do reasonable emulations of two entirely different editors without resorting to magic modes or special tricks.

    For occasional vim users or less experienced users wanting to progress, fake_vim.jot may, at some future point in it's development, offer a progression route for those daunted by the labyrinthine complexity of the emacs and, to a lesser extent, of vim and the immensity of it's user documentation (the vim quick-reference guide quickref.txt runs to over 1500 lines)

    The end point for this project is defined by a vim quick-reference guide I found at http://users.ece.utexas.edu/~adnan/vimqrc.html. It's clearly not a complete guide to all the features but it looks like a good solid introduction.

    fake_nano.jot

    $ jot -st="fake_nano <pathName/option1>[ <pathName/option2>[ ...]]"
    

    or

    $ jot -in="%r=fake_nano <path/opt1>[ <path/opt2>[ ...]];"
    

    The fake-nano.jot script respects a few of the genuine nano command-line options, these must be added as qualifiers to the fake_nano script not as jot options.

    If it is required to run some -init="..." commands these may also be added in the usual way (see -init) but note that these do not get executed until exiting nano mode. This is because fake_nano has it's own command scanner. This is not a big restriction as two {Alt+i} commands in quick succession will run your initialization and then return you to nano mode.

    The startup options it currently accepts are:

    The fake_nano.jot script also respects many of the most important nano hotkeys - one big problem is that each new version of nano seems to have an entirely different set of hotkey actions. In the end fake_nano approximates to nano v2.5.3

    One significant difference is that fake_nano uses the jot console area to display messages - but jot, jot insists that the console must always follow the display windows. Thus it is that fake_nano messages appear in a one-line console at the bottom of the screen whereas, with genuine nano, these appear immediately above the help menu.

    The help screen ( {F1} ) is copied from the v2.5.3 man page and the v2.5.3 help screen but with a hashmark prefix on line describing features not respected by fake_nano. At the very end of the help screen is a little report giving the current fake_nano setup.

    Important deficiencies:

    Initialization commands may be entered after the

    Commands supported by fake_nano.jot

    fake_vim.jot

    $ jot -st="fake_vim <pathName1>[ <pathName2>[ ...]][ -<option1>[ -<option2>[...]]"
    
    Commands supported by fake_vim.jot

    fake_emacs.jot

    $ jot <filePathName> -st=fake_emacs
    

    The fake_emacs script is designed to replace the normal startup script - in fact it calls the normal startup script (see startup.jot) so most of the normal jot functionality is also available.

    The end point for this project is a good implementation of the functions described in the mg man page (mg is a minimal-functionality emacs). Unfortunately, as it stands, fake_emacs.jot is not anywhere near that endpoint.

    There are some features of emacs features which will probably never be fully implemented in jot because they're either too hard, impossible or because jot already has a better approach:

    Commands supported by fake_emacs.jot
    $ jot <pathName> -st=fake_emacs
    

    or

    $ jot <pathName> -st="fake_emacs -option1>[ -<option2>[ ...]]"
    

    The fake_emacs script recognizes the following options:

    The following have been tested and seem to work pretty-much as for the genuine article:

    fake_emacs function Escape sequence

    get.jot

    > get[ -to|-allto=<chr>][ -depth=<n>][ -list][ -stdout][ -indent][ <pathSpec>]{F2}

    If an initial path is given then the contents of the specified directory is displayed as the parent pathname followed by a list of it's children in the ( + ) buffer. The ( + ) buffer is effectively a menu - navigate up and down with the Up/DownArrow buttons and hit {F1} to descend to an item. Four types of item are recognized and the behaviour for each is as follows:

    comp.jot

    > comp[ <key>][ -Backup[=<backupVersion>]][ -Nosplit| -Horizontal]{F2}

    This sets up macros 4 and 5 to compare the contents of two buffers. The current buffer and a nominated reference buffer. If no comparison buffer is nominated, then the buffer is assumed to be a file image and is compared to the version spinning on disc.

    It also sets up macro 6, initially this repeats the last given command in the other buffer,subsequent invocations of macro-6 repeat the same command in both buffers.

    If the <key> arg value is given, this is the identity of the Reference buffer. If the reference buffer is not given, then the buffer is assumed to be a file image and the current filing-system version of the file is read into the ! buffer and that is compared to the current buffer.

    If the -backup value is given, then the most recent backup version is read to the ! buffer - see backup.jot. The path for the backup directory is assumed to be <originalFilePath>/backup - if no backupVersion string is specified it takes the most recent backup version. If a backupVersion string is specified then the extracted version name will match this string. In the even of more than one backup versions matching the given string, an error message is issued.

    By default, comp.jot will redefine the windows to give you a split-screen view of the two buffers. The left pane is floating and will show the current buffer, the right pane is fixed to the nominated reference buffer. To run comp.jot with your current window configuration - use the optional the -nosplit option.

    The -horizontal qualifier causes the screen to be split into two equal-sized horizontal windows.

    It also redefines macros 4, 5 and 6 (bound to numeric-keypad buttons 4, 5 and 6).

    See also CompareBufs.

    recover.jot

    $ jot <fileName> -st=recover[ -norun]
    

    Journal files are collected when the editor is started with the -journal qualifier see About not losing your work. These can be used to retrace every step in an editor session in the event of an abnormal exit. The journal files are held in a subdirectory alongside the primary file named <filename>.jnl (where fileName is the primary file). It holds snapshots of all files and system queries read by the session and a history.txt file containing a log of your keyboard and mouse activity. All these files are deleted when the editor restarts normally. The journal directory also holds a lockfile, imaginatively named LOCK, this is normally deleted as the session exits - unless the session terminates abnormally. The LOCK file has the effect of preventing a new session starting and destroying the journal files.

    The recover.jot script works by translating the history.txt file into a command script (named recover_now.jot) that will retrace your interactive session with snapshot copies of your input files and then winding it's way through all of your interactive commands and keystrokes.

    The identities of saved-copies of files is preserved but they are uniquified by suffixing them with the file modification-time datestamp. An extended session may read, modify and write a file and then read it in again later. It therefor keeps a separate snapshot of every read of the same file. If, on inspection, it finds the file's modification time is unchanged on the second or subsequent re-reads, the file is not copied again.

    The history.txt file, in addition to all your interactive activity, contains the uniquified pathnames for the various snapshot files. As they are read, the editor checks that the files are read in the same order as in the original session. It does this by verifying the new pathname against the original, which is also held in the history file.

    For the duration of the recovery run all file writes are disabled - when the recover_now script script terminates the session should continue normally, Appending any new commands to the original history.txt file and adding new snapshot files.

    On completion of a successful recovery, the original journal files are left untouched, you must delete them before launching a new editing session.

    The recovery process starts with a special initialisation script recover.jot which reads the history.txt file and creates a runnable recovery script in your pwd, named recover_now.jot it then runs this recovery script. Here is the full process, from the start of the crashing session:

    $ jot <fileName> -journal
    

    There are several things that might go wrong with this approach to session recovery:

    to set an immediate breakpoint or

    > %s=tracedefault 0F901;

    to enable the next t or %s=commandcounter command. Otherwise these will be treated as though they were from the original session.

    Disaster

    At line <n> of recovery script "recover_now.jot": recovery file-name (<pathName1>) does not match original (<pathName2>)

  • Users may navigate around the using the page-up/down keys, this means that the recovery-session terminal dimensions must match those of the original session. Furthermore, users may change the terminal size mid session and these changes must be reflected in the recovery session. These details are recorded in the history file and recover.jot initially scans the history to find the maximum terminal size - if the current term is smaller then recovery halts with a suitable message.

  • Note: the history file in the journal area is entirely separate from the history maintained for the %Q query history and is not affected by the the CLI -history setting.

    Undoing changes

    Every now and then even the most sure-fingered of us makes a mistake that means losing a lot of work. While many editors have an undo feature that allows us to restore the state of a file image and thus wriggle out of bad situation, jot has no such feature, which might be considered to be a bad omission. Here is the jot approach to the problem.

    annotate_recovery_file.jot

    $ jot recover_now.jot -in=%r=annotate_recovery_file;
    

    This script has two main uses;

    The script reads the recover_now.jot script (this is generated by recover.jot, see also about not losing your work) and displays it in a vertically-split window with the recovery file in the righthand slice and the linenumbers and annotation in the left. Note that the recovery script contains escape sequences and this script is intended to simplify the manipulation of these scripts by showing the functions attached to the key codes in the recover_now script.

    $ jot <fileName> -st=recover -norun
    

    It is recommended that the recovery script be run with the -norun option - this exits immediately after creating the recover_now script.

    You should now be the proud owner of a recover_now.jot script. Run this now (as described in recover.jot) and you should be in the same position as you were when the original session stopped.

    However, since you are editing the recover_now script you are having problems with the recovery or, maybe you just want to let it run until some mistake was made in the editing - jot does not have an undo function. Now the recovery script contains the escape sequences picked up by the original session and, just looking at these, it is not always easy to see what's going on.

    recover.jot Restrictions

    A simple editor session will involve only one file and will not involve any interactions with other files or the system.

    More complex sessions can be problematic ... essentially the difficulty is that we tend to browse around text buffers and menus using cursor-control keys rather than searching. If a menu (say a list of files generated by get.jot) has a different number of entries because files have been added or removed from that pat of the filing system, then the recovery session might end up picking the wrong item.

    In most cases, problems can be wriggled around by editing the recover_now.jot script and restarting as described above.

    $ jot <fileName> -startup -init="%r= -asConsole ./recover_now.jot"
    

    Recovery notes

    32 18<<MOUSE>> -- The event position was line 32, column 18 in buffer ( . )

  • If it reads a file to a buffer then a copy of the file is saved in the journal file and the following entries are made in the history file - in this case the original command was "%iq=x.lis":

  • %iq=x.lis
    %%Recovery pathname:  32 l99.t.jnl//x.lis_20220417_114221, Original pathname:   5 x.lis
    

  • If the original session interrupted a long-running command, the recovery session uses the command counter to replicate the exact point where the interrupt struck. This is an example with an endless loop:

  • (r, m, m-0)0  
    
    <<INT 27745818 0>>

  • Now, it is not always the case that there are no lines of history separating the command from the interrupt line. In many cases the commands are buried in some complicated macro or function but this is an example of why the recovery session needs to know this:

  • %qz=file .; z. (r, m, m-0)0
    %%Recovery record:                  Name = "."
    %%Recovery record:                 inode = 410
    %%Recovery record:                  Mode =  40755
    %%Recovery record:                   uid = 1000
    %%Recovery record:                   gid = 1000
    %%Recovery record:                  size = 2920
    %%Recovery record:  writable by this UID = yes
    %%Recovery record:             directory = 1
    %%Recovery record:                  link = 0
    %%Recovery record:           Access time = 2022/04/17, 13:04:03 (1650197043)
    %%Recovery record:           Modify time = 2022/04/17, 13:16:42 (1650197802)
    %%Recovery record:         Creation time = 2022/04/17, 13:16:42 (1650197802)
    
    <<INT 32317555 12>>

    ...

    cerr.jot

    > cerr{F2}

    This picks up a compiler report and defines macros 3 and 4 which allow you to step between error or warning reports in the C source.

    For this to work you must have the C source file in the current buffer and the compiler report must be in the same directory and with the same filename as the source but with the .lis name extension.

    The script uses line numbers picked up from the compiler report even if the actual line numbers have shifted because of changes already made to the source file. The report linenumber is adjusted linenumbers to compensate for lines added or removed before the current line. This only works if your compiler reports problems in line-number order.

    The current version of cerr.jot will work with the output from either gcc or microsoft cl compilers.

    do.jot

    > do <CliCommand>{F2}

    This simply performs the shell commands and it's arguments, the result is read back into the @ buffer.

    ls2list.jot

    > ls2list{F2}

    Transforms the output of a unix ls -laRF listing to a list of paths for multi_do.jot, multi_ed.jot etc.

    multi_do.jot

    > multi_do <cmd1>[ $1 | <cmd2> ... [ -quick]]

    This script assumes that the current buffer is a list of pathnames. It takes a CLI command as it's argument this is applied to all files in the list and the results are captured in the @ buffer. See also ls2list.jot.

    Examples:

    $ ls $JOT_RESOURCES/*.txt | jot_dev -in="%r=multi_do cat \$1 | sed s/ and / AND / -quick"
    $ ls $JOT_RESOURCES/*.txt | jot_dev -in="%r=multi_do cat \$1 | sed s/ and / AND /"
    

    multi_pair

    > multi_pair <shell command>{F2}

    The multi_pair.jot script applies pairs of arguments (typically pathnames) to a unix command requiring two arguments - e.g cp, ln, mv, diff etc.

    This requires the current buffer to contain a two-column tab separated table, each entry being a pathname. The Unix command is applied to each pair of pathnames in turn. This is only useful for unix commands which apply to two pathnames.

    Typically, you start off with a list of pathnames (derived, perhaps, using 'ls2list.jot') then copy, filter and modify each path to obtain the secondary pathname.

    It works by creating a temporary command file containing the expanded command string for each pair of operands. The generated script is written for bourne shell and, consequently, multi_pair will not work in windows environments.

    This example demonstrates multi_pair used with ls2list.jot to compare the contents of two directory subtrees.

    $  mkdir test; cd test
    

    Copy the resources tree to the test directory

    $  cp -R $JOT_RESOURCES/* .
    

    Compare all files with their originals - here, each pathname has been copied and modified by prefixing it with '\t$JOT_RESOURCES/':

    $  ls -aRF | jot -in="%r=ls2list; (rr-n.r0aa&i:\t$JOT_RESOURCES/:ham)0 %r=multi_pair diff"
    

    Now change a local file and one deeper down the tree.

    $  jot l99.t -in=f/__50/s/zzz/ %c
    $  chmod u+w test_get/another_dir1/t.t; jot test_get/another_dir1/t.t -in=f/jon/s/zzz/ %c
    

    This time diff should find two changes:

    $  ls -aRF | jot -in="%r=ls2list; (rr-n.r0aa&i:\t$JOT_RESOURCES/:ham)0 %r=multi_pair diff"
    

    multi_ed.jot

    > multi_ed[ -use <key1> <key2>][ -command <jot commands>]{F2}

    This script requires that that the current buffer is a list of valid pathNames. It prompts you for a series of jot commands, when you've finished entering the jot commands, the complete set of jot commands is applied to every file in the list.

    This script picks up your specified commands and constructs a command macro to execute these commands for all of the files in the list (in the @ buffer, by default). This macro reads each of the files in turn to a working buffer (!, by default) where the commands are run.

    If no -commands list is given, it prompts you to give it some, theses commands may extend over several lines, the list of commands is terminated with a line containing only a colon ':'.

    Note - many command scripts us either or both of the default working buffers used by this script, to wriggle around this problem, the -use <key> <key> qualifier allows you to nominate an alternative pair of buffers. Typically you should chose a pair of buffers in the range A to Z, since jot scripts normally avoid these.

    Also use the -command qualifier to specify commands from the command line.

    Note that multi_ed does not write out anything so, if you want to write the modified files, the last command must be %o.

    e.g If this these are the commands we want to run:

    > f/chapter/l0i/1 /{Return} > doc2fold{F2} > %o{Return}

    We want to apply the same process to a list of pathnames, in this example they are generated by ls, processed by ls2list and filtered to extract just .doc files:

    > %ep=ls -laRF{Return} > ls2list{F2} > m-0 (r0v-/.doc/m,k)0{Return} > multi_ed -use q w -command f/chapter/l0i/1 / %r=doc2fold; %o;{F2}

    or something like this, starting from a unix prompt:

    $ ls *.doc | jot
    

    then, in jot:

    > multi_ed -use q w -command f/chapter/l0i/1 / %r=doc2fold; %o;{F2}

    sync.jot

    Synchronizes a memory stick and the main filing system by copying recent versions of files.

    $ jot -st=sync
    

    or

    $ jot -st="sync[ -check|tostick|fromstick][ -bydate][ -newstick][ -newfs][ -localpath <path>][ -debug][ -setstick][ -newfs]"
    

    By default, sync.jot synchronizes selected directories in the local the local filing system with a memory stick.

    By default sync.jot is driven by differences in file datestamps. A similar file tree exists both in the local and in the stick, when sync.jot detects an instance of a file with different datestamps then it copies the newer version to replace the older one.

    So what can possibly go wrong ... er well, the datestamps on linux memory sticks are not very reliable. The datestamps are frequently frequently one second earlier than the corresponding datestamp in the main filing system. Also, following a change to daylight-saving time datestamps there could be a one-hour discrepancy in the datestamps. It deduces the time the local and stick trees were updated by placing special tag files (named syncTimeTagFile) in you're home area and in the tom directory of the memory stick.

    The sync.jot script has the directory tree hard coded inside - to change this you need to change the coding.

    There are some sync.jot features designed to avoid problems with memory-stick datestamps.

    Other options:

    ced.jot

    Compiles a development version of the jot editor for linux (using gcc) or windows ( using cl).

    $ jot -st="ced [-lin][ -win][ -notest][ -preproc][ -debug][ -dynamic][ -strip]
    

    This compiles a jot executable. The linux compiler is gcc with gnu libraries. The windows compiler is cl (part of VC) with VC libraries.

    retab.jot

    > retab[ <string>]{F2}

    Searches the entire buffer for the given string, when found, the first instance of the string in any line is prefixed with a tab character. Also removes any whitespace adjacent the inserted tab. Note that jot displays tabs, along with other control characters are displayed as tildes ( ~ ).

    This script is intended for use as a precursor to autotab.jot, autotabjust.jot, autotabdp.jot - see tabulated text.

    retabhere.jot

    > retabhere{F2}

    This inserts tabs in the current-character column. This is used in conjunction with retab.jot, autotab.jot and autotabjust.jot.

    This script is useful for preservation of one column of a partly-formatted table - see tabulated text. If you have several tab points to insert, it is important to start with the rightmost tab point and work leftwards.

    autotab.jot

    > autotab{F2}

    Aligns tab points in a buffer.

    This operates by searching the buffer for lines containing tabs, it locates the leftmost tab character on each line and finds the rightmost first tab. The position of the rightmost first tab defines the tab points for all the other first tabs.

    It then replaces the first tab on any line with sufficient whitespace to align the text following the first tab on any line.

    Lines which do not contain any tabs are ignored - see tabulated text.

    autotabjust.jot

    > autotabjust{F2}

    Similar to autotab, but right-justifies so that, on any line containing tabs, the following tabs are aligned - see tabulated text.

    autotabdp.jot

    > autotabdp{F2}

    Similar to autotab but inserts blanks so as to align decimal points in the column following the tab - see tabulated text.

    tab.jot

    > tab[<n>]{F2}

    Resolves all tabs to the specified tab spacing - defaults to 8.

    mail.jot

    > mail[ -FOlder <folderName>][ -Last <n>][ -FINd <string>][ -New][[ -File <MailPathName>]{F2}

    Usage example

    jot -in="%r=mail -file=${JOT_RESOURCES}/mail"

    Defined escape sequences

    <list> {Esc+m} - send current buffer as mail using "To:" , "Cc:" and "Bcc:" lines

    [<CClist>] {Esc+r} - reply to sender [and users on CC list], if list contains a '*'

    [<n>] {Esc+i} - include indented current [or nominated] message, in current buffer

    This script is not really seriously intended to be used as a general-purpose mailer. However with the mail handling agents correctly set up for a local POP mail file it can read and send mails. It may be useful to users of MUTT or similar POP-based mailers as a means of integrating with an editor session.

    This script sets up a simple Mail User Agent (MUA) - a programme that reads from a POP file and constructs a mail index. POP (Post Office Protocol) is a simple text-based format. This POP file is generally created by your Mail Delivery Agent (MDA) working with your Mail Transfer Agent (MTA) which interacts with your mail provider.

    Linux users should set up their MDA to deliver in POP3 form to /var/spool/mail/<yourUserName> a reasonably simple and robust setup involving fetchmail and procmail is described in http://www.andrews-corner.org/mutt.html You can test your setup using mutt - a useful text-based MUA.

    The POP-file image and mail index are held in the * buffer, to return to the mail index, type in the z* command.

    Mail adds the following control functions:

    <list> {Esc m} - send (Mail) current buffer using "To:" , "Cc:" and

    [<CClist>] {Esc r} - Reply to sender [and users on CC list], if list

    [<n>] {Esc i} - Include indented current [or nominated] message, in

    {Esc a} - Autograph - add the autograph message to the current

    c.jot

    > c[ -tag]{F2}

    Redefines macros 1 and 2 (bound to numeric-keypad 1 and 2) to functions suitable for browsing C code. It is reasonably bulletproof but it will fail to set up the hashtables when it finds a mismatch in the curly-brace structure of your coding. Note that c.jot has no knowledge of what compile-time variables are set - it assumes #ifdefs are TRUE. Hence c.jot can fail to match braces even valid C when braces are inside #ifdef (etc.) blocks.

    Once set up, macros 1 and 2 (numeric keypad buttons 1 and 2) will first create a block index for the current c function. With the index set up, the 2 macro will locate the next block-start character '{' in the c code or, if already at a block-start, will locate the corresponding block-end character '}'. Similarly, macro 1 will locate the move back in the c code to the nearest block-end character or, if already at a block-end, move to the corresponding block start character.

    The optional -tag qualifier adds colour tags to comments.

    It also sets the env variable GetDefaultPath to /usr/include - the effect of this is to tell the get.jot script to default to the specified path, with this set you can set the cursor to a library include file and it will find it.

    The speedup due to the hashtables, although welcome, is not really the principal motivation for their use. Because C allows multi-line comments and text strings, it is difficult, perhaps impossible, to reliably parse C when plodding back through the code. The c script plods forwards once to get forward and back links for the hashtable.

    jot.jot

    > jot{F2}

    Sets up macros 1, 2 and 3 (bound to numeric-keypad 1-3) to functions suitable for browsing jot command scripts. As with the c.jot script, it uses hash tables. Jot code is another one of those difficult ones where it's difficult to plod back through the code.

    In interactive usage, unterminated strings are allowed - e.g. f/fred{Return}, jot also allows these in macros although this is not recommended. When one of these is left unterminated in a script it is generally a coding mistake, but it might lead to the jot command parser being unable to match parenthesis. Such errors are difficult to trace. Use {* KP_3} to locate unterminated strings in your scripts.

    Note that jot.jot adds tags to the code, this will cause code called via the %H=call command to fail when it is next recompiled. See Calling functions by name.

    perl.jot

    > perl{F2}

    Defines macros 1 and 2 (bound to numeric-keypad 1 & 2) assigning functions suitable for browsing perl code.

    Normally, macro 1 should be started with the cursor over a block-end brace (a '}'} or ']' character) or over whitespace to the right of one. If started with the cursor at some other point, the macro locates a suitable start point and stops - you need to check the chosen start point and press the '1' key once more.

    Similarly, macro 2 matches to the current open-brace character or the whitespace immediately before one, if the cursor is over some other character, it locates a suitable start point and stops to let you check before restarting.

    skill.jot

    > skill{F2}

    This is one for users of Cadence design frameworks interface language (skill) - a lisp-like language.

    Defines macros 1, 2, 3, 4 and 5 (bound to numeric-keypad 1-5) assigning functions useful for browsing skill code. The functions dedicated to skill keywords recognize the following skill keywords: if, when, unless, foreach, for, while, case, cond and procedure

    csh.jot

    > csh{F2}

    Redefines macros 1, 2, 3, 4 and 5 to functions suitable for browsing C-shell scripts (these macros are normally bound to Numeric-keypad buttons 1, 2, 3, 4 and 5 respectively).

    In the context of a C-shell script, a block is a series of commands controlled by some recognized C-shell built-in structure. The following structures are supported:

    The following macros are defined:

    sh.jot

    > sh{F2}

    Redefines macros 1 and 2 (bound to numeric-keypad 1 and 2) to functions suitable for browsing Bourne-shell scripts.

    Both functions work by counting block depth, there is no checking of block-start to block-end keyword-consistency, e.g. an 'if' block terminated by 'end' is matched without complaint.

    ksh.jot

    > ksh{F2}

    Similar to sh.jot but supports some additional ksh keywords.

    mif.jot

    > mif{F2}

    Sets up macros 1, 2 and 3 (bound to numeric-keypad 1-3) for browsing mif files.

    edif.jot

    <P>edif{F2}</P>

    Sets up macros 1, 2 and 3 (bound to numeric-keypad 1-3) to functions suitable for browsing edif files.

    verilog.jot

    > verilog{F2}

    Sets up editor for navigating verilog files.

    Restrictions/Assumptions:

    No line breaks between the end of a netname and the ')' in an instance-terminal connection.

    the '0 macro assumes a flat netlist - leads to problems when a signal name exists in more than one module.

    Assumes the hierarchy delimiter to be "|".

    Buffer usage:

    0 - Command macro to find other instance terminals on a net. @ - Journal of net names visited. + - In '0 macro holds list of Instance-terminals visited by the net.

    $ - Temporary names,

    HotKeys

    Esc-d descends into the definition of the current module.

    <netName>Esc-n - descends hierarchy and locates first instance terminal on the net.

    <instName>Esc-i - descends hierarchy and locates the first instance-terminal in the instance.

    0 - Makes list of instance terminals, then moves to selected inst term.

    vhdl.jot

    > vhdl{F2}

    This sets up macros 1 to 5 (bound to numeric-keypad 1-5) to functions suitable for browsing VHDL files.

    Notes and restrictions:

    tcl.jot

    > tcl{F2}

    Sets up macros 1, 2 and 3 (bound to numeric-keypad 1-3) to functions suitable for browsing edif files.

    bt.jot

    > bt{F2}

    This script is useful when debugging complicated modular jot scripts. It sets up some backtrace functions using the query backtrace report.

    > {Esc b t}

    trap_failure.jot

    > trap_failure <commandSequence>[ -init=<initializationSequence>]{F2}

    or

    > trap_failure [ -init=<initializationSequence>]{F2}

    This script can be useful for debugging scripts, functions and commands. When something fails it's not always immediately obvious what went wrong. This script runs the command sequence (or macro or function) through to failure, notes the command counter and then re-launches the command with the command counter set to trigger a breakpoint at the point of failure - see the jot debugger and %s=commandcounter.

    Note that, in order to get a repeatable command count, the initialization must be consistent. Many initialization command sequences can just be included in the command sequence but, where the initialization involves conditional commands this might not be the case and a separate initialization sequence must be specified using the optional -init=... modifier.

    See setting command-counter breakpoints for examples of usage.

    searchbuffers.jot

    > searchbuffers <delim><string><delim>{F2}

    This searches all buffers for the string, results are presented in the form of a list of buffers where a string match was found. In each buffer where the string-match was found, the current line is set to the first matching line, for other buffers the current line ends up being the last line of the buffer.

    listbufs.jot

    > listbufs[ -demo][ -all][ -system][ -changed]{F2}

    age.jot

    > age{F2}

    Tells you the age of the file in the current buffer. Note that it takes no account of leap years - each year is assumed to be 365 days. Hence, for files older than one year, the day-count is less than totally accurate.

    date.jot

    > date[ -Rev][ -Time]{F2}

    Inserts the current date at the current-character position in the text. If there is a substring, then the selected text is replaced by the current date.

    If the -r qualifier is given, the date section is reversed and the separating slashes removed.

    if the -t qualifier is given, then also inserts current time.

    backup.jot

    > backup [<comment>|-again]{F2}

    This script makes a backup copy in the <path>/backup subdirectory, where <path> is the path element of the file being backed up. It also maintains a README_backup file in the same area, this contains the comments.

    Before doing anything the script checks for existence of <path>/backup if it does not exist, the script fails immediately with a suitable message.

    The buffer is written to the backup area with it's normal name suffixed with '_<dateStamp>'

    The script insists on being given either a comment or the -a modifier, this is included in the metadata in the README_backup file in the backup subdirectory. If -a (again) is given it inherits the datestamp and comment from the last entry in the same README_backup file.

    copy.jot

    > copy{F2}

    Copies all of the current buffer into the X-windows PRIMARY selection buffer (see the xsel (1x) man page for details). This is useful for exporting an entire buffer to some x application.

    N.B: This script requires the unix utility xsel to be on your search path and, it kind of goes without saying really, copy.jot does not work in windowsland.

    paste.jot

    > paste[ <key>][ -here]{F2}

    If neither the destination buffer or -here is specified it prompts for the destination buffer.

    If the destination buffer is specified then the contents of that buffer are replaced with the contents of the x-windows paste buffer.

    The current contents of the X-windows PRIMARY selection buffer buffer is inserted into the nominated buffer (see the xsel (1x) manpage for details). If -here is specified then it is inserted at current character position of the current buffer.

    N.B: This script requires the unix utility xsel to be on your search path and, it kind of goes without saying really, paste.jot does not work in windowsland.

    count.jot

    > count{F2}

    Counts the number of words in the current buffer.

    This script predates the ability to pipe the current buffer into a unix command - the unix wc command should do the job just as well:

    > %e$=|wc;

    unlockall.jot

    > unlockall{F2}

    Goes to every buffer activated in your session and sets the write lock to unrestricted.

    freeall.jot

    > freeall{F2}

    Unlocks and then deletes all buffers.

    exit.jot

    > exit{F2}

    Frees all buffers then exits the editor without saving any files.

    doc2fold.jot

    > doc2fold{F2}

    This translates a document to a folded help document suitable for use in the jot help system. The document sections and paragraphs must be structured according to the jot document form - see text document preparation and about help files.

    fold2doc.jot

    > fold2doc{F2}

    This performs the reverse of the doc2fold.jot process, it is only useful when a help file requires major changes and the original source document is not available - see also about help files.

    doc2mif.jot

    > doc2mif{F2}

    Translates the text in the current buffer into a framemaker mif file - sections and paragraph format - see text document preparation

    txt2html.jot

    > txt2html[ -style <styleSheetPath>][ -tablinks][ -noLinks]
             [ -split [ -head <fooheadterImagePath>][ -foot <footerImagePath>][ -index]]{F2}
    

    Translates the text in the current buffer into html.

    Any text in backticks is assumed to be a hyperlink - several forms are supported:

    For example, the following line (from the examples text), refers to functions defined at startup and key bindings.

    HREF references are checked - these must match a section heading either in the current document or in some other html in the same directory. If, after searching these, it still cannot resolve the HREF then the HREF target is added to a list of unresolved HREFs and the script terminates without writing any html.

    If the document contains more than one section with the same section-name string, then this is listed and the script terminates without writing any html.

    pdf2txt.jot

    > pdf2txt <pathName>{F2}

    Extracts text from a PDF document, extracted text is appended to the current buffer.

    doc2txt.jot

    > doc2txt <pathName>{F2}

    Extracts text from an MS-word document, extracted text is appended to the current buffer.

    txt2

    > txt2help{F2}

    Transforms an jot doc-format document into a folded-help file suitable for including in the jot help system.

    html2txt.jot

    > html2doc [{-url=<url>|-seturl=<url>|-raw=<pathName>|-list}]{F2}

    or (from the CLI):

    $ jot [listPathName>] -in="%r="html2txt [{-url=<url>|-seturl=<url>|-raw=<pathName>|-list}];"
    

    Transforms an html document or a simple list of documents) to the jot text-document format. Some examples:

    > html2txt[ -url=<a valid URL pointing to an html>]|{F2}

    or

    $ ls ~/Downloads/* | jot -in="%r=html2txt -list;"
    

    The -list qualifier causes the plain-text translations of each document to appear as a separate chapter appended to the original buffer.

    Note: the list is terminated by the first blank line.

    The html2txt.jot script defines two functions and two macros, it also uses pdf2txt.jot and doc2txt.jot to define functions pdf2txt_translate and doc2txt_translate respectively. It also uses curl to download references.

    Note that it can only descend into referenced documents for simple web sites

    dic.jot

    > dic{F2}

    This looks up definitions of words using the gutenberg.org version of the websters dictionary. You must first download a copy of the dictionary from the Gutenberg project www.gutenberg.org

    and save it in your JOT_RESOURCES area naming it websters.txt

    When you run dic.jot for the first time an index file is written to your JOT_RESOURCES area - you must have write access to this area. The index file is named ${JOT_RESOURCES}/websters_index.txt it is plain text file, about one tenth the size of the actual dictionary (about 2.2Mb compared to about 28Mb for the complete dictionary). The index file structure is a bit more complicated than the index files used by big_file.jot - it has an explicit entry for the length of each section.

  • It may take a while to digest the dictionary, once that's done an index file is written to your resources area and you should never need to do it again. In any jot session you can now launch a query as follows:

  • > dic{F2} > <word>{{Esc 7}

    big_file.jot

    Typical usage, launched from the shell command line:

    $ jot -in="%r=big_file -file=<pathName>[ -size=<n>][ -all][  -cdlIndex|-vlogindex]
    

    The big_file script will collect sections in the primary buffer ( . ) this buffer also hods the big_file hashtable.

    Or, it can be launched from a jot session from any empty buffer, this buffer will be used to collect sections of the big file, the big_filehashtable is still created in the primary buffer ( . ):

    > big_file [<options as above>]{F2}

    The big_file script defines the following escape sequences:

    This script is designed to facilitate browsing and, to a limited extent, editing of very large files (see about large files). It works on the assumption that nobody's ever going to want to look at all of some huge file and that these files are structured and sections and that each section be identified by a unique name. The file is first scanned to create a section-name index which can be read by the editor. The user can then interactively pull sections into the editor session.

    If there is some text before the first section listed in the index, this is assigned the section name "Initial_gumpf" to make it accessible.

    In practice, grep, or something similar, can be used to create the index, this task can be performed in advance, maybe as part of the batch job that created the big files. The jot session reads the index file, and responds to interactive requests to view named sections of the big file by pulling them into view. The index provides jot with two values a byte-count offset to the start of the section and a byte-count length of the section. It uses the offset and byte-count to read these sections using the -seek=<value> and -bytes=<value> %I qualifiers.

    The index file can be prepared earlier and read from disc or it can be generated as the session starts up. The index file is marked with with the big-file's original datestamp. When the index file is contains this datestamp the big_file.jot script can detect situations when the index is out of date e.g: the big-file has been re-extracted or edited in some way.

    The optional -index qualifier specifies an index-file pathname - this defaults to the big-file's pathname with "_index" appended. The script uses the index file to reference your big file.

    If either the -grep=<Rex>, -vlogindex or cdlindex qualifiers are given then the script will generate a new index file, even if the file already exits. Otherwise it fails if the index file does not exist.

    The -grep qualifier is grep command string that can be used to create a new index file with the appropriate datestamp mark. The -trim qualifier specifies some jot commands that transform a line of raw grep output to a usable entry for the index file. Typically grep outputs three colon-separated fields - linebumber, byte startpoint and the matching line. The trim command is required to reduce the matching line to a useful key.

    The script defines these functions:

    e.g:

    > fred{Esc b q}

  • bf_grepQuery - searches the main file for the specified string and calls bf_simpleQuery to read each one of the matching sections.

  • > <string>{Esc b g}

    e.g:

    > VDD_1234{Esc b g} -- this might load all subcircuits touching the net VDD_1234

    The index file is used to create hashtable entries for the named sections which can then be accessed reasonably quickly using the -section=<key> qualifier of the %I command.

    The index file contains a one-line header followed by any number of one-line entries - one for each for each section in the file.

    The header line specifies the index creation time, f the file is found to be later than this, the index is deemed to be obsolete and is rejected.

    Each section entry has three colon-separated fields.:

    <StartLineNumber>:<startByteNumber>:<key>

    multi_file.jot

    > multi_file[ -index=<pathName>][ -indextype=<type>][ -htabsize=<n>][ -destbuf=<key>]{F2}

    or, a more typical usage, from the shell command line, to create a new index:

    $ ls -aRF <rootDir> | jot -in="%r=multi_file [ ... ]"
    

    or, to use an existing index:

    $ jot -in="%r=multi_file[ <options as above>"
    

    There is an example at first with multi_file.jot index files (a subsection of working with collections of source files).

    The multi_file script is intended for browsing large collections of source files belonging to some system see about large collections of files. Selected sections are read into a buffer for viewing - typically the sections will correspond to programming-language modules. These are typically referenced by module name.

    The optional arguments are:

    The script define these functions:

    Usage:

    > <sectionName>{KP_7}

    or, if you're lacking a numeric keypad:

    > <sectionName>{Esc 7}

    Passes the section name to multi_file_simpleQuery. If successful, the module text is appended to the primary buffer.

    > <string>{KP_8}

    or, if you're lacking a numeric keypad:

    > <string>{Esc 8}

    Passes the string to multi_search_section_names, this searches all the valid keys for any matching the string. The matching process is pretty crude - it obtains a list of keys and then filters out lines that don't match the string. Note that queries using the strings Byte, Section, Seek or any other strings that appear a lot in query keys reports are going to return lots of results.

    Note that there is no facility for writing back modified versions of these files from a multi_file session - you must load the relevant files normally, in a separate buffer, then make your changes and write the complete file.

    As with big_file.jot, multi_file.jot is driven by user queries and an index file. In this case, however, the files will normally be of moderate size but there may be hundreds of them with each one defining dozens of sections.

    In the event of a name collision, the first instance of a name, as it appears in the index file, is taken as-is. Subsequent instances are uniquified by suffixing the name with __nnn, where nnn is the index-file line number for the duplicated name.

    ctags.jot

    $ jot <tagsFile> -in=%r=ctags;
    

    and

    $ jot <tagsFile> -in=%r=ctags -AtoZ;
    

    There is an example in now a ctags-generated index (a subsection of working with collections of source files).

    Exuberant Ctags is a GNU tool that generates source-code index files except that these are, for reasons unknown, called tags files. Anyway these function as index files and can be picked up by jot using this script. The script was developed and tested using ctags files generated by ctags 5.9, this announces it's _TAG_FILE_FORMAT as being type 2. The ctags.jot script therefore performs a similar function to multi_file.jot

    Once it has read and inwardly-digested the ctags-generated index you can launch queries using macro ( 7 ), which is bound to key 7 on the numeric keypad ( {KP_7} ). If you do not have a numeric keypad or, if you have not set it up for jot (see X-windows setup) then Escape followed by 7 {Esc 7} will do. There is an example exercise - see working with collections of source files and now a Ctags-generated index e.g:

    $ jot -st=dbg ${JOT_HOME}/source/tags -in="%r=ctags;"  
    
    > SubstituteString{Esc 7}

    This opens an editor view of source file ${JOT_HOME}/source/jot.c and sets up the view to the start of the function SubstituteString.

    > FreeTag{Esc 7}

    In the same editor buffer it changes view to the start of the c function FreeTag.

    ctags.jot reads the ctags-generated index file and defines a macro which takes an index-key and checks to see if it already has the relevant source file in memory. If not, the source file is read before the editor focuses to the start of the relevant section.

    If you have more than a handful of source files in memory, you may find it helpful to run the listbufs.jot script especially with the -changed option, this reports the status of file images in jot buffers.

    Without the -AtoZ qualifier, the script will always display the requested definition in a secondary buffer - that is a buffer created on the stack, with the buffer key ( ~ ). This allows the session to hold and display any number of source files but, in the general case, it's not possible to switch between them.

    In contrast, with the -AtoZ qualifier, the source files are read into buffers A, B, ... Z, this limits the number of viewable files to 26 but navigating between them is quick and convenient. For collections of 26 files or less, the buffer keys are allocated at the start of the session, then all sessions using the same ctags index will have the same, fixed, buffer-key assignments.

    If, however, there are more than 26 source files but you won't need to view more than 26 but maybe this doesn't matter since keeping track of more than 26 source files in a session would take some doing. The buffer keys are allocated at query time - the first will be ( A ), then ( B ) ... to ( Z ).

    This script may be combined with ide.jot if desired.

    thes.jot

    > thes{F2}

    This reads the Gutenberg Ebook version of Roget's thesaurus and sets up a simple macro to process queries. It reads the Ebook from ${JOT_RESOURCES}/thesaurus.txt, this can be downloaded from the gutenberg project - www.gutenberg.org.

    The query macro expects a list of words, it then returns all Roget's sections which contain all of the given words, the results are in the @ buffer.

    duplicates.jot

    > duplicates{F2}

    The current buffer is searched for duplicated lines, starting from the current line. The script halts at a duplicated line or the end of the buffer.

    purge.jot

    > purge[ -rev | -count]{F2}

    The current buffer is searched for duplicated lines, starting from the current line. Duplicated lines are removed leaving just the first instance of each unique line of text.

    If the optional qualifier -rev is given, then it is the unduplicated lines that are removed.

    If the optional qualifier -count is given then the number of purged duplicate lines is appended to the undeleted lines separated by a tab character.

    mc.jot

    > mc[ -size=<width>x<height>{F2}

    mc is useful for scanning through long files with very short lines. Such files are reasonably common when maintaining IT system files and CAD files etc - but it's not usually much use for viewing natural language documents.

    The mc script calculates your window size and then chops up a copy of your buffer into columns to fill the display. You may be more interested in printing the multicolumned text in which case the size of the window is irrelevant - you can specify the size of your paper with the -size qualifier.

    The script also defines macro 1 and macro 2 as page-up and page-down functions, respectively. The standard page-up and page-down functions are not suitable for viewing the mc result buffer.

    e.g:

    $ jot ${JOT_HOME}/docs/spell.dic -ini="%r=mc"
    $ ls /usr/lib64 | jot -ini=%r=mc
    $ ls /usr/lib64 | jot_dev -ini="%r=mc -size=80x90"
    

    mc2.jot

    Similar to mc.jot except that it always splits the page int two columns.

    mc3.jot

    Similar to mc.jot except that it always splits the page int three columns.

    mc4.jot

    Similar to mc.jot except that it always splits the page int four columns.

    mc5.jot

    Similar to mc.jot except that it always splits the page int five columns.

    mc6.jot

    Similar to mc.jot except that it always splits the page int six columns.

    expand_verilog_busses.jot

    > expand_verilog_busses{F2}

    Locates verilog busses of the form name[start:end] (where end < start), and replaces them with fully-expanded form

    findcol.jot

    > findcol<delim><string><delim>{F2}

    The current buffer is assumed to be text written written vertically top-to-bottom. The current column is searched for the string.

    find

    > findhelp <string>{F2}

    The ${JOT_RESOURCES}/help tree is searched for the string, results appear in the help menu buffer.

    This uses the unix find and egrep commands, this search is always case insensitive.

    hex2ascii.jot

    > %i ... -binary; > %r=hex2ascii

    This simple script appends a text annotation to each line in the hex dump generated by the -binary option of %I.

    Example output - this is a fragment of hex dump of the test file ${JOT_RESOURCES}/l99.t, the text "80: abc ..." was added by hex2ascii.jot notice that any nonprinting characters are represented by carats ( ^ ).

    2 1 1 A 20 61 62 63 20 64 65 66 20 67 68 69 20  80: abc def ghi                               
    3 A 6B 6C 20 6D 6E 6F 20 70 71 72 20 73 74 75 20  jkl mno pqr stu                               
    4 1 1 1 1 A 3A 30 31 32 33 34 35 36 37 38 39  vwxyz:0123456789                              
    5 1 F 5F 37 39 3A 20 61 62 63 20 64 65 66 20 67  ^__79: abc def g            
    

    updatehelp.jot

    > updatehelp[ -NODATEstamp]{F2}

    This command file is used after you've updated an entry in the help buffer (;). The current buffer must be the help buffer and the fold marks must be unchanged (these are used to locate the fold in the file). It locates the current file fold by searching for the previous file fold in the help buffer (:) then reads the file into a temporary buffer and updates it with your revised fold.

    The changes must not affect the fold structure in any way, or the script will fail.

    The updatehelp script will insert a datestamp mark near the start of the fold indicating when the change was made. The -nodatestamp qualifier will prevent it doing this

    manhelp.jot

    > manhelp <manArgs>[ -fold]

    Generates requested man page and adds it to sessions help repository.

    The manargs are passed directly to the man utility and the reply becomes a new page in the jot-sessions help repository.

    The -fold option folds sections inside the new help page.

    nonprinting.jot

    > nonprinting{F2}

    Detects any nonprinting characters in the current buffer.

    csvprop.jot

    > csvprop{F2}

    Sets up macro 3 to follow values in a tab-separated table where the first nonblank entry at the top of each column is the property name e.g (for a property named fred):

    > fred{Esc 3}

    cli.jot

    > cli <cliCommand>{F2}

    The cli script assumes that the current buffer is a file image, the file's pathName is picked up and the specified CLI (Command-Line Interpreter - or shell, in unix parlance) command is applied to it.

    path.jot

    > path <cliCommand>{F2}

    The path script assumes that the current buffer is a file image, the file's path is picked up and the specified command is applied to it.

    sccs.jot

    > sccs <sccsCommand>{F2}

    This assumes that the current buffer is a file image, it applies the sccs command to the current file.

    sort.jot

    > sort <options>{F2}

    This script uses the %b=sort command to reorder the lines in a buffer. Whereas the sort command will only sort by UTF-8 character codes (typically ASCII codes), the sort.jot script allows various alternatives.

    Optional qualifiers

    pascal.jot

    This replaces the contents of the current buffer with the first n rows of pascals triangle.

    The number of rows defaults to 30 but can be set as an argument to the script. Note that the size of the numerical values in the triangle increases very rapidly, 30 rows is about as many as can be accommodated with 64-bit integer arithmetic.

    > pascal{F2}

    print.jot

    > print[ -break]{F2}

    The current buffer is checked and, if there are no unresolved tabs or overlong lines, it is written out to a temporary file, this temporary file is printed using a2ps.

    The optional -break qualifier causes overlong lines ( >80 characters) to be broken at a suitable point.

    wideprint.jot

    > wideprint[ -break][ -preview][ -l <n>][ -1, 2, 3, ... 9]{F2}

    The current buffer is checked and, if there are no unresolved tabs or overlong lines, it is written out to a temporary file, this temporary file is printed using a2ps.

    renumber.jot

    > renumber{F2}

    The line numbers in the current buffer are reset so that the first line becomes line no. 1 again.

    timex.jot

    > timex{F2}

    Sets up macro 1 to generate an activity summary report from your titracks (formerly known as timex) files.

    trace.jot

    > trace[ <args>]{F2}

    This sets the trace-vector bits (see %s=trace) symbolically. If no args are given, it displays the options (shown below) and prompts.

    Trace bits 0x0001 to 0x0040 define the trigger points - i.e. they select which class of event will trigger a trace or other diagnostic response. Trace bits 0x1000 to 0x8000 define the desired action.

    These can be set directly - e.g. to set a breakpoint on the start of each new command line we would say %s=trace 8002 to dump the stack we would OR with 0x1000 giving %s=trace 9002 - trace.jot sets these symbolically.

    Trace arguments - trigger points:

    Trace arguments - trace actions:

    So to dump the stack and breakpoint at each new line of a script or macro:

    > trace lsb{F2}

    cal.jot

    > cal[ <year>][ -split]{F2}

    This runs the unix cal command, by default, it takes the current year.

    The result is similar to that of the unix cal command except that week numbers are prefixed before each week.

    The -split qualifier splits the output listing each day on a separate line.

    match_words.jot

    > match_words <bufferKey>[<anotherBufferKey>][<...>]][ -split][ -nosort][ -notab][ -map]{F2}

    This The object of this script is to match lists of words in various buffers. Typically, the words will be the names of objects defined in different places (e.g. file names in various directories or backup discs or module names from a linker map).

    linkdocs.jot

    > linkdocs[ -allxrefs][ -bufs <BufferKey1>[<BufferKey2>[ ...]]]{F2}

    This script identifies links in jot-style documents (see text document preparation) and add colour tags, hashtables and sets up a mouse-event handler to allow clicking through the links.

    The -bufs qualifier introduces a whitespace-separated list of buffer keys, these are the buffers to be analyzed. If -bufs list is not given, then it analyses the primary buffer ( . ) and all buffer with an alphabetical buffer key (a, b, c ...).

    The -allxrefs matches references to headings in all text - by default it only matches to cross-references enclosed in backticks.

    Macro_1 is defined for users without mice - first navigate the cursor to a link (or a non-link if returning) then {Esc 0}

    The list of buffer keys specifies the buffers containing suitable documents, if this list is not given then linkdocs inspects each buffer in the range A-Z and processes those which appear to have doc-style section headings - see text document preparation.

    A good example to try would be the jot user documents:

    $ jot ${JOT_HOME}/docs/jot_qr.txt -in="%it=jot_tech; %ic=jot_coms; \
    

    The file images are displayed normally except that links are highlighted in green (unresolved links are highlighted in red). Clicking the left button with the mouse over over a green link will switch context to that section.

    The linkdocs script also checks for obvious errors such as duplicated headings and unresolved references. If any are detected, the script displays these in buffer ( ; ) and invites the user to hit return to continue.

    See also qr.jot

    time_trial.jot

    $ jot -in="%r=time_trial [ -tasks <taskSpec>]
    

    [ -logfile <pathName>][ -append][ -viasvim][ -small| -tiny];"

    Runs execution-time trials for a selection of editors. Each of the editors is given a selection of simple tasks, the script reports the elapsed times for each editor/task.

    iconv.jot

    > iconv [<PathName>[<BufferKey>]]

    or from a unix prompt:

    $ jot <pathname> -in=%r=iconv
    

    This uses the linux utility iconv to convert a UTF-n file to UTF-8 that jot can read and display. It uses the iconv utility to create a temporary version in /tmp/... and then reads the converted file into the specified buffer.

    If the buffer is not specified it reads the converted file into the current buffer. If the pathName is not specified then it assumes the current-buffers file requires converting and rereading.

    It defines macro '4, this will write the file back to it's original pathname and in it's original format.

    See also practicalities of unicode etc. and jot

    bookings.jot

    $ jot ${JOT_RESOURCES}/resources.txt -in="%r=bookings -mail=${JOT_RESOURCES}/mail -resource=The House"
    

    This is an application designed to simplify the process of maintaining a bookings register for a holiday let or some similar resource that's hired out on a weekly basis. One of the worst things that can happen, apart from getting the place totally trashed, is a double booking. This app is designed to provide strict control of the bookings calendar and the associated database to prevent double bookings keep track of payments and client details etc.

    Although few jot users will actually require such an application, it is a useful example of how to implement similar interactive applications. It maintains various different views (e.g. the calendar, the accounts table, emails and various lists relating to each booking. These views are linked by hash-tables and tags containing metadata (typically hashtable keys).

    Looking at the calendar (in buffer C) we notice that it's organized from Saturday to the following Saturday - this is because the letting week starts Saturday afternoon and ends the following Saturday morning - that's because Saturday is the default changeover day.

    The changeover day is an important day in the world of holiday letting. It's intended to give the previous weeks guests time to pack up their things and get off home while also allowing the incoming guests time for their travelling and getting themselves organized as well as giving the housekeeper a chance to prepare the house for the incoming guests.

    Many operators chose either Friday or Saturday for their changeover day - bookings.jot defaults to Saturday but can be set for changeover on any other day of the week.

    The most important document is the resources.txt file - this contains a list of resources (e.g. properties to let) and, for each resource, an accounts table and bookings, each consisting of lists of emails and notes relating to the booking.

    The bookings system also has a simple Email reader. Although this lacks even the ability to send emails, it can still be useful because incoming messages are integrated into the bookings system. It is assumed that most users will be using a modern webmail mailer based on a remote imap server, bookings.jot uses a local POP mail file. POP is a simple plain-text file containing mail messages. In most cases this will be copied from the remote imap server using a mail-retrieval agent (MRA) such as fetchmail. Messages are then assembled in a POP mail file using a mail delivery agent (MDA) such as procmail. See http://dev.mutt.org/trac/wiki/MailConcept for a basic description of how this works and http://www.andrews-corner.org/mutt.html for a description of how to set up your MRA and MDA.

    Buttons and Menus

    At the top of the screen are two lines with mauve-tagged text - clicking on these has the following effects:

    The "Options:" menu, below, changes according to view:

    Mouse and keyboard actions:

    In any view, position the cursor onto some colour-tagged text and the following actions are defined:

    xword.jot

    > xword{F2}

    This is a little fun script primarily intended to demonstrate features of jot. It's a crossword puzzle assistant, it looks up words and phrases of a predetermined length matching various criteria.

    The words and phrases are read from the on-line Roget's (see thes.jot), these are munged into a database that's saved as xword_db.txt in your JOT_RESOURCES area. The xword_db.txt file is designed for speedy searching, altough takes a few moments to create, subsequent calls take no time to read the database.

    The query syntax is

    where

    Queries are entered using macro 4, defined by xword and attached to {KP_4}. Suppose we're looking for a 6 letter word with the 3rd. letter t and the 5th letter e - then any of these queries would identify the same set of matching words:

    > 6 3=t 5=e{KP_4} > 6 5=e 3=t{KP_4}

    Other jot scripts

    The jot installation contains more scripts of variable usefulness - they are listed here along with a brief description:

    Many are obsolete/superseded/incomplete or otherwise broken, some may serve as examples of how to perform various tasks but most are, most likely, examples of how not to do something.