Kaynağa Gözat

Autocompletion now works for multiple flags instead of for the first only. Does require the flags to be valid ones. Also some cleanup.

Martijn Laan 10 ay önce
ebeveyn
işleme
c73c8e7125

+ 14 - 4
Projects/Src/IDE.MainForm.pas

@@ -5271,7 +5271,7 @@ begin
               if not FoundSemicolon then begin
               if not FoundSemicolon then begin
                 var ParameterWordEndPos := I;
                 var ParameterWordEndPos := I;
                 var ParameterWordStartPos := FActiveMemo.GetWordStartPosition(ParameterWordEndPos, True);
                 var ParameterWordStartPos := FActiveMemo.GetWordStartPosition(ParameterWordEndPos, True);
-                var ParameterWord := FActiveMemo.GetTextRange(ParameterWordStartPos,ParameterWordEndPos);
+                var ParameterWord := FActiveMemo.GetTextRange(ParameterWordStartPos, ParameterWordEndPos);
                 FoundFlagsOrType := SameText(ParameterWord, 'Flags') or
                 FoundFlagsOrType := SameText(ParameterWord, 'Flags') or
                                     ((Section in [scInstallDelete, scUninstallDelete]) and SameText(ParameterWord, 'Type'));
                                     ((Section in [scInstallDelete, scUninstallDelete]) and SameText(ParameterWord, 'Type'));
               end else
               end else
@@ -5287,9 +5287,19 @@ begin
                 Exit;
                 Exit;
               I := LangNamePos;
               I := LangNamePos;
               FoundDot := True;
               FoundDot := True;
-            end
-            else begin
-              if C > ' ' then
+            end else if C > ' ' then begin
+              if IsParamSection and not (Section in [scInstallDelete, scUninstallDelete]) and
+                 (FMemosStyler.FlagsWordList[Section] <> '') then begin
+                { Verify word before the current word (or before that when we get here again) is
+                  a valid flag and if so, continue looking before it instead of stopping }
+                var FlagEndPos := FActiveMemo.GetWordEndPosition(I, True);
+                var FlagStartPos := FActiveMemo.GetWordStartPosition(I, True);
+                var FlagWord := FActiveMemo.GetTextRange(FlagStartPos, FlagEndPos);
+                if FMemosStyler.SectionHasFlag(Section, FlagWord) then
+                  I := FlagStartPos
+                else
+                  Exit;
+              end else
                 Exit;
                 Exit;
             end;
             end;
           end;
           end;

+ 48 - 22
Projects/Src/IDE.ScintStylerInnoSetup.pas

@@ -73,6 +73,7 @@ type
     stPascalReservedWord, stPascalString, stPascalNumber,
     stPascalReservedWord, stPascalString, stPascalNumber,
     stISPPReservedWord, stISPPString, stISPPNumber);
     stISPPReservedWord, stISPPString, stISPPNumber);
 
 
+  TWordsBySection = TObjectDictionary<TInnoSetupStylerSection, TStringList>;
   TFunctionDefinitions = array of AnsiString;
   TFunctionDefinitions = array of AnsiString;
   TFunctionDefinitionsByName = TDictionary<String, TFunctionDefinitions>;
   TFunctionDefinitionsByName = TDictionary<String, TFunctionDefinitions>;
 
 
@@ -80,6 +81,7 @@ type
   private
   private
     FEventFunctionsWordList: array[Boolean] of AnsiString;
     FEventFunctionsWordList: array[Boolean] of AnsiString;
     FKeywordsWordList, FFlagsWordList: array[TInnoSetupStylerSection] of AnsiString;
     FKeywordsWordList, FFlagsWordList: array[TInnoSetupStylerSection] of AnsiString;
+    FFlagsWords: TWordsBySection;
     FISPPDirectivesWordList, FConstantsWordList: AnsiString;
     FISPPDirectivesWordList, FConstantsWordList: AnsiString;
     FSectionsWordList: AnsiString;
     FSectionsWordList: AnsiString;
     FScriptFunctionsByName: array[Boolean] of TFunctionDefinitionsByName; { Only has functions with at least 1 parameter }
     FScriptFunctionsByName: array[Boolean] of TFunctionDefinitionsByName; { Only has functions with at least 1 parameter }
