home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 5 / 05.iso / a / a009 / 6.ddi / PE.LIF / PE.PRG next >
Encoding:
Text File  |  1991-04-14  |  12.0 KB  |  529 lines

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