home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / rexxedt1.zip / REXXEDIT.CMD
OS/2 REXX Batch file  |  1994-07-15  |  20KB  |  633 lines

  1. /***************************************************************************
  2.  *                                                                         *
  3.  * REXXEDIT.CMD - A simple text editor, written completely in REXX.        *
  4.  *                                                                         *
  5.  * Craig Morrison 15 July 1994, released into the Public Domain this day.  *
  6.  *                                                                         *
  7.  * REXXEdit can handle a file of any size, subject to available memory.    *
  8.  * One big restriction is the line size, lines are limited to 78 or so     *
  9.  * characters in length. I didn't feel like going through the trouble of   *
  10.  * handling the horizontal scrolling.                                      *
  11.  *                                                                         *
  12.  * REXXEdit *is* a bit slow at scrolling, but it doesn't do too bad of a   *
  13.  * job of keeping up. I could have written an add-on DLL to take care of   *
  14.  * it, but this was an exercise in REXX using just those tools available   *
  15.  * from the basic REXX installation of OS/2. Call me a purist.. ;-)        *
  16.  *                                                                         *
  17.  * You'll have to snoop through the code to find out what functions are    *
  18.  * available. Most of the common editor functions are present. All the     *
  19.  * standard navigation keys work.                                          *
  20.  *                                                                         *
  21.  * The line lengths of this file itself have been kept in the range that   *
  22.  * REXXEdit can handle. You can use REXXEdit to modify the code.           *
  23.  *                                                                         *
  24.  * Here's the basic philosophy behind REXXEdit:                            *
  25.  *                                                                         *
  26.  *    If you want it, add it, you've got the source code.                  *
  27.  *                                                                         *
  28.  *  Changes:                                                               *
  29.  *                                                                         *
  30.  *  Person       Date        Changes                                       *
  31.  * ───────────  ──────────  ────────────────────────────────────────────── *
  32.  * C. Morrison  15 Jul 94   First release.                                 *
  33.  *                                                                         *
  34.  ***************************************************************************/
  35. '@echo off'
  36.  
  37. Parse Upper Arg textfile .
  38.  
  39. Call rxfuncadd 'SysLoadFuncs', 'RexxUtil', 'SysLoadFuncs'
  40. Call SysLoadFuncs
  41.  
  42. fKey = x2c('00')
  43. hfKey = x2c('e0')
  44. escKey = x2c('1b')
  45. enter = x2c('0d')
  46. lfeed = x2c('0a')
  47. bSpace = d2c(8)
  48. CTRLj = d2c(10)
  49. CTRLy = d2c(25)
  50. CTRLn = d2c(14)
  51. CTRLx = d2c(24)
  52. CTRLh = d2c(9)
  53. fkUp = 'H'
  54. fkDown = 'P'
  55. fkLeft = 'K'
  56. fkRight = 'M'
  57. fkHome = 'G'
  58. fkEnd = 'O'
  59. fkPgUp = 'I'
  60. fkPgDn = 'Q'
  61. fkIns = 'R'
  62. fkDel = 'S'
  63. fkCHome = 'w'
  64. fkCEnd = 'u'
  65. fkCPgDn = 'v'
  66. fkCPgUp = 'ä'
  67. fkCLeft = 's'
  68. fkCRight = 't'
  69. fkF2 = '<'
  70. fkF3 = '='
  71. fkF4 = '>'
  72. fRow = 1
  73. fCol = 1
  74. Row = fRow
  75. Col = fCol
  76. lRow = 23
  77. lCol = 78
  78. fVisRow = 1
  79. linePos = 1
  80. lineRow = 1
  81. Changes = 0
  82. InsMode = 1
  83. TabSize = 4
  84. Title = ' REXXEdit v1.0 '
  85. GetOut = ' ESC or F3 to Quit, F2 saves '
  86. spacestr = Copies(' ', lCol)
  87. Footer = ' '||Copies('─', lCol)
  88. Banner = OverLay(Title, Footer, Trunc((lCol + 2 - Length(Title)) / 2))
  89. Footer = OverLay(GetOut, Footer, Trunc((lCol + 2 - Length(GetOut)) / 2))
  90.  
  91. Text.0 = 1
  92. Text.1 = ''
  93.  
  94. if textfile <> '' Then Do
  95.     if Stream(textfile, 'c', 'query exists') <> '' Then Do
  96.         Say 'One moment, reading 'textfile'...'
  97.         index = 1
  98.         Do Until Lines(textfile) = 0
  99.             Text.index = LineIn(textfile)
  100.             if Length(Text.index) >= lCol Then Do
  101.                 txt = Text.index
  102.                 Text.index = GetOneLine(lCol, txt)
  103.                 index = index + 1
  104.                 txt = Space(DelWord(txt, 1, Words(txt)), 1)
  105.                 Do While Length(txt) \= 0
  106.                     wText = GetOneLine(lCol, txt)
  107.                     Text.index = wText
  108.                     txt = Space(DelWord(txt, 1, Words(wText)), 1)
  109.                     index = index + 1
  110.                 End
  111.             End
  112.             Else
  113.                 index = index + 1
  114.         End
  115.         ok = Stream(textfile, 'c', 'close')
  116.         Text.0 = index - 1
  117.     End
  118. End
  119.  
  120. Call SysCls
  121. Call SysCurPos lRow + 1, fCol - 1
  122. Call CharOut , Footer
  123. Call SysCurPos fRow - 1, fCol - 1
  124. Call CharOut , Banner
  125. Call SysCurPos Row, Col
  126. Call DisplayStats
  127. Call DisplayScreenful fVisRow
  128.  
  129. Do Until inkey = escKey
  130.     inkey = GetKey()
  131.     Select
  132.         When inkey = fKey Then Call DoFuncKey GetKey()
  133.         When inkey = enter Then Call DoReturnKey
  134.         When inkey = bSpace Then Call DoBackSpace
  135.         Otherwise
  136.             If c2d(inkey) > 31 Then Call WriteOutChar(inkey)
  137.             Else Call DoControlKey inkey
  138.     End
  139. End
  140.  
  141. GetOuttaDodge:
  142.  
  143. Call SysCls
  144. if Changes = 1 Then Do
  145.     if textfile = '' Then Do
  146.         Say
  147.         Say 'Filename to save changes under (enter to discard)?'
  148.         Pull textfile .
  149.         if textfile <> '' Then YesNo = 'Y'
  150.     End
  151.     Else Do
  152.         Say
  153.         Say textfile' has been modified.'
  154.         Say 'Save the changes (Y or N)?'
  155.         Pull YesNo .
  156.     End
  157.     if (YesNo = 'Y') | (YesNo = '') Then Do
  158.         Call FileSave
  159.     End
  160. End
  161.  
  162. Exit
  163.  
  164. FileSave:
  165.  
  166.     if textfile <> '' Then Do
  167.         if Stream(textfile, 'c', 'query exists') <> '' Then Do
  168.             'DEL 'textfile
  169.             Do index = 1 to Text.0
  170.                 Text.index = Strip(Text.index, 'T')
  171.                 Call LineOut textfile, Text.index
  172.             End
  173.             ok = Stream(textfile, 'c', 'close')
  174.             Changes = 0
  175.         End
  176.         Else
  177.             Call Beep 100, 250
  178.     End
  179.  
  180. Return
  181.  
  182. DoBackSpace:
  183.  
  184.     If Col > fCol Then Do
  185.         Col = Col - 1
  186.         linePos = linePos - 1
  187.         rStr = Right(Text.lineRow, Length(Text.lineRow) - linePos)
  188.         nStr = Overlay(rStr, Text.lineRow, linePos)
  189.         Text.lineRow = Left(nStr, Length(nStr) - 1)
  190.         Call SysCurState 'OFF'
  191.         Call SysCurPos Row, Col
  192.         Call CharOut , rStr
  193.         if Length(Text.lineRow) < lCol Then
  194.             Call Charout ,,
  195.                 Left(spacestr, Length(spacestr) - Length(Text.lineRow))
  196.         Call SysCurPos Row, Col
  197.         Call SysCurState 'ON'
  198.         Changes = 1
  199.     End
  200.  
  201. Return
  202.  
  203. DoReturnKey:
  204.  
  205.     If Row < lRow Then Do
  206.         Row = Row + 1
  207.         lineRow = lineRow + 1
  208.     End
  209.     Else Do
  210.         lineRow = lineRow + 1
  211.         fVisRow = fVisRow + 1
  212.         Call DisplayScreenful fVisRow
  213.     End
  214.  
  215.     If lineRow > Text.0 Then Do
  216.         Text.lineRow = ''
  217.         Text.0 = lineRow
  218.         Changes = 1
  219.     End
  220.     Else Do
  221.         i = Text.0 + 1
  222.         Do Until i = lineRow
  223.             ni = i - 1
  224.             Text.i = Text.ni
  225.             i = i - 1
  226.         End
  227.         Text.lineRow = ''
  228.         Text.0 = Text.0 + 1
  229.         Call DisplayScreenful fVisRow
  230.         Changes = 1
  231.     End
  232.  
  233.     Col = fCol
  234.     linePos = fCol
  235.     Call SysCurPos Row, Col
  236.  
  237. Return
  238.  
  239. WriteOutChar:
  240.  
  241.     Parse Arg key
  242.  
  243.     If Col < lCol Then Do
  244.         Text.lineRow = AddCharToString(key, Text.lineRow, linePos)
  245.         Call CharOut , key
  246.         Col = Col + 1
  247.         linePos = linePos + 1
  248.     End
  249.  
  250. Return
  251.  
  252. GetKey:
  253.  
  254.     k = SysGetKey('NOECHO')
  255.     If k = hfKey Then k = fKey
  256.  
  257. return k
  258.  
  259. DoControlKey:
  260.  
  261.     Parse Arg key
  262.  
  263.     Select
  264.         When key = CTRLh Then Do
  265.                 nTab = ((linePos % TabSize) + 1) * TabSize
  266.                 if nTab < lCol Then Do
  267.                     nTab = (nTab - linePos) + 1
  268.                     Do nt = 1 to nTab
  269.                         Call WriteOutChar ' '
  270.                     End
  271.                 End
  272.             End
  273.         When key = CTRLy Then Do
  274.                 if lineRow < Text.0 Then Do
  275.                     Do i = lineRow To Text.0
  276.                         ni = i + 1
  277.                         Text.i = Text.ni
  278.                     End
  279.                     Text.0 = Text.0 - 1
  280.                     Call DisplayScreenful fVisRow
  281.                     Changes = 1
  282.                 End
  283.             End
  284.         When key = CTRLn Then Do
  285.                 i = Text.0 + 1
  286.                 Do Until i = lineRow
  287.                     ni = i - 1
  288.                     Text.i = Text.ni
  289.                     i = i - 1
  290.                 End
  291.                 Text.lineRow = ''
  292.                 Text.0 = Text.0 + 1
  293.                 Call DisplayScreenful fVisRow
  294.                 Changes = 1
  295.             End
  296.         When key = CTRLx Then Do
  297.                 if linePos <= Length(Text.lineRow) Then Do
  298.                     i = Text.0 + 1
  299.                     Do Until i = lineRow
  300.                         ni = i - 1
  301.                         Text.i = Text.ni
  302.                         i = i - 1
  303.                     End
  304.                     Text.0 = Text.0 + 1
  305.                     li = lineRow + 1
  306.                     Text.li = Text.lineRow
  307.                     if linePos <> 1 Then
  308.                         Text.lineRow = Left(Text.lineRow, linePos - 1)
  309.                     Else
  310.                         Text.lineRow = ''
  311.                     Text.li = Right(Text.li,,
  312.                                     (Length(Text.li) - linePos) + 1)
  313.                     Call DisplayScreenful fVisRow
  314.                     Changes = 1
  315.                 End
  316.             End
  317.         When key = CTRLj Then Do
  318.                 if lineRow + 1 <= Text.0 Then Do
  319.                     lr = lineRow + 1
  320.                     tmp = Text.lineRow||' '||Text.lr
  321.                     if Length(tmp) < lCol Then Do
  322.                         Text.lineRow = tmp
  323.                         Do i = lr To Text.0
  324.                             ni = i + 1
  325.                             Text.i = Text.ni
  326.                         End
  327.                         Text.0 = Text.0 - 1
  328.                     End
  329.                     Else Do
  330.                         wi = lCol - 1
  331.                         Do While SubStr(tmp, wi, 1) <> ' '
  332.                             wi = wi - 1
  333.                             if wi = 0 Then Leave
  334.                         End
  335.                         if wi = 0 Then wi = lCol - 1
  336.                         Text.lineRow = Left(tmp, wi)
  337.                         Text.lr = Right(tmp, Length(tmp)-wi)
  338.                     End
  339.                     Call DisplayScreenful fVisRow
  340.                     Changes = 1
  341.                 End
  342.             End
  343.         Otherwise
  344.             Nop
  345.     End
  346.     if linePos > Length(Text.lineRow) + 1 Then Do
  347.         linePos = Length(Text.lineRow) + 1
  348.         if linePos = 0 Then linePos = fCol
  349.         Col = linePos
  350.     End
  351.  
  352.     Call SysCurPos Row, Col
  353.  
  354. return
  355.  
  356. DoFuncKey:
  357.  
  358.     Parse Arg funcKey
  359.  
  360.     Parse Value SysCurPos() With Row Col
  361.  
  362.     Select
  363.         When funcKey = fkCLeft Then Do
  364.                 if Words(Text.lineRow) > 0 Then Do
  365.                     wpos = Words(Text.lineRow)
  366.                     if wpos > 1 Then Do
  367.                         fword = WordIndex(Text.lineRow, 1)
  368.                         Do wi = 1 To wpos
  369.                             i = WordIndex(Text.lineRow, wi)
  370.                             if i < linePos Then
  371.                                 if i > fword Then fword = i
  372.                         End
  373.                         linePos = fword
  374.                     End
  375.                     Else Do
  376.                         linePos = WordIndex(Text.lineRow, 1)
  377.                     End
  378.                     Col = linePos
  379.                 End
  380.             End
  381.         When funcKey = fkCRight Then Do
  382.                 if Words(Text.lineRow) > 1 Then Do
  383.                     wpos = Words(Text.lineRow)
  384.                     fword = WordIndex(Text.lineRow, wpos)
  385.                     Do wi = 1 To wpos
  386.                         i = WordIndex(Text.lineRow, wi)
  387.                         if i > linePos Then
  388.                             if i < fword Then fword = i
  389.                     End
  390.                     linePos = fword
  391.                     Col = linePos
  392.                 End
  393.             End
  394.         When funcKey = fkIns Then Do
  395.                 if InsMode = 1 Then
  396.                     InsMode = 0
  397.                 Else
  398.                     InsMode = 1
  399.                 Call DisplayStats
  400.             End
  401.         When funcKey = fkDel Then Do
  402.             if linePos <= Length(Text.lineRow) Then Do
  403.                 if linePos < Length(Text.lineRow) Then Do
  404.                     rStr = Right(Text.lineRow,,
  405.                                  Length(Text.lineRow) - linePos)
  406.                     nStr = Overlay(rStr, Text.lineRow, linePos)
  407.                 End
  408.                 Else Do
  409.                     rStr = ''
  410.                     nStr = Text.lineRow;
  411.                 End
  412.                 Text.lineRow = Left(nStr, Length(nStr) - 1)
  413.                 Call SysCurState 'OFF'
  414.                 Call SysCurPos Row, Col
  415.                 Call CharOut , rStr
  416.                 if Length(Text.lineRow) < lCol Then
  417.                     Call Charout ,,
  418.                        Left(spacestr,,
  419.                             Length(spacestr) - Length(Text.lineRow))
  420.                 Call SysCurPos Row, Col
  421.                 Call SysCurState 'ON'
  422.                 Changes = 1
  423.             End
  424.         End
  425.         When funcKey = fkUp Then Do
  426.                 if Row > fRow Then Do
  427.                     Row = Row - 1
  428.                     lineRow = lineRow - 1
  429.                 End
  430.                 Else if fVisRow > 1 Then Do
  431.                     lineRow = lineRow - 1
  432.                     fVisRow = fVisRow - 1
  433.                     Call DisplayScreenful fVisRow
  434.                 End
  435.             End
  436.         When funcKey = fkDown Then Do
  437.                 if Row < lRow Then Do
  438.                     if lineRow < Text.0 Then Do
  439.                         Row = Row + 1
  440.                         lineRow = lineRow + 1
  441.                     End
  442.                 End
  443.                 Else Do
  444.                     if lineRow < Text.0 Then Do
  445.                         lineRow = lineRow + 1
  446.                         fVisRow = fVisRow + 1
  447.                         Call DisplayScreenful fVisRow
  448.                     End
  449.                 End
  450.             End
  451.         When funcKey = fkLeft Then Do
  452.                 if Col > fCol Then Do
  453.                     Col = Col - 1
  454.                     linePos = linePos - 1
  455.                 End
  456.             End
  457.         When funcKey = fkRight Then Do
  458.                 if Col < lCol Then Do
  459.                     If linePos < Length(Text.lineRow) + 1 Then Do
  460.                         Col = Col + 1
  461.                         linePos = linePos + 1
  462.                     End
  463.                 End
  464.             End
  465.         When funcKey = fkHome Then Do
  466.                 Col = fCol
  467.                 linePos = Col
  468.             End
  469.         When funcKey = fkEnd Then Do
  470.                 Col = lCol
  471.                 linePos = Col
  472.             End
  473.         When funcKey = fkPgUp Then Do
  474.                 if fVisRow - 23 > 0 Then Do
  475.                     Row = fRow
  476.                     fVisRow = fVisRow - 23
  477.                     lineRow = fVisRow
  478.                     Call DisplayScreenful fVisRow
  479.                 End
  480.                 Else Do
  481.                     Row = fRow
  482.                     fVisRow = Row
  483.                     lineRow = fVisRow
  484.                     Call DisplayScreenful fVisRow
  485.                 End
  486.             End
  487.         When funcKey = fkPgDn Then Do
  488.                 if fVisRow + 23 < = Text.0 Then Do
  489.                     Row = fRow
  490.                     fVisRow = fVisRow + 23
  491.                     lineRow = fVisRow
  492.                     Call DisplayScreenful fVisRow
  493.                 End
  494.             End
  495.         When funcKey = fkCHome Then Do
  496.                 fVisRow = fRow
  497.                 Row = fRow
  498.                 lineRow = fVisRow
  499.                 Call DisplayScreenful fVisRow
  500.             End
  501.         When funcKey = fkCEnd Then Do
  502.                 if Text.0 - 22 > 0 Then Do
  503.                     fVisRow = Text.0 - 22
  504.                     lineRow = fVisRow + 22
  505.                     Row = lRow
  506.                     Call DisplayScreenful fVisRow
  507.                 End
  508.             End
  509.         When funcKey = fkCPgUp Then Do
  510.                 lineRow = fVisRow
  511.                 Row = fRow
  512.             End
  513.         When funcKey = fkCPgDn Then Do
  514.                 if fVisRow + 22 <= Text.0 Then Do
  515.                     lineRow = fVisRow + 22
  516.                     Row = lRow
  517.                 End
  518.             End
  519.         When funcKey = fkF3 Then Signal GetOuttaDodge
  520.         When funcKey = fkF2 Then Call FileSave
  521.         OtherWise
  522.             Nop
  523.     End
  524.     if linePos > Length(Text.lineRow) + 1 Then Do
  525.         linePos = Length(Text.lineRow) + 1
  526.         if linePos = 0 Then linePos = fCol
  527.         Col = linePos
  528.     End
  529.  
  530.     Call SysCurPos Row, Col
  531.  
  532. Return
  533.  
  534. AddCharToString:
  535.     Procedure Expose InsMode fCol lCol Changes
  536.  
  537.     Parse Arg key, text, position
  538.  
  539.     Select
  540.         When position > Length(text) Then Do
  541.                 text = text||key
  542.                 Changes = 1
  543.             End
  544.         When InsMode = 1 Then
  545.             Do
  546.                 If position = 1 Then Do
  547.                     lStr = ''
  548.                     rStr = text
  549.                 End
  550.                 Else Do
  551.                     lStr = Left(text, position - 1)
  552.                     rStr = DelStr(text, 1, Length(lStr))
  553.                 End
  554.                 text = lStr||key||rStr
  555.                 if Length(text) >= lCol Then
  556.                     text = Left(text, lCol-1)
  557.                 Call SysCurState 'OFF'
  558.                 Parse Value SysCurPos() With oRow oCol
  559.                 Call SysCurPos oRow, fCol
  560.                 Call CharOut , text
  561.                 Call SysCurPos oRow, oCol
  562.                 Call SysCurState 'ON'
  563.                 Changes = 1
  564.             End
  565.         When InsMode = 0 Then Do
  566.                 text = OverLay(key, text, position)
  567.                 Changes = 1
  568.             End
  569.         Otherwise
  570.             Nop
  571.     End
  572.  
  573. return text
  574.  
  575. DisplayScreenful:
  576.  
  577.     Parse Arg fv
  578.  
  579.     if fv + 23 > Text.0 Then top = (Text.0 - fv)
  580.     Else top = 22
  581.  
  582.     iRow = 1
  583.     oText = ''
  584.     Do li = fv to top + fv
  585.         oText = oText||' '||OverLay(Text.li, spacestr, 1)||enter||lfeed
  586.         iRow = iRow + 1
  587.     End
  588.     if iRow <= lRow Then Do
  589.         iRow = (lRow - iRow) + 1
  590.         oText = oText||Copies(' '||spacestr||enter||lfeed, iRow)
  591.     End
  592.     Call SysCurState 'OFF'
  593.     Call SysCurPos fRow, fCol - 1
  594.     Call CharOut , oText
  595.     Call SysCurPos Row, Col
  596.     Call SysCurState 'ON'
  597.  
  598. return
  599.  
  600. DisplayStats:
  601.  
  602.     stats = ''
  603.  
  604.     Parse Value SysCurPos() With oRow oCol
  605.     Call SysCurState 'OFF'
  606.     Call SysCurPos lRow + 1, fCol
  607.     if InsMode = 1 Then
  608.         stats = stats||'─ INS ─'
  609.     Else
  610.         stats = stats||'───────'
  611.     Call CharOut , stats
  612.     Call SysCurPos oRow, oCol
  613.     Call SysCurState 'ON'
  614.  
  615. return
  616.  
  617. GetOneLine:
  618.  
  619.     Parse Arg llen, inText
  620.  
  621.     cText = ''
  622.     Do While Length(cText' 'Word(inText, 1)) < llen
  623.         cText = cText' 'Word(inText, 1)
  624.         inText = DelWord(inText, 1, 1)
  625.         If inText = '' Then Leave
  626.     End
  627.  
  628.     if cText = '' Then Do
  629.         cText = Left(inText, llen)
  630.     End
  631.  
  632. Return Space(cText, 1)
  633.