How to write macros for "tkedit"

This description tries to give an overview over the special functionality which
can be used within TCL-macros for tkedit

There are three types of macros:
1. The simple "Function key" macros which can be directly programmed from
   within tkedit by simply using all available editing functions
2. "Simple" TCL-macros which do not add functions or menupoints to "tkedit"
   These macros can be assigned to "Function keys" or can be called once with
   the "Macro / Call External" function.
   They should have names ending with ".tcl"
3. Complex TCL-macros which extend the functionality of tkedit and add 
   menupoints and "procs" to tkedit. These Macros can be added to the
   "tkedit_macros" directory to be loaded on startup or they can be called by
   the "Macro / Call External" menu point to be included for a special purpose.
   All macros stored in $HOME/tkedit_macros with names ending in ".startup" are
   loaded at startup time.
   
General style:
   startup-Macros should have names ending with ".startup" in order to be found
   by tkedit at startup.
   They should also have an accompanying "help file" with a name "*.txt"
   At the first lines any macro should add an entry to the "Macro_Help"
   menu with the following line:
         .mBar.machelp.m add command -label "MacroName" \
                  -command {MacHelp "MacroName.txt" "SearchText"}
   The macro and the help file should be copied to the "tkedit_storage"
   directory in order to be found by the "Macro / Load at Startup" function.
   Macros must ensure, that they are not called several times and they should
   provide a function to unload the macro
   The name of the function which is called to unload the macro has a name
   similar to the base name of the macro preceded by "unload_".
   The mechanism to prevent a macro loaded several time is to test if a
   variable has been set (like include files for C)
   If a Macro adds a Variable to the Preferences Menu, the Variable should
   have a name beginning with "XPref". Variables with names "XPref*" are
   automatically saved by the "SavePreferences" Procedure.

Modifying text:
  there are 3 functions for inserting and deleting text: InsertText {text},
  InsertTextAt {pos text}, DeleteTextAt {po1 pos2} If your macro modifies text,
  you MUST use these functions since only this way guarantees that modifications
  can be "undone"
  
Adding HighLighting macros:
   The HighLighting macros should do the following things:
   1. Reading the current line and highlighting it "on line"
   2. Reading asynchronously the surrounding lines and highlighting these
   3. recognizing "language specific" keywords
   4. recognizing Comments
   5. recognizing user functions
   6. recognizing a set of global symbols
   7. recognizing "language specific" special elements (like lables or widgets)
   8. interacting with the corresponding "ProcList" macro to update "HotLists"
      and to receive a complete list of user functions
   9. optionally interacting with the "ctags"-support to get a function list
   A foreign language must be introduced in the "Language/Language" Menu.
   Add a line in the form
 .mBar.lse.m.lang add radiobutton -label "UNFUG" -value "UNFUG" \
                  -variable FileType
   You can now add a special notification routine for synchronous reading by
   setting the variable "ExtNewLine(name_of_language)" to the synchronous
   routine:
 set ExtNewLine(UNFUG) HLU_Mark_Line
   HLU_Mark_Line will typically read the current line and mark all keywords in
   the current line.
   Asynchronous read will usually highlight the surrounding of the current line.
   (We do not use a polled routine here because this would take too much
   CPU-time. Instead asynchronous means simply "on any keypress")
   Such a routine can be added in the variable "ExtAfter(name_of_language)":
 set ExtAfter(UNFUG) HLU_After
   The automatic filetype recognition needs the array element of "FileTypes" to
   be set to the identifier of the language:
 set FileTypes(.ufg) "UNFUG"
   You may also include a way to interact with a corresponding ProcList macro
   so that your function keyword list is updated when a keywordlist is
   generated and a function hotlist is updated when you type a new function.
   For this you may set special variables to the entry points of the
   corresponding routines.
   
   The Ctags part is optional. The CTAGS-support macro offers the list
   "ExtCT" to include a notification when a new ctags file is read
   Setting up this list is rather crude, but you could not rely on a
   routine for this since you do not know if the CTAGS-support is loaded:
 if {![info exists ExtCT]} {set ExtCT NoAction}
 set ExtCT "$ExtCT ; HLU_ReadKeysCT"

