home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 25 / CD_ASCQ_25_1095.iso / dos / tools / auror21a / ext.aml < prev    next >
Text File  |  1995-08-31  |  77KB  |  2,946 lines

  1.  
  2. // -------------------------------------------------------------------
  3. // The Aurora Editor v2.1
  4. // Copyright 1993-1995 nuText Systems. All Rights Reserved Worldwide.
  5. //
  6. // Editor library extensions (included by MAIN.AML)
  7. //
  8. // *You should be very familiar with AML before making changes here*
  9. // If you have made any changes, save this file and select 'Recompile
  10. // the Editor' <alt f2> from the Set menu. Exit and re-enter the
  11. // editor for your changes to take effect.
  12. // -------------------------------------------------------------------
  13.  
  14. // -------------------------------------------------------------------
  15. //  All windows
  16. // -------------------------------------------------------------------
  17.  
  18.   object  a
  19.  
  20.     // get the drive and path portion of a filespec
  21.     function  getpath (file)
  22.       return  file [1 : pos "\\" file 'r']
  23.     end
  24.  
  25.     // get the name and extension portion of a filespec
  26.     function  getname (file)
  27.       return  file [(pos "\\" file 'r') + 1 : TO_END]
  28.     end
  29.  
  30.     // get the extension portion of a filespec
  31.     function  getext (file)
  32.       p = pos '.' file 'r'
  33.       if? p file [p : TO_END] ''
  34.     end
  35.  
  36.     // append a default extension for filenames that don't have one
  37.     function  defext (file extension)
  38.       if pos '.' file then
  39.         file
  40.       else
  41.         file + '.' + extension
  42.       end
  43.     end
  44.  
  45.     // force a filename to have an extension
  46.     function  forceext (file ext)
  47.       p = pos '.' file 'r'
  48.       return (if? p  file [1 : p]  file + '.') + ext
  49.     end
  50.  
  51.     // generate shiftkey events from raw <shiftkey> event
  52.     function  <shiftkey> (newstate oldstate)
  53.       send ( if newstate & 3 and not (oldstate & 3) then
  54.                "shiftdown"
  55.              elseif oldstate & 3 and not (newstate & 3) then
  56.                "shiftup"
  57.              elseif newstate & 10h and not (oldstate & 10h) then
  58.                "scrlockdown"
  59.              elseif oldstate & 10h and not (newstate & 10h) then
  60.                "scrlockup"
  61.              end )
  62.     end
  63.  
  64.     // generate multi-key events
  65.     function  prefix (keycode)
  66.       keyname = locase (getkeyname keycode)
  67.       say  keyname + "<more...>"
  68.       keyname2 = locase (getkeyname (getkey))
  69.       queue  keyname + keyname2
  70.       // allow the <ctrl> key to be held down...
  71.       if keyname [1:5] == "<ctrl" and keyname2 [1:5] == "<ctrl" then
  72.         queue keyname + '<' + keyname2 [7 : TO_END]
  73.       end
  74.       display
  75.     end
  76.  
  77.     // repeat keys for a user-specified number of times
  78.     function  askrepkey
  79.       var keystring
  80.       var i
  81.       say "Enter keys to repeat, then <esc>:"
  82.       hidecursor
  83.       keycode = getkey
  84.       while keycode <> <esc> do
  85.         keystring = keystring + (char2 keycode)
  86.         keycode = getkey
  87.       end
  88.       if keystring then
  89.         count = ask "Number of repetitions"
  90.         if count then
  91.           strlen = sizeof keystring
  92.           while count do
  93.             j = 1
  94.             while j < strlen do
  95.               queuekey (bin2int keystring [j : 2])
  96.               j = j + 2
  97.             end
  98.             repeat
  99.               dispatch
  100.             until not event?
  101.             count = count - 1
  102.           end
  103.         end
  104.       end
  105.     end
  106.  
  107.     // write to the screen background
  108.     function  writebak (string attr x y)
  109.       w = getcurrwin
  110.       while w do
  111.         hidewindow w
  112.         w = getprevwin w
  113.       end
  114.       gotoscreen
  115.       writestr string attr x y
  116.     end
  117.  
  118.     // a simple file picklist
  119.     function  picklist (filespec title)
  120.       filespec = qualify filespec (getbufname)
  121.       repeat
  122.         filespec = askfile filespec  filespec + title _FmgrSort _FmgrOpt
  123.       until not (filespec and (dir? filespec))
  124.       return filespec
  125.     end
  126.  
  127.     // execute a fully qualified DOS program
  128.     // (saving and restoring the current path)
  129.     function  os (program options)
  130.       cp = getcurrpath
  131.       currpath (getpath (getbufname))
  132.       r = exec program options
  133.       currpath cp
  134.       return r
  135.     end
  136.  
  137.     // shell to DOS by executing COMMAND.COM
  138.     function  shell
  139.       os (getenv "COMSPEC") "ch"
  140.     end
  141.  
  142.     // execute DOS commands, programs, and .bat files
  143.     function  run (file options)
  144.       if file then
  145.         os (getenv "COMSPEC") + " /c " + file  options
  146.       else
  147.         shell
  148.       end
  149.     end
  150.  
  151.     // execute DOS commands or programs and capture the output
  152.     // via DOS piping (will not capture .bat file output)
  153.     function  runcap (command options)
  154.       _cap = _cap + 1
  155.       capfile = qualify  "capture." + _cap  (getbufname)
  156.       run  command + '>' + capfile  options
  157.       open capfile
  158.       deletefile capfile
  159.     end
  160.  
  161.     // translate an AML compiler error code to an error message
  162.     function  errormsg (error)
  163.       case error
  164.         when 1001  "Can't open file"
  165.         when 1002, 1003  "Read error"
  166.         when 1004  "Not an executable macro file"
  167.         when 1031  "Write error"
  168.         when 1032  "Can't open compiler output file"
  169.         when 1101  "No closing quote"
  170.         when 1102  "No closing bracket"
  171.         when 1103  "Invalid symbol"
  172.         when 1104  "Invalid key or event"
  173.         when 1301  "No terminator"
  174.         when 1302  "Unexpected end of source"
  175.         when 1303  "No closing parenthesis"
  176.         when 1310  "Unexpected argument"
  177.         when 1311  "Unexpected terminator"
  178.         when 1312  "Unexpected function"
  179.         when 1313  "Unexpected operator"
  180.         when 1318  "Invalid number"
  181.         when 1319  "Identifier '" + (geterror 's') + "' not defined"
  182.         when 1320  "Bad assignment"
  183.         when 1330  "Bad when clause"
  184.         when 1336  "Improperly placed break"
  185.         when 1337  "Invalid reference"
  186.         when 1501  "Can't open include file " + (geterror 's')
  187.         when 1502  "Include level exceeded"
  188.         when 1503  "Can't include compiled file in expression"
  189.         when 1504  "Include must be at top level"
  190.         when 1505  "Define can't be nested"
  191.         when 1506  "Function must be at top level"
  192.         when 1507  "Can't redefine builtin function"
  193.         when 1508  "Duplicated function argument"
  194.         when 1509  "Object statement not permitted"
  195.         when 1701  "Too many variables"
  196.         when 1702  "Too many function arguments"
  197.         when 1703  "Function or expression too large"
  198.         when 1704, 1705, 1707   "Internal stack overflow"
  199.         when 1706  "Out of symbol space"
  200.         otherwise "Fatal compilation error " + error
  201.       end
  202.     end
  203.  
  204.     // compile a macro with error messages
  205.     // the cursor is moved to any syntax errors
  206.     function  compilemacro2 (source dest msg)
  207.       if not source then
  208.         source = getbufname
  209.       end
  210.       if msg then
  211.         say msg
  212.       end
  213.       source = qualify (defext source "aml") (getbufname)
  214.       error = compilemacro source (if? dest dest (forceext source 'x'))
  215.  
  216.       if error then
  217.  
  218.         // get additional error info
  219.         column = geterror 'k'
  220.         line = geterror 'l'
  221.         file = geterror 'f'
  222.  
  223.         // translate error code to an error message
  224.         msg = errormsg error
  225.  
  226.         // position the cursor to the error
  227.         if error <> 1001 and (open file) then
  228.           gotopos column line
  229.           send "onfound"
  230.         end
  231.  
  232.         // display the error
  233.         location = file + " (line " + line + ", col " + column + "): "
  234.         // 1 or 2 line msgbox
  235.         msgbox location +
  236.                (if? ((sizeof location) + (sizeof msg)) > getvidcols - 8 "\n") +
  237.                msg  "Error!" 'b'
  238.       else
  239.         if wintype? "edit_fmgr" then
  240.           say "Done."
  241.         end
  242.       end
  243.  
  244.       return error
  245.     end
  246.  
  247.     // regenerate the editor boot macro (a.x)
  248.     function  regen (msg)
  249.       dest = bootpath "main.x"
  250.       error = compilemacro2 (bootpath "main.aml") dest msg
  251.       if not error then
  252.         bootfile = bootpath "a.x"
  253.         deletefile bootfile
  254.         renamefile dest bootfile
  255.       end
  256.       return error
  257.     end
  258.  
  259.     // regenerate the editor boot macro (a.x) with a message
  260.     function  recompile
  261.       if not regen then
  262.         msgbox "Exit and re-enter for changes to take effect. "
  263.       end
  264.     end
  265.  
  266.     // load, run, and discard a compiled macro file
  267.     function  runmacro2 (macrofile)
  268.       runmacro (qualify (forceext
  269.                  (if? macrofile macrofile (getbufname)) 'x') (getbufname))
  270.     end
  271.  
  272.     // run a configuration macro
  273.     function  runcfg (macrosuffix)
  274.       runmacro getbootpath + "CFG\\CFG" + macrosuffix + ".X"
  275.     end
  276.  
  277.     // save current configuration to CONFIG.AML and COLOR.AML and recompile
  278.     function  savecfg
  279.       runcfg "upd"
  280.     end
  281.  
  282.     // run a macro in the macro subdirectory
  283.     function  runmac (macro)
  284.       runmacro getbootpath + "MACRO\\" + macro + ".X"
  285.     end
  286.  
  287.     // send a string to the default printer device
  288.     function  printstr (string)
  289.       if string then
  290.         fileid = openfile _PrtDev 'w'
  291.         if fileid then
  292.           writefile fileid string
  293.           closefile fileid
  294.         end
  295.       end
  296.     end
  297.  
  298.     // open a new file
  299.     function  opennew (file options)
  300.       prevbufname = getbufname
  301.       buffer = createbuf
  302.       if buffer then
  303.         setbufname (qualify (if? file file "NEW.TXT") prevbufname)
  304.         openbuf buffer options
  305.       end
  306.     end
  307.  
  308.     // toggle the video mode between 80x25 and 80x50
  309.     function  togglemode
  310.       videomode 80 (if? getvidrows == 25  50 25)
  311.     end
  312.  
  313.  
  314.     // search/replace with verification
  315.     // (returns the number of replacements made)
  316.     function  replver (searchstr replstr options)
  317.  
  318.       var title
  319.       var count
  320.  
  321.       repeat
  322.         length = find searchstr options
  323.         if length then
  324.  
  325.           if not title then
  326.             title = gettitle
  327.             settitle  "Replace (Yes/No/All/One/Reverse/Undo/Quit)? "
  328.             // remove global for next find
  329.             options = sub 'g' '' options
  330.           end
  331.  
  332.           send "onfound" length
  333.  
  334.           // get keycode and convert to lower case
  335.           p = getkey | 020h
  336.           case p
  337.  
  338.             when <y>, <o>, <a>
  339.               undobegin
  340.               l = (replace searchstr replstr  (sub 'r' '' options) + "*") - 1
  341.               if not (pos 'r' options) then
  342.                 right l
  343.                 if (pos 'x' options) and (getcol == getlinelen) then
  344.                   right
  345.                 end
  346.               end
  347.               count = count + 1
  348.               if p <> <y> then
  349.                 length = ''
  350.                 if p == <a> then
  351.                   count = count + (replace searchstr replstr  options + "a")
  352.                 end
  353.               end
  354.               undoend
  355.  
  356.             when <u>
  357.               if count then
  358.                 undo
  359.                 count = count - 1
  360.                 if pos 'r' options then
  361.                   right 1
  362.                 else
  363.                   if getcol == 1 then
  364.                     if up then
  365.                       col 16000
  366.                     end
  367.                   else
  368.                     left l
  369.                   end
  370.                 end
  371.               end
  372.  
  373.             when <n>
  374.                // do nothing
  375.  
  376.             when <r>
  377.                options = if? (pos 'r' options) (sub 'r' '' options)  options + 'r'
  378.  
  379.             otherwise
  380.               if not count then
  381.                 count = '0'
  382.               end
  383.               break
  384.           end
  385.         end
  386.       until not length
  387.  
  388.       if title then
  389.         settitle title
  390.       end
  391.  
  392.       return count
  393.     end
  394.  
  395.  
  396.     // search for a multi-string search argument
  397.     function  search (searchstr reverse rep refopt refrepl)
  398.  
  399.       var replstr
  400.       var options
  401.  
  402.       // split up search multi-string
  403.       if pos '/' searchstr then
  404.         n = splitstr '' searchstr  ref searchstr  ref replstr  ref options
  405.         if n > 1 then
  406.           if n == 2 then
  407.             options = replstr
  408.             replstr = ''
  409.             // case sensitive
  410.             if not options then
  411.               options = 'c'
  412.             end
  413.           end
  414.         end
  415.       end
  416.  
  417.       if searchstr then
  418.  
  419.         // default options
  420.         if not options then
  421.           options = _SearchOpt
  422.           if n > 2 then
  423.             options = options + _ReplaceOpt
  424.           end
  425.         end
  426.  
  427.         // reverse search direction if specified
  428.         if reverse then
  429.           options = if pos 'r' options then
  430.                       sub 'r' '' options
  431.                     else
  432.                       options + 'r'
  433.                     end
  434.         end
  435.  
  436.         // remove global for repeat find
  437.         if rep and (pos 'g' options) then
  438.           options = sub 'g' '' options
  439.         end
  440.  
  441.         // return values for calling function to check
  442.         refopt  = options
  443.         refrepl = n >= 3
  444.  
  445.         // resurface marked window for block search
  446.         if pos 'b' options then
  447.           buffer = getmarkbuf
  448.           if buffer and buffer <> getcurrbuf then
  449.             currwin (getcurswin (getcurrcurs buffer))
  450.           end
  451.         end
  452.  
  453.         // search and replace
  454.         if n >= 3 then
  455.  
  456.           // do the replace
  457.           if pos 'a' options then
  458.             replace searchstr replstr options
  459.           else
  460.             replver searchstr replstr options
  461.           end
  462.  
  463.         // search only
  464.         else
  465.           find searchstr options
  466.         end
  467.       end
  468.     end
  469.  
  470.     // hot key for the file mgr and file picklists
  471.     function  onhotkey (character)
  472.       if _oL == getrow then
  473.         // backspace
  474.         if character == '\x08' then
  475.           popcursor
  476.           _oS = if? ((sizeof _oS) > 1) _oS [1 : (sizeof _oS) - 1] ''
  477.         else
  478.           _oS = _oS + character
  479.           pushcursor
  480.         end
  481.       else
  482.         if character == '\\' then
  483.           character = '\x00'
  484.         end
  485.         _oS = character
  486.         pushcursor
  487.       end
  488.       searchstr = '^ *' + _oS
  489.       length = (find searchstr 'xi*') or (find searchstr 'xig')
  490.       if length then
  491.         if getrow > getviewbot or getrow < getviewtop then
  492.           adjustrow getviewrows / 3
  493.         end
  494.         if _oS then
  495.           display
  496.           hilite length 1 (getpalette (if? (wintype? "fmgr") 33 18)) 1
  497.         end
  498.         _oL = getrow
  499.       else
  500.         popcursor 'ad'
  501.         _oL = ''
  502.         if (sizeof _oS) > 1 then
  503.           onhotkey character
  504.         // not found
  505.         else
  506.           beep 320 70
  507.         end
  508.       end
  509.     end
  510.  
  511.     // generic prompt for a string
  512.     function  ask (prompt history init title options width)
  513.  
  514.       var value
  515.  
  516.       if not options then
  517.         options = _PromptStyle
  518.         suffix = if? (pos '2' options) ':' '>'
  519.       end
  520.  
  521.       if pos 'd' options then
  522.         if suffix then
  523.           prompt = prompt + ':'
  524.         end
  525.         if not width then
  526.           width = 48
  527.         end
  528.  
  529.         dialog (if? title title "Prompt")  18 + width  5 'cp'
  530.         field  prompt 3 2 width - (if? prompt [0] == '>' ((sizeof prompt) - 3) -2) init history
  531.         button "O&k"    width + 8 2 8
  532.         button "Cancel" width + 8 4 8
  533.  
  534.         if (getdialog ref value) == 'Ok' then
  535.           return (if? value value ' ')
  536.         end
  537.       else
  538.         if (case options
  539.               when 'c' askline ref value prompt + suffix       history init
  540.               when '1' askbox1 ref value prompt + suffix + ' ' history init
  541.               when '2' askbox  ref value prompt + suffix       history init
  542.             end) then
  543.           return (if? value value ' ')
  544.         end
  545.       end
  546.     end
  547.  
  548.  
  549.   object  mon
  550.  
  551.     // erase key macros
  552.     function  erasekey2 (options)
  553.       if erasekey options then
  554.         _kd = TRUE
  555.         display
  556.         say (if? (pos options 'a') "All keys macros erased"
  557.                                    "Scrap key macro erased")
  558.       end
  559.     end
  560.  
  561.     // toggle the key macro record mode
  562.     function  record
  563.       if not playing? then
  564.         _kd = TRUE
  565.         if not setting? 'R' then
  566.           erasekey
  567.           record_on = TRUE
  568.         end
  569.         setting 'R' TOGGLE
  570.         say "Record" + (if? record_on "ing..." " OFF")
  571.       end
  572.     end
  573.  
  574.     // play a key macro
  575.     function  play (keymacro)
  576.       setdisplay OFF
  577.       if not (playkey keymacro) then
  578.         say "No key macro to play." 'b'
  579.       end
  580.       setdisplay ON
  581.     end
  582.  
  583.  
  584. // -------------------------------------------------------------------
  585. //  Edit windows and File Manager windows
  586. // -------------------------------------------------------------------
  587.  
  588.   object  edit_fmgr
  589.  
  590.     // close all windows
  591.     function  closeall (options)
  592.       setxobj "__G" ON 'a'
  593.       begdesk
  594.       while getwincount and (send "close" options) end
  595.       enddesk
  596.       setxobj "__G" OFF 'a'
  597.     end
  598.  
  599.     // move the cursor to any edge of a mark
  600.     function  gotomark (options)
  601.       if mark? then
  602.  
  603.         window = getcurswin (getcurrcurs (getmarkbuf))
  604.         if window then
  605.           currwin window
  606.         end
  607.  
  608.         // left or right
  609.         if pos 'l' options then
  610.           col (getmarkleft)
  611.         elseif pos 'r' options then
  612.           col (getmarkright)
  613.         end
  614.  
  615.         // top or bottom
  616.         if pos 't' options then
  617.           row (getmarktop)
  618.         elseif pos 'b' options then
  619.           row (getmarkbot)
  620.         end
  621.  
  622.         if window then
  623.           send "onfound"
  624.         end
  625.  
  626.       else
  627.         say "Block not found" 'b'
  628.       end
  629.     end
  630.  
  631.     // goto a bookmark with message
  632.     function  gotobook2 (bookmark)
  633.       msg = "Bookmark '" + bookmark + "'"
  634.       bookbuf = getbookbuf bookmark
  635.       if bookbuf <> getwinbuf then
  636.         open (getbufname bookbuf)
  637.       end
  638.       if gotobook bookmark then
  639.         display
  640.         say msg
  641.       else
  642.         say msg + " not found"  'b'
  643.       end
  644.     end
  645.  
  646.     // prompt to goto a bookmark
  647.     function  askbook (msg)
  648.       askx (if? msg msg "Bookmark Name") "_book" "gotobook2"
  649.     end
  650.  
  651.     // cycle though all existing bookmarks
  652.     function  cyclebook
  653.       repeat
  654.         l = _lb
  655.         bookmark = if? l (getprevbook l) (getcurrbook)
  656.         buffer = getcurrbuf
  657.         while not bookmark and buffer do
  658.           buffer = getprevbuf buffer
  659.           bookmark = getcurrbook buffer
  660.         end
  661.         _lb = bookmark
  662.       until bookmark or not l
  663.       gotobook2 bookmark
  664.     end
  665.  
  666.     // print the current buffer or mark
  667.     function  print (options)
  668.       printstr _PrtIni
  669.       header = _PrtHdr
  670.       printformat '' _PrtOpt _PrtPag _PrtLeft _PrtTop _PrtRight _PrtBot
  671.                      _PrtSpace _PrtCop
  672.       if not (posnot ' ' header) or (dir? (getbufname)) then
  673.         date = getdate
  674.         header = getbufname + "   (" + date [posnot ' ' date : TO_END] +
  675.                                  ' ' + gettime + ')'
  676.       end
  677.       if not ( if pos 'b' options  then printblock _PrtDev header ''
  678.                 else    printbuf _PrtDev header end ) then
  679.         say "Print failed" 'b'
  680.       end
  681.     end
  682.  
  683.     // replace/append/cancel or ok/cancel menus
  684.     function  askrac (file menuname)
  685.       if _ConRpl == 'y' and (locatefile file) then
  686.         locase (popup (if? menuname menuname "rac" )
  687.                         file + " Exists" +
  688.                         (if? menuname == "ok" ". Replace?")) [1]
  689.       else
  690.         'r'
  691.       end
  692.     end
  693.  
  694.     // generic prompt to change a configuration variable
  695.     function  askc (pstring variable history)
  696.       newvalue = ask pstring history (lookup variable "prf")
  697.       if newvalue then
  698.         setxobj variable newvalue "prf"
  699.       end
  700.     end
  701.  
  702.     // prompts to change specific configuration variables
  703.     function  askclip    askc "Clipboard Name" "ClipName"    end
  704.     function  askprthdr  askc "Current Header/Footer" "PrtHdr" end
  705.  
  706.     // generic prompt with command execution
  707.     function  askx (pstring history func parm2)
  708.       parm1 = ask pstring history
  709.       if parm1 then
  710.         send func parm1 parm2
  711.         if history then
  712.           addhistory history parm1
  713.         end
  714.         return 1
  715.       end
  716.     end
  717.  
  718.     // open prompt
  719.     function  askopen
  720.       file = ask "[file/ibcenz] Open" "_load"
  721.       if file then
  722.         // addhistory not needed for open
  723.         open file
  724.       end
  725.     end
  726.  
  727.     // open binary prompt
  728.     function  askopenb
  729.       askx "File to open in Binary Mode" "_load" "open" 'b'
  730.     end
  731.  
  732.     // macro expression prompt
  733.     function  askeval
  734.       if askx "Macro Expression" "_cmd" "eval" then
  735.         error = geterror 'c'
  736.         if error then
  737.           msgbox "Expression column " + (geterror 'k') +
  738.                  ": " + (errormsg error)  "Error" 'b'
  739.         end
  740.       end
  741.     end
  742.  
  743.     // prompt to run a macro
  744.     function  askrmacro
  745.       askx "Run Macro File"  "_load" "runmacro2"
  746.     end
  747.  
  748.     // prompt to compile a macro
  749.     function  askcmacro
  750.       askx "Compile Macro File"  "_load" "compilemacro2"
  751.     end
  752.  
  753.     // macro picklist
  754.     function  pickmacro
  755.       macro = askfile getbootpath + "MACRO\\*.X" "Select a macro to run"
  756.                       _FmgrSort _FmgrOpt "maclist"
  757.       if macro then
  758.         runmacro macro
  759.       end
  760.     end
  761.  
  762.     // DOS command prompt
  763.     function  askrun
  764.       askx "DOS Command" "_os" "run" "ck"
  765.     end
  766.  
  767.     // prompt to capture DOS output
  768.     function  askruncap
  769.       askx "Capture DOS Output" "_os" "runcap" 'c'
  770.     end
  771.  
  772.     // open key macro file with messages
  773.     function  openkey2 (file)
  774.       if openkey file then
  775.         say (getname file) + " loaded"
  776.       else
  777.         say "Load failed" 'b'
  778.       end
  779.     end
  780.  
  781.     // prompt to open a key macro file
  782.     function  askopenkey
  783.       file = ask "Key macro filename" "_load"
  784.       if file then
  785.         openkey2 (qualify (defext file "mac") (getbufname))
  786.       end
  787.     end
  788.  
  789.     // prompt to save current key macros
  790.     function  asksavekey
  791.       file = ask "Save current key macros as" "_load"
  792.       if file then
  793.         file = qualify (defext file "mac") (getbufname)
  794.         if pos (askrac file "ok") "or" 'i' then
  795.           if not savekey file then
  796.             say "Save failed" 'b'
  797.           end
  798.         end
  799.       end
  800.     end
  801.  
  802.     // search files for a string in multi-string format with msgs
  803.     function  searchfiles (s)
  804.       var searchstr
  805.       var filespec
  806.       var options
  807.       n = splitstr '' s  ref searchstr  ref filespec  ref options
  808.       if n < 3 then
  809.         options = _SearchOpt
  810.         if n < 2 then
  811.           filespec = '.'
  812.         end
  813.       end
  814.       if searchstr then
  815.         r = scanfiles filespec searchstr options
  816.         if r <= 0 then
  817.           say (if? r filespec s) + " not found" 'b'
  818.         else
  819.           addhistory "_find" (joinstr '' searchstr options)
  820.         end
  821.       end
  822.     end
  823.  
  824.     // prompt to scan files for a string
  825.     function  askscan
  826.       scanstring = if _PromptStyle == 'd' then
  827.                      scandlg
  828.                    else
  829.                      ask "[string/files/iwx] Scan" "_scan"
  830.                    end
  831.       if scanstring then
  832.         searchfiles scanstring
  833.         addhistory "_scan" scanstring
  834.       end
  835.     end
  836.  
  837.     // reload the current file from disk
  838.     function  reopen (file)
  839.       open (if? file file (getbufname)) 'r'
  840.     end
  841.  
  842.     // open last file or directory
  843.     function  openlast
  844.       file = gethiststr "_load"
  845.       if file then
  846.         open file
  847.       end
  848.     end
  849.  
  850.     // open an AML configuration file in boot directory
  851.     function  opencfg (file)
  852.       open (bootpath  file + ".aml")
  853.     end
  854.  
  855.     // quick reference help
  856.     function  quickref (options openopt)
  857.       quickfile = getbootpath + (if? options <> 'o' "DOC\\") +
  858.                     case options [1]
  859.                       when 'l'  "LANGUAGE.DOX"
  860.                       when 'f'  "FUNCTION.DOX"
  861.                       when 'q'  "QUICKFUN.DOX"
  862.                       when 'o'  "ORDERFRM.DOC"
  863.                       when 't'  "TIPS.DOX"
  864.                       otherwise "USER.DOX"
  865.                     end
  866.       if (wintype? "edit") and (pos 'w' options) then
  867.         wordstr = send "getword" "a-zA-Z0-9?"
  868.       end
  869.       open quickfile openopt
  870.  
  871.       // make read/only
  872.       if options [1] <> 'o' then
  873.         bufferflag 'r'
  874.       end
  875.  
  876.       if wordstr then
  877.         gotopos 1 1
  878.  
  879.         // find string in reference
  880.         if find (char 0ffh) + wordstr + (char 0ffh) then
  881.           right
  882.           send "onfound" (sizeof wordstr)
  883.  
  884.         // not found? then try function header in EXT.AML
  885.         elseif poschar 'fq' options then
  886.           close
  887.           ext = bootpath "EXT.AML"
  888.           closeit = _MultCopy == 'n' and not (findbuf ext)
  889.           open ext openopt
  890.           gotopos 1 1
  891.           n = find "function #" + wordstr  'x'
  892.           if n then
  893.             send "onfound" n
  894.  
  895.           else
  896.             // still not found? then go back to the reference
  897.             if closeit then
  898.               close
  899.             end
  900.             open quickfile openopt
  901.             // make read/only
  902.             bufferflag 'r'
  903.           end
  904.         end
  905.       end
  906.     end
  907.  
  908.  
  909. // -------------------------------------------------------------------
  910. //  Prompts and Edit windows
  911. // -------------------------------------------------------------------
  912.  
  913.   object  prompt
  914.  
  915.     // support for cua-style <shift> key marking
  916.     function  smark
  917.       if shiftkey? then
  918.         if _shfx then
  919.           undobegin
  920.           destroymark
  921.           markstream _shfx _shfx _shfy _shfy
  922.           _shfx = ''
  923.           _shfy = ''
  924.         end
  925.         extendmark
  926.       end
  927.     end
  928.  
  929.     // set anchor for shift-key marking
  930.     function  shiftdown
  931.       _shfx = getcol
  932.       _shfy = getrow
  933.       pass
  934.     end
  935.  
  936.     // end shift-key mark
  937.     function  shiftup
  938.       if not _shfx then
  939.         stopmark
  940.         undoend
  941.       end
  942.       pass
  943.     end
  944.  
  945.     // backspace in a prompt
  946.     function  backsp
  947.       if getcol > 1 then
  948.         left
  949.         delchar
  950.       end
  951.     end
  952.  
  953.     // get the word at the cursor
  954.     function  getword (charset column mark)
  955.       if not column then
  956.         column = getcol
  957.       end
  958.       if column <= getlinelen then
  959.         if not charset then
  960.           charset = _CSet
  961.         end
  962.         b = posnot charset (gettext column)
  963.         if b <> 1 then
  964.           b = if? b  column + b - 2  getlinelen
  965.           a = posnot charset (gettext 1 column) 'r'
  966.           a = if? a  a + 1  1
  967.           if mark then
  968.             undobegin
  969.             destroymark
  970.             markchar a b
  971.             undoend
  972.           else
  973.             gettext a  b - a + 1
  974.           end
  975.         end
  976.       end
  977.     end
  978.  
  979.     // mark the word at the cursor using getword
  980.     function  markword (charset)
  981.       getword charset '' 1
  982.     end
  983.  
  984.     // mark to end-of-line
  985.     function  markeol
  986.       undobegin
  987.       destroymark
  988.       if getcol <= getlinelen then
  989.         markchar '' (getlinelen)
  990.       end
  991.       undoend
  992.     end
  993.  
  994.     // delete a block
  995.     function  deleteblock2
  996.       if getmarkbuf == getcurrbuf then
  997.         deleteblock
  998.       else
  999.         if wintype? "edit" then
  1000.           if _DelLine == 'y' then
  1001.             delline
  1002.           end
  1003.         end
  1004.       end
  1005.     end
  1006.  
  1007.     // prompt to enter character literally
  1008.     function  literal
  1009.       say "Enter Literal..."
  1010.       queue <char> (char getkey & 0ffh)
  1011.     end
  1012.  
  1013.     // ascii chart with character entry
  1014.     function  asciilist
  1015.       buffer = asciibuf
  1016.       // name it so the position can be remembered
  1017.       setbufname "_asc"
  1018.       character = (popup buffer '' 13) [10]
  1019.       destroybuf
  1020.       if character then
  1021.         queue <char> character
  1022.       end
  1023.     end
  1024.  
  1025.     // support for file name completion (open prompts only)
  1026.     function  askcomplete
  1027.       if gethistname == "_load" then
  1028.         filespec = gettext
  1029.         if filespec then
  1030.           if not pos "*.*" filespec then
  1031.             filespec = filespec + (if? (pos '.' filespec) '*' "*.*")
  1032.           end
  1033.         else
  1034.           filespec = "*.*"
  1035.         end
  1036.         file = picklist (qualify filespec (getbufname (getwinbuf (getprevwin (getcurrwin)))))
  1037.         if file then
  1038.           col 1
  1039.           delchar (getlinelen)
  1040.           writetext file
  1041.           return file
  1042.         end
  1043.       end
  1044.     end
  1045.  
  1046.     // get the first line of text in the default mark
  1047.     function  getmarktext
  1048.       if mark? then
  1049.         buffer = getmarkbuf
  1050.         topline = getmarktop
  1051.         if getmarktype == 'l' then
  1052.           gettext (getlinebeg topline buffer) (getlinelen topline buffer)
  1053.                   (getmarktop) buffer
  1054.         else
  1055.           gettext (getmarkleft) (getmarkcols) topline buffer
  1056.         end
  1057.       end
  1058.     end
  1059.  
  1060.     // copy or copy-append to the clipboard
  1061.     function  copy (options)
  1062.  
  1063.       if mark? then
  1064.  
  1065.         // copy to ms windows
  1066.         if pos 'w' options then
  1067.           if not saveblock "^:c" _SaveOpt + 'x' then
  1068.             msgbox "The MS Windows clipboard is not available."
  1069.           end
  1070.  
  1071.         else
  1072.           currentbuf = getcurrbuf
  1073.           clip = _ClipName
  1074.           destroymark clip
  1075.           copymark (getmarkuse) clip
  1076.  
  1077.           // copy append
  1078.           if options and (buffer? clip) then
  1079.             if getmarktype <> 'l' then
  1080.               insline '' '' (getlines clip) clip
  1081.             end
  1082.             copyblock clip clip 1 (getlines clip)
  1083.             markline 1 (getlines clip) clip clip
  1084.  
  1085.           // copy
  1086.           else
  1087.             destroybuf clip
  1088.             createbuf clip
  1089.             copyblock clip clip
  1090.             if getmarktype == 'l' then
  1091.               delline 1 1 clip
  1092.             end
  1093.           end
  1094.           currbuf currentbuf
  1095.         end
  1096.       end
  1097.     end
  1098.  
  1099.     // cut or cut-append to the clipboard
  1100.     function  cut (options)
  1101.       if mark? then
  1102.         copy options
  1103.         deleteblock
  1104.       end
  1105.     end
  1106.  
  1107.     // enter a character or string into the current prompt
  1108.     function  write (charstring)
  1109.       writetext charstring
  1110.     end
  1111.  
  1112.  
  1113. // -------------------------------------------------------------------
  1114. //  Edit windows
  1115. // -------------------------------------------------------------------
  1116.  
  1117.   object  edit
  1118.  
  1119.     // mark a paragraph
  1120.     function  markpara (options)
  1121.  
  1122.       if getlinelen then
  1123.  
  1124.         undobegin
  1125.         destroymark
  1126.  
  1127.         // find the beginning of the paragraph
  1128.         pushcursor
  1129.         // check for mark-to-end of paragraph
  1130.         if not pos 'e' options then
  1131.           while up and getlinelen end
  1132.           if not getlinelen then
  1133.             down
  1134.           end
  1135.           markline
  1136.         end
  1137.         popcursor
  1138.  
  1139.         // find the end of the paragraph
  1140.         pushcursor
  1141.         while down and getlinelen end
  1142.         if not getlinelen then
  1143.           up
  1144.         end
  1145.         markline
  1146.         popcursor
  1147.  
  1148.         undoend
  1149.  
  1150.         return 1
  1151.       end
  1152.     end
  1153.  
  1154.     // setup for insert-above (copy, move, paste - lineblocks only)
  1155.     function  begabove
  1156.       _ba = ''
  1157.       undobegin
  1158.       if getmarktype == 'l' and _InsAbove == 'y' then
  1159.         _ba = 1
  1160.         if not up then
  1161.           insabove
  1162.           up
  1163.           _ba = 2
  1164.         end
  1165.       end
  1166.     end
  1167.  
  1168.     // end insert-above
  1169.     function  endabove
  1170.       case _ba
  1171.         when 1 down
  1172.         when 2 delline
  1173.       end
  1174.       undoend
  1175.     end
  1176.  
  1177.     // paste or paste-over from the clipboard
  1178.     function  paste (options)
  1179.       // paste from ms windows
  1180.       if pos 'w' options then
  1181.         undobegin
  1182.         old_size = getlines
  1183.         if insertbuf "^:c" then
  1184.           // mark inserted text
  1185.           if getlines > old_size then
  1186.             markline  getrow + 1  getrow + getlines - old_size
  1187.           end
  1188.         else
  1189.           msgbox "The MS Windows clipboard is not available."
  1190.         end
  1191.         undoend
  1192.       elseif mark? _ClipName then
  1193.         destroymark
  1194.         copymark _ClipName (getmarkuse)
  1195.         if options then
  1196.           copyblockover
  1197.         else
  1198.           begabove
  1199.           copyblock
  1200.           endabove
  1201.         end
  1202.       else
  1203.         say "Nothing to paste" 'b'
  1204.       end
  1205.     end
  1206.  
  1207.     // clear the clipboard
  1208.     function  clear
  1209.       destroybuf _ClipName
  1210.     end
  1211.  
  1212.     // copy a block
  1213.     function  copyblock2
  1214.       if mark? then
  1215.         begabove
  1216.         if not copyblock then
  1217.           say "Copy failed" 'b'
  1218.         end
  1219.         endabove
  1220.       else
  1221.         if _CopyLine == 'y' then
  1222.           undobegin
  1223.           markline
  1224.           copyblock
  1225.           destroymark
  1226.           undoend
  1227.         end
  1228.       end
  1229.     end
  1230.  
  1231.     // move a block
  1232.     function  moveblock2
  1233.       begabove
  1234.       if getmarktop < getviewtop then
  1235.         y = 1 + getrow - (apparentrow  getviewtop - getrow)
  1236.       end
  1237.       if moveblock then
  1238.         if y then
  1239.           adjustrow y
  1240.         end
  1241.       else
  1242.         say "Move failed" 'b'
  1243.       end
  1244.       endabove
  1245.     end
  1246.  
  1247.     // move a block over text
  1248.     function  moveblockover
  1249.       if mark? then
  1250.         undobegin
  1251.         // use a temporary clipboard
  1252.         clip = _ClipName
  1253.         setobj ClipName 'T' 'prf'
  1254.         copy
  1255.         fillblock ' '
  1256.         paste 'o'
  1257.         setobj ClipName clip 'prf'
  1258.         destroybuf 'T'
  1259.         undoend
  1260.       end
  1261.     end
  1262.  
  1263.     // reformat a block or the current paragraph
  1264.     function  formatblock2 (options)
  1265.       if not options then
  1266.         options = _FormatOpt
  1267.       end
  1268.  
  1269.       // advance cursor
  1270.       if not getlinelen and (pos 'c' options) then
  1271.         loop
  1272.           if not down then
  1273.             return
  1274.           end
  1275.           if getlinelen then
  1276.             break
  1277.           end
  1278.         end
  1279.       end
  1280.  
  1281.       undobegin
  1282.       if not mark? then
  1283.         if markpara options then
  1284.           markcolumn (getcol) _RMargin (getmarktop) (getmarkbot)
  1285.           flag = ON
  1286.         end
  1287.       end
  1288.       // special case for single lines
  1289.       if getmarkrows == 1 and getcol < getlinebeg then
  1290.         delchar getlinebeg - getcol
  1291.       else
  1292.         formatblock _LMargin _RMargin options
  1293.       end
  1294.  
  1295.       if flag then
  1296.         // advance cursor
  1297.         if pos 'c' options then
  1298.           row getmarkbot + 1
  1299.         end
  1300.         destroymark
  1301.       end
  1302.       undoend
  1303.     end
  1304.  
  1305.     // simple text quoting support for a block or the current paragraph
  1306.     function  quote
  1307.       undobegin
  1308.       if getmarkbuf <> getcurrbuf then
  1309.         tempmark = TRUE
  1310.         oldmark = usemark 'T'
  1311.         markpara
  1312.       end
  1313.       if mark? then
  1314.         shiftblock 1 '' '>'
  1315.         if tempmark then
  1316.           destroymark
  1317.           usemark oldmark
  1318.         end
  1319.       else
  1320.         say "Nothing to quote"
  1321.       end
  1322.       undoend
  1323.     end
  1324.  
  1325.     // sort a block
  1326.     function  sortblock2
  1327.       if mark? and (runcfg "sort") then
  1328.         sortblock _SortOpt
  1329.       end
  1330.     end
  1331.  
  1332.     // prompt to fill a block with a string
  1333.     function  fillblock2
  1334.       askx "Enter fill string" '' "fillblock"
  1335.     end
  1336.  
  1337.     // prompt to save a block
  1338.     function  saveblock2 (options file)
  1339.       var c1
  1340.       var c2
  1341.       if mark? then
  1342.         if not file then
  1343.           file = ask "Save block as" "_load"
  1344.         end
  1345.         if file then
  1346.           file = qualify file (getbufname)
  1347.           addhistory "_load" file
  1348.           if fileattr? file 'r' then
  1349.             say "Read Only!" 'b'
  1350.           else
  1351.             action = locase (askrac file)
  1352.             if pos action "ra" then
  1353.               send "oncomment" file ref c1 ref c2
  1354.               options = _SaveOpt + options
  1355.               if not saveblock file
  1356.                       (if? (pos 'e' options) 'e' + _TabWidth) + options +
  1357.                       (if? action == 'a' 'a')
  1358.                       '' '' '' (if? c1 c1 + _FoldSign) c2 then
  1359.                 msgbox "Save Failed!" "Error!" 'b'
  1360.               end
  1361.             end
  1362.           end
  1363.         end
  1364.       else
  1365.         say "No marked block" 'b'
  1366.       end
  1367.     end
  1368.  
  1369.     // left justify, center, or right justify a block
  1370.     function  justblock2 (options)
  1371.       justblock options '' _LMargin _RMargin
  1372.     end
  1373.  
  1374.     // destroy open and closed folds
  1375.     function  destroyfold2
  1376.       undobegin
  1377.       if not fold? then
  1378.         closefold
  1379.       end
  1380.       destroyfold
  1381.       undoend
  1382.     end
  1383.  
  1384.     // do fold operations on entire file
  1385.     function  foldall (options)
  1386.       undobegin
  1387.       oldmark = usemark 'T'
  1388.       markline 1 (getlines)
  1389.       foldblock options
  1390.       destroymark
  1391.       usemark oldmark
  1392.       undoend
  1393.     end
  1394.  
  1395.     // fold a block or the current paragraph
  1396.     function  foldblock2
  1397.       undobegin
  1398.       if mark? then
  1399.         foldblock
  1400.       elseif markpara then
  1401.         foldblock
  1402.         destroymark
  1403.       end
  1404.       undoend
  1405.     end
  1406.  
  1407.     // fold a block and destroy subfolds
  1408.     function  foldflat
  1409.       undobegin
  1410.       foldblock 'ds'
  1411.       foldblock
  1412.       undoend
  1413.     end
  1414.  
  1415.     // fold or unfold a line
  1416.     function  foldline (options)
  1417.       undobegin
  1418.       oldmark = usemark 'T'
  1419.       markline
  1420.       unfold = pos 'u' options
  1421.       if fold? then
  1422.         foldblock 'd'
  1423.         if not unfold or getmarkrows > 1 then
  1424.           bottom = actualrow (if? unfold -1 1) (getmarkbot)
  1425.           if not (getfold 'o' bottom) then
  1426.             markline (getrow) bottom
  1427.           end
  1428.           foldblock
  1429.         end
  1430.       else
  1431.         if not unfold then
  1432.           foldblock
  1433.         end
  1434.       end
  1435.       destroymark
  1436.       usemark oldmark
  1437.       undoend
  1438.     end
  1439.  
  1440.     // detab or entab the current file
  1441.     // (+width=detab, -width=entab)
  1442.     function  tabfile (width)
  1443.       undobegin
  1444.       oldmark = usemark 'T'
  1445.       markline 1 (getlines)
  1446.       tabblock (if? width width _TabWidth)
  1447.       destroymark
  1448.       usemark oldmark
  1449.       undoend
  1450.     end
  1451.  
  1452.     // insert a line after the current line with autoindent
  1453.     function  insline2
  1454.       undobegin
  1455.       insline
  1456.       if setting? 'A' then
  1457.         if getlinelen then
  1458.           col (getlinebeg)
  1459.         else
  1460.           nextline = getrow + 2
  1461.           if getlinelen nextline then
  1462.             col (getlinebeg nextline)
  1463.           end
  1464.         end
  1465.       end
  1466.       down
  1467.       undoend
  1468.     end
  1469.  
  1470.     // swap the current line with the next line
  1471.     function  swapline
  1472.       undobegin
  1473.       oldmark = usemark 'T'
  1474.       markline
  1475.       stopmark
  1476.       down
  1477.       moveblock
  1478.       destroymark
  1479.       usemark oldmark
  1480.       undoend
  1481.     end
  1482.  
  1483.     // center the current line
  1484.     function  centerline
  1485.       undobegin
  1486.       oldmark = usemark 'T'
  1487.       markline
  1488.       justblock 'c' '' _LMargin _RMargin
  1489.       destroymark
  1490.       usemark oldmark
  1491.       undoend
  1492.     end
  1493.  
  1494.     // comment or uncomment a line
  1495.     function  commentline (c1 c2)
  1496.       if not c1 then
  1497.         send "oncomment" (getbufname) ref c1 ref c2
  1498.         if not c1 then
  1499.           c1 = '>'
  1500.         end
  1501.       end
  1502.       undobegin
  1503.       column = getlinebeg
  1504.       if (gettext column (sizeof c1)) == c1 then
  1505.         delchar (sizeof c2) getlinelen - (sizeof c2) + 1
  1506.         delchar (sizeof c1) column
  1507.       elseif getlinelen then
  1508.         instext c1 (getlinebeg)
  1509.         if column then
  1510.           ovltext c2  getlinelen + 1
  1511.         end
  1512.       end
  1513.       down
  1514.       undoend
  1515.     end
  1516.  
  1517.     // find previous word
  1518.     function  prevword
  1519.       oldcolumn = getcol
  1520.       while (poschar _CSet (getchar)) and left do end
  1521.       if oldcolumn <> getcol then
  1522.         if poschar _CSet (getchar) then
  1523.           return
  1524.         end
  1525.         if oldcolumn - getcol > 1 then
  1526.           right
  1527.           return
  1528.         end
  1529.       end
  1530.       find _CSet '[r'
  1531.       while (poschar _CSet (getchar getcol - 1)) and left do end
  1532.     end
  1533.  
  1534.     // find next word
  1535.     function  nextword
  1536.       while poschar _CSet (getchar) do
  1537.         right
  1538.       end
  1539.       find _CSet '['
  1540.     end
  1541.  
  1542.     // change the case of the word at the cursor
  1543.     function  caseword (options charset)
  1544.       undobegin
  1545.       oldmark = usemark 'T'
  1546.       markword charset
  1547.       caseblock options
  1548.       destroymark
  1549.       usemark oldmark
  1550.       undoend
  1551.     end
  1552.  
  1553.     // open the filename at the cursor
  1554.     function  openword (charset)
  1555.       file = getword (if? charset charset _CSetB)
  1556.       if file then
  1557.         open file
  1558.       end
  1559.     end
  1560.  
  1561.     // delete the character at the cursor
  1562.     function  delchar2
  1563.       undobegin
  1564.       if getcol > getlinelen and _DelJoin == 'y' then
  1565.         joinline
  1566.       else
  1567.         delchar
  1568.         if setting? 'L' then
  1569.           livewrap
  1570.         end
  1571.       end
  1572.       undoend
  1573.     end
  1574.  
  1575.     // backspace
  1576.     function  backsp
  1577.       undobegin
  1578.       if getcol > 1 then
  1579.         left
  1580.         if not insert? and _BakOvl == 'y' then
  1581.           ovltext ' '
  1582.         else
  1583.           delchar
  1584.           if setting? 'L' then
  1585.             livewrap
  1586.           end
  1587.         end
  1588.       elseif getrow > 1 and _BakJoin == 'y' then
  1589.         up
  1590.         col getlinelen + 1
  1591.         joinline
  1592.       end
  1593.       undoend
  1594.     end
  1595.  
  1596.     // delete right word
  1597.     function  delword (charset)
  1598.       if not charset then
  1599.         charset = _CSet
  1600.       end
  1601.       undobegin
  1602.       if getcol > getlinelen then
  1603.         joinline
  1604.       else
  1605.         p = posnot charset (gettext (getcol))
  1606.         if p > 1 then
  1607.           delchar p - 1
  1608.         end
  1609.         delchar (
  1610.           if p then
  1611.             if getchar == ' ' and
  1612.                  (getcol == 1 or
  1613.                  (posnot charset (getchar getcol - 1))) then
  1614.               (posnot ' ' (gettext (getcol))) - 1
  1615.             else
  1616.               p == 1
  1617.             end
  1618.           else
  1619.             getlinelen
  1620.           end
  1621.         )
  1622.       end
  1623.       if setting? 'L' then
  1624.         livewrap
  1625.       end
  1626.       undoend
  1627.     end
  1628.  
  1629.     // splitline with autoindent
  1630.     function splitline2 (column)
  1631.       undobegin
  1632.       b = getlinebeg
  1633.       if splitline column then
  1634.         if not setting? 'A' then
  1635.           b = _LMargin
  1636.         end
  1637.         if b > 1 then
  1638.           pushcursor
  1639.           down
  1640.           oldmark = usemark 'T'
  1641.           markline
  1642.           shiftblock (if? getcol > b  b  (getcol)) - 1
  1643.           destroymark
  1644.           usemark oldmark
  1645.           popcursor
  1646.         end
  1647.       end
  1648.       undoend
  1649.     end
  1650.  
  1651.     // <enter> key behavior
  1652.     function  enter
  1653.  
  1654.       // terminate a word for text translation
  1655.       lastrow = getrow
  1656.       if getcol == getlinelen + 1 and getlinelen then
  1657.         if setting? 'T' then
  1658.           send <char> ' '
  1659.         end
  1660.       end
  1661.  
  1662.       if getrow == lastrow then
  1663.         case (if? (insert?) _EnterIns _EnterOvl)
  1664.           when 'i'
  1665.             insline2
  1666.           when 's'
  1667.             if fold? then
  1668.               insline2
  1669.             else
  1670.               startcolumn = getlinebeg
  1671.               length = getlinelen
  1672.               splitline2
  1673.               down
  1674.               if setting? 'A' then
  1675.                 if length then
  1676.                   col startcolumn
  1677.                 end
  1678.               else
  1679.                 startcolumn = _LMargin
  1680.                 col (if? startcolumn startcolumn 1)
  1681.               end
  1682.             end
  1683.           otherwise
  1684.             down
  1685.             col (if? (getlinelen) (getlinebeg) _LMargin)
  1686.         end
  1687.       end
  1688.     end
  1689.  
  1690.     // for use by variable tab right
  1691.     function  vtabr
  1692.       i = 1
  1693.       while i <= arg do
  1694.         if (arg i) <= getcol then
  1695.           i = i + 1
  1696.         else
  1697.           return arg i
  1698.         end
  1699.       end
  1700.       return 0
  1701.     end
  1702.  
  1703.     // for use by variable tab left
  1704.     function  vtabl
  1705.       i = arg
  1706.       while i do
  1707.         if (arg i) >= getcol then
  1708.           i = i - 1
  1709.         else
  1710.           return arg i
  1711.         end
  1712.       end
  1713.       return 0
  1714.     end
  1715.  
  1716.     // tab support
  1717.     function  tabfunc (next)
  1718.  
  1719.       oldcolumn = getcol
  1720.  
  1721.       // smart tabs
  1722.       if setting? 'S' then
  1723.         prevline = getrow - 1
  1724.         while prevline and not (getlinelen prevline) do
  1725.           prevline = prevline - 1
  1726.         end
  1727.         if prevline then
  1728.           pushcursor
  1729.           row prevline
  1730.           send (if? next "nextword" "prevword")
  1731.           if prevline == getrow then
  1732.             newcolumn = getcol
  1733.           end
  1734.           popcursor
  1735.         end
  1736.       end
  1737.  
  1738.       // variable tabs
  1739.       if not newcolumn then
  1740.         if setting? 'V' then
  1741.           newcolumn = eval (if? next "vtabr " "vtabl ") + _VarTabs
  1742.         end
  1743.  
  1744.         // standard interval tabs
  1745.         if not newcolumn then
  1746.           width = _TabWidth
  1747.           if not width then
  1748.             width = 8
  1749.           end
  1750.           newcolumn = oldcolumn +
  1751.                         if next then
  1752.                           width - (oldcolumn - 1) mod width
  1753.                         elseif oldcolumn > 1 then
  1754.                           -((oldcolumn - 2) mod width + 1)
  1755.                         end
  1756.         end
  1757.       end
  1758.  
  1759.       // move to tabstop and shift text if needed
  1760.       if newcolumn then
  1761.         if _TabShift == 'y' and insert? then
  1762.           if newcolumn < oldcolumn then
  1763.             delchar  oldcolumn - newcolumn  newcolumn
  1764.           elseif newcolumn > oldcolumn then
  1765.             instext (copystr ' ' newcolumn - oldcolumn)
  1766.           end
  1767.         end
  1768.         col newcolumn
  1769.       end
  1770.     end
  1771.  
  1772.     // tab left and right
  1773.     function  tabright    tabfunc 1  end
  1774.     function  tableft     tabfunc    end
  1775.  
  1776.     // prompt to verify close
  1777.     function  close?
  1778.       if bufchanged? and not getprevcurs then
  1779.         savechanges = popup "ync"  "Save changes to " +
  1780.                                         (getname (getbufname)) + '?'
  1781.         if savechanges == "Yes" then
  1782.           if not save then
  1783.             return ''
  1784.           end
  1785.         end
  1786.         icompare savechanges "Yes" "No"
  1787.       else
  1788.         1
  1789.       end
  1790.     end
  1791.  
  1792.     // close an edit window
  1793.     function  close (options)
  1794.       if pos 's' options then
  1795.         if save then
  1796.           pass
  1797.         end
  1798.       elseif close? then
  1799.         pass
  1800.       end
  1801.     end
  1802.  
  1803.     // open and insert prompt
  1804.     function  askinsert (file)
  1805.       if not file then
  1806.         file = ask  "File to insert into " + (getname (getbufname)) "_load"
  1807.       end
  1808.       if file then
  1809.         // addhistory not needed for open
  1810.         old_size = getlines
  1811.         undobegin
  1812.         if open file 'i' then
  1813.           // mark the inserted text
  1814.           if not (dir? (getbufname)) then
  1815.             if getlines > old_size then
  1816.               markline  getrow + 1  getrow + getlines - old_size
  1817.             end
  1818.           end
  1819.         end
  1820.         undoend
  1821.       end
  1822.     end
  1823.  
  1824.     // prompt to change the current file name
  1825.     function  askname
  1826.       newname = ask  "Rename " + (getname (getbufname)) + " to"  "_load"
  1827.       if newname then
  1828.         case setname newname
  1829.           when -1 say "Failed" 'b'
  1830.           when -2 say "Failed - file already loaded" 'b'
  1831.           otherwise
  1832.             addhistory "_load" (getbufname)
  1833.         end
  1834.       end
  1835.     end
  1836.  
  1837.     // search and replace with messages and highlighting
  1838.     function  search2 (search_str reverse again)
  1839.       var opt
  1840.       var rpl
  1841.       n = search search_str reverse again ref opt ref rpl
  1842.       if n then
  1843.         // replace occurred
  1844.         if rpl then
  1845.           display
  1846.           say (thousands n) + " changes made"
  1847.         // count occurrences
  1848.         elseif pos 'a' opt then
  1849.           display
  1850.           say (thousands n) + " occurrences of '" + search_str + "' found"
  1851.         // search only
  1852.         else
  1853.           onfound n
  1854.         end
  1855.       else
  1856.         display
  1857.         say "'" + search_str + "' not found"  'b'
  1858.       end
  1859.       return n
  1860.     end
  1861.  
  1862.     // find prompt
  1863.     function  askfind (reverse)
  1864.       search_string = if _PromptStyle == 'd' then
  1865.                         finddlg
  1866.                       else
  1867.                         ask "[string/abgirswx] Find"  "_find"
  1868.                       end
  1869.       if search_string then
  1870.         search2 search_string reverse
  1871.         addhistory "_find" search_string
  1872.       end
  1873.     end
  1874.  
  1875.     // replace prompt
  1876.     function  askrepl (reverse)
  1877.       search_string = if _PromptStyle == 'd' then
  1878.                         repldlg
  1879.                       else
  1880.                         ask "[string/replstr/abgirswx] Repl"  "_find"
  1881.                       end
  1882.       if search_string then
  1883.         search2 search_string reverse
  1884.         addhistory "_find" search_string
  1885.       end
  1886.     end
  1887.  
  1888.     // do the last find/replace operation
  1889.     // (reverse=r reverses the search direction)
  1890.     function  findlast (reverse)
  1891.       search2 (gethiststr "_find") reverse TRUE
  1892.     end
  1893.  
  1894.     // incremental search
  1895.     function  isearch
  1896.  
  1897.       var search_string
  1898.  
  1899.       repeat
  1900.  
  1901.         settitle  "I-search for [" + search_string + "] "
  1902.         keycode = getkey
  1903.         options = _SearchOpt
  1904.         new_char = ''
  1905.  
  1906.         case  keycode
  1907.  
  1908.           when <backspace>
  1909.             if search_string then
  1910.               popcursor
  1911.               search_string = if (sizeof search_string) > 1 then
  1912.                                 search_string [1 : (sizeof search_string) - 1]
  1913.                               else
  1914.                                 ''
  1915.                               end
  1916.               if not search_string then
  1917.                 display
  1918.               end
  1919.               options = '*'
  1920.             end
  1921.  
  1922.           when <ctrl p>, <ctrl r>
  1923.             options = 'r'
  1924.  
  1925.           when <ctrl n>, <ctrl l>
  1926.             // do nothing
  1927.  
  1928.           when <ctrl g>, <ctrl b>
  1929.             options = 'g'
  1930.  
  1931.           otherwise
  1932.             keyname = getkeyname keycode
  1933.             if (sizeof keyname) == 3 then
  1934.               pushcursor
  1935.               new_char = keyname [2]
  1936.               options = '*'
  1937.             else
  1938.  
  1939.               // restore window title
  1940.               settitle (getbufname)
  1941.               display
  1942.  
  1943.               // clear all pushed cursors
  1944.               popcursor "ad"
  1945.               addhistory "_find" search_string
  1946.  
  1947.               if keycode <> <enter> and keycode <> <esc> then
  1948.                 queuekey keycode
  1949.               end
  1950.  
  1951.               done = TRUE
  1952.             end
  1953.         end
  1954.  
  1955.         if not done and (search_string or new_char) then
  1956.           new_string = concat search_string new_char
  1957.           str_length = find new_string  _SearchOpt + options
  1958.           if str_length then
  1959.             onfound str_length
  1960.             search_string = new_string
  1961.           else
  1962.             say  new_string + " not found"  'b'
  1963.             if new_char then
  1964.               popcursor
  1965.             end
  1966.             onfound (sizeof search_string)
  1967.           end
  1968.         end
  1969.  
  1970.       until done
  1971.     end
  1972.  
  1973.  
  1974.     // find occurrences search
  1975.     function  findo (string_and_opt)
  1976.  
  1977.       var search_string
  1978.       var options
  1979.       var o
  1980.  
  1981.       n = splitstr '' string_and_opt
  1982.                    ref search_string  ref options  ref o
  1983.  
  1984.       // initialize search options
  1985.       if n >= 2 then
  1986.         if n > 2 then
  1987.           options = o
  1988.         end
  1989.       else
  1990.         options = _SearchOpt
  1991.       end
  1992.       if pos 'g' options then
  1993.         options = sub 'g' '' options
  1994.       end
  1995.       options = options + '*'
  1996.  
  1997.       // do the search
  1998.       buffer = createbuf
  1999.       ovltext "≡≡≡≡≡≡ Select this line to edit occurrences ≡≡≡≡≡≡"
  2000.       gotobuf (getprevbuf)
  2001.       pushcursor
  2002.       gotopos 1 1
  2003.       while find  search_string options  do
  2004.         addline  getrow + ": " + gettext  '' '' buffer
  2005.         col MAX_COL
  2006.       end
  2007.       popcursor
  2008.  
  2009.       // display occurrences
  2010.       if (getlines buffer) > 1 then
  2011.         bname = getbufname
  2012.         line = popup buffer
  2013.                  "Occurrences of '" + search_string + "' in "
  2014.                  + (getname bname) + " - " + ((getlines buffer) - 1) +
  2015.                  " lines"   getvidcols - 11 getvidrows - 8
  2016.         if line then
  2017.           if line [1] == '≡' then
  2018.             delline 1 1 buffer
  2019.             setbufname (qualify "TEMP.TXT" bname) buffer
  2020.             openbuf buffer
  2021.           else
  2022.             destroybuf buffer
  2023.             gotopos 1 line [1 : (pos ':' line) - 1]
  2024.             onfound (find search_string  options + '*l')
  2025.           end
  2026.         end
  2027.       else
  2028.         destroybuf buffer
  2029.         display
  2030.         say  "'" + string_and_opt + "' not found"  'b'
  2031.       end
  2032.     end
  2033.  
  2034.     // prompt to find occurrences
  2035.     function  askfindo
  2036.       search_str = ask "[string/birswx] Find occurrences of"  "_find"
  2037.       if search_str then
  2038.         findo search_str
  2039.         addhistory "_find" search_str
  2040.       end
  2041.     end
  2042.  
  2043.     // find all occurrences of last find string
  2044.     function  findlasto
  2045.       findo (gethiststr "_find")
  2046.     end
  2047.  
  2048.     // find matching character (){}[]<>
  2049.     function  gotomatch2
  2050.       if gotomatch "(){}[]<>" then
  2051.         onfound 1
  2052.       else
  2053.         say "Not found" 'b'
  2054.       end
  2055.     end
  2056.  
  2057.     // goto column
  2058.     function  col2 (column)
  2059.       case column [1]
  2060.         when '+'   right  column [2 : TO_END]
  2061.         when '-'   left   column [2 : TO_END]
  2062.         otherwise  col (if? column > MAX_COL MAX_COL column)
  2063.       end
  2064.       onfound
  2065.     end
  2066.  
  2067.     // goto line
  2068.     function  row2 (line)
  2069.       case line [1]
  2070.         when '+'   down line [2 : TO_END]
  2071.         when '-'   up   line [2 : TO_END]
  2072.         otherwise  row (if? line > getlines (getlines) line)
  2073.       end
  2074.       onfound
  2075.     end
  2076.  
  2077.     // goto line prompt
  2078.     function  askrow
  2079.       askx "Line number" "_line" "row2"
  2080.     end
  2081.  
  2082.     // goto column prompt
  2083.     function  askcol
  2084.       askx "Column Number" '' "col2"
  2085.     end
  2086.  
  2087.     // set a quick bookmark
  2088.     function  quickbook
  2089.       _bk = _bk + 1
  2090.       bookmark = "Book" + _bk
  2091.       setbook bookmark
  2092.       display
  2093.       say "Bookmark " + bookmark + " set"
  2094.     end
  2095.  
  2096.     // place a bookmark
  2097.     function  placebook (bookmark)
  2098.       if not bookmark then
  2099.         bookmark = ask "Bookmark Name" "_book"
  2100.       end
  2101.       if bookmark then
  2102.         setbook bookmark
  2103.         display
  2104.         say "Bookmark '" + bookmark + "' set"
  2105.       end
  2106.     end
  2107.  
  2108.  
  2109.     // Go to the compiler error on the current line of a compiler
  2110.     // error output file. This function recognizes compiler errors
  2111.     // of the form:
  2112.     //
  2113.     //   <text>  FILENAME.EXT  <text>  LINENUMBER  <text> : MESSAGE
  2114.     //
  2115.     // (implemented by using the 'parse' builtin function with regular
  2116.     // expression searching)
  2117.  
  2118.     function  gotoerror
  2119.       var filename
  2120.       var line
  2121.       var message
  2122.  
  2123.       // filename charclass to use (max closure without the period)
  2124.       fileset = "[a-zA-Z0-9_\-/\\\\@~:^!#$%&`']#"
  2125.  
  2126.       // parse the current line into filename/line/message variables
  2127.       if parse '.*{' + fileset + '\\.' + fileset + "}.*{[0-9]#}.*:{.*}$"
  2128.                (gettext) 'x' ref filename ref line ref message then
  2129.  
  2130.         // open the file
  2131.         if open filename then
  2132.  
  2133.           // get the real line number if folds are present
  2134.           if (getfold 'n') and
  2135.              (loadbuf (getbufname) '' (hex2bin _LineDlm) 'x') then
  2136.             row line
  2137.             line = line - (find _FoldSign 'ar')
  2138.             destroybuf
  2139.           end
  2140.  
  2141.           row line
  2142.  
  2143.           // open folds until the line is exposed
  2144.           while (getfold 'c') and getrow <> line do
  2145.             openfold
  2146.             row line
  2147.           end
  2148.  
  2149.           col (getlinebeg)
  2150.           send "onfound"
  2151.           say  message + '  '
  2152.           return
  2153.         end
  2154.       end
  2155.       display
  2156.       say "Compiler message not recognized."
  2157.     end
  2158.  
  2159.  
  2160.     // backup a file and return the backup filename if sucessful
  2161.     function  backup (file)
  2162.       if locatefile file then
  2163.         dir = _BackupDir
  2164.         if dir then
  2165.           if (sizeof dir) > 3 and  dir [LAST_CHAR] == "\\" then
  2166.             dir = dir [1 : (sizeof dir) - 1]
  2167.           end
  2168.           createdir dir
  2169.           dir = qualify dir
  2170.           backup_file = if pos "*.*" dir then
  2171.                           qualify (getname file) dir
  2172.                         else
  2173.                           msgbox "Unable to create backup file!"
  2174.                                  "Warning!"
  2175.                           return 1
  2176.                         end
  2177.         else
  2178.           backup_file = forceext file _BackupExt
  2179.         end
  2180.  
  2181.         // delete the old backup file
  2182.         deletefile backup_file
  2183.  
  2184.         // attempt a rename
  2185.         if not renamefile file backup_file then
  2186.           // try copy if rename fails
  2187.           if (copyfile file backup_file) <= 0 then
  2188.             msgbox "File backup failed!" "Error"
  2189.             return 0
  2190.           end
  2191.         end
  2192.         return backup_file
  2193.       else
  2194.         return 1
  2195.       end
  2196.     end
  2197.  
  2198.     // save the current file to disk
  2199.     function  save (file options)
  2200.       var c1
  2201.       var c2
  2202.  
  2203.       // check for a truncated file
  2204.       if trunc? and
  2205.          not (icompare (popup "ok" "Truncated file - are you sure?") "Ok") then
  2206.         return
  2207.       end
  2208.  
  2209.       file = if file then
  2210.                qualify file (getbufname)
  2211.              else
  2212.                getbufname
  2213.              end
  2214.       // check for read/only
  2215.       if (bufferflag? 'r') or (fileattr? file 'r') then
  2216.         say "Read Only!" 'b'
  2217.       else
  2218.         backup_file = 1
  2219.         if setting? 'B' then
  2220.           backup_file = backup file
  2221.         end
  2222.         if not backup_file then
  2223.           say "Backup failed" 'b'
  2224.         else
  2225.           send "onsave" file
  2226.  
  2227.           // get fold comments for the file (if any)
  2228.           send "oncomment" file ref c1 ref c2
  2229.           options = _SaveOpt + options
  2230.           if not savebuf file
  2231.                    (if? (pos 'e' options) 'e' + _TabWidth) + options  ''
  2232.                    (if not getbinarylen then hex2bin _LineDlm end) ''
  2233.                    (if? c1 c1 + _FoldSign) c2 then
  2234.  
  2235.             // restore the backup after save failure
  2236.             if backup_file <> 1 then
  2237.               if not renamefile backup_file file then
  2238.                 copyfile backup_file file
  2239.               end
  2240.             end
  2241.             msgbox "Save failed!  Check file path / file attributes / disk space"  "Error!" 'b'
  2242.             return 0
  2243.           else
  2244.             1
  2245.           end
  2246.         end
  2247.       end
  2248.     end
  2249.  
  2250.     // save-as prompt
  2251.     function  asksaveas (options)
  2252.       file = ask "Save " + (getname (getbufname)) + " as"  "_load"
  2253.       if file then
  2254.         file = qualify file (getbufname)
  2255.         addhistory "_load" file
  2256.         save file options
  2257.       end
  2258.     end
  2259.  
  2260.     // start, stop, or do autosave
  2261.     function  autosave (seconds)
  2262.       if not arg then
  2263.         if bufchanged? then
  2264.           save
  2265.         end
  2266.       elseif seconds <= 0 then
  2267.         destroytimer "asav"
  2268.       else
  2269.         setrepeat "asav" seconds * 1000  '' "autosave"
  2270.       end
  2271.     end
  2272.  
  2273.     // prompt for autosave interval in seconds
  2274.     function  askasave
  2275.       seconds = ask "Autosave interval in secs (-1=disable)"
  2276.       if seconds then
  2277.         autosave seconds
  2278.       end
  2279.     end
  2280.  
  2281.     // highlight all occurrences of the word at the cursor
  2282.     function  hiliteword
  2283.       sobj = send "onsyntax" (getbufname)
  2284.       if not sobj then
  2285.         setting 'X' DEFAULT
  2286.         sobj = "syndef"
  2287.       end
  2288.       if sobj then
  2289.         w = send "getword" "a-zA-Z_0-9?"
  2290.         if w then
  2291.           // create a color selection menu
  2292.           menu "hcolor"
  2293.             item " &None"           -1
  2294.             item " &Default"        -2
  2295.             item "-"
  2296.             item " &Black"          color white on black
  2297.             item " B&lue"           color yellow on blue
  2298.             item " &Green"          color white on green
  2299.             item " &Cyan"           color white on cyan
  2300.             item " &Red"            color white on red
  2301.             item " &Magenta"        color white on magenta
  2302.             item " Br&own"          color white on brown
  2303.             item " Gr&ay"           color white on gray
  2304.             item "-"
  2305.             item " Dar&kgray"       color white on darkgray
  2306.             item " Brightbl&ue"     color white on brightblue
  2307.             item " Brightgr&een"    color black on brightgreen
  2308.             item " Brig&htcyan"     color black on brightcyan
  2309.             item " Br&ightred"      color white on brightred
  2310.             item " Brightmagen&ta"  color white on brightmagenta
  2311.             item " &Yellow"         color black on yellow
  2312.             item " &White"          color black on white
  2313.           end
  2314.           setbufname "colorlist"
  2315.           hcolor = popup "hcolor" "select a color "
  2316.           // destroy the menu
  2317.           destroybuf "hcolor"
  2318.           if hcolor then
  2319.             if hcolor == -1 then
  2320.               unsetx w sobj
  2321.             else
  2322.               setxobj w (if? hcolor == -2 '' hcolor) sobj
  2323.             end
  2324.           end
  2325.           display
  2326.         end
  2327.       end
  2328.     end
  2329.  
  2330.     // live word wrap support
  2331.     function  livewrap
  2332.  
  2333.       if fold? then
  2334.         return
  2335.       end
  2336.  
  2337.       startcol = getlinebeg
  2338.       if getrow < getlines and (getlinelen  getrow + 1) then
  2339.         n = getlinebeg  getrow + 1
  2340.         startcol = if? n < startcol  n  startcol
  2341.       elseif not getlinelen or not (setting? 'A') then
  2342.         startcol = _LMargin
  2343.       end
  2344.  
  2345.       if getcol < startcol then
  2346.         startcol = getcol
  2347.       end
  2348.  
  2349.       if getlinelen then
  2350.         undobegin
  2351.         saved_char = getchar
  2352.         ovltext '²'
  2353.  
  2354.         // mark to the end of the paragraph
  2355.         pushcursor
  2356.         top = getrow
  2357.         while down and getlinelen do end
  2358.         if not getlinelen then
  2359.           up
  2360.         end
  2361.         bottom = getrow
  2362.         popcursor
  2363.  
  2364.         // reformat
  2365.         oldmark = usemark 'T'
  2366.         markcolumn startcol _RMargin top bottom
  2367.         formatblock '' '' "kr"
  2368.         destroymark
  2369.         usemark oldmark
  2370.  
  2371.         // find the original cursor position
  2372.         col 1
  2373.         find '²' '*'
  2374.         ovltext (if? saved_char saved_char ' ')
  2375.  
  2376.         undoend
  2377.       end
  2378.     end
  2379.  
  2380.     // enter a character or string at the cursor, with support for:
  2381.     //   - match character
  2382.     //   - translate
  2383.     //   - standard word wrap
  2384.     //   - live word wrap
  2385.  
  2386.     function  write (write_str)
  2387.  
  2388.       // group together as one undoable operation
  2389.       undobegin
  2390.  
  2391.       // enter the character or string at the cursor and
  2392.       // advance the cursor
  2393.       writetext write_str
  2394.  
  2395.       // get the current window settings
  2396.       setting_str = getsettings
  2397.  
  2398.       // match character
  2399.       if pos 'M' setting_str then
  2400.         instext ( case write_str
  2401.                     when '"'  '"'
  2402.                     when '('  ')'
  2403.                     when '['  ']'
  2404.                     when '{'  '}'
  2405.                     otherwise ''
  2406.                   end )
  2407.       end
  2408.  
  2409.       // translate
  2410.       if pos 'T' setting_str then
  2411.  
  2412.         // delimited lookup?
  2413.         to_word_end = if? (posnot _TranCSet write_str) 2 1
  2414.  
  2415.         // get the last word typed
  2416.         word_str = getword _TranCSet (getcol - to_word_end)
  2417.         if word_str then
  2418.           lookup_str = word_str + (if? to_word_end == 2 '*')
  2419.  
  2420.           // lookup the word in the translate object
  2421.           value = lookup lookup_str _TranObj
  2422.  
  2423.           if value then
  2424.             // is it a function? ..then evaluate it
  2425.             if function? lookup_str _TranObj then
  2426.               eval value
  2427.  
  2428.             // otherwise replace the word
  2429.             else
  2430.               word_column = getcol - (sizeof word_str) - to_word_end + 1
  2431.               delchar (sizeof word_str) word_column
  2432.               instext value word_column
  2433.               col word_column + (sizeof value) + to_word_end - 1
  2434.             end
  2435.           end
  2436.         end
  2437.       end
  2438.  
  2439.       // check for word wrap and live wrap
  2440.       if getlinelen > _RMargin then
  2441.  
  2442.         // live word wrap
  2443.         if pos 'L' setting_str then
  2444.           livewrap
  2445.  
  2446.         // standard word wrap
  2447.         elseif (pos 'W' setting_str) and (not fold?) then
  2448.           column = getcol
  2449.           limit = _RMargin + 1
  2450.           if column > limit then
  2451.             if write_str <> ' ' then
  2452.               first_col = if? (setting? 'A') (getlinebeg) _LMargin
  2453.               split_col = pos ' ' (gettext 1 limit) 'r'
  2454.               split_col = if? split_col > first_col  split_col + 1  limit
  2455.               splitline split_col
  2456.               down
  2457.               markline '' '' 'T'
  2458.               shiftblock  first_col - 1 'T'
  2459.               destroymark 'T'
  2460.               col  column - split_col + first_col
  2461.             end
  2462.           end
  2463.         end
  2464.       end
  2465.  
  2466.       undoend
  2467.     end
  2468.  
  2469.     // enter a date/time stamp at the cursor
  2470.     function  timestamp
  2471.       write getdate + ' ' + gettime
  2472.     end
  2473.  
  2474.  
  2475. // -------------------------------------------------------------------
  2476. //  File Manager windows
  2477. // -------------------------------------------------------------------
  2478.  
  2479.   object  fmgr
  2480.  
  2481.     // return the file name for fmgr commands
  2482.     function  fname2
  2483.       if fmark? then
  2484.         "MARKED FILES"
  2485.       else
  2486.         getname (getffile)
  2487.       end
  2488.     end
  2489.  
  2490.     // error notification
  2491.     function  ferror (s)
  2492.       msgbox  s + " Failed"  "Error!" 'b'
  2493.     end
  2494.  
  2495.     // fmgr confirmation prompt
  2496.     function  fconfirm (confirm pstring func)
  2497.       if (icompare confirm 'n') or
  2498.          (icompare (popup "ok" pstring + ' ' + fname2 + '?') "ok") then
  2499.         fdomark func
  2500.         reopen
  2501.       end
  2502.     end
  2503.  
  2504.     // internal fopen
  2505.     function  fopn (file options)
  2506.       if file then
  2507.         openf file options
  2508.       else
  2509.         fdomark "fopn" options
  2510.       end
  2511.     end
  2512.  
  2513.     // fmgr open file(s) command
  2514.     function  fopen (options)
  2515.  
  2516.       var searchopt
  2517.  
  2518.       if pos '1' options then
  2519.         if shiftkey? then
  2520.           options = options + 'v'
  2521.         end
  2522.         scanstr = fscanstr
  2523.         openf '' options
  2524.  
  2525.         // find first occurrence for scan windows
  2526.         if scanstr then
  2527.           addhistory "_find" scanstr
  2528.           splitstr '' scanstr '' ref searchopt
  2529.           gotopos 1 (if? (pos 'r' searchopt) (getlines) 1)
  2530.           send "onfound" (search scanstr)
  2531.         end
  2532.  
  2533.       else
  2534.         fopn '' options
  2535.       end
  2536.     end
  2537.  
  2538.     // fmgr change file attributes command
  2539.     function  fattr (file attr)
  2540.       if file then
  2541.         chgfileattr file attr
  2542.       else
  2543.         attr = ask "New attributes [AHSR] for " + fname2
  2544.         if attr then
  2545.           fdomark "fattr" (if? attr <> ' ' attr)
  2546.           reopen
  2547.         end
  2548.       end
  2549.     end
  2550.  
  2551.     // fmgr delete file(s) command
  2552.     function  fdelete (file)
  2553.       if file then
  2554.         if pos "*.*" file then
  2555.           file = getpath file
  2556.         end
  2557.         if not deletefile file 'd' then
  2558.           ferror "Delete"
  2559.         end
  2560.       else
  2561.         fconfirm _ConDel "Delete" "fdelete"
  2562.       end
  2563.     end
  2564.  
  2565.     // fmgr touch file(s) command
  2566.     function  ftouch (file)
  2567.       if file then
  2568.         if not touchfile file then
  2569.           ferror "Touch"
  2570.         end
  2571.       else
  2572.         fconfirm _ConTch "Touch" "ftouch"
  2573.       end
  2574.     end
  2575.  
  2576.     // print a file or directory with the current printer settings
  2577.     function  printfile (file)
  2578.       if loadbuf file '' '' _FmgrOpt _TruncLength then
  2579.         print
  2580.         destroybuf
  2581.       end
  2582.     end
  2583.  
  2584.     // fmgr print file(s) command
  2585.     function  fprint (file)
  2586.       if file then
  2587.         if not printfile file then
  2588.           ferror "Print"
  2589.         end
  2590.       else
  2591.         fconfirm 'y' "Print" "fprint"
  2592.       end
  2593.     end
  2594.  
  2595.     // fmgr run file command
  2596.     function  frun (options)
  2597.       run (getffile) options
  2598.       reopen
  2599.     end
  2600.  
  2601.     // fmgr rename file command
  2602.     function  frename
  2603.       oldname = getffile
  2604.       newname = ask  "Rename " + (getname oldname) + " to"  "_load"
  2605.       if newname then
  2606.         if renamefile oldname (qualify newname (getbufname)) then
  2607.           reopen
  2608.         else
  2609.           ferror "Rename"
  2610.         end
  2611.       end
  2612.     end
  2613.  
  2614.     // fmgr copy (or move) file(s) command
  2615.     function  fcopy (source dest options)
  2616.       if source then
  2617.         if dir? dest then
  2618.           dest = qualify (getname source) dest
  2619.         end
  2620.         action = askrac dest
  2621.         if pos action "ra" 'i' then
  2622.           move? = options == 'm'
  2623.           say (if? move? "Mov" "Copy") + "ing " + source "..."
  2624.           if not move? or (icompare action 'a') or not (renamefile source dest) then
  2625.             if not copyfile source dest (if? (icompare action 'a') 'a') then
  2626.               ferror (if? move? "Move" "Copy")
  2627.               fdobrk
  2628.             else
  2629.               if move? then
  2630.                 deletefile source
  2631.               end
  2632.             end
  2633.           end
  2634.         end
  2635.       else
  2636.         if fmark? then
  2637.           dir_dest = qualify (getffile)
  2638.           if not dir? dir_dest then
  2639.             dir_dest = ''
  2640.           end
  2641.         end
  2642.         dest = ask (if? options == 'm' "Move " "Copy ") + fname2 + " to"
  2643.                    "_load" dir_dest
  2644.         if dest then
  2645.           fdomark "fcopy" (qualify dest (getbufname)) options
  2646.           reopen
  2647.         end
  2648.       end
  2649.     end
  2650.  
  2651.     // fmgr move file(s) command
  2652.     function  fmove
  2653.       fcopy '' '' 'm'
  2654.     end
  2655.  
  2656.     // fmgr create new directory command
  2657.     function  fmkdir
  2658.       dir = ask "New directory name" "_load"
  2659.       if dir then
  2660.         if createdir (qualify dir (getbufname)) then
  2661.           reopen
  2662.         else
  2663.           ferror "Create directory"
  2664.         end
  2665.       end
  2666.     end
  2667.  
  2668.  
  2669. // -------------------------------------------------------------------
  2670. //  On-Event functions called by the editor
  2671. // -------------------------------------------------------------------
  2672.  
  2673.   // edit windows & file manager windows only
  2674.   object  edit_fmgr
  2675.  
  2676.     // called while loading files
  2677.     function  onloading (lines)
  2678.       say (if? lines  "Loading [" + lines + "]..."  getbufname)
  2679.     end
  2680.  
  2681.     // called while saving files
  2682.     function  onsaving (lines)
  2683.       say (if? lines  "Saving [" + lines + "]..."  getbufname)
  2684.     end
  2685.  
  2686.     // called while printing files
  2687.     function  onprinting (lines)
  2688.       say (if? lines  "Printing [" + lines + "]... <ctrl break> to stop "
  2689.            getbufname)
  2690.     end
  2691.  
  2692.     // called while scanning files
  2693.     function  onscanning (file found)
  2694.  
  2695.       // create scan progress window
  2696.       if not window? 'scan' then
  2697.  
  2698.         obj = geteventobj
  2699.         createwindow 'scan'
  2700.         setwinobj
  2701.         setframe ">b"
  2702.         setcolor  border_color   color white on gray
  2703.         setcolor  text_color     color black on gray
  2704.         settitle "Scanning" 'c'
  2705.         setborder "1i"
  2706.         setshadow 2 1
  2707.  
  2708.         // center the window
  2709.         width = (sizeof (getpath file)) + 24
  2710.         height = 16
  2711.         ox = (getvidcols - width) / 2
  2712.         oy = (getvidrows - height) / 2
  2713.         sizewindow ox oy ox + width oy + height "ad"
  2714.         writestr   file + "..."
  2715.         eventobject obj
  2716.  
  2717.       elseif found then
  2718.         writestr " FOUND" (color brightgreen on gray) (getcoord 'x1') - 7
  2719.  
  2720.       elseif file then
  2721.         writeline
  2722.         writestr   file + "..."
  2723.  
  2724.       else
  2725.         obj = geteventobj
  2726.         destroywindow
  2727.         eventobject obj
  2728.       end
  2729.  
  2730.       display
  2731.     end
  2732.  
  2733.     // called while compiling files
  2734.     function  oncompiling (file lines)
  2735.       say (if? lines  "Compiling " + file + " [" + lines + "]..."  getbufname)
  2736.     end
  2737.  
  2738.  
  2739.   // edit windows only
  2740.   object  edit
  2741.  
  2742.     // called after a file is opened and before it's displayed
  2743.     function  onopen
  2744.  
  2745.       // set window event object
  2746.       setwinobj "edit"
  2747.  
  2748.       // default window settings (if not remembered by open)
  2749.       if not getsettings then
  2750.         setting _DefaultSet ON
  2751.       end
  2752.  
  2753.       // check for file truncation
  2754.       if trunc? then
  2755.         display
  2756.         say "File Truncated!" 'b'
  2757.       end
  2758.     end
  2759.  
  2760.     // called immediately before a file is saved
  2761.     //function  onsave (file)
  2762.     //end
  2763.  
  2764.     // called when switching to a file or window
  2765.     //function  onfocus
  2766.     //end
  2767.  
  2768.     // called when closing a file
  2769.     //function  onclose
  2770.     //end
  2771.  
  2772.     // called after a search to change the window view and
  2773.     // optionally highlight a string
  2774.     function  onfound (stringlength)
  2775.  
  2776.       // check if the cursor is outside the window view
  2777.       if getcol < getviewleft then
  2778.         if getcol < getviewcols then
  2779.           rollcol -getviewleft
  2780.         else
  2781.           adjustcol 3
  2782.         end
  2783.       elseif getcol + stringlength >= getviewright then
  2784.         adjustcol
  2785.       end
  2786.  
  2787.       if getrow > getviewbot then
  2788.         adjustrow 3
  2789.       elseif getrow < getviewtop then
  2790.         adjustrow
  2791.       end
  2792.       display
  2793.  
  2794.       // highlight a string if stringlength is specified
  2795.       if stringlength then
  2796.         hilite stringlength 1 (getpalette (if? (inmark?) 9 8))
  2797.       end
  2798.     end
  2799.  
  2800.  
  2801.   object  fmgr
  2802.  
  2803.     // called after a fmgr window is opened and before it's displayed
  2804.     function  onopen
  2805.  
  2806.       // set the window event object
  2807.       setwinobj "fmgr"
  2808.  
  2809.       // check for include picklist
  2810.       if ftype? 'i' then
  2811.         display
  2812.         say "Select file to insert"
  2813.       end
  2814.     end
  2815.  
  2816.  
  2817.   // all windows
  2818.   object  a
  2819.  
  2820.     // called when sounding an alarm
  2821.     // (allows you to customize the alarm sound)
  2822.     function  onalarm
  2823.       beep 750 70
  2824.     end
  2825.  
  2826.     // get default comments for a filename (c1, c2 passed by reference)
  2827.     // (associates a filename with comment symbols)
  2828.     function  oncomment (file c1 c2)
  2829.       case getext (upcase file)
  2830.         when ".C", ".AML", ".CPP", ".H"   c1 = "//"
  2831.         when ".ASM"                       c1 = ';'
  2832.         when ".PAS"                       c1 = '{'   c2 = '}'
  2833.         otherwise                         c1 = '>'
  2834.       end
  2835.     end
  2836.  
  2837.  
  2838.     // called when entering the editor before any windows are open.
  2839.     // DOS command-line filespecs are passed to this function
  2840.     function  onentry
  2841.  
  2842.       // save the DOS entry path
  2843.       _cp = getcurrpath
  2844.  
  2845.       // open prompt and window history
  2846.       if _SaveHistory == 'y' then
  2847.         openhistory (bootpath "history.dat")
  2848.       end
  2849.  
  2850.       // process command-line parameters passed to the editor
  2851.       param_num = 1
  2852.       parameter = arg 1
  2853.  
  2854.       while parameter do
  2855.  
  2856.         // check for command line options
  2857.         if parameter [1:2] == "-e"  then
  2858.           queue parameter [3 : TO_END]
  2859.  
  2860.         // open files/directories
  2861.         else
  2862.           open parameter
  2863.         end
  2864.  
  2865.         // next command line parm
  2866.         param_num = param_num + 1
  2867.         parameter = arg param_num
  2868.       end
  2869.  
  2870.       // still no windows open? then do bootoptions...
  2871.       if not getcurrwin then
  2872.         case _BootOpt
  2873.           when 'd'  restoredesk
  2874.           when 'f'  open '.'
  2875.           when 'n'  opennew
  2876.           otherwise
  2877.             filespec = ask "File or Directory" "_load"
  2878.             if filespec then
  2879.               open filespec
  2880.             else
  2881.               halt
  2882.             end
  2883.         end
  2884.       end
  2885.  
  2886.       // initialize the mouse
  2887.       if _Mouse == 'y' then
  2888.         if openmouse _MouseOpt then
  2889.           mousepos  15999 + getvidcols  15999 + getvidrows
  2890.           y_sens = _MouSenY
  2891.           if (getos 'v') > 9 then
  2892.             mousesense (_MouSenX * 5) / 8  (y_sens * 5) / 8  _MouDST
  2893.           else
  2894.             mousesense _MouSenX y_sens _MouDST
  2895.           end
  2896.         end
  2897.       end
  2898.  
  2899.       // open key macros if configured
  2900.       if _SaveMac == 'y' then
  2901.         openkey (bootpath "a.mac")
  2902.       end
  2903.  
  2904.       // set autosave timer
  2905.       send "autosave" _AutoSave
  2906.     end
  2907.  
  2908.  
  2909.     // called when exiting the editor after all windows are closed
  2910.     function  onexit
  2911.  
  2912.       // open prompt on non-global exit (if configured)
  2913.       if not __G then
  2914.         if _ExitOpen == 'y' then
  2915.           filespec = ask "File or Directory" "_load"
  2916.           if filespec then
  2917.             open filespec
  2918.           end
  2919.         end
  2920.       end
  2921.  
  2922.       // final exit if no windows open
  2923.       if not getcurrwin then
  2924.  
  2925.         // save prompt and window history
  2926.         if _SaveHistory == 'y' then
  2927.           savehistory (bootpath "history.dat")
  2928.         end
  2929.  
  2930.         // save key macros if configured
  2931.         if _SaveMac == 'y' then
  2932.           // check if record occurred
  2933.           if lookup "kd" "mon" then
  2934.             savekey (bootpath "a.mac")
  2935.           end
  2936.         end
  2937.  
  2938.         // restore entry path saved in onentry
  2939.         currpath _cp
  2940.  
  2941.         closemouse
  2942.         halt
  2943.       end
  2944.     end
  2945.  
  2946.