home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload / ShartewareOverload.cdr / progm / tptools.zip / FIRSTED.ZIP / EDMAIN.PAS < prev    next >
Pascal/Delphi Source File  |  1987-12-21  |  18KB  |  572 lines

  1. {                          EDMAIN.PAS
  2.                              ED 4.0
  3.              Copyright (c) 1985, 87 by Borland International, Inc.            }
  4.  
  5. {$I eddirect.inc}
  6.  
  7. unit EdMain;
  8.  
  9. interface
  10.  
  11. uses
  12.   crt,                       {Basic video operations - standard unit}
  13.   Dos,                       {DOS calls - standard unit}
  14.   Errors,                    {Runtime error handler}
  15.   EdVars,                    {Global types and declarations}
  16.   EdScrn1,                   {Fast screen writing routines}
  17.   EdString,                  {String primitives}
  18.   EdPtrOp,                   {Primitive pointer operations}
  19.   EdCmds,                    {Maps keystrokes to commands}
  20.   int24,                     {DOS critical error handler}
  21.   Message,                   {Message system}
  22.   EdUser,                    {User keyboard input, line editing and error reporting}
  23.   EdMemOp,                   {Text buffer allocation and deallocation}
  24.   EdBack,                    {Background processes}
  25.   EdScrn2,                   {Editor screen updating}
  26.   EdEdit,                    {Basic editing commands}
  27.   EdText,                    {Text processing commands}
  28.   EdBlok,                    {Block move, copy, delete}
  29.   EdFinds,                   {Find and replace routines}
  30.   EdFile;                    {File I/O routines}
  31.  
  32. procedure EdInitialize;
  33.   {-Initialize editor variables and data structures}
  34.  
  35. procedure EdMainMenu;
  36.   {-Get command line parameters or prompt for initial file}
  37.  
  38. procedure EdSchedule;
  39.   {-Schedule editor}
  40.  
  41.   {==========================================================================}
  42.  
  43. implementation
  44.  
  45. var
  46.   Argcount : Byte;           {Number of DOS command line arguments}
  47.  
  48.   procedure EdInitialize;
  49.     {-Initialize editor variables and data structures}
  50.  
  51.   begin                      {EdInitialize}
  52.  
  53.     EdZapPromptLine;         {Empty message line}
  54.  
  55.     {Initialize the first window}
  56.     CurWin :=
  57.     EdAllocateWindow(
  58.                      LogTopScr, {Physical top of window}
  59.                      LogScrRows, {Length of window}
  60.                      Line1,  {Initial position in window}
  61.                      Col1,   {Initial position in window}
  62.                      NoFile  {Editing no file}
  63.                      );
  64.  
  65.     {Define top window}
  66.     Window1 := CurWin;
  67.     Window1^.FwdLink := Window1;
  68.     Window1^.Backlink := Window1;
  69.  
  70.     {Last cursor position}
  71.     LastPosition.Line := CurWin^.TopLine;
  72.     LastPosition.Col := 1;
  73.  
  74.   end;                       {EdInitialize}
  75.  
  76.   procedure EdMainMenu;
  77.     {-Get command line parameters or prompt for initial file}
  78.   var
  79.     CmdString, Arg : String255;
  80.     Fcount : Integer;
  81.     AddWindStr : CommandString;
  82.  
  83.   begin                      {EdMainMenu}
  84.     AddWindStr := EdCommandKeys(CmdAddWindow, Primary);
  85.     if Argcount > 0 then begin
  86.       {Take DOS command line for file names, up to 3 windows}
  87.       EdClearString(CmdString);
  88.       Fcount := 1;
  89.       if not(EdStringEmpty(AddWindStr)) then
  90.         while (Argcount > 0) and (Fcount <= 3) do begin
  91.           Arg := ParamStr(Fcount);
  92.           CmdString := CmdString+AddWindStr+Arg+^M;
  93.           Inc(Fcount);
  94.           if Pos('*', Arg)+Pos('?', Arg) <> 0 then begin
  95.             {Bring up noname file if wildcards detected}
  96.             CmdString := AddWindStr+^M;
  97.             Argcount := 1;
  98.           end;
  99.           Dec(Argcount);
  100.         end;
  101.       Argcount := 0;
  102.     end else
  103.       {Start up with noname file}
  104.       CmdString := AddWindStr+^M;
  105.  
  106.     {Push commands onto keyboard buffer}
  107.     EdUserPush(CmdString);
  108.   end;                       {EdMainMenu}
  109.  
  110.   procedure EdWriteNamedFile;
  111.     {-Get file name, save current text stream to it, change stream names}
  112.   var
  113.     Fname, Junk : Filepath;
  114.  
  115.   begin                      {EdWriteNamedFile}
  116.  
  117.     {Get a file name}
  118.     EdClearString(Junk);
  119.     Fname := EdGetFileName(EdGetMessage(386), DefExtension, 0, Junk);
  120.     if Abortcmd or EdStringEmpty(Fname) then
  121.       Exit;
  122.  
  123.     if EdExistFile(Fname) then begin
  124.       {Prompt to overwrite}
  125.       if not(EdYesNo(EdGetMessage(319))) then
  126.         Exit;
  127.       if Abortcmd then
  128.         Exit;
  129.     end;
  130.  
  131.     EdFileWrite(Fname, False);
  132.     if GotError then
  133.       Exit;
  134.  
  135.     {Change the names of all linked streams}
  136.     EdChangeStreamName(Fname);
  137.  
  138.   end;                       {EdWriteNamedFile}
  139.  
  140.   procedure EdSaveFile;
  141.     {-Save file and return to same position for further editing}
  142.   var
  143.     C : BlockMarker;
  144.  
  145.   begin                      {EdSaveFile}
  146.     with CurWin^, C do begin
  147.       Line := CurLine;
  148.       Col := ColNo;
  149.       if Filename = NoFile then
  150.         EdWriteNamedFile
  151.       else
  152.         EdFileWrite(Filename, False);
  153.     end;
  154.     EdJumpMarker(C);
  155.   end;                       {EdSaveFile}
  156.  
  157.   procedure EdSaveQuit;
  158.     {-Save file and leave editor if all windows are closed}
  159.  
  160.   begin                      {EdSaveQuit}
  161.     with CurWin^ do begin
  162.       if Filename = NoFile then begin
  163.         EdWriteNamedFile;
  164.         if Abortcmd or (Filename = NoFile) then
  165.           Exit;
  166.       end else
  167.         EdFileWrite(Filename, (Window1^.FwdLink = Window1));
  168.       if GotError then
  169.         Exit;
  170.       EdShutWindow(True);
  171.     end;
  172.   end;                       {EdSaveQuit}
  173.  
  174.   {***}
  175.   procedure EdFindNext;
  176.     {-Process find next command}
  177.  
  178.   begin                      {EdFindNext}
  179.     PromptForInput := False;
  180.     case LastSearchOp of
  181.       Find : EdFind;
  182.       Replace : EdFindReplace;
  183.     end;
  184.     PromptForInput := True;
  185.   end;                       {EdFindNext}
  186.  
  187.   {***}
  188.   procedure EdAddWindow;
  189.     {-Add a text window, get a file for it, read it in, and move to it}
  190.   var
  191.     WindToDivide : Integer;
  192.  
  193.   begin                      {EdAddWindow}
  194.  
  195.     {Add a window only if allowed}
  196.     if (WindowCount >= MaxWindows) then begin
  197.       EdErrormsg(127);
  198.       Exit;
  199.     end;
  200.  
  201.     if WindowCount > 0 then begin
  202.       {Get most likely window to divide into two}
  203.       WindToDivide := EdGetWindowToDivide;
  204.  
  205.       {Divide window if possible}
  206.       EdWindowCreate(WindToDivide);
  207.       if GotError then
  208.         {Could not create window, message already displayed}
  209.         Exit;
  210.  
  211.       {Move to new window}
  212.       EdWindowGoto(Succ(WindToDivide));
  213.     end;
  214.  
  215.     {Read the new file into memory}
  216.     EdReadFile(EdGetFileName(EdGetMessage(320), DefExtension, 0, LastFileEdit));
  217.  
  218.     if GotError then begin
  219.       if WindowCount > 0 then begin
  220.         {Didn't get file, remove window just created}
  221.         EdWindowGoto(WindToDivide);
  222.         EdWindowDelete(Succ(WindToDivide));
  223.       end else
  224.         {Quit the editor}
  225.         EdFlagExit;
  226.     end else
  227.       Inc(WindowCount);
  228.  
  229.   end;                       {EdAddwindow}
  230.  
  231.   procedure EdPromptLogDrive;
  232.     {-Prompt for and move to new directory}
  233.   var
  234.     Junk : Filepath;
  235.  
  236.   begin                      {EdPromptLogDrive}
  237.     {Current directory is default}
  238.     GetDir(0, Junk);
  239.     EdLogDrive(EdGetFileName(EdGetMessage(317), '', 16, Junk));
  240.   end;                       {EdPromptLogDrive}
  241.  
  242.   {***}
  243.   procedure EdProcessCommand(C : CommandType);
  244.     {-Top level dispatcher for all editor commands}
  245.   var
  246.     LastLine : PlineDesc;
  247.     LastCol : Integer;
  248.  
  249.     procedure EdCursorCommands(C : CommandType);
  250.       {-Dispatcher for cursor movement commands}
  251.  
  252.     begin                    {EdCursorCommands}
  253.       case C of
  254.         CmdLeftChar : EdLeftChar; {Left character}
  255.         CmdRightChar : EdRightChar; {Right character}
  256.         CmdLeftWord : EdLeftWord; {Left lexeme}
  257.         CmdRightWord : EdRightWord; {Right lexeme}
  258.         CmdUpLine :          {Up line}
  259.           begin
  260.             EdUpLine;
  261.             FullScroll := FullScroll+TempScroll;
  262.           end;
  263.         CmdDownLine :        {Down line}
  264.           begin
  265.             EdDownLine;
  266.             FullScroll := FullScroll+TempScroll;
  267.           end;
  268.         CmdScrollUp : EdScrollUp; {Scroll up}
  269.         CmdScrollDown : EdScrollDown; {Scroll down}
  270.         CmdDownPage : EdDownPage; {Down page}
  271.         CmdUpPage : EdUpPage; {Up page}
  272.       end;
  273.     end;                     {EdCursorCommands}
  274.  
  275.     {***}
  276.     procedure EdQuickCommands(C : CommandType);
  277.       {-Dispatcher for quick movement commands}
  278.  
  279.     begin                    {EdQuickCommands}
  280.       case C of
  281.         CmdWindowTopFile : EdWindowTopFile; {Top of window}
  282.         CmdWindowBottomFile : EdWindowBottomFile; {Bottom of window}
  283.         CmdLeftLine : EdLeftLine; {Cursor to left side}
  284.         CmdRightLine : EdRightLine; {Cursor to right side}
  285.         CmdTopScreen : EdTopScreen; {Top of screen}
  286.         CmdBottomScreen : EdBottomScreen; {Bottom of screen}
  287.         CmdCpgotoln : EdPromptGotoLine; {Goto line n}
  288.         CmdGotoColumn : EdPromptGotoCol; {Goto column n}
  289.         CmdJumpLastPosition : EdJumpMarker(LastPosition); {Previous cursor position}
  290.       end;
  291.     end;                     {EdQuickCommands}
  292.  
  293.     {***}
  294.     procedure EdDeleteCommands(C : CommandType);
  295.       {-Dispatcher for commands which delete or insert text}
  296.  
  297.     begin                    {EdDeleteCommands}
  298.       case C of
  299.         CmdUndo : EdUndo;    {Undo last deletion}
  300.         CmdRestoreCurrentLine : EdRestoreCurrentLine; {Restore line as on entry}
  301.         CmdTab : EdTab;      {Tab}
  302.         CmdInsertCtrlChar : EdInsertCtrlChar; {Insert control character into text}
  303.         CmdNewLine : EdNewLine; {New line in text buffer}
  304.         CmdInsertLine : EdInsertLine; {Insert line}
  305.         CmdDeleteRightChar : EdDeleteRightChar; {Delete current character}
  306.         CmdDeleteLeftChar : EdDeleteLeftChar; {Delete left character}
  307.         CmdDeleteRightWord : EdDeleteRightWord; {Delete right lexeme}
  308.         CmdDeleteLineRight : EdDeleteLineRight; {Delete line right}
  309.         CmdDeleteLine : EdDeleteLine; {Delete line}
  310.       end;
  311.  
  312.     end;                     {EdDeleteCommands}
  313.  
  314.     {***}
  315.     procedure EdFileCommands(C : CommandType);
  316.       {-Dispatcher for commands which read and write files}
  317.  
  318.     begin                    {EdFileCommands}
  319.       case C of
  320.         CmdFind : EdFind;    {Find pattern}
  321.         CmdFindReplace : EdFindReplace; {Find and replace}
  322.         CmdFindNext : EdFindNext; {Find next}
  323.         CmdAbandonFile : EdAbandonFile(True); {Abandon file and leave editor}
  324.         CmdReadBlock :       {Read file into window}
  325.           EdReadtextfile(EdGetFileName(EdGetMessage(321), DefExtension, 0, LastBlockRead), True);
  326.         CmdSaveFile : EdSaveFile; {Save file}
  327.         CmdWriteBlock : EdPromptWriteBlock;
  328.         CmdSaveQuit : EdSaveQuit; {Save file and exit}
  329.       end;
  330.     end;                     {EdFileCommands}
  331.  
  332.     procedure EdWindowCommands(C : CommandType);
  333.       {-Dispatcher for commands which manipulate windows}
  334.  
  335.     begin                    {EdWindowCommands}
  336.       case C of
  337.         CmdAddWindow : EdAddWindow; {Add another window}
  338.         CmdSizeWindow : EdSizeWindow; {Size current window}
  339.         CmdWindowDown : EdWindowDown; {Switch windows}
  340.       end;
  341.     end;                     {EdWindowCommands}
  342.  
  343.     procedure EdBlockCommands(C : CommandType);
  344.       {-Dispatcher for block operations and markers}
  345.  
  346.     begin                    {EdBlockCommands}
  347.       case C of
  348.         CmdBlockBegin : EdBlockBegin; {Begin block}
  349.         CmdBlockEnd : EdBlockEnd; {End block}
  350.         CmdJumpTopOfBlock : EdJumpMarker(Blockfrom); {Top of block}
  351.         CmdJumpBottomBlock : EdJumpMarker(Blockto); {Bottom of block}
  352.         CmdBlockCopy : EdBlockCopy; {Copy block}
  353.         CmdBlockMove : EdBlockMove; {Move block}
  354.         CmdBlockDelete : EdBlockDelete; {Delete block}
  355.         CmdBlockHide : EdBlockHide; {Hide/display toggle block}
  356.         CmdBlockWord : EdBlockWord; {Mark current word as block}
  357.         CmdToggleTextMarker : EdToggleTextMarker; {Toggle text marker display}
  358.         CmdSetMarker0..CmdSetMarker9 :
  359.           EdSetMarker(Ord(C)-Ord(CmdSetMarker0)); {Set marker}
  360.         CmdJumpMarker0..CmdJumpMarker9 :
  361.           EdJumpMarker(Marker[Ord(C)-Ord(CmdJumpMarker0)]); {Jump marker}
  362.       end;
  363.  
  364.       {Assure that current line buffer is updated}
  365.       Blockop := True;
  366.     end;                     {EdBlockCommands}
  367.  
  368.     {***}
  369.     procedure EdTextCommands(C : CommandType);
  370.       {-Dispatcher for commands which perform word processing functions}
  371.  
  372.     begin                    {EdTextCommands}
  373.       case C of
  374.         CmdSysInfo : EdSysInfo; {Show editor version}
  375.         CmdShowMem : EdShowMemory; {Show available memory}
  376.         CmdToggleInsert : EdToggleBoolean(CurWin^.InsertFlag); {Toggle insert mode}
  377.         CmdToggleAutoindent : EdToggleBoolean(CurWin^.AI); {Toggle autoindent mode}
  378.       end;
  379.     end;                     {EdTextCommands}
  380.  
  381.     {***}
  382.     procedure EdUtilityCommands(C : CommandType);
  383.       {-Dispatcher for commands which perform utility functions}
  384.  
  385.     begin                    {EdUtilityCommands}
  386.       case C of
  387.         CmdLogDrive : EdPromptLogDrive; {Prompt for and move to new directory}
  388.         CmdSetUndoLimit : EdSetUndoLimit; {Set default undo limit}
  389.         CmdGetDefaultExtension : EdGetDefaultExtension; {Get a new default extension}
  390.         CmdWriteNamedFile : EdWriteNamedFile;
  391.         CmdWindowUp : EdWindowUp;
  392.       end;
  393.     end;                     {EdUtilityCommands}
  394.  
  395.   begin                      {EdProcessCommand}
  396.  
  397.     {Clear the command line indicator}
  398.     EdResetPromptLine;
  399.  
  400.     {Store the soon to be a previous position}
  401.     with CurWin^ do begin
  402.       LastCol := ColNo;
  403.       LastLine := CurLine;
  404.     end;
  405.  
  406.     {Branch based on basic command groups}
  407.     case C of
  408.       CmdLeftChar..CmdUpPage : EdCursorCommands(C);
  409.       CmdWindowTopFile..CmdJumpLastPosition : EdQuickCommands(C);
  410.       CmdUndo..CmdDeleteLine : EdDeleteCommands(C);
  411.       CmdFind..CmdSaveQuit : EdFileCommands(C);
  412.       CmdAddWindow..CmdWindowDown : EdWindowCommands(C);
  413.       CmdBlockBegin..CmdJumpMarker9 : EdBlockCommands(C);
  414.       CmdSysInfo..CmdToggleAutoindent : EdTextCommands(C);
  415.       CmdLogDrive..CmdWindowUp : EdUtilityCommands(C);
  416.     end;
  417.  
  418.     {Reset from any effect of the called command}
  419.     EdZapPromptLine;
  420.     Abortcmd := False;
  421.     GotError := False;
  422.     AbortEnable := False;
  423.  
  424.     if WindowCount > 0 then begin
  425.  
  426.       with LastPosition, CurWin^ do begin
  427.         if (CurLine <> LastLine) or (ColNo <> LastCol) then begin
  428.           {Store the previous position}
  429.           Line := LastLine;
  430.           Col := LastCol;
  431.         end;
  432.  
  433.         {Buffer line if it changed}
  434.         if Blockop or (CurLine <> LastLine) then begin
  435.           EdBufferCurrentLine;
  436.           Blockop := False;
  437.         end;
  438.       end;
  439.  
  440.       {Don't update the screen inside of macros}
  441.       if (EditUsercommandInput = 0) then begin
  442.         {Special handling of single line scrolls for CGA speed}
  443.         if FullScroll <> 0 then
  444.           EdBiosScroll;
  445.         {The screen may need to be updated}
  446.         UpdateScreen := True;
  447.       end;
  448.  
  449.     end;
  450.  
  451.   end;                       {EdProcessCommand}
  452.  
  453.   procedure EdClassifyInput;
  454.     {-Route keyboard input to text or command handlers}
  455.   var
  456.     Ch : Char;
  457.     CmdCode : CommandType;
  458.  
  459.   begin                      {EdClassifyInput}
  460.  
  461.     {Read a character}
  462.     Ch := EdGetInput;
  463.  
  464.     if (CmdPtr = 0) and (Ch >= #32) and (Ch <> #127) then begin
  465.  
  466.       {A normal character}
  467.       {Store previous position}
  468.       with LastPosition, CurWin^ do begin
  469.         Col := ColNo;
  470.         Line := CurLine;
  471.       end;
  472.  
  473.       {Process the character}
  474.       EdProcesstext(Ch);
  475.  
  476.       if EditUsercommandInput = 0 then
  477.         {Buffer line if it changed}
  478.         if CurWin^.CurLine <> LastPosition.Line then
  479.           EdBufferCurrentLine;
  480.  
  481.     end else begin
  482.  
  483.       {Potentially a command}
  484.       Inc(CmdPtr);
  485.       if (CmdPtr > 1) and (CmdBuf[Pred(CmdPtr)] <> Null) then
  486.         {Accept lower/upper/control chars as equivalent for second char of command}
  487.         CmdBuf[CmdPtr] := EdControlFilter(Ch)
  488.       else
  489.         CmdBuf[CmdPtr] := Ch;
  490.  
  491.       case EdScanCmdList(CmdPtr, CmdCode) of
  492.  
  493.         Match :
  494.           {Process the command}
  495.           EdProcessCommand(CmdCode);
  496.  
  497.         NoMatch :
  498.           {Reset and ignore}
  499.           EdResetPromptLine;
  500.  
  501.         PartMatch :
  502.           {Leave char in cmdbuf to complete match}
  503.           {Indicate via command line that a partial command has been entered}
  504.           EdDisplayCommandBuffer;
  505.  
  506.       end;                   {Case}
  507.     end;                     {Potential command}
  508.  
  509.   end;                       {EdClassifyInput}
  510.  
  511.   {***}
  512.   procedure EdSchedule;
  513.     {-Schedule editor}
  514.  
  515.     procedure EdBackgroundProcess;
  516.       {-Process background functions}
  517.  
  518.     begin                    {EdBackgroundProcess}
  519.  
  520.       {Align windows horizontally}
  521.       EdHscroll;
  522.  
  523.       {Update the cursor}
  524.       if UpdateCursor then
  525.         EdUpdateCursor;
  526.  
  527.       {Update the screen if something's new}
  528.       if UpdateScreen then begin
  529.         {Redraw the screen}
  530.         EdUpdateScreen;
  531.       end;
  532.       if EdKeyInterrupt then
  533.         Exit;
  534.  
  535.       {Mark any new lines in block}
  536.       EdMarkblock;
  537.       if EdKeyInterrupt then
  538.         Exit;
  539.  
  540.       {Update the screen again if attributes changed}
  541.       if UpdateScreen then begin
  542.         EdUpdateScreen;
  543.         if EdKeyInterrupt then
  544.           Exit;
  545.       end;
  546.  
  547.       {Keep window modified flags up to date}
  548.       EdCloneModifiedFlags;
  549.       if EdKeyInterrupt then
  550.         Exit;
  551.  
  552.       {Generate line number and byte count for every window}
  553.       EdGenLineNo;
  554.  
  555.     end;                     {EdBackgroundProcess}
  556.  
  557.   begin                      {EdSchedule}
  558.     Rundown := False;
  559.     repeat
  560.       if EdKeyPressed then
  561.         {Foreground operations - classify keystroke and act accordingly}
  562.         EdClassifyInput
  563.       else
  564.         {Horizontal scroll, paint screen, etc.}
  565.         EdBackgroundProcess;
  566.     until Rundown;
  567.   end;                       {EdSchedule}
  568.  
  569. begin
  570.   Argcount := ParamCount;    {Number of DOS command line parameters}
  571. end.
  572.