Преглед на файлове

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 месеца
родител
ревизия
c73c8e7125
променени са 3 файла, в които са добавени 63 реда и са изтрити 26 реда
  1. 14 4
      Projects/Src/IDE.MainForm.pas
  2. 48 22
      Projects/Src/IDE.ScintStylerInnoSetup.pas
  3. 1 0
      whatsnew.htm

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

@@ -5271,7 +5271,7 @@ begin
               if not FoundSemicolon then begin
                 var ParameterWordEndPos := I;
                 var ParameterWordStartPos := FActiveMemo.GetWordStartPosition(ParameterWordEndPos, True);
-                var ParameterWord := FActiveMemo.GetTextRange(ParameterWordStartPos,ParameterWordEndPos);
+                var ParameterWord := FActiveMemo.GetTextRange(ParameterWordStartPos, ParameterWordEndPos);
                 FoundFlagsOrType := SameText(ParameterWord, 'Flags') or
                                     ((Section in [scInstallDelete, scUninstallDelete]) and SameText(ParameterWord, 'Type'));
               end else
@@ -5287,9 +5287,19 @@ begin
                 Exit;
               I := LangNamePos;
               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;
             end;
           end;

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

@@ -73,6 +73,7 @@ type
     stPascalReservedWord, stPascalString, stPascalNumber,
     stISPPReservedWord, stISPPString, stISPPNumber);
 
+  TWordsBySection = TObjectDictionary<TInnoSetupStylerSection, TStringList>;
   TFunctionDefinitions = array of AnsiString;
   TFunctionDefinitionsByName = TDictionary<String, TFunctionDefinitions>;
 
@@ -80,6 +81,7 @@ type
   private
     FEventFunctionsWordList: array[Boolean] of AnsiString;
     FKeywordsWordList, FFlagsWordList: array[TInnoSetupStylerSection] of AnsiString;
+    FFlagsWords: TWordsBySection;
     FISPPDirectivesWordList, FConstantsWordList: AnsiString;
     FSectionsWordList: AnsiString;
     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;
     function GetScriptFunctionDefinition(const ClassMember: Boolean;
       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 EventFunctionsWordList[Procedures: Boolean]: AnsiString read GetEventFunctionsWordList;
     property FlagsWordList[Section: TInnoSetupStylerSection]: AnsiString read GetFlagsWordList;
@@ -653,6 +656,7 @@ constructor TInnoSetupStyler.Create(AOwner: TComponent);
 
 begin
   inherited;
+  FFlagsWords := TWordsBySection.Create([doOwnsValues]);
   BuildConstantsWordList;
   BuildEventFunctionsWordList;
   BuildFlagsWordLists;
@@ -668,6 +672,7 @@ destructor TInnoSetupStyler.Destroy;
 begin
   FScriptFunctionsByName[False].Free;
   FScriptFunctionsByName[True].Free;
+  FFlagsWords.Free;
   inherited;
 end;
 
@@ -732,10 +737,10 @@ procedure TInnoSetupStyler.BuildKeywordsWordList(
   const Section: TInnoSetupStylerSection;
   const Parameters: array of TScintRawString);
 begin
-  var SL :=TStringList.Create;
+  var SL := TStringList.Create;
   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);
   finally
     SL.Free;
@@ -759,13 +764,27 @@ end;
 procedure TInnoSetupStyler.BuildFlagsWordList(const Section: TInnoSetupStylerSection;
   const Flags: array of TScintRawString);
 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
-    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
-    SL.Free;
+    SL2.Free;
   end;
 end;
 
@@ -798,8 +817,8 @@ procedure TInnoSetupStyler.BuildISPPDirectivesWordList;
 begin
   var SL := TStringList.Create;
   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);
   finally
     SL.Free;
@@ -810,14 +829,14 @@ procedure TInnoSetupStyler.BuildConstantsWordList;
 begin
   var SL := TStringList.Create;
   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
       AddWordToList(SL, '{#', awtConstant);
       AddWordToList(SL, '{#file ', awtConstant);
     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);
   finally
     SL.Free;
@@ -831,9 +850,9 @@ begin
   try
     SLFunctions := 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 S := RemoveScriptFuncHeader(FullEventFunctions[I], WasFunction);
+      var S := RemoveScriptFuncHeader(FullEventFunction, WasFunction);
       if WasFunction then
         AddWordToList(SLFunctions, S, awtScriptEvent)
       else
@@ -1189,8 +1208,8 @@ begin
     FinishDirectiveNameOrShorthand(True); { All shorthands require a parameter }
   end else begin
     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
           ErrorDirective := True
         else if SameRawText(S, 'include') then
@@ -1198,12 +1217,12 @@ begin
         else
           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 }
-        Inc(OpenCount, ISPPDirectives[I].OpenCountChange);
+        Inc(OpenCount, ISPPDirective.OpenCountChange);
         if OpenCount < 0 then begin
           CommitStyleSq(stCompilerDirective, True);
           OpenCount := 0; { Reset so that next doesn't automatically gets error as well }
         end;
-        FinishDirectiveNameOrShorthand(ISPPDirectives[I].RequiresParameter);
+        FinishDirectiveNameOrShorthand(ISPPDirective.RequiresParameter);
         Break;
       end;
     if InlineDirective then
@@ -1236,8 +1255,8 @@ begin
       end;
       if CurChar in ISPPIdentFirstChars then begin
         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);
             Break;
           end;
@@ -1553,6 +1572,13 @@ begin
   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);
 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 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>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>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>