Adding ProcList macros:
   A ProcList macro should do the following things:
   1. finding functions and special elements
   2. Providing a Hotlist for functions
   3. Providing a LSE buffer with the functions
   4. Adding more specific extraction routines
   5. Providing a function to find the declaration of a function
   6. interacting with the "HighLighting" macro to update the user function list
      and update the Hotlists with new added user functions.
   All special functionality should be added in the language specific entry at
   the "Language" menu:
 .mBar.lse.m add cascade -label "UNFUG" -menu .mBar.lse.m.ufg
 .mBar.lse.m.ufg add command -label "Extr. HobBits" \
            -command {DoCmd "^YDoHobBits"}
 .
 .
   The general entry for making a hotlist is set up as follows:
 set ExtHotListCMD(UNFUG) "MakeHotListUNFUG"
   And the general entry for finding a declaration:
 set ExtGotoCMD(UNFUG) "GotoHobBitDeclaration"
   The interaction with the corresponding highlighter can be organized in a way
   so that the User-Function list is searched for the keywords found and if
   they are not in the list the new keywords are added.
   The following functions and conventions are used to aid in building HotLists:
 LSEOpenHotWin Window_Name
      This function spawns a new text window with scrollbar and closebutton
      which can be filled with the function declarations.
      The parameter "Window_Name" has a strict format:
      .lseHot_xxxxx_filename
      where "xxxxx" denotes a sub identifier which distinguishes between
      different hotlists for the same buffer (e.g. procs and widgets)
      it must start at position 8 and must consist of 5 characters
      (sorry for this, but I did not want to do much parsing inside the
      HotWindow itself). The filename must not contain any dots "." because
      this would be read as window child. I found it practical to replace all
      dots in the file name by asterisks "*" since these will normally not
      occur in file names.
      The textwidget has then the name
      .lseHot_xxxxx_filename.win
      The linenumbers which correspond to the lines listed in the "HotList"
      are stored as list in the array
      LSELines(xxxxx,filename)
      "xxxxx" is the same identifier as before, but filename is now the correct
      filename (with dots instead of asterisks)

Hooks for special things:
   "tkedit" offers a number of "interrupts" which a macro can get.
   The macro can request to insert a routine into the interrupt chain and
   it can remove a routine from the chain. The following routines should be
   used for this:
 AddAfterCMD function         After each keypress is handled
 RemoveAfterCMD function
 AddBeforeCMD function        Before each keypress is handled
 RemoveBeforeCMD function
 AddPoll function             Asynchronous Polling routine
 RemovePoll function
 AddNewLine function          When the current line has changed
 RemoveNewLine function
 AddSave function             When a save of the buffer is requested
                              (is used for the "Fold/Expand" macro to save only
                              expanded text)
 RemoveSave function

   There is also another class of interrupts which is handled on a language
   basis. If your routine does something only for a certain language, it may
   use the following arrays:
   
 ExtHotListCMD(name_of_language)    Called when a "HotList" is requested
 ExtGotoCMD(name_of_language)       Called when a declaration is to be searched
 ExtReturn(name_of_language)        Called after a <Return> was executed
                                    could contain custom LSE-Formating routines
 ExtTab(name_of_language)           Called after a <Tab> was executed
 ExtSpace(name_of_language)         Called after a <Space> was executed
 ExtAfter(Name_of_language)         Called after each keypress
 ExtNewLine(Name_of_language)       Called when line has changed
 
   The third way is to include a routine into a chain simply by adding the
   routine to the existing list of routines or replacing existing routines by
   custom routines. This can be done with the following lists:
   
 ExtReturnCMD                 Called when <Return> is to be executed
 ExtTabCMD                    Called when <Tab> is to be executed
 ExtSpaceCMD                  Called when <Space> is to be executed
 DoOnExit                     Called before editor exits

--------------------------------------------------------------------------------
1. Global variables

Name                    purpose

CWD                     Directory in which "tkedit" was called
ThisFileName            entry of Filename widget
SearchString            entry of Search string widget
SearchCaseYN            If search is case sensitiv
SearchPatternYN         If search is with regular expressions
ReplaceString           entry of Replace widget
Result                  Result of last search
AWin                    Active text widget (.text or .textv)
YankBuffer              result of last "kill" action
SplitOnYN               tells you if splitted views are active
Usage                   Usage of actual buffer "File" or "More" or "All" ...
FileTypes(.type)        The language for a file withe the ending ".type"
FileType                The language of the curent buffer


