home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 16 / 16.iso / w / w048 / 2.ddi / MSSRC.ARC / MSCMDS.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1987-12-21  |  9.4 KB  |  288 lines

  1. {                            MSCMDS.PAS
  2.                                MS 4.0
  3.                 Copyright (c) 1985, 87 by Borland International, Inc.         }
  4.  
  5. {$I msdirect.inc}
  6.  
  7. unit MsCmds;
  8.   {-Map keystrokes to commands}
  9.  
  10. interface
  11.  
  12. uses
  13.   EscSeq,                    {Returns text string for extended scan codes}
  14.   MsVars;                    {Global types and declarations}
  15.  
  16.   {$I MSCMDS.INC}            {Defines enumerated type of all editor commands}
  17.  
  18. type
  19.   CommandString = string[4]; {Longest key sequence for a command}
  20.   CmdMatchType = (Match, NoMatch, PartMatch); {Used in matching key sequences to editor commands}
  21.   CommandPriority = (Primary, Secondary); {Two sequences allowed for each command}
  22.   CmdSet = set of CommandType; {To classify groups of commands}
  23.   LengthArray = array[0..255] of Byte; {Holds length of text representation of keystrokes}
  24.  
  25. var
  26.   {Keyboard-related}
  27.   CmdBuf : CommandString;    {Holds current command until complete command reached}
  28.   CmdPtr : Byte;             {Points to last character in current command}
  29.   AbortChar : Char;          {Character used to abort operation}
  30.   GlobalCmd : CommandType;   {Currently active command used by help system}
  31.   MenuPrime : CommandString; {Primary keystrokes which activate menus}
  32.   MenuSecon : CommandString; {Secondary keystrokes which activate menus}
  33.   TogglePrime : CommandString; {Primary keystrokes which toggle macro recording}
  34.   ToggleSecon : CommandString; {Secondary keystrokes which toggle macro recording}
  35.   AddwinPrime : CommandString; {Keystrokes which open a file in a new window}
  36.   CtrlCharStr : string[10];  {String displayed when control char prefix is entered}
  37.  
  38. function EdScanCmdList(CmdPtr : Byte; var CmdCode : CommandType) : CmdMatchType;
  39.   {-See if current command buffer matches any installed commands}
  40.   {-Return Match if so, PartMatch if possible match, NoMatch if a loser}
  41.   {-Return cmdcode if matched}
  42.  
  43. function EdCommandKeys(C : CommandType; P : CommandPriority) : CommandString;
  44.   {-Return the primary or secondary key sequence for command c}
  45.  
  46. function EdTextRepresentation(Keys : string; var Kptr : Integer;
  47.                               var Special : Boolean) : string;
  48.   {-Return a text representation of command keystrokes}
  49.  
  50. procedure EdSetupKeyLength(var AsciiLength, ExtendedLength : LengthArray);
  51.   {-Define lengths of text key representations}
  52.  
  53.   {==========================================================================}
  54.  
  55. implementation
  56.  
  57. const
  58.   CmdListBytes = 1024;       {Maximum Number of bytes in installable command list}
  59. type
  60.   CmdListBuffer = array[0..CmdListBytes] of Char;
  61. var
  62.   CmdList : ^CmdListBuffer;  {Points to legal list of command keystrokes}
  63.  
  64.   {The machine code contains an ID string used by the installation program}
  65.   {It also contains the default command to keystroke mapping}
  66.   {$L MSCMDS}
  67.  
  68.   function EdInitCmdListPtr : Pointer; external;
  69.   {-Return a pointer to the beginning of command list}
  70.  
  71.   function EdScanCmdList(CmdPtr : Byte; var CmdCode : CommandType) : CmdMatchType;
  72.     {-See if current command buffer matches any installed commands}
  73.     {-Return Match if so, PartMatch if possible match, NoMatch if a loser}
  74.     {-Return cmdcode if matched}
  75.   var
  76.     Cpos, Cofs, CmdLen : Integer;
  77.     Done : Boolean;
  78.     Result : CmdMatchType;
  79.  
  80.   begin                      {EdScancmdlist}
  81.  
  82.     {Initialize}
  83.     CmdCode := CmdLeftChar;  {First command in CommandType}
  84.     Cpos := 0;
  85.     CmdLen := Ord(CmdList^[0]);
  86.  
  87.     repeat
  88.       {Offset within this command}
  89.       Cofs := 1;
  90.       Result := PartMatch;
  91.  
  92.       while (Result = PartMatch) and (Cofs <= CmdPtr) and (Cofs <= CmdLen) do
  93.         if CmdBuf[Cofs] <> CmdList^[Cpos+Cofs] then
  94.           Result := NoMatch
  95.         else
  96.           Inc(Cofs);
  97.  
  98.       Done := (Result = PartMatch);
  99.  
  100.       if not(Done) then begin
  101.         {Move to next command}
  102.         Cpos := Cpos+CmdLen+2;
  103.         {Bytes in next command}
  104.         CmdLen := Ord(CmdList^[Cpos]);
  105.       end else if (CmdPtr = CmdLen) then begin
  106.         {The whole command matched}
  107.         Result := Match;
  108.         CmdCode := CommandType(CmdList^[Cpos+Cofs]);
  109.       end;
  110.  
  111.     until Done or (CmdLen = 0);
  112.  
  113.     EdScanCmdList := Result;
  114.   end;                       {EdScancmdlist}
  115.  
  116.   function EdCommandKeys(C : CommandType; P : CommandPriority) : CommandString;
  117.     {-Return the primary or secondary key sequence for command c}
  118.   var
  119.     Cofs : Integer;
  120.     Cmd : CommandString;
  121.  
  122.     function EdNextCommandKeys(C : CommandType; var Cofs : Integer) : CommandString;
  123.       {-Return the next command sequence matching c, starting at cofs}
  124.     var
  125.       Clen : Byte;
  126.       Cmd : CommandString;
  127.  
  128.     begin                    {EdNextCommandKeys}
  129.       Cmd := '';
  130.       repeat
  131.         Clen := Byte(CmdList^[Cofs]);
  132.         if Clen <> 0 then begin
  133.           if Char(C) = CmdList^[Succ(Cofs+Clen)] then begin
  134.             Move(CmdList^[Cofs], Cmd, Succ(Clen));
  135.             Inc(Cofs, Clen+2);
  136.             {Force exit}
  137.             Clen := 0;
  138.           end else
  139.             Inc(Cofs, Clen+2);
  140.         end;
  141.       until (Clen = 0);
  142.       EdNextCommandKeys := Cmd;
  143.     end;                     {EdNextCommandKeys}
  144.  
  145.   begin                      {EdCommandKeys}
  146.     {Get the primary key sequence}
  147.     Cofs := 0;
  148.     Cmd := EdNextCommandKeys(C, Cofs);
  149.     if (P = Secondary) and (Cmd <> '') then
  150.       {Get the secondary command}
  151.       Cmd := EdNextCommandKeys(C, Cofs);
  152.     EdCommandKeys := Cmd;
  153.   end;                       {EdCommandKeys}
  154.  
  155.   function EdTextRepresentation(Keys : string; var Kptr : Integer;
  156.                                 var Special : Boolean) : string;
  157.     {-Return a text representation of command keystrokes}
  158.   var
  159.     Ch : Char;
  160.     Dis, Num : string[20];
  161.  
  162.   begin                      {EdTextRepresentation}
  163.     Dis := '';
  164.     Special := True;
  165.  
  166.     if Kptr <= Length(Keys) then begin
  167.       Ch := Keys[Kptr];
  168.  
  169.       case Ch of
  170.  
  171.         Null :               {Null}
  172.           if (Kptr = Length(Keys)) or not(UseExtendedSequence) then
  173.             {A lone null, or one forced to be interpreted as such}
  174.             Dis := Dis+'<Null>'
  175.           else begin
  176.             {An extended sequence}
  177.             Inc(Kptr);
  178.             Dis := Dis+EscapeSequence(Keys[Kptr]);
  179.           end;
  180.  
  181.         #27 :                {Escape}
  182.           Dis := Dis+'<Esc>';
  183.  
  184.         #13 :                {Enter}
  185.           Dis := Dis+'<Enter>';
  186.  
  187.         #1..#31 :            {Remaining control characters}
  188.           Dis := Dis+'<Ctrl'+Chr(Ord(Ch)+64)+'>';
  189.  
  190.         #127 :               {ASCII DEL}
  191.           Dis := Dis+'<CtrlBks>';
  192.  
  193.         #128..#255 :         {Extended ASCII}
  194.           begin
  195.             Str(Ord(Ch), Num);
  196.             Dis := Dis+'<#'+Num+'>';
  197.           end;
  198.  
  199.       else
  200.         {Normal characters}
  201.         Dis := Dis+Ch;
  202.         Special := False;
  203.       end;
  204.  
  205.       Inc(Kptr);
  206.     end;
  207.     EdTextRepresentation := Dis;
  208.   end;                       {EdTextRepresentation}
  209.  
  210.   procedure EdSetupKeyLength(var AsciiLength, ExtendedLength : LengthArray);
  211.     {-Define lengths of text key representations}
  212.   var
  213.     Ch : Char;
  214.  
  215.   begin                      {EdSetupKeyLength}
  216.     {Default length for ascii}
  217.     FillChar(AsciiLength, SizeOf(AsciiLength), 1);
  218.     {Control chars}
  219.     FillChar(AsciiLength[1], 31, 7);
  220.     {Extended chars}
  221.     FillChar(AsciiLength[128], 128, 6);
  222.     {Special cases}
  223.     AsciiLength[0] := 6;
  224.     AsciiLength[27] := 5;
  225.     AsciiLength[127] := 9;
  226.     {Extended ASCII chars}
  227.     for Ch := #0 to #255 do
  228.       ExtendedLength[Ord(Ch)] := Length(EscapeSequence(Ch));
  229.   end;                       {EdSetupKeyLength}
  230.  
  231.   function EdGetControlCharStr(CtrlKeys : CommandString) : VarString;
  232.     {-Return the string to display on prompt line when inserting control chars}
  233.   var
  234.     Cmd : VarString;
  235.     I : Integer;
  236.     Ch : Char;
  237.  
  238.   begin                      {EdGetControlCharStr}
  239.     I := 1;
  240.     Cmd := '';
  241.     while I <= Length(CtrlKeys) do begin
  242.       Ch := CtrlKeys[I];
  243.       if Ch = Null then begin
  244.         {Don't try to interpret extended keystrokes}
  245.         Inc(I);
  246.         Cmd := Cmd+'+';
  247.       end else if Ch < Blank then
  248.         Cmd := Cmd+'^'+Chr(Ord(Ch)+64)
  249.       else
  250.         Cmd := Cmd+Ch;
  251.       Inc(I);
  252.     end;
  253.     EdGetControlCharStr := Cmd;
  254.   end;                       {EdGetControlCharStr}
  255.  
  256.   procedure InitKeySequences;
  257.     {-Set character used to abort operation}
  258.   var
  259.     AbortString : CommandString;
  260.  
  261.   begin                      {InitKeySequences}
  262.  
  263.     AbortString := EdCommandKeys(CmdAbort, Primary);
  264.     if AbortString = '' then
  265.       AbortChar := ^U
  266.     else
  267.       AbortChar := AbortString[1];
  268.  
  269.     MenuPrime := EdCommandKeys(CmdMenu, Primary);
  270.     MenuSecon := EdCommandKeys(CmdMenu, Secondary);
  271.     TogglePrime := EdCommandKeys(CmdToggleMacroRecord, Primary);
  272.     ToggleSecon := EdCommandKeys(CmdToggleMacroRecord, Secondary);
  273.     AddwinPrime := EdCommandKeys(CmdAddWindow, Primary);
  274.  
  275.     {Get the string to display on prompt line when inserting control chars}
  276.     CtrlCharStr := EdGetControlCharStr(EdCommandKeys(CmdInsertCtrlChar, Primary));
  277.   end;                       {InitKeySequences}
  278.  
  279. begin
  280.   {Initialize pointer to the command list stored in this code segment}
  281.   CmdList := EdInitCmdListPtr;
  282.   {Number of chars currently in command buffer}
  283.   CmdPtr := 0;
  284.  
  285.   {Initialize AbortChar and other required keystroke sequences}
  286.   InitKeySequences;
  287. end.
  288.