@@ -140,6 +142,7 @@ type
     class function IsSymbolStyle(const Style: TScintStyleNumber): Boolean;
     class function IsSymbolStyle(const Style: TScintStyleNumber): Boolean;
     function GetScriptFunctionDefinition(const ClassMember: Boolean;
     function GetScriptFunctionDefinition(const ClassMember: Boolean;
       const Name: String; const Index: Integer; out Count: Integer): AnsiString;
       const Name: String; const Index: Integer; out Count: Integer): AnsiString;
+    function SectionHasFlag(const Section: TInnoSetupStylerSection; const Flag: String): Boolean;
     property ConstantsWordList: AnsiString read FConstantsWordList;
     property ConstantsWordList: AnsiString read FConstantsWordList;
     property EventFunctionsWordList[Procedures: Boolean]: AnsiString read GetEventFunctionsWordList;
     property EventFunctionsWordList[Procedures: Boolean]: AnsiString read GetEventFunctionsWordList;
     property FlagsWordList[Section: TInnoSetupStylerSection]: AnsiString read GetFlagsWordList;
     property FlagsWordList[Section: TInnoSetupStylerSection]: AnsiString read GetFlagsWordList;
@@ -653,6 +656,7 @@ constructor TInnoSetupStyler.Create(AOwner: TComponent);
 
 
 begin
 begin
   inherited;
   inherited;
+  FFlagsWords := TWordsBySection.Create([doOwnsValues]);
   BuildConstantsWordList;
   BuildConstantsWordList;
   BuildEventFunctionsWordList;
   BuildEventFunctionsWordList;
   BuildFlagsWordLists;
   BuildFlagsWordLists;
@@ -668,6 +672,7 @@ destructor TInnoSetupStyler.Destroy;
 begin
 begin
   FScriptFunctionsByName[False].Free;
   FScriptFunctionsByName[False].Free;
   FScriptFunctionsByName[True].Free;
   FScriptFunctionsByName[True].Free;
+  FFlagsWords.Free;
   inherited;
   inherited;
 end;
 end;
 
 
@@ -732,10 +737,10 @@ procedure TInnoSetupStyler.BuildKeywordsWordList(
   const Section: TInnoSetupStylerSection;
   const Section: TInnoSetupStylerSection;
   const Parameters: array of TScintRawString);
   const Parameters: array of TScintRawString);
 begin
 begin
-  var SL :=TStringList.Create;
+  var SL := TStringList.Create;
   try
   try
-    for var I := 0 to High(Parameters) do
-      AddWordToList(SL, Parameters[I], awtParameter);
+    for var Parameter in Parameters do
+      AddWordToList(SL, Parameter, awtParameter);
     FKeywordsWordList[Section] := BuildWordList(SL);
     FKeywordsWordList[Section] := BuildWordList(SL);
   finally
   finally
     SL.Free;
     SL.Free;
@@ -759,13 +764,27 @@ end;
 procedure TInnoSetupStyler.BuildFlagsWordList(const Section: TInnoSetupStylerSection;
 procedure TInnoSetupStyler.BuildFlagsWordList(const Section: TInnoSetupStylerSection;
   const Flags: array of TScintRawString);
   const Flags: array of TScintRawString);
 begin
 begin
-  var SL := TStringList.Create;
+  { Build FFlagsWords }
+  var SL1 := TStringList.Create;
+  try
+    SL1.CaseSensitive := False;
+    for var Flag in Flags do
+      SL1.Add(String(Flag));
+    FFlagsWords.Add(Section, SL1);
+    SL1 := nil; //SL1 is now owned by FFlagsWords
+  except
+    SL1.Free;
+    raise;
+  end;
+
+  { Build FFlagsWordList }
+  var SL2 := TStringList.Create;
   try
   try
-    for var I := 0 to High(Flags) do
-      AddWordToList(SL, Flags[I], awtFlag);
-    FFlagsWordList[Section] := BuildWordList(SL);
+    for var Flag in Flags do
+      AddWordToList(SL2, Flag, awtFlag);
+    FFlagsWordList[Section] := BuildWordList(SL2);
   finally
   finally
-    SL.Free;
+    SL2.Free;
   end;
   end;
 end;
 end;
 
 