BufferStoT              Array of buffer texts
BufferStoM              Array of buffer "dirty" flags
BufferStoS              Array of buffer Auto save flags
BufferStoP              Array of buffer insert positions
BufferStoU              Array of buffer usages
BufferStoV              Array of buffer insert positions of view
BufferSto1              Array of buffer mark 1
BufferSto2              Array of buffer mark 2
BufferSto3              Array of buffer mark 3
BufferSto4              Array of buffer mark 4
BufferSto5              Array of buffer paste begin
BufferSto6              Array of buffer paste end
BufferSto7              Array of buffer last found
BufferSto8              Array of buffer last position
BufferStoRet            Array of buffer Return commands
BufferStoTab            Array of buffer Tab commands
BufferStoSpc            Array of Buffer Space commands
BufferStoView           Array of buffer Protection flags

FSgreenCMD              Command to execute if file status is "Save"
FSredCMD                Command to execute if file status is "Modified"
FSamberCMD              Command to execute if fiel status is "Auto saved"
FSvioletCMD             Command to execute if macro recording is on
FSblueCMD               Command to execute if text selection is on
PrintCMD                Command to use for printing
ExtReturnCMD            Command to execute if <Return> is typed
ExtTabCMD               Command to execute if <Tab> is typed
ExtSpaceCMD             Command to execute if <Space> is typed
DoAfterCMD              Command to execute after any special key
DoBeforeCMD             Command to execute before any special key
DelayedCMD              Command to execute within "Idle" loop
PollFunctions           Command to execute asynchronously

--------------------------------------------------------------------------------
2. Functions

Name                    purpose

NextChar                ->
PrevChar                <-
EndOfWord               WORD|
BeginOfWord             |WORD
EndOfLine               LINE|
BeginOfLine             |LINE
NextLine                v
PrevLine                ^
NextScreen              Down 24 lines
PrevScreen              Up 24 Lines
TopOfFile               pos 1.0
BottomOfFile            goto end
#
# procs for File I/O
#
SaveTo <filename>       Save actual buffer to specified file
loadFile <filename>     load specified file to actual buffer
OpenNew                 start a new editor with file from box
IncludeFile <filename>  include file at cursor position
SaveClip                save selected text to file
CrLf2Lf                 convert DOS -> UNIX
Cr2Lf                   convert OS-9 -> UNIX
SaveCrLf                convert UNIX -> DOS
SaveCr                  convert UNIX -> OS-9
CheckAndQuit            check modify status and leave editor
#
# procs for Edit
#
MarkBegin               selection starts at cursor
MarkEnd                 selection end at cursor, copy to paste buffer
CopyToClip              copy text between markers to paste buffer
CutToClip               copy text between markers and delete text
PasteFromClip           insert paste buffer
DelToEOW                Delete to end of word
DelWord                 Delete word at cursor position
DelLine                 Delete Line at cursor position
DelSelect               Delete X-Selected text
DelSpace                Delete spaces up to next word
JoinLines               join lines
Capitalize              set word to upper case
LowerCase               set word to lower case
DoIndent                indent text according to previous line
YankLine                insert yank buffer from last delete operation
DoTab                   insert tab with correct with
#
# procs for Search / Replace
#
# proc AskGotoLine
GotoLine                GotoLine from LineNumber variable (widget)
AskSearchString         clear search widget and read string
SearchNext              Search next occurence of SearchString
SearchPrev              Search previous occurence of SearchString
MatchBracket            find matching bracket
AskReplaceString        clear replace widget and read string
ReplaceNext             replace next occurence of SearchString
ReplaceAll              replace all occurences of Searchstring
InsertText <text>       insert text at cursor position
InsertTextAt <pos> <text>  insert text at specified position
DeleteTextAt <pos1> <pos2> delete text at specified position
#
# Procs for handling Buffers
#
RenameBuffer <old> <new>
ChangeBuffer <buffer>   change to specified buffer
CloseThis               close actual buffer
#
# Special procs
#
MacHelp <file> <searchstring> Load Help file and start search
DoCmd <^Ycmd>                 execute a command and do "macro recording"
AddAfterCMD <function>        Add to functions called after any special key
RemoveAfterCMD <function>     Remove from the list
AddBeforeCMD <function>       Add to functions called before any special key
RemoveBeforeCMD <function>    Remove from list
AddPoll <function>            Add to pollin queue
RemovePoll <function>         Remove from polling queue

--------------------------------------------------------------------------------
3. Menu Entry names

.mBar.file.m
.mBar.edit.m
.mBar.search.m
.mBar.prefs.m
.mBar.macro.m
.mBar.buffer.m
.mBar.lse.m
.mBar.misc.m
.mBar.help.m
.mBar.machelp.m


