home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Database / CLIPR503.W96 / PE.PR_ / PE.PR
Text File  |  1995-06-26  |  12KB  |  532 lines

  1. /***
  2. *
  3. *    Pe.prg
  4. *
  5. *  Simple program editor in Clipper.
  6. *
  7. *  Copyright (c) 1993, Computer Associates International, Inc.
  8. *  All rights reserved.
  9. *
  10. *  Compile:    CLIPPER pe /n/w/m
  11. *  Link:       RTLINK FILE pe
  12. *  Execute:    pe <file>
  13. *
  14. */
  15.  
  16. #include "inkey.ch"
  17. #include "setcurs.ch"
  18. #include "memoedit.ch"
  19.  
  20.  
  21. /* key defs for pe */
  22. #define EK_WRITE K_ALT_W
  23. #define EK_QUIT  K_ESC
  24. #define EK_WQUIT K_CTRL_W
  25.  
  26.  
  27. /* structure used to contain information about edit in progress */
  28. #define ES_TOP      1
  29. #define ES_LEFT     2
  30. #define ES_BOTTOM   3
  31. #define ES_RIGHT    4
  32.  
  33. #define ES_FILE     5
  34. #define ES_TEXT     6
  35.  
  36. #define ES_WIDTH    7
  37. #define ES_TABSIZE  8
  38. #define ES_SCROLL   9
  39. #define ES_WRAP     10
  40. #define ES_INS      11
  41.  
  42. #define ES_ROW      12
  43. #define ES_COL      13
  44. #define ES_RELROW   14
  45. #define ES_RELCOL   15
  46.  
  47. #define ES_CHANGED  16
  48. #define ES_LASTKEY  17
  49.  
  50. #define ES_PATTERN  18
  51.  
  52. #define ES_LENGTH   18
  53.  
  54.  
  55. #define NextTab(y, z)   ( ( (y) + z ) - ( (y) % z ) )
  56.  
  57.  
  58. /* static vars scope to entire module */
  59. static aEdit
  60. static nMaxRow
  61. static nMaxCol
  62. static nStatCol
  63.  
  64.  
  65. ****
  66. *   pe()
  67. *
  68.  
  69. func pe(cFile)
  70. local nKey, lDone, cScreen
  71.  
  72.     Set(_SET_BELL, .f.)
  73.     Set(_SET_SCOREBOARD, .f.)
  74.     SetKey(K_F1, NIL)
  75.  
  76.     if ( IsColor() )
  77.         SetColor("w+/b, b/w, b")
  78.     else
  79.         SetColor("w/n, n/w")
  80.     end
  81.  
  82.     if ( Empty(cFile) )
  83.         cFile := "untitled"
  84.     elseif ( Rat(".", cFile) <= Rat("\", cFile) )
  85.         cFile := cFile + ".prg"
  86.     end
  87.  
  88.     nMaxRow := Maxrow()
  89.     nMaxCol := Maxcol()
  90.     nStatCol := nMaxCol - 19
  91.  
  92.     /* create the edit structure */
  93.     aEdit               := Array(ES_LENGTH)
  94.     aEdit[ES_FILE]      := Lower(cFile)
  95.     aEdit[ES_TEXT]      := MemoRead(cFile)
  96.  
  97.     aEdit[ES_TOP]       := 0
  98.     aEdit[ES_LEFT]      := 0
  99.     aEdit[ES_BOTTOM]    := nMaxRow - 2
  100.     aEdit[ES_RIGHT]     := nMaxCol
  101.  
  102.     aEdit[ES_WIDTH]     := 132
  103.     aEdit[ES_TABSIZE]   := 4
  104.     aEdit[ES_SCROLL]    := .f.
  105.     aEdit[ES_WRAP]      := .t.
  106.     aEdit[ES_INS]       := Set(_SET_INSERT)
  107.  
  108.     aEdit[ES_ROW]       := 1
  109.     aEdit[ES_COL]       := 0
  110.     aEdit[ES_RELROW]    := 0
  111.     aEdit[ES_RELCOL]    := 0
  112.  
  113.     aEdit[ES_CHANGED]   := .f.
  114.     aEdit[ES_LASTKEY]   := 0
  115.  
  116.     aEdit[ES_PATTERN]   := ""
  117.  
  118.     cScreen := SaveScreen(0, 0, nMaxRow, nMaxCol)
  119.     cls
  120.  
  121.     @ nMaxRow - 1, 0 TO nMaxRow - 1, nMaxCol
  122.     Msg( "File: " + aEdit[ES_FILE] )
  123.     lDone := .f.
  124.  
  125.  
  126.     while (!lDone)
  127.         DoEditing()
  128.  
  129.         nKey := aEdit[ES_LASTKEY]
  130.  
  131.         do case
  132.         case (nKey == K_ALT_S)
  133.             Search()
  134.  
  135.         case (nKey == K_ALT_A)
  136.             SearchAgain()
  137.  
  138.         case (nKey == EK_WRITE)
  139.             EditWrite()
  140.  
  141.         case (nKey == EK_QUIT)
  142.             lDone := PExit()
  143.  
  144.         case (nKey == EK_WQUIT)
  145.             EditWrite()
  146.             lDone := PExit()
  147.  
  148.         otherwise
  149.         end
  150.  
  151.     end
  152.  
  153.     if ( IsColor() )
  154.         SetColor(",,n")
  155.     end
  156.  
  157.     RestScreen(0, 0, nMaxRow, nMaxCol, cScreen)
  158.     @ nMaxRow, nMaxCol SAY ""
  159.  
  160. return (NIL)
  161.  
  162.  
  163. ****
  164. *   DoEditing()
  165. *
  166.  
  167. func DoEditing()
  168.  
  169.     aEdit[ES_WRAP] := .t.
  170.     aEdit[ES_TEXT] := MemoEdit( aEdit[ES_TEXT],     ;
  171.                                 aEdit[ES_TOP],      ;
  172.                                 aEdit[ES_LEFT],     ;
  173.                                 aEdit[ES_BOTTOM],   ;
  174.                                 aEdit[ES_RIGHT],    ;
  175.                                 .t., "ufunc",       ;
  176.                                 aEdit[ES_WIDTH],    ;
  177.                                 aEdit[ES_TABSIZE],  ;
  178.                                 aEdit[ES_ROW],      ;
  179.                                 aEdit[ES_COL],      ;
  180.                                 aEdit[ES_RELROW],   ;
  181.                                 aEdit[ES_RELCOL]    ;
  182.                               )
  183.  
  184. return (NIL)
  185.  
  186.  
  187. ****
  188. *   Prompt()
  189. *
  190.  
  191. func Prompt(cSay, cGet)
  192. local getList := {}, bInsSave, bAltISave
  193.  
  194.     bInsSave := SetKey(K_INS, {|| SetCursor(if( Set(_SET_INSERT,            ;
  195.                                                 !Set(_SET_INSERT) ),        ;
  196.                                                 SC_NORMAL, SC_INSERT) ) }   ;
  197.                       )
  198.  
  199.     bAltISave := SetKey(K_ALT_I, SetKey(K_INS))
  200.  
  201.     Msg(Space(nStatCol))
  202.     @ nMaxRow,0 SAY cSay    ;
  203.                 GET cGet    ;
  204.                 Picture "@KS" + Ltrim(Str(nStatCol - (Len(cSay) + 2)))
  205.     READ
  206.  
  207.     SetKey(K_INS, bInsSave)
  208.     SetKey(K_ALT_I, bAltISave)
  209.     aEdit[ES_INS] := Set(_SET_INSERT)
  210.  
  211. return (cGet)
  212.  
  213.  
  214. ****
  215. *   NewName()
  216. *
  217.  
  218. func NewName()
  219. local name
  220.  
  221.     name := Prompt("Enter new output file name:", PadR(aEdit[ES_FILE], 64))
  222.     name := Lower(Ltrim(Rtrim(name)))
  223.     if ( !Empty(name) .and. name != aEdit[ES_FILE] )
  224.         aEdit[ES_FILE] := name
  225.         aEdit[ES_CHANGED] := .t.
  226.     end
  227.  
  228.     Msg("File: " + aEdit[ES_FILE])
  229.  
  230. return (NIL)
  231.  
  232.  
  233. ****
  234. *   xSearch()
  235. *
  236.  
  237. func xSearch(x)
  238. local nRow, pos, offset, newcol, a
  239.  
  240.     if ( !Empty(aEdit[ES_PATTERN]) )
  241.         nRow := aEdit[ES_ROW]
  242.         pos := x + MLCToPos(aEdit[ES_TEXT],     ;
  243.                             aEdit[ES_WIDTH],    ;
  244.                             aEdit[ES_ROW],      ;
  245.                             aEdit[ES_COL],      ;
  246.                             aEdit[ES_TABSIZE],  ;
  247.                             aEdit[ES_WRAP]      ;
  248.                            )
  249.  
  250.         offset := pos + At(aEdit[ES_PATTERN],Substr(aEdit[ES_TEXT], pos)) - 1
  251.         if ( offset >= pos )
  252.             a := MPosToLC(aEdit[ES_TEXT],   ;
  253.                           aEdit[ES_WIDTH],  ;
  254.                           offset,           ;
  255.                           aEdit[ES_TABSIZE],;
  256.                           aEdit[ES_WRAP]    ;
  257.                          )
  258.  
  259.             aEdit[ES_ROW] := a[1]
  260.             newcol := a[2]
  261.             aEdit[ES_RELCOL] := aEdit[ES_RELCOL] + newcol - aEdit[ES_COL]
  262.             aEdit[ES_COL] := newcol
  263.  
  264.             if ( aEdit[ES_ROW] - nRow <=                                ;
  265.                  aEdit[ES_BOTTOM] - aEdit[ES_TOP] - aEdit[ES_RELROW]    ;
  266.                )
  267.  
  268.                 aEdit[ES_RELROW] := aEdit[ES_RELROW] + aEdit[ES_ROW] - nRow
  269.  
  270.             end
  271.  
  272.             Msg("Search completed.")
  273.  
  274.         else
  275.             Msg("Pattern not found.")
  276.         end
  277.     else
  278.         Msg("")
  279.     end
  280.  
  281. return (NIL)
  282.  
  283.  
  284. ****
  285. *   Search()
  286. *
  287.  
  288. func Search()
  289. local pattern
  290.  
  291.     pattern := Prompt("Search for:", PadR(aEdit[ES_PATTERN], 64))
  292.     pattern := Ltrim(Rtrim(pattern))
  293.     if ( !Empty(pattern) )
  294.         aEdit[ES_PATTERN] := pattern
  295.         xSearch(0)
  296.     else
  297.         Msg("")
  298.     end
  299.  
  300. return (NIL)
  301.  
  302.  
  303. ****
  304. *   SearchAgain()
  305. *
  306.  
  307. func SearchAgain()
  308. return (xSearch(1))
  309.  
  310.  
  311. ****
  312. *   ufunc()
  313. *
  314.  
  315. func ufunc(nMode, nLine, nCol)
  316. local nKey
  317.  
  318.     aEdit[ES_LASTKEY]   := nKey := LastKey()
  319.     aEdit[ES_ROW]       := nLine
  320.     aEdit[ES_COL]       := nCol
  321.     aEdit[ES_RELROW]    := Row() - aEdit[ES_TOP]
  322.     aEdit[ES_RELCOL]    := Col() - aEdit[ES_LEFT]
  323.  
  324.  
  325.     if (nMode == ME_INIT)
  326.         if (aEdit[ES_WRAP])
  327.             /* turn off word wrap */
  328.             aEdit[ES_WRAP] := .f.
  329.             return (ME_TOGGLEWRAP)  /* NOTE */
  330.         end
  331.  
  332.         SetCursor( if(aEdit[ES_INS], SC_INSERT, SC_NORMAL) )
  333.  
  334.     elseif (nMode == ME_IDLE)
  335.         StatMsg()
  336.  
  337.     else
  338.         /* keystroke exception */
  339.         if (nMode == ME_UNKEYX)
  340.             aEdit[ES_CHANGED] := .t.
  341.         end
  342.  
  343.         do case
  344.         case (nKey == K_F1)
  345.             DisplayHelp()
  346.  
  347.         case (nKey == K_ALT_H)
  348.             DisplayHelp()
  349.  
  350.         case (nKey == K_ALT_F)
  351.             Msg( "File: " + aEdit[ES_FILE] )
  352.  
  353.         case (nKey == K_ALT_O)
  354.             NewName()
  355.  
  356.         case (nKey == K_INS)
  357.             aEdit[ES_INS] := !Set(_SET_INSERT)
  358.             SetCursor( if(aEdit[ES_INS], SC_INSERT, SC_NORMAL) )
  359.             return (nKey)
  360.  
  361.         case (nKey == K_ALT_I)
  362.             aEdit[ES_INS] := !Set(_SET_INSERT)
  363.             SetCursor( if(aEdit[ES_INS], SC_INSERT, SC_NORMAL) )
  364.             return (K_INS)
  365.  
  366.         case (nKey == K_ALT_S)
  367.             /* search */
  368.             return (K_CTRL_W)
  369.  
  370.         case (nKey == K_ALT_A)
  371.             /* search again */
  372.             return (K_CTRL_W)
  373.  
  374.         case (nKey == K_ALT_X)
  375.             aEdit[ES_LASTKEY] := EK_QUIT
  376.             return (K_CTRL_W)
  377.  
  378.         case (nKey == EK_QUIT)
  379.             return (K_CTRL_W)
  380.  
  381.         case (nKey == EK_WRITE)
  382.             return (K_CTRL_W)
  383.  
  384.         otherwise
  385.         end
  386.     end
  387.  
  388. return (0)
  389.  
  390.  
  391.  
  392. ****
  393. *   EditWrite()
  394. *
  395.  
  396. func EditWrite()
  397. local lRet
  398.  
  399.     lRet := .t.
  400.     if ( aEdit[ES_CHANGED] )
  401.         Msg( "Writing " + aEdit[ES_FILE] )
  402.  
  403.         if ( MemoWrit(aEdit[ES_FILE], aEdit[ES_TEXT]) )
  404.             Msg("Write OK")
  405.             aEdit[ES_CHANGED] := .f.
  406.  
  407.         else
  408.             Msg("Write error")
  409.             lRet := .f.
  410.  
  411.         end
  412.     else
  413.         Msg("File has not been modified -- not written.")
  414.  
  415.     end
  416.  
  417. return (lRet)
  418.  
  419.  
  420. ****
  421. *   Msg()
  422. *
  423.  
  424. func Msg(text)
  425. static oldLength := 0
  426.  
  427.     if (oldLength != 0)
  428.         @ nMaxRow, 0 SAY Replicate(" ", oldLength)
  429.     end
  430.  
  431.     @ nMaxRow, 0 SAY text
  432.     oldLength := Len(text)
  433.  
  434. return (NIL)
  435.  
  436.  
  437. ****
  438. *   StatMsg()
  439. *
  440.  
  441. func StatMsg()
  442. local cLine, cCol, nCtype, nRow, nCol
  443.  
  444.     cLine := PadR( LTrim(Str(aEdit[ES_ROW])), 6 )
  445.     cCol := LTrim( Str(aEdit[ES_COL]) )
  446.  
  447.     nCtype := SetCursor(0)
  448.     nRow := Row()
  449.     nCol := Col()
  450.     @ nMaxRow, nStatCol SAY "Line: " + cLine + "Col: " + cCol + "  "
  451.     DevPos(nRow, nCol)
  452.     SetCursor(nCtype)
  453.  
  454. return (NIL)
  455.  
  456.  
  457. ****
  458. *   PExit()
  459. *
  460.  
  461. func PExit()
  462. local c, lRet, nCtype
  463.  
  464.     lRet = .t.
  465.     if ( aEdit[ES_CHANGED] )
  466.         nCtype := SetCursor(SC_NORMAL)
  467.  
  468.         Msg("Abandon " + aEdit[ES_FILE] + " [ynw]?" )
  469.         while ( !((c := Upper(Chr(InKey(0)))) $ ("YNW" + Chr(K_ESC))) )
  470.         end
  471.  
  472.         if ( c == "W" )
  473.             lRet := EditWrite()
  474.  
  475.         else
  476.  
  477.             if ( c != "Y" )
  478.                 lRet := .f.
  479.             end
  480.  
  481.             Msg("")
  482.         end
  483.  
  484.         SetCursor(nCtype)
  485.  
  486.     end
  487.  
  488. return (lRet)
  489.  
  490.  
  491. ****
  492. * DisplayHelp()
  493. *
  494.  
  495. func DisplayHelp()
  496. local cScreen := SaveScreen(0, 0, MaxRow(), MaxCol()), nCtype
  497.  
  498.     cls
  499.     @ 0, 1 say "PE Help"
  500.     @ 1, 0 to nMaxRow - 1, nMaxCol
  501.     @ 2, 2 say "Uparrow/Ctrl-E          Line up           │ Alt-H, F1    Display Help screen "
  502.     @ 3, 2 say "Dnarrow/Ctrl-X          Line down         │ Ctrl-W       Save and exit       "
  503.     @ 4, 2 say "Leftarrow/Ctrl-S        Char left         │ Alt-W        Save and continue   "
  504.     @ 5, 2 say "Rightarrow/Ctrl-D       Char right        │ Alt-O        New Output filename "
  505.     @ 6, 2 say "Ctrl-Leftarrow/Ctrl-A   Word left         │ Alt-X, Esc   Exit                "
  506.     @ 7, 2 say "Ctrl-Rightarrow/Ctrl-F  Word right        │ Alt-F        Display Filename    "
  507.     @ 8, 2 say "Home                    Beginning of line │ Alt-S        Search              "
  508.     @ 9, 2 say "End                     End of line       │ Alt-A        Search Again        "
  509.     @ 10,2 say "Ctrl-Home               Top of window     │ Alt-I, Ins   Toggle Insert mode  "
  510.     @ 11,2 say "Ctrl-End                End of window     │ "
  511.     @ 12,2 say "PgUp                    Previous window   │ "
  512.     @ 13,2 say "PgDn                    Next window       │ "
  513.     @ 14,2 say "Ctrl-PgUp               Top of file       │ "
  514.     @ 15,2 say "Ctrl-PgDn               End of file       │ "
  515.     @ 16,2 say "Return                  Begin next line   │ "
  516.     @ 17,2 say "Delete                  Delete char       │ "
  517.     @ 18,2 say "Backspace               Delete char left  │ "
  518.     @ 19,2 say "Tab                     Insert tab/spaces │ "
  519.     @ 20,2 say "Ctrl-Y                  Delete line       │ "
  520.     @ 21,2 say "Ctrl-T                  Delete word right │ "
  521.     @ 22,2 say "                                          │ "
  522.  
  523.     @ nMaxRow, 1 say "Press any key to return to the edit screen..."
  524.  
  525.     nCtype := SetCursor(SC_NORMAL)
  526.     Inkey(0)
  527.     SetCursor(nCtype)
  528.  
  529.     RestScreen(0, 0, nMaxRow, nMaxCol, cScreen)
  530.   
  531. return (NIL)
  532.