@@ -798,8 +817,8 @@ procedure TInnoSetupStyler.BuildISPPDirectivesWordList;
 begin
 begin
   var SL := TStringList.Create;
   var SL := TStringList.Create;
   try
   try
-    for var I := 0 to High(ISPPDirectives) do
-      AddWordToList(SL, '#' + ISPPDirectives[I].Name, awtPreprocessorDirective);
+    for var ISPPDirective in ISPPDirectives do
+      AddWordToList(SL, '#' + ISPPDirective.Name, awtPreprocessorDirective);
     FISPPDirectivesWordList := BuildWordList(SL);
     FISPPDirectivesWordList := BuildWordList(SL);
   finally
   finally
     SL.Free;
     SL.Free;
@@ -810,14 +829,14 @@ procedure TInnoSetupStyler.BuildConstantsWordList;
 begin
 begin
   var SL := TStringList.Create;
   var SL := TStringList.Create;
   try
   try
-    for var I := 0 to High(Constants) do
-      AddWordToList(SL, '{' + Constants[I] + '}', awtConstant);
+    for var Constant in Constants do
+      AddWordToList(SL, '{' + Constant + '}', awtConstant);
     if ISPPInstalled then begin
     if ISPPInstalled then begin
       AddWordToList(SL, '{#', awtConstant);
       AddWordToList(SL, '{#', awtConstant);
       AddWordToList(SL, '{#file ', awtConstant);
       AddWordToList(SL, '{#file ', awtConstant);
     end;
     end;
-    for var I := 0 to High(ConstantsWithParam) do
-      AddWordToList(SL, '{' + ConstantsWithParam[I], awtConstant);
+    for var ConstantWithParam in ConstantsWithParam do
+      AddWordToList(SL, '{' + ConstantWithParam, awtConstant);
     FConstantsWordList := BuildWordList(SL);
     FConstantsWordList := BuildWordList(SL);
   finally
   finally
     SL.Free;
     SL.Free;
@@ -831,9 +850,9 @@ begin
   try
   try
     SLFunctions := TStringList.Create;
     SLFunctions := TStringList.Create;
     SLProcedures := TStringList.Create;
     SLProcedures := TStringList.Create;
-    for var I := 0 to High(FullEventFunctions) do begin
+    for var FullEventFunction in FullEventFunctions do begin
       var WasFunction: Boolean;
       var WasFunction: Boolean;
-      var S := RemoveScriptFuncHeader(FullEventFunctions[I], WasFunction);
+      var S := RemoveScriptFuncHeader(FullEventFunction, WasFunction);
       if WasFunction then
       if WasFunction then
         AddWordToList(SLFunctions, S, awtScriptEvent)
         AddWordToList(SLFunctions, S, awtScriptEvent)
       else
       else
@@ -1189,8 +1208,8 @@ begin
     FinishDirectiveNameOrShorthand(True); { All shorthands require a parameter }
     FinishDirectiveNameOrShorthand(True); { All shorthands require a parameter }
   end else begin
   end else begin
     var S := ConsumeString(ISPPIdentChars);
     var S := ConsumeString(ISPPIdentChars);
-    for var I := Low(ISPPDirectives) to High(ISPPDirectives) do
-      if SameRawText(S, ISPPDirectives[I].Name) then begin
+    for var ISPPDirective in ISPPDirectives do
+      if SameRawText(S, ISPPDirective.Name) then begin
         if SameRawText(S, 'error') then
         if SameRawText(S, 'error') then
           ErrorDirective := True
           ErrorDirective := True
         else if SameRawText(S, 'include') then
         else if SameRawText(S, 'include') then
