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

  1. {                          EDUSER.PAS
  2.                              ED 4.0
  3.              Copyright (c) 1985, 87 by Borland International, Inc.            }
  4.  
  5. {$I eddirect.inc}
  6.  
  7. unit EdUser;
  8.   {-User keyboard, prompt and error interactions}
  9.  
  10. interface
  11.  
  12. uses
  13.   crt,                       {Basic video}
  14.   Dos,                       {DOS calls - standard unit}
  15.   Errors,                    {Runtime error handler}
  16.   EdVars,                    {Global types and declarations}
  17.   EdScrn1,                   {Fast screen writing routines}
  18.   EdString,                  {String primitives}
  19.   EdPtrOp,                   {Primitive pointer operations}
  20.   EdCmds,                    {Maps keystrokes to commands}
  21.   int24,                     {DOS critical error handler}
  22.   Message;                   {Message system}
  23.  
  24. function EdGetInput : Char;
  25.   {-Read next character from typeahead buffer}
  26.  
  27. function EdKeyPressed : Boolean;
  28.   {-Determine if input is available}
  29.  
  30. function EdKeyInterrupt : Boolean;
  31.   {-Determine whether a keystroke should interrupt background processes}
  32.  
  33. procedure EdBreathe;
  34.   {-Stimulate typeahead routines without returning a character}
  35.  
  36. procedure EdUserPush(S : String255);
  37.   {-Push string onto typeahead buffer}
  38.  
  39. function EdGetAnyChar : Char;
  40.   {-Wait for and return a character from internal keyboard buffer}
  41.  
  42. procedure EdUpdateCursor;
  43.   {-Move the cursor to the right spot}
  44.  
  45. procedure EdUpdateCmdLine;
  46.   {-Update the message line}
  47.  
  48. procedure EdAppPromptLine(S : VarString);
  49.   {-Append command name to message line}
  50.  
  51. procedure EdZapPromptLine;
  52.   {-Zap message line, leaving it blank}
  53.  
  54. procedure EdResetPromptLine;
  55.   {-Clear partial command indicator from command line}
  56.  
  57. procedure EdWritePromptLine(S : VarString);
  58.   {-Write a new message line to the screen}
  59.  
  60. procedure EdDisplayCommandBuffer;
  61.   {-Indicate that a partial command has been entered}
  62.  
  63. procedure EdDisplayPromptWindow(Msg : VarString; Yp : Integer; OKset : Charset; var Ch : Char);
  64.   {-Display a one line message, and wait for char to clear it}
  65.  
  66. procedure EdErrormsg(Msgno : Integer);
  67.   {-Write error message and dump typeahead buffer}
  68.  
  69. procedure EdAskforEditor(Xp, Yp, XSize, MaxLen : Byte; HaveWindow : Boolean; var Rs : VarString);
  70.   {-Perform line editing functions for string input}
  71.  
  72. procedure EdAskfor(Prompt : VarString; Xp, Yp, Wid : Byte; var Rs : VarString);
  73.   {-Edit and return a string}
  74.  
  75. function EdYesNo(Prompt : VarString) : Boolean;
  76.   {-Return True for Yes, False for No}
  77.  
  78. function EdGetnumber(Prompt : VarString; Default : Integer) : Integer;
  79.   {-Prompt for and return a number, 0 if invalid or empty}
  80.   {-Plus or minus in input strings return results relative to default}
  81.  
  82. procedure EdSetNumber(var Num; Msg, Min, Max : Integer; var Empty : Boolean);
  83.   {-Prompt for and set an integer value in range min..max}
  84.  
  85. procedure EdWait;
  86.   {-Display a Wait signal}
  87.  
  88.   {==========================================================================}
  89.  
  90. implementation
  91.  
  92. const
  93.   DefTypeahead = 256;        {Capacity of typeahead buffer}
  94.  
  95. type
  96.   CircularBuffer = array[0..DefTypeahead] of Char;
  97.  
  98. var
  99.   Circbuf : CircularBuffer;  {Our keyboard buffer}
  100.   Circin : Integer;          {Pointer to put data into CircBuf}
  101.   Circout : Integer;         {Pointer to take data out of CircBuf}
  102.   AskforInsertflag : Boolean; {Insert mode state in prompt boxes}
  103.  
  104.   function EdGetInput : Char;
  105.     {-Read next character from typeahead buffer}
  106.  
  107.   begin                      {EdGetinput}
  108.     if EditUsercommandInput > 0 then
  109.       Dec(EditUsercommandInput);
  110.     EdGetInput := Circbuf[Circout];
  111.     Circout := Succ(Circout) mod DefTypeahead;
  112.   end;                       {EdGetinput}
  113.  
  114.   function EdKeyPressed : Boolean;
  115.     {-Determine if input is available}
  116.   var
  117.     Counter : Integer;
  118.     Ch : Char;
  119.  
  120.     procedure EdAbort;
  121.       {-Abort command and delete typeahead buffer's contents}
  122.  
  123.     begin                    {EdAbort}
  124.       if not(Aborting) then begin
  125.         Aborting := True;
  126.         Abortcmd := False;
  127.         EdErrormsg(37);
  128.         Abortcmd := True;
  129.         Aborting := False;
  130.       end;
  131.     end;                     {EdAbort}
  132.  
  133.   begin                      {EdKeypressed}
  134.  
  135.     {Transfer keystrokes from BIOS to our keyboard buffer}
  136.     Counter := 0;
  137.     while (Counter < 6) and (Succ(Circin) mod DefTypeahead <> Circout) and KeyPressed do begin
  138.       Inc(Counter);
  139.       Ch := ReadKey;
  140.       if (Ch = AbortChar) and (AbortEnable or (EditUsercommandInput <> 0)) then
  141.         EdAbort
  142.       else begin
  143.         Circbuf[Circin] := Ch;
  144.         Circin := Succ(Circin) mod DefTypeahead;
  145.       end;
  146.     end;
  147.  
  148.     EdKeyPressed := (Circin <> Circout);
  149.   end;                       {EdKeypressed}
  150.  
  151.   function EdKeyInterrupt : Boolean;
  152.     {-Determine whether to interrupt background process}
  153.  
  154.   begin                      {EdKeyInterrupt}
  155.     if (IntrFlag <> Interr) then
  156.       EdKeyInterrupt := False
  157.     else if (Circin <> Circout) then
  158.       EdKeyInterrupt := True
  159.     else
  160.       EdKeyInterrupt := EdKeyPressed;
  161.   end;                       {EdKeyInterrupt}
  162.  
  163.   procedure EdBreathe;
  164.     {-Enable keyboard buffering without returning a character}
  165.   var
  166.     B : Boolean;
  167.  
  168.   begin                      {EdBreathe}
  169.     B := EdKeyPressed;
  170.   end;                       {EdBreathe}
  171.  
  172.   procedure EdUserPush(S : String255);
  173.     {-Push string onto typeahead buffer}
  174.   var
  175.     I : Integer;
  176.  
  177.     procedure EdPushTypeahead(Ch : Char);
  178.       {-Push character onto front of typeahead buffer}
  179.  
  180.     begin                    {EdPushTypeahead}
  181.       if Succ(Circin) mod DefTypeahead = Circout then
  182.         EdErrormsg(21)
  183.       else begin
  184.         Circout := Pred(Circout+DefTypeahead) mod DefTypeahead;
  185.         Circbuf[Circout] := Ch;
  186.       end
  187.     end;                     {EdPushTypeahead}
  188.  
  189.   begin                      {EdUserpush}
  190.     for I := Length(S) downto 1 do
  191.       EdPushTypeahead(S[I]);
  192.     EditUsercommandInput := EditUsercommandInput+Length(S);
  193.   end;                       {EdUserpush}
  194.  
  195.   {***}
  196.   function EdGetAnyChar : Char;
  197.     {-Wait for and return a character from internal keyboard buffer}
  198.  
  199.   begin                      {EdGetAnyChar}
  200.     while not(EdKeyPressed or Abortcmd) do
  201.       ;
  202.     if not(Abortcmd) then
  203.       EdGetAnyChar := EdGetInput;
  204.   end;                       {EdGetAnyChar}
  205.  
  206.   {***}
  207.   procedure EdGotoxy(C, R : Byte);
  208.     {-Move the cursor to the specified row and column}
  209.  
  210.   begin                      {EdGotoxy}
  211.     {Keep the hardware cursor positioned}
  212.     GoToXY(C, R);
  213.   end;                       {EdGotoxy}
  214.  
  215.   {***}
  216.   procedure EdSetInsertMode(Inserting : Boolean);
  217.     {-Keep the cursor appearance and BIOS keyboard flag up to date}
  218.   var
  219.     BiosKbdFlag : Byte absolute $0040 : $0017;
  220.  
  221.   begin                      {EdSetInsertMode}
  222.     if Inserting then begin
  223.       EdSetCursor(BigCursor);
  224.       BiosKbdFlag := BiosKbdFlag or $80;
  225.     end else begin
  226.       EdSetCursor(CursorType);
  227.       BiosKbdFlag := BiosKbdFlag and $7F;
  228.     end;
  229.   end;                       {EdSetInsertMode}
  230.  
  231.   {***}
  232.   procedure EdUpdateCursor;
  233.     {-Move the cursor to the right spot}
  234.  
  235.   begin                      {EdUpdateCursor}
  236.     with CurWin^ do begin
  237.       {Position cursor within a window}
  238.       EdSetInsertMode(InsertFlag);
  239.       EdGotoxy(Succ(ColNo-LeftEdge+LeftCol), Pred(FirstTextNo+LineNo));
  240.     end;
  241.     UpdateCursor := False;
  242.   end;                       {EdUpdateCursor}
  243.  
  244.   procedure EdUpdateCmdLine;
  245.     {-Update the top command line}
  246.  
  247.   begin                      {EdUpdateCmdLine}
  248.     Move(PromptLine[1], Tline, PhyScrCols);
  249.     FillChar(Aline, PhyScrCols, ScreenAttr[CmdColor]);
  250.     EdWrline(PromptRow);
  251.   end;                       {EdUpdateCmdLine}
  252.  
  253.   procedure EdAppPromptLine(S : VarString);
  254.     {-Append command name to message line}
  255.  
  256.   begin                      {EdAppPromptLine}
  257.     if Length(S) > 0 then begin
  258.       Move(S[1], PromptLine[PromptCol], Length(S));
  259.       PromptCol := PromptCol+Length(S);
  260.       EdGotoxy(PromptCol, PromptRow);
  261.     end;
  262.   end;                       {EdAppPromptLine}
  263.  
  264.   procedure EdZapPromptLine;
  265.     {-Zap message line, leaving it blank}
  266.  
  267.   begin                      {EdZapPromptLine}
  268.     FillChar(PromptLine[1], PhyScrCols, Blank);
  269.     {Reset the next column number}
  270.     PromptCol := 1;
  271.     UpdateCursor := True;
  272.   end;                       {EdZapPromptLine}
  273.  
  274.   procedure EdResetPromptLine;
  275.     {-Clear partial command indicator from command line}
  276.  
  277.   begin                      {EdResetPromptLine}
  278.     CmdPtr := 0;
  279.     EdZapPromptLine;
  280.     UpdateScreen := True;
  281.     UpdateCursor := True;
  282.   end;                       {EdResetPromptLine}
  283.  
  284.   procedure EdWritePromptLine(S : VarString);
  285.     {-Write a new message line to the screen}
  286.  
  287.   begin                      {EdWritePromptLine}
  288.     EdZapPromptLine;
  289.     EdAppPromptLine(S);
  290.     EdUpdateCmdLine;
  291.   end;                       {EdWritePromptLine}
  292.  
  293.   procedure EdDisplayCommandBuffer;
  294.     {-Indicate that a partial command has been entered}
  295.   var
  296.     Cmd : VarString;
  297.     I : Integer;
  298.     Ch : Char;
  299.  
  300.   begin                      {EdDisplayCommandBuffer}
  301.     {Get out fast if other keys are waiting}
  302.     if (Circin = Circout) then begin
  303.       I := 1;
  304.       Cmd := '';
  305.       while I <= CmdPtr do begin
  306.         Ch := CmdBuf[I];
  307.         case Ch of
  308.           #0 :
  309.             begin
  310.               {Don't try to interpret extended keystrokes}
  311.               Inc(I);
  312.               Cmd := Cmd+'+';
  313.             end;
  314.           #1..#31 :
  315.             Cmd := Cmd+'^'+Chr(Ord(Ch)+64)
  316.         else
  317.           Cmd := Cmd+Ch;
  318.         end;
  319.         Inc(I);
  320.       end;
  321.       EdWritePromptLine(Cmd);
  322.     end;
  323.   end;                       {EdDisplayCommandBuffer}
  324.  
  325.   {***}
  326.   procedure EdDisplayPromptWindow(Msg : VarString; Yp : Integer; OKset : Charset; var Ch : Char);
  327.     {-Display a one line message, and wait for char to clear it}
  328.  
  329.   begin                      {EdDisplayPromptWindow}
  330.     {Write message to top line}
  331.     EdWritePromptLine(Msg);
  332.  
  333.     {Wait for a key in OKset}
  334.     repeat
  335.       Ch := EdControlFilter(EdGetAnyChar);
  336.     until Abortcmd or (Ch in OKset);
  337.   end;                       {EdDisplayPromptWindow}
  338.  
  339.   {***}
  340.   procedure EdErrormsg(Msgno : Integer);
  341.     {-Write error message and dump typeahead buffer}
  342.   var
  343.     Ch : Char;
  344.  
  345.   begin                      {EdErrormsg}
  346.     {Zap typeahead buffer before read}
  347.     Circin := Circout;
  348.     {Clear any pushed characters}
  349.     EditUsercommandInput := 0;
  350.     {Set error flag to be polled as needed by calling routines}
  351.     GotError := True;
  352.     {Show the message}
  353.     EdDisplayPromptWindow(EdGetMessage(Msgno)+'-'+EdGetMessage(305), 1, [#27], Ch);
  354.     {Clear typeahead buffer again}
  355.     Circin := Circout;
  356.     UpdateCursor := True;
  357.     EdZapPromptLine;
  358.   end;                       {EdErrormsg}
  359.  
  360.   procedure EdAskforEditor(Xp, Yp, XSize, MaxLen : Byte; HaveWindow : Boolean; var Rs : VarString);
  361.     {-Perform line editing functions for string input}
  362.   const
  363.     Del = #127;
  364.   var
  365.     Wp : Byte;
  366.     Ws : VarString;
  367.     Ch : Char;
  368.     Quitting, FirstRead : Boolean;
  369.  
  370.     function EdReadChar : Char;
  371.       {-Read a character and convert extended keystrokes to single char}
  372.     const
  373.       WScommands : string[11] = ^@^A^D^F^G^B^E^S^V^X^Y;
  374.       ExCommands : string[10] = 'sMtSGOKRwu';
  375.     var
  376.       Ch : Char;
  377.  
  378.     begin                    {EdReadchar}
  379.       {Wait for a key to enter the typeahead buffer}
  380.       Ch := EdGetAnyChar;
  381.       if Abortcmd then
  382.         Exit;
  383.  
  384.       if (Ch = Null) then begin
  385.         {Get an extended character}
  386.         Ch := EdGetAnyChar;
  387.         {Convert IBM keypad to equivalent control char}
  388.         Ch := WScommands[Succ(Pos(Ch, ExCommands))];
  389.       end;
  390.       EdReadChar := Ch;
  391.     end;                     {EdReadchar}
  392.  
  393.     procedure EdDisplayString(S : VarString; Start : Byte);
  394.       {-Display the working string starting at position start}
  395.     var
  396.       I, X, Clr : Byte;
  397.       Ch : Char;
  398.  
  399.     begin                    {EdDisplayString}
  400.       if not(HaveWindow) then
  401.         Exit;
  402.       X := Xp+Start;
  403.       for I := Start to Length(S) do begin
  404.         {Display the string, converting control characters to highlighted uppercase}
  405.         Ch := S[I];
  406.         if Ch < Blank then begin
  407.           Clr := CtrlAttr;
  408.           Ch := Chr(Ord(Ch)+64);
  409.         end else
  410.           Clr := ScreenAttr[CmdColor];
  411.         EdFastWrite(Ch, Yp, X, Clr);
  412.         Inc(X);
  413.       end;
  414.       {Clear the rest of the line}
  415.       Clr := ScreenAttr[CmdColor];
  416.       Ch := Blank;
  417.       while X < Pred(Xp+XSize) do begin
  418.         EdFastWrite(Ch, Yp, X, Clr);
  419.         Inc(X);
  420.       end;
  421.     end;                     {EdDisplayString}
  422.  
  423.     procedure EdClear(var Ws : VarString; var Wp : Byte);
  424.       {-Clear the working string}
  425.  
  426.     begin                    {EdClear}
  427.       EdClearString(Ws);
  428.       Wp := 1;
  429.       EdDisplayString(Ws, 1);
  430.       if HaveWindow then
  431.         GoToXY(Xp+Wp, Yp);
  432.     end;                     {EdClear}
  433.  
  434.     procedure EdInsertCharacter(Ch : Char; var Ws : VarString; var Wp : Byte);
  435.       {-Insert a character into the string}
  436.  
  437.     begin                    {EdInsertCharacter}
  438.       if Length(Ws) < MaxLen then begin
  439.         if AskforInsertflag then
  440.           Insert(Ch, Ws, Wp)
  441.         else if Wp > Length(Ws) then
  442.           Ws := Ws+Ch
  443.         else
  444.           Ws[Wp] := Ch;
  445.         EdDisplayString(Ws, Wp);
  446.         Inc(Wp);
  447.       end else if not(AskforInsertflag) and (Wp <= Length(Ws)) then begin
  448.         Ws[Wp] := Ch;
  449.         EdDisplayString(Ws, Wp);
  450.       end;
  451.     end;                     {EdInsertCharacter}
  452.  
  453.   begin                      {EdAskforEditor}
  454.  
  455.     {Get working copy of the input string}
  456.     Ws := Copy(Rs, 1, MaxLen);
  457.     Wp := Succ(Length(Ws));
  458.  
  459.     {Display the initial string}
  460.     EdDisplayString(Ws, 1);
  461.     FirstRead := True;
  462.     Quitting := False;
  463.  
  464.     repeat
  465.  
  466.       {Update the cursor}
  467.       if HaveWindow then begin
  468.         GoToXY(Xp+Wp, Yp);
  469.         EdSetInsertMode(AskforInsertflag);
  470.       end;
  471.  
  472.       {Get the next keyboard character}
  473.       Ch := EdReadChar;
  474.       if Abortcmd then
  475.         {Get out of here}
  476.         Ch := ^[;
  477.  
  478.       if FirstRead then begin
  479.         if (Ch = ^P) or (Ch > ^Z) then
  480.           {Clear the default string}
  481.           EdClear(Ws, Wp);
  482.         FirstRead := False;
  483.       end;
  484.  
  485.       case Ch of
  486.  
  487.         ^@ :                {Null key}
  488.           ;
  489.  
  490.         ^M :                 {Enter, accept string and exit}
  491.           Quitting := True;
  492.  
  493.         ^[ :                 {Escape, clear string and exit}
  494.           begin
  495.             EdClear(Ws, Wp);
  496.             Quitting := True;
  497.             Abortcmd := True;
  498.           end;
  499.  
  500.         ^B :                 {Begin of line}
  501.           Wp := 1;
  502.  
  503.         ^E :                 {End of line}
  504.           Wp := Succ(Length(Ws));
  505.  
  506.         ^Y :                 {Clear to end of line}
  507.           begin
  508.             Ws := Copy(Ws, 1, Pred(Wp));
  509.             EdDisplayString(Ws, 1);
  510.           end;
  511.  
  512.         ^X :                 {Clear line}
  513.           EdClear(Ws, Wp);
  514.  
  515.         ^R :                 {Restore line to default}
  516.           begin
  517.             Ws := Copy(Rs, 1, MaxLen);
  518.             Wp := Succ(Length(Ws));
  519.             EdDisplayString(Ws, 1);
  520.           end;
  521.  
  522.         ^S :                 {Cursor left one}
  523.           if Wp > 1 then
  524.             Dec(Wp);
  525.  
  526.         ^D :                 {Cursor right one}
  527.           if Wp <= Length(Ws) then
  528.             Inc(Wp);
  529.  
  530.         ^A :                 {Cursor left one word}
  531.           if Wp > 1 then begin
  532.             Dec(Wp);
  533.             while (Wp >= 1) and ((Wp > Length(Ws)) or (Ws[Wp] = Blank)) do
  534.               Dec(Wp);
  535.             while (Wp >= 1) and (Ws[Wp] <> Blank) do
  536.               Dec(Wp);
  537.             Inc(Wp);
  538.           end;
  539.  
  540.         ^F :                 {Cursor right one word}
  541.           if Wp <= Length(Ws) then begin
  542.             Inc(Wp);
  543.             while (Wp <= Length(Ws)) and (Ws[Wp] <> Blank) do
  544.               Inc(Wp);
  545.             while (Wp <= Length(Ws)) and (Ws[Wp] = Blank) do
  546.               Inc(Wp);
  547.           end;
  548.  
  549.         ^G :                 {Delete current character}
  550.           if Wp <= Length(Ws) then begin
  551.             Delete(Ws, Wp, 1);
  552.             EdDisplayString(Ws, Wp);
  553.           end;
  554.  
  555.         ^H, Del :            {Delete character left}
  556.           if Wp > 1 then begin
  557.             Dec(Wp);
  558.             Delete(Ws, Wp, 1);
  559.             EdDisplayString(Ws, Wp);
  560.           end;
  561.  
  562.         ^P :                 {Accept control character}
  563.           EdInsertCharacter(Chr(Ord(EdReadChar) and $1F), Ws, Wp);
  564.  
  565.         ^V :                 {Toggle insert mode}
  566.           AskforInsertflag := not(AskforInsertflag);
  567.  
  568.       else
  569.         {Insert normal character}
  570.         if Ch > ^Z then
  571.           EdInsertCharacter(Ch, Ws, Wp);
  572.       end;
  573.  
  574.     until Quitting;
  575.  
  576.     {Return the working string}
  577.     Rs := Ws;
  578.  
  579.   end;                       {EdAskforEditor}
  580.  
  581.   {*** xp and yp are ignored in FirstEd}
  582.   procedure EdAskfor(Prompt : VarString; Xp, Yp, Wid : Byte; var Rs : VarString);
  583.     {-Edit and return a string}
  584.   var
  585.     Width : Byte;
  586.     HaveWindow : Boolean;
  587.  
  588.   begin                      {EdAskFor}
  589.  
  590.     if Abortcmd then
  591.       Exit;
  592.     AbortEnable := True;
  593.  
  594.     if EditUsercommandInput = 0 then begin
  595.       {Not in a macro, update the screen}
  596.       EdWritePromptLine(Prompt);
  597.       HaveWindow := True;
  598.     end else
  599.       {Don't waste time on screen within macros}
  600.       HaveWindow := False;
  601.  
  602.     {Truncate widths that won't fit on screen}
  603.     if Wid > PhyScrCols-Length(Prompt) then
  604.       Width := PhyScrCols-Length(Prompt)
  605.     else
  606.       Width := Wid;
  607.  
  608.     {Perform the edit, returning a new string Rs}
  609.     EdAskforEditor(Succ(Length(Prompt)), 1, Width, Width-2, HaveWindow, Rs);
  610.  
  611.     if HaveWindow then begin
  612.       {Put the screen back in shape}
  613.       EdUpdateCursor;
  614.       EdWritePromptLine('');
  615.     end;
  616.  
  617.   end;                       {EdAskfor}
  618.  
  619.   procedure EdString2integer(Src : VarString; var Result : Integer);
  620.     {-Convert string to integer}
  621.     {-Note 0 returned may mean ERROR - also check GotError}
  622.   var
  623.     V, Code : Integer;
  624.  
  625.   begin                      {EdString2integer}
  626.     Val(Src, V, Code);
  627.     if Code = 0 then
  628.       Result := V
  629.     else begin
  630.       Result := 0;
  631.       EdErrormsg(36);
  632.     end;
  633.   end;                       {EdString2integer}
  634.  
  635.   {***}
  636.   function EdYesNo(Prompt : VarString) : Boolean;
  637.     {-Return True for Yes, False for No}
  638.   var
  639.     Ch : Char;
  640.  
  641.   begin                      {EdYesNo}
  642.     AbortEnable := True;
  643.     EdDisplayPromptWindow(Prompt, 1, [^Y, ^N, #27], Ch);
  644.     EdYesNo := (Ch = ^Y);
  645.     if Ch = #27 then
  646.       AbortCmd := true;
  647.   end;                       {EdYesNo}
  648.  
  649.   function EdGetnumber(Prompt : VarString; Default : Integer) : Integer;
  650.     {-Prompt for and return a number, 0 if invalid or empty}
  651.     {-Plus or minus in input strings return results relative to default}
  652.   var
  653.     St : VarString;
  654.     Result : Integer;
  655.     PlusPos, MinusPos : Byte;
  656.  
  657.   begin                      {EdGetnumber}
  658.     Str(Default, St);
  659.     EdAskfor(Prompt, 1, 1, 30, St);
  660.  
  661.     if Abortcmd or EdStringEmpty(St) then
  662.       Result := 0
  663.     else begin
  664.  
  665.       {Check for relative indicators}
  666.       PlusPos := Pos('+', St);
  667.       if PlusPos <> 0 then
  668.         Delete(St, PlusPos, 1);
  669.       MinusPos := Pos('-', St);
  670.       if MinusPos <> 0 then
  671.         Delete(St, MinusPos, 1);
  672.  
  673.       {Convert string to number}
  674.       EdString2integer(St, Result);
  675.  
  676.       if Result > 0 then begin
  677.         {Apply relative offsets}
  678.         if PlusPos <> 0 then
  679.           Result := Default+Result
  680.         else if MinusPos <> 0 then
  681.           Result := Default-Result;
  682.       end;
  683.  
  684.     end;
  685.     EdGetnumber := Result;
  686.  
  687.   end;                       {EdGetNumber}
  688.  
  689.   {***}
  690.   procedure EdSetNumber(var Num; Msg, Min, Max : Integer; var Empty : Boolean);
  691.     {-Prompt for and set an integer value}
  692.   var
  693.     Number : Integer absolute Num;
  694.     St : VarString;
  695.     Temp : Integer;
  696.  
  697.   begin                      {EdSetNumber}
  698.     with CurWin^ do begin
  699.       Empty := False;
  700.       Str(Number, St);
  701.       EdAskfor(EdGetMessage(Msg), 1, 1, 10, St);
  702.       if Abortcmd then
  703.         Exit;
  704.       if EdStringEmpty(St) then begin
  705.         Empty := True;
  706.         Exit;
  707.       end;
  708.       EdString2integer(St, Temp);
  709.       if (Temp >= Min) and (Temp <= Max) then
  710.         Number := Temp;
  711.     end;
  712.   end;                       {EdSetNumber}
  713.  
  714.   procedure EdWait;
  715.     {-Display a Wait signal}
  716.   begin                      {EdWait}
  717.     EdWritePromptLine(EdGetMessage(327));
  718.   end;                       {EdWait}
  719.  
  720. begin
  721.   {Assure break checking is off}
  722.   CheckBreak := False;
  723.   {No buffered keystrokes}
  724.   Circin := 0;
  725.   Circout := 0;
  726.   {Command line editor starts in insert mode}
  727.   AskforInsertflag := True;
  728. end.
  729.