@@ -1198,12 +1217,12 @@ begin
         else
         else
           NeedIspp := True; { Built-in preprocessor only supports '#include' }
           NeedIspp := True; { Built-in preprocessor only supports '#include' }
         ForDirectiveExpressionsNext := SameRawText(S, 'for'); { #for uses ';' as an expressions list separator so we need to remember that ';' doesn't start a comment until the list is done }
         ForDirectiveExpressionsNext := SameRawText(S, 'for'); { #for uses ';' as an expressions list separator so we need to remember that ';' doesn't start a comment until the list is done }
-        Inc(OpenCount, ISPPDirectives[I].OpenCountChange);
+        Inc(OpenCount, ISPPDirective.OpenCountChange);
         if OpenCount < 0 then begin
         if OpenCount < 0 then begin
           CommitStyleSq(stCompilerDirective, True);
           CommitStyleSq(stCompilerDirective, True);
           OpenCount := 0; { Reset so that next doesn't automatically gets error as well }
           OpenCount := 0; { Reset so that next doesn't automatically gets error as well }
         end;
         end;
-        FinishDirectiveNameOrShorthand(ISPPDirectives[I].RequiresParameter);
+        FinishDirectiveNameOrShorthand(ISPPDirective.RequiresParameter);
         Break;
         Break;
       end;
       end;
     if InlineDirective then
     if InlineDirective then
@@ -1236,8 +1255,8 @@ begin
       end;
       end;
       if CurChar in ISPPIdentFirstChars then begin
       if CurChar in ISPPIdentFirstChars then begin
         var S := ConsumeString(ISPPIdentChars);
         var S := ConsumeString(ISPPIdentChars);
-        for var I := Low(ISPPReservedWords) to High(ISPPReservedWords) do
-          if SameRawText(S, ISPPReservedWords[I]) then begin
+        for var ISPPReservedWord in ISPPReservedWords do
+          if SameRawText(S, ISPPReservedWord) then begin
             CommitStyle(stISPPReservedWord);
             CommitStyle(stISPPReservedWord);
             Break;
             Break;
           end;
           end;
@@ -1553,6 +1572,13 @@ begin
   end;
   end;
 end;
 end;
 
 
+function TInnoSetupStyler.SectionHasFlag(const Section: TInnoSetupStylerSection;
+  const Flag: String): Boolean;
+begin
+  var SL := FFlagsWords[Section];
+  Result := (SL <> nil) and not SL.CaseSensitive and (SL.IndexOf(Flag) <> -1);
+end;
+
 procedure TInnoSetupStyler.SetISPPInstalled(const Value: Boolean);
 procedure TInnoSetupStyler.SetISPPInstalled(const Value: Boolean);
 begin
 begin
   if Value <> FISPPInstalled then begin
   if Value <> FISPPInstalled then begin

+ 1 - 0
whatsnew.htm

@@ -56,6 +56,7 @@ For conditions of distribution and use, see <a href="files/is/license.txt">LICEN
   <li>Added parameter hints and autocompletion support for all Pascal Scripting support class members and properties. Both always show all classes' members and properties instead of just those of the current object's class.</li>
   <li>Added parameter hints and autocompletion support for all Pascal Scripting support class members and properties. Both always show all classes' members and properties instead of just those of the current object's class.</li>
   <li>Added autocompletion support for all Pascal Scripting event function parameters. Always shows all parameters instead of just those of the current event function.</li>
   <li>Added autocompletion support for all Pascal Scripting event function parameters. Always shows all parameters instead of just those of the current event function.</li>
   <li>Added autocompletion support for the [Messages] section.</li>
   <li>Added autocompletion support for the [Messages] section.</li>
+  <li>Improved autocompletion support for all Flags parameters: now works for multiple flags instead of for the first only.</li>
   <li>Added new <i>Enable section folding</i> option which allows you to temporarily hide sections while editing by clicking the new minus or plus icons in the editor's gutter or by using the new keyboard shortcuts (Ctrl+Shift+[ to fold and Ctrl+Shift+] to unfold) or menu items. Enabled by default.</li>
   <li>Added new <i>Enable section folding</i> option which allows you to temporarily hide sections while editing by clicking the new minus or plus icons in the editor's gutter or by using the new keyboard shortcuts (Ctrl+Shift+[ to fold and Ctrl+Shift+] to unfold) or menu items. Enabled by default.</li>
   <li>The editor's gutter now shows change history to keep track of saved and unsaved modifications. Always enabled.</li>
   <li>The editor's gutter now shows change history to keep track of saved and unsaved modifications. Always enabled.</li>
   <li>The editor's font now defaults to Consolas if available, consistent with most other modern editors.</li>
   <li>The editor's font now defaults to Consolas if available, consistent with most other modern editors.</li>