Forráskód Böngészése

Merge branch 'autocompleteclasses'

Martijn Laan 1 éve
szülő
commit
38a5caae98

+ 8 - 0
Components/ScintEdit.pas

@@ -24,6 +24,7 @@ type
   TScintChangeHistory = (schDisabled, schMarkers, schIndicators);
   TScintCommand = type NativeInt;
   TScintEditAutoCompleteSelectionEvent = TNotifyEvent;
+  TScintEditCallTipArrowClick = procedure(Sender: TObject; const Up: Boolean) of object;
   TScintEditChangeInfo = record
     Inserting: Boolean;
     StartPos, Length, LinesDelta: Integer;
@@ -115,6 +116,7 @@ type
     FLineNumbers: Boolean;
     FLines: TScintEditStrings;
     FOnAutoCompleteSelection: TScintEditAutoCompleteSelectionEvent;
+    FOnCallTipArrowClick: TScintEditCallTipArrowClick;
     FOnChange: TScintEditChangeEvent;
     FOnCharAdded: TScintEditCharAddedEvent;
     FOnDropFiles: TScintEditDropFilesEvent;
@@ -427,6 +429,7 @@ type
     property WordWrap: Boolean read FWordWrap write SetWordWrap default False;
     property Zoom: Integer read GetZoom write SetZoom default 0;
     property OnAutoCompleteSelection: TScintEditAutoCompleteSelectionEvent read FOnAutoCompleteSelection write FOnAutoCompleteSelection;
+    property OnCallTipArrowClick: TScintEditCallTipArrowClick read FOnCallTipArrowClick write FOnCallTipArrowClick;
     property OnChange: TScintEditChangeEvent read FOnChange write FOnChange;
     property OnCharAdded: TScintEditCharAddedEvent read FOnCharAdded write FOnCharAdded;
     property OnDropFiles: TScintEditDropFilesEvent read FOnDropFiles write FOnDropFiles;
@@ -1424,6 +1427,11 @@ begin
         if Assigned(FOnAutoCompleteSelection) then
           FOnAutoCompleteSelection(Self);
       end;
+    SCN_CALLTIPCLICK:
+      begin
+        if (N.position in [1, 2]) and Assigned(FOnCallTipArrowClick) then
+          FOnCallTipArrowClick(Self, N.position = 1);
+      end;
     SCN_CHARADDED:
       begin
         if Assigned(FOnCharAdded) then

BIN
Files/isscint.dll


+ 30 - 10
ISHelp/ISHelpGen/UIsxclassesParser.pas

@@ -6,7 +6,7 @@ uses
   Classes;
 
 type
-  TIsxclassesParserStoredString = (ssLine, ssType, ssEnumValue, ssConstant, ssMember);
+  TIsxclassesParserStoredString = (ssLine, ssType, ssEnumValue, ssConstant, ssMemberName, ssMember, ssProperty);
   TIsxclassesParserStrings = array [TIsxclassesParserStoredString] of TStringList;
 
   TIsxclassesParser = class
@@ -40,8 +40,12 @@ begin
   FStrings[ssConstant].Duplicates := dupError;
   FStrings[ssConstant].Sorted := True;
   { Sorted for ignoring duplicates }
+  FStrings[ssMemberName].Duplicates := dupIgnore;
+  FStrings[ssMemberName].Sorted := True;
   FStrings[ssMember].Duplicates := dupIgnore;
   FStrings[ssMember].Sorted := True;
+  FStrings[ssProperty].Duplicates := dupIgnore;
+  FStrings[ssProperty].Sorted := True;
 end;
 
 destructor TIsxclassesParser.Destroy;
@@ -71,7 +75,7 @@ procedure TIsxclassesParser.Parse(const FileName: String);
     if P = 0 then
       P := Pos(C3, Result);
     if P = 0 then
-      raise Exception.CreateFmt('Invalid FunctionDefinitionWithoutHeader: %s', [Result]);
+      raise Exception.CreateFmt('Invalid ScriptFuncWithoutHeader: %s', [Result]);
 
     Delete(Result, P, Maxint);
   end;
@@ -110,16 +114,21 @@ begin
         Continue;
       end;
 
+      var Typ := ssMemberName;
       P := Pos('procedure ', S);
       if P = 0 then
         P := Pos('function ', S);
-      if P = 0 then
+      if P = 0 then begin
+        Typ := ssProperty;
         P := Pos('property ', S);
+      end;
       if P <> 0 then begin
+        if Typ = ssMemberName then
+          FStrings[ssMember].Add(StringReplace(S.TrimLeft, 'const ', '', [rfReplaceAll]));
         Delete(S, 1, P-1);
         P := Pos(' ', S);
         Delete(S, 1, P);
-        FStrings[ssMember].Add(ExtractScriptFuncWithoutHeaderName(S));
+        FStrings[Typ].Add(ExtractScriptFuncWithoutHeaderName(S));
         Continue;
       end;
     end;
@@ -228,7 +237,7 @@ begin
   AssignFile(F, OutputFileName);
   Append(F);
   try
-    for var Typ in [ssType, ssEnumValue, ssConstant, ssMember] do begin
+    for var Typ in [ssType, ssEnumValue, ssConstant, ssMemberName, ssProperty] do begin
       for var S in FStrings[Typ] do begin
         var A := S.Split([', ']);
         for var S2 in A do begin
@@ -268,17 +277,21 @@ end;
 procedure TIsxclassesParser.SaveWordLists(const OutputFileName: String);
 
   procedure WriteStringArray(const F: TextFile; const Name, Indent: String;
-    const Values: TStrings; const NewLineLength: Integer);
+    const Values: TStrings; const NewLineLength: Integer;
+    const AddQuotesAroundCommas: Boolean = True;
+    const ArrayType: String = 'array of AnsiString');
   begin
-    WriteLn(F, Indent + Name + ': array of AnsiString = [');
+    WriteLn(F, Indent + Name + ': ' + ArrayType + ' = [');
     var S: String;
     for var I := 0 to Values.Count-1 do begin
       if S <> '' then
         S := S + ', ';
       var V := Values[I];
-      V := StringReplace(V, ', ', ',', [rfReplaceAll]);
-      V := '''' + StringReplace(V, ',', ''', ''', [rfReplaceAll]) + '''';
-      S := S + V;
+      if AddQuotesAroundCommas then begin
+        V := StringReplace(V, ', ', ',', [rfReplaceAll]);
+        V := StringReplace(V, ',', ''', ''', [rfReplaceAll]);
+      end;
+      S := S + '''' + V + '''';
       if Length(S) > NewLineLength then begin
         if I <> Values.Count-1 then
           S := S + ',';
@@ -303,6 +316,9 @@ begin
     WriteLn(F);
     WriteLn(F, 'interface');
     WriteLn(F);
+    WriteLn(F, 'uses');
+    WriteLn(F, Indent + 'ScriptFunc;');
+    WriteLn(F);
     WriteLn(F, 'var');
     WriteStringArray(F, 'PascalConstants_Isxclasses', Indent, FStrings[ssConstant], 0);
     WriteLn(F);
@@ -310,6 +326,10 @@ begin
     WriteLn(F);
     WriteStringArray(F, 'PascalEnumValues_Isxclasses', Indent, FStrings[ssEnumValue], 0);
     WriteLn(F);
+    WriteStringArray(F, 'PascalMembers_Isxclasses', Indent, FStrings[ssMember], 0, False, 'TScriptTable');
+    WriteLn(F);
+    WriteStringArray(F, 'PascalProperties_Isxclasses', Indent, FStrings[ssProperty], 80);
+    WriteLn(F);
     WriteLN(F, 'implementation');
     WriteLn(F);
     Write(F, 'end.');

+ 1 - 1
ISHelp/isetup.xml

@@ -3345,7 +3345,7 @@ Filename: "{win}\MYPROG.INI"; Section: "InstallSettings"; Key: "InstallPath"; St
   <td>Fillup autocompletion</td><td>Space for ISPP directives and Flags and Type parameters<br />\ for constants<br />: for constants and section parameters<br />] for sections<br />= for section directives<br />( for [Code]</td>
 </tr>
 <tr>
-  <td>Invoke parameter hint</td><td>Ctrl+Shift+Space</td>
+  <td>Invoke parameter hint or show next definition</td><td>Ctrl+Shift+Space</td>
 </tr>
 <tr>
   <td>Cancel autocomplete or parameter hint</td><td>Esc</td>

+ 138 - 0
ISHelp/isxclasses_wordlists_generated.pas

@@ -4,6 +4,9 @@ unit isxclasses_wordlists_generated;
 
 interface
 
+uses
+  ScriptFunc;
+
 var
   PascalConstants_Isxclasses: array of AnsiString = [
     'clBlack', 'clMaroon', 'clGreen', 'clOlive', 'clNavy', 'clPurple', 'clTeal', 'clGray', 'clSilver', 'clRed', 'clLime', 'clYellow', 'clBlue', 'clFuchsia', 'clAqua', 'clLtGray', 'clDkGray', 'clWhite', 'clNone', 'clDefault', 'clScrollBar', 'clBackground', 'clActiveCaption', 'clInactiveCaption', 'clMenu', 'clWindow', 'clWindowFrame', 'clMenuText', 'clWindowText', 'clCaptionText', 'clActiveBorder', 'clInactiveBorder', 'clAppWorkSpace', 'clHighlight', 'clHighlightText', 'clBtnFace', 'clBtnShadow', 'clGrayText', 'clBtnText', 'clInactiveCaptionText', 'clBtnHighlight', 'cl3DDkShadow', 'cl3DLight', 'clInfoText', 'clInfoBk', 'clHotLight',
@@ -68,6 +71,141 @@ var
     'taLeftJustify', 'taRightJustify', 'taCenter'
   ];
 
+  PascalMembers_Isxclasses: TScriptTable = [
+    'function Add(ACaption: String): Integer;',
+    'function Add(APrompt, AFilter, ADefaultExtension: String): Integer;',
+    'function Add(APrompt: String): Integer;',
+    'function Add(APrompt: String; APassword: Boolean): Integer;',
+    'function Add(S: String): Integer;',
+    'function AddCheckBox(ACaption, ASubItem: String; ALevel: Byte; AChecked, AEnabled, AHasInternalChildren, ACheckWhenParentChecked: Boolean; AObject: TObject): Integer;',
+    'function AddEx(ACaption: String; ALevel: Byte; AExclusive: Boolean): Integer;',
+    'function AddGroup(ACaption, ASubItem: String; ALevel: Byte; AObject: TObject): Integer;',
+    'function AddRadioButton(ACaption, ASubItem: String; ALevel: Byte; AChecked, AEnabled: Boolean; AObject: TObject): Integer;',
+    'function AdjustHeight: Integer;',
+    'function AdjustLabelHeight(ALabel: TNewStaticText): Integer;',
+    'function AdjustLinkLabelHeight(ALinkLabel: TNewLinkLabel): Integer;',
+    'function CalculateButtonWidth(ButtonCaptions: array of String): Integer;',
+    'function CanFocus: Boolean;',
+    'function CheckItem(Index: Integer; AOperation: TCheckItemOperation): Boolean;',
+    'function CopyFrom(Source: TStream; ByteCount: Int64): Int64;',
+    'function Download: Int64;',
+    'function Find(S: String; var Index: Integer): Boolean;',
+    'function FindComponent(AName: String): TComponent;',
+    'function FindNextPage(CurPage: TNewNotebookPage; GoForward: Boolean): TNewNotebookPage;',
+    'function Focused: Boolean;',
+    'function IndexOf(S: String): Integer;',
+    'function Read(var Buffer: AnyString; ByteCount: Longint): Longint;',
+    'function Seek(Offset: Int64; Origin: Word): Int64;',
+    'function ShouldSizeX: Boolean;',
+    'function ShouldSizeY: Boolean;',
+    'function ShowModal: Integer;',
+    'function TextHeight(Text: String): Integer;',
+    'function TextWidth(Text: String): Integer;',
+    'function Write(Buffer: AnyString; ByteCount: Longint): Longint;',
+    'procedure Add(Url, BaseName, RequiredSHA256OfFile: String);',
+    'procedure AddEx(Url, BaseName, RequiredSHA256OfFile, UserName, Password: String);',
+    'procedure AddStrings(Strings: TStrings);',
+    'procedure Animate;',
+    'procedure Append(S: String);',
+    'procedure Arc(X1, Y1, X2, Y2, X3, Y3, X4, Y4: Integer);',
+    'procedure Assign(Source: TPersistent);',
+    'procedure BringToFront;',
+    'procedure ChangeDirectory(Value: String; CreateNewItems: Boolean);',
+    'procedure Chord(X1, Y1, X2, Y2, X3, Y3, X4, Y4: Integer);',
+    'procedure Clear;',
+    'procedure ClearSelection;',
+    'procedure Close;',
+    'procedure CreateNewDirectory(ADefaultName: String);',
+    'procedure Delete(Index: Integer);',
+    'procedure DestroyComponents;',
+    'procedure Destroying;',
+    'procedure Draw(X, Y: Integer; Graphic: TGraphic);',
+    'procedure Ellipse(X1, Y1, X2, Y2: Integer);',
+    'procedure FlipSizeAndCenterIfNeeded(ACenterInsideControl: Boolean; CenterInsideControlCtl: TWinControl; CenterInsideControlInsideClientArea: Boolean);',
+    'procedure FloodFill(X, Y: Integer; Color: TColor; FillStyle: Byte);',
+    'procedure Free;',
+    'procedure FreeNotification(AComponent: TComponent);',
+    'procedure Hide;',
+    'procedure IncTopDecHeight(AControl: TControl; Amount: Integer);',
+    'procedure Insert(Index: Integer; S: String);',
+    'procedure InsertComponent(AComponent: TComponent);',
+    'procedure Invalidate;',
+    'procedure LineTo(X, Y: Integer);',
+    'procedure LoadFromFile(FileName: String);',
+    'procedure LoadFromStream(Stream: TStream);',
+    'procedure MoveTo(X, Y: Integer);',
+    'procedure Pie(X1, Y1, X2, Y2, X3, Y3, X4, Y4: Integer);',
+    'procedure ReadBuffer(var Buffer: AnyString; ByteCount: Longint);',
+    'procedure Rectangle(X1, Y1, X2, Y2: Integer);',
+    'procedure Refresh;',
+    'procedure Release;',
+    'procedure RemoveComponent(AComponent: TComponent);',
+    'procedure Repaint;',
+    'procedure RoundRect(X1, Y1, X2, Y2, X3, Y3: Integer);',
+    'procedure SaveToFile(FileName: String);',
+    'procedure SaveToStream(Stream: TStream);',
+    'procedure ScrollInView(AControl: TControl);',
+    'procedure SelectAll;',
+    'procedure SendToBack;',
+    'procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer);',
+    'procedure SetPaths(AUserPrograms, ACommonPrograms, AUserStartup, ACommonStartup: String);',
+    'procedure SetProgress(Position, Max: Longint);',
+    'procedure SetText(Msg1, Msg2: String);',
+    'procedure Show;',
+    'procedure ShowAboutBox;',
+    'procedure Sort;',
+    'procedure TextOut(X, Y: Integer; Text: String);',
+    'procedure Update;',
+    'procedure WriteBuffer(Buffer: AnyString; ByteCount: Longint);'
+  ];
+
+  PascalProperties_Isxclasses: array of AnsiString = [
+    'AbortButton', 'AbortedByUser', 'Active', 'ActiveControl', 'ActivePage', 'Align', 'Alignment',
+    'AllowGrayed', 'AlphaFormat', 'Anchors', 'AutoScroll', 'AutoSelect', 'AutoSize', 'BackButton',
+    'BackColor', 'Bevel', 'Bevel1', 'BeveledLabel', 'BevelInner', 'BevelKind', 'BevelOuter',
+    'BevelWidth', 'Bitmap', 'BorderIcons', 'BorderStyle', 'BorderWidth', 'Brush', 'Buttons',
+    'Cancel', 'CancelButton', 'Canvas', 'Caption', 'Center', 'CharCase', 'Checked', 'CheckListBox',
+    'ClientHeight', 'ClientWidth', 'Color', 'CommaText', 'ComponentCount', 'ComponentIndex',
+    'Components', 'ComponentsDiskSpaceLabel', 'ComponentsList', 'ComponentState', 'Constraints',
+    'ControlCount', 'Controls', 'ControlsFlipped', 'CopyMode', 'Count', 'CurPageID', 'Cursor',
+    'Default', 'Description', 'DesignInfo', 'DirBrowseButton', 'DirEdit', 'DiskSpaceLabel',
+    'DropDownCount', 'DroppedDown', 'Duplicates', 'Edits', 'Empty', 'Enabled', 'FilenameLabel',
+    'FinishedHeadingLabel', 'FinishedLabel', 'FinishedPage', 'Flat', 'FlipControlsOnShow',
+    'FocusControl', 'Font', 'ForceLTRReading', 'FormStyle', 'GroupBrowseButton', 'GroupEdit',
+    'Handle', 'Height', 'HideSelection', 'Hint', 'ID', 'InfoAfterClickLabel', 'InfoAfterMemo',
+    'InfoAfterPage', 'InfoBeforeClickLabel', 'InfoBeforeMemo', 'InfoBeforePage', 'InnerNotebook',
+    'InnerPage', 'InstallingPage', 'IsSaveButton', 'ItemCaption', 'ItemEnabled', 'ItemFontStyle',
+    'ItemIndex', 'ItemLevel', 'ItemObject', 'Items', 'ItemSubItem', 'KeepSizeY', 'KeyPreview',
+    'Left', 'LicenseAcceptedRadio', 'LicenseLabel1', 'LicenseMemo', 'LicenseNotAcceptedRadio',
+    'LicensePage', 'Lines', 'MainPanel', 'Max', 'MaxHeight', 'MaxLength', 'MaxWidth', 'Min',
+    'MinHeight', 'MinItemHeight', 'MinWidth', 'ModalResult', 'Mode', 'Modified', 'Msg1Label',
+    'Msg2Label', 'MsgLabel', 'MultiSelect', 'Name', 'NextButton', 'NoIconsCheck', 'NoRadio',
+    'Notebook', 'Objects', 'Offset', 'OnActivate', 'OnBackButtonClick', 'OnCancelButtonClick',
+    'OnChange', 'OnChanging', 'OnClick', 'OnClickCheck', 'OnClose', 'OnCloseQuery', 'OnCreate',
+    'OnDblClick', 'OnDeactivate', 'OnDestroy', 'OnDropDown', 'OnHide', 'OnKeyDown', 'OnKeyPress',
+    'OnKeyUp', 'OnLinkClick', 'OnNextButtonClick', 'OnRename', 'OnResize', 'OnShouldSkipPage',
+    'OnShow', 'OuterNotebook', 'Owner', 'PageCount', 'PageDescriptionLabel', 'PageIndex',
+    'PageNameLabel', 'Pages', 'Parent', 'ParentBackground', 'Password', 'PasswordChar',
+    'PasswordEdit', 'PasswordEditLabel', 'PasswordLabel', 'PasswordPage', 'Pen', 'Pitch',
+    'Pixels', 'PixelsPerInch', 'Position', 'PreparingErrorBitmapImage', 'PreparingLabel',
+    'PreparingMemo', 'PreparingNoRadio', 'PreparingPage', 'PreparingYesRadio', 'PrevAppDir',
+    'ProgressBar', 'ProgressGauge', 'PromptLabels', 'ReadOnly', 'ReadyLabel', 'ReadyMemo',
+    'ReadyPage', 'ReplaceColor', 'ReplaceWithColor', 'RequireRadioSelection', 'RichEditViewer',
+    'RightToLeft', 'RTFText', 'RunList', 'ScrollBars', 'SelCount', 'SelectComponentsLabel',
+    'SelectComponentsPage', 'SelectDirBitmapImage', 'SelectDirBrowseLabel', 'SelectDirLabel',
+    'SelectDirPage', 'Selected', 'SelectedValueIndex', 'SelectGroupBitmapImage', 'SelectProgramGroupPage',
+    'SelectStartMenuFolderBrowseLabel', 'SelectStartMenuFolderLabel', 'SelectTasksLabel',
+    'SelectTasksPage', 'SelLength', 'SelStart', 'SelText', 'Shape', 'ShowAccelChar', 'ShowBaseNameInsteadOfUrl',
+    'ShowHint', 'Showing', 'ShowLines', 'Size', 'SizeAndCenterOnShow', 'Sorted', 'State',
+    'StatusLabel', 'Stretch', 'Strings', 'Style', 'SubCaptionLabel', 'SubItemFontStyle',
+    'Surface', 'SurfaceColor', 'SurfaceHeight', 'SurfaceWidth', 'TabOrder', 'TabStop',
+    'Tag', 'TasksList', 'Text', 'Top', 'TypesCombo', 'UseRichEdit', 'UserInfoNameEdit',
+    'UserInfoNameLabel', 'UserInfoOrgEdit', 'UserInfoOrgLabel', 'UserInfoPage', 'UserInfoSerialEdit',
+    'UserInfoSerialLabel', 'UseVisualStyle', 'Values', 'Visible', 'WantReturns', 'WantTabs',
+    'WelcomeLabel1', 'WelcomeLabel2', 'WelcomePage', 'Width', 'WizardBitmapImage', 'WizardBitmapImage2',
+    'WizardSmallBitmapImage', 'WordWrap', 'YesRadio'
+  ];
+
 implementation
 
 end.

+ 56 - 30
Projects/Src/Compil32/CompForm.pas

@@ -73,6 +73,11 @@ type
     StartCallTipWord: Integer;
     FunctionDefinition: AnsiString;
     BraceCount: Integer;
+    LastPosCallTip: Integer;
+    ClassOrRecordMember: Boolean;
+    CurrentCallTipWord: String;
+    CurrentCallTip: Integer;
+    MaxCallTips: Integer;
   end;
 
   TCompileForm = class(TUIStateForm)
@@ -513,11 +518,13 @@ type
     function InitiateAutoCompleteOrCallTipAllowedAtPos(const AMemo: TCompScintEdit;
       const WordStartLinePos, PositionBeforeWordStartPos: Integer): Boolean;
     procedure InitiateAutoComplete(const Key: AnsiChar);
+    procedure UpdateCallTipFunctionDefinition(const Pos: Integer = -1);
     procedure InitiateCallTip(const Key: AnsiChar);
     procedure ContinueCallTip;
     procedure InvalidateStatusPanel(const Index: Integer);
     procedure LoadBreakPointLinesAndUpdateLineMarkers(const AMemo: TCompScintFileEdit);
     procedure LoadKnownIncludedAndHiddenFilesAndUpdateMemos(const AFilename: String);
+    procedure MemoCallTipArrowClick(Sender: TObject; const Up: Boolean);
     procedure MemoChange(Sender: TObject; const Info: TScintEditChangeInfo);
     procedure MemoCharAdded(Sender: TObject; Ch: AnsiChar);
     procedure MainMemoDropFiles(Sender: TObject; X, Y: Integer; AFiles: TStrings);
@@ -711,6 +718,7 @@ begin
   Memo.ShowHint := True;
   Memo.Styler := FMemosStyler;
   Memo.PopupMenu := PopupMenu;
+  Memo.OnCallTipArrowClick := MemoCallTipArrowClick;
   Memo.OnChange := MemoChange;
   Memo.OnCharAdded := MemoCharAdded;
   Memo.OnHintShow := MemoHintShow;
@@ -987,6 +995,8 @@ begin
 
   FKeyMappedMenus := TKeyMappedMenus.Create;
 
+  FCallTipState.MaxCallTips := 1; { Just like SciTE 5.50 }
+
   if CommandLineCompile then begin
     ReadSignTools(FSignTools);
     PostMessage(Handle, WM_StartCommandLineCompile, 0, 0)
@@ -1299,8 +1309,12 @@ begin
     end;
   end else if (Key = VK_SPACE) and (Shift * [ssShift, ssAlt, ssCtrl] = [ssShift, ssCtrl]) then begin
     Key := 0;
-    if not FActiveMemo.CallTipActive then begin
-      FCallTipState.BraceCount := 1;
+    { Based on SciTE 5.50's SciTEBase::MenuCommand IDM_SHOWCALLTIP }
+    if FActiveMemo.CallTipActive then begin
+      FCallTipState.CurrentCallTip := IfThen(FCallTipState.CurrentCallTip + 1 = FCallTipState.MaxCallTips, 0, FCallTipState.CurrentCallTip + 1);
+      UpdateCallTipFunctionDefinition;
+    end else begin
+      FCallTipState.BraceCount := 1; { Missing in SciTE, see https://sourceforge.net/p/scintilla/bugs/2446/ }
       InitiateCallTip(#0);
     end;
   end else begin
@@ -4789,6 +4803,19 @@ begin
     UpdateModifiedPanel;
 end;
 
+procedure TCompileForm.MemoCallTipArrowClick(Sender: TObject;
+  const Up: Boolean);
+begin
+  { Based on SciTE 5.50's SciTEBase::Notify SA::Notification::CallTipClick }
+  if Up and (FCallTipState.CurrentCallTip > 0) then begin
+    Dec(FCallTipState.CurrentCallTip);
+    UpdateCallTipFunctionDefinition;
+  end else if not Up and (FCallTipState.CurrentCallTip + 1 < FCallTipState.MaxCallTips) then begin
+    Inc(FCallTipState.CurrentCallTip);
+    UpdateCallTipFunctionDefinition;
+  end;
+end;
+
 procedure TCompileForm.MemoChange(Sender: TObject; const Info: TScintEditChangeInfo);
 
   procedure MemoLinesInsertedOrDeleted(Memo: TCompScintFileEdit);
@@ -4966,10 +4993,8 @@ begin
             types, etc if the current word has no dot before it }
           if WordList = '' then begin
             var ClassOrRecordMember := (PositionBeforeWordStartPos >= LinePos) and (FActiveMemo.GetByteAtPosition(PositionBeforeWordStartPos) = '.');
-            if not ClassOrRecordMember then begin
-              WordList := FMemosStyler.ScriptWordList;
-              FActiveMemo.SetAutoCompleteFillupChars('');
-            end;
+            WordList := FMemosStyler.ScriptWordList[ClassOrRecordMember];
+            FActiveMemo.SetAutoCompleteFillupChars('');
           end;
 
           if WordList = '' then
@@ -5042,6 +5067,25 @@ begin
   FActiveMemo.ShowAutoComplete(CharsBefore, WordList);
 end;
 
+procedure TCompileForm.UpdateCallTipFunctionDefinition(const Pos: Integer { = -1 });
+begin
+  { Based on SciTE 5.50's SciTEBase::FillFunctionDefinition }
+    
+  if Pos > 0 then
+    FCallTipState.LastPosCallTip := Pos;
+
+  // Should get current api definition
+  var Word := FMemosStyler.GetScriptFunctionDefinition(FCallTipState.ClassOrRecordMember, FCallTipState.CurrentCallTipWord, FCallTipState.CurrentCallTip, FCallTipState.MaxCallTips);
+  if Word <> '' then begin
+    FCallTipState.FunctionDefinition := Word;
+    if FCallTipState.MaxCallTips > 1 then
+      FCallTipState.FunctionDefinition := AnsiString(Format(#1'%d of %d'#2'%s', [FCallTipState.CurrentCallTip+1, FCallTipState.MaxCallTips, FCallTipState.FunctionDefinition]));
+
+    FActiveMemo.ShowCallTip(FCallTipState.LastPosCallTip - Length(FCallTipState.CurrentCallTipWord), FCallTipState.FunctionDefinition);
+    ContinueCallTip;
+  end;
+end;
+
 procedure TCompileForm.InitiateCallTip(const Key: AnsiChar);
 begin
   var Pos := FActiveMemo.CaretPosition;
@@ -5052,12 +5096,10 @@ begin
        FActiveMemo.GetPositionBefore(Pos))) then
     Exit;
 
-  { Based on SciTE 5.50's SciTEBase::StartAutoComplete and
-    SciTEBase::FillFunctionDefinition, without support for multiple calltips }
+  { Based on SciTE 5.50's SciTEBase::StartAutoComplete }
 
-  { StartAutoComplete }
-
-  var CurrentCallTipWord := '';
+  FCallTipState.CurrentCallTip := 0;
+  FCallTipState.CurrentCallTipWord := '';
   var Line := FActiveMemo.CaretLineText;
   var Current := FActiveMemo.CaretPositionInLine;
   var CalltipWordCharacters := FActiveMemo.WordCharsAsSet;
@@ -5091,30 +5133,14 @@ begin
   {$ZEROBASEDSTRINGS ON}
 	while (FCallTipState.StartCalltipWord > 0) and CharInSet(Line[FCallTipState.StartCalltipWord-1], CalltipWordCharacters) do
     Dec(FCallTipState.StartCallTipWord);
-  var ClassOrRecordMember := (FCallTipState.StartCalltipWord > 0) and (Line[FCallTipState.StartCalltipWord-1] = '.');
+  FCallTipState.ClassOrRecordMember := (FCallTipState.StartCalltipWord > 0) and (Line[FCallTipState.StartCalltipWord-1] = '.');
   {$ZEROBASEDSTRINGS OFF}
 
   SetLength(Line, Current);
-  CurrentCallTipWord := Line.Substring(FCallTipState.StartCallTipWord); { Substring is zero-based }
+  FCallTipState.CurrentCallTipWord := Line.Substring(FCallTipState.StartCallTipWord); { Substring is zero-based }
 
   FCallTipState.FunctionDefinition := '';
-
-  { FillFunctionDefinition - if this is separated for multiple calltips support like in SciTE then the following vars
-    need to be moved into FCallTipState: CurrentCallTipWord, ClassOrRecordMember, LastPosCallTip }
-
-  var LastPosCallTip := Pos;
-
-  // Should get current api definition
-  var Word: AnsiString;
-  if not ClassOrRecordMember then
-    Word := FMemosStyler.ScriptFunctionDefinition[CurrentCallTipWord]
-  else
-    Word := '';
-  if Word <> '' then begin
-    FCallTipState.FunctionDefinition := Word;
-    FActiveMemo.ShowCallTip(LastPosCallTip - Length(CurrentCallTipWord), FCallTipState.FunctionDefinition);
-    ContinueCallTip;
-  end;
+  UpdateCallTipFunctionDefinition(Pos);
 end;
 
 procedure TCompileForm.ContinueCallTip;

+ 61 - 20
Projects/Src/Compil32/ScintStylerInnoSetup.pas

@@ -73,7 +73,8 @@ type
     stPascalReservedWord, stPascalString, stPascalNumber,
     stISPPReservedWord, stISPPString, stISPPNumber);
 
-  TFunctionDefinitionsByName = TDictionary<String, AnsiString>;
+  TFunctionDefinitions = array of AnsiString;
+  TFunctionDefinitionsByName = TDictionary<String, TFunctionDefinitions>;
 
   TInnoSetupStyler = class(TScintCustomStyler)
   private
@@ -81,8 +82,8 @@ type
     FKeywordsWordList, FFlagsWordList: array[TInnoSetupStylerSection] of AnsiString;
     FISPPDirectivesWordList, FConstantsWordList: AnsiString;
     FSectionsWordList: AnsiString;
-    FScriptFunctionsByName: TFunctionDefinitionsByName; { Only has functions with at least 1 parameter }
-    FScriptWordList: AnsiString;
+    FScriptFunctionsByName: array[Boolean] of TFunctionDefinitionsByName; { Only has functions with at least 1 parameter }
+    FScriptWordList: array[Boolean] of AnsiString;
     FISPPInstalled: Boolean;
     FTheme: TTheme;
     procedure AddWordToList(const SL: TStringList; const Word: AnsiString;
@@ -100,7 +101,7 @@ type
     procedure BuildKeywordsWordListFromTypeInfo(const Section: TInnoSetupStylerSection;
       const EnumTypeInfo: Pointer);
     procedure BuildScriptFunctionsLists(const ScriptFuncTable: TScriptTable;
-      const SL: TStringList);
+      const ClassMembers: Boolean; const SL: TStringList);
     function BuildWordList(const WordStringList: TStringList): AnsiString;
     procedure BuildSectionsWordList;
     procedure CommitStyleSq(const Style: TInnoSetupStylerStyle;
@@ -109,7 +110,6 @@ type
     function GetEventFunctionsWordList(Procedures: Boolean): AnsiString;
     function GetFlagsWordList(Section: TInnoSetupStylerSection): AnsiString;
     function GetKeywordsWordList(Section: TInnoSetupStylerSection): AnsiString;
-    function GetScriptFunctionDefinition(Name: String): AnsiString;
     procedure HandleCodeSection(var SpanState: TInnoSetupStylerSpanState);
     procedure HandleKeyValueSection(const Section: TInnoSetupStylerSection);
     procedure HandleParameterSection(const ValidParameters: array of TScintRawString);
@@ -122,6 +122,7 @@ type
     procedure StyleConstsUntilChars(const Chars: TScintRawCharSet;
       const NonConstStyle: TInnoSetupStylerStyle; var BraceLevel: Integer);
     procedure SetISPPInstalled(const Value: Boolean);
+    function GetScriptWordList(ClassOrRecordMembers: Boolean): AnsiString;
   protected
     procedure CommitStyle(const Style: TInnoSetupStylerStyle);
     procedure GetFoldLevel(const LineState, PreviousLineState: TScintLineState;
@@ -137,14 +138,15 @@ type
     class function IsCommentOrPascalStringStyle(const Style: TScintStyleNumber): Boolean;
     class function IsParamSection(const Section: TInnoSetupStylerSection): Boolean;
     class function IsSymbolStyle(const Style: TScintStyleNumber): Boolean;
+    function GetScriptFunctionDefinition(const ClassMember: Boolean;
+      const Name: String; const Index: Integer; out Count: Integer): AnsiString;
     property ConstantsWordList: AnsiString read FConstantsWordList;
     property EventFunctionsWordList[Procedures: Boolean]: AnsiString read GetEventFunctionsWordList;
     property FlagsWordList[Section: TInnoSetupStylerSection]: AnsiString read GetFlagsWordList;
     property ISPPDirectivesWordList: AnsiString read FISPPDirectivesWordList;
     property ISPPInstalled: Boolean read FISPPInstalled write SetISPPInstalled;
     property KeywordsWordList[Section: TInnoSetupStylerSection]: AnsiString read GetKeywordsWordList;
-    property ScriptFunctionDefinition[Name: String]: AnsiString read GetScriptFunctionDefinition;
-    property ScriptWordList: AnsiString read FScriptWordList;
+    property ScriptWordList[ClassOrRecordMembers: Boolean]: AnsiString read GetScriptWordList;
     property SectionsWordList: AnsiString read FSectionsWordList;
     property Theme: TTheme read FTheme write FTheme;
   end;
@@ -598,10 +600,11 @@ constructor TInnoSetupStyler.Create(AOwner: TComponent);
     var SL := TStringList.Create;
     try
       { Add stuff from ScriptFunc }
+      var ClassMembers := False;
       for var ScriptFuncTable in ScriptFuncTables do
-        BuildScriptFunctionsLists(ScriptFuncTable, SL);
-      BuildScriptFunctionsLists(DelphiScriptFuncTable, SL);
-      BuildScriptFunctionsLists(ROPSScriptFuncTable, SL);
+        BuildScriptFunctionsLists(ScriptFuncTable, ClassMembers, SL);
+      BuildScriptFunctionsLists(DelphiScriptFuncTable, ClassMembers, SL);
+      BuildScriptFunctionsLists(ROPSScriptFuncTable, ClassMembers, SL);
       { Add stuff from this unit }
       for var S in PascalConstants do
         AddWordToList(SL, S, awtScriptConstant);
@@ -626,8 +629,15 @@ constructor TInnoSetupStyler.Create(AOwner: TComponent);
       end;
       for var S in PascalVariables do
         AddWordToList(SL, S, awtScriptVariable);
-
-      FScriptWordList := BuildWordList(SL);
+      FScriptWordList[False] := BuildWordList(SL);
+
+      { Add stuff from Isxclasses }
+      SL.Clear;
+      ClassMembers := True;
+      BuildScriptFunctionsLists(PascalMembers_Isxclasses, ClassMembers, SL);
+      for var S in PascalProperties_Isxclasses do
+        AddWordToList(SL, S, awtScriptProperty);
+      FScriptWordList[True] := BuildWordList(SL);
     finally
       SL.Free;
     end;
@@ -641,13 +651,15 @@ begin
   BuildISPPDirectivesWordList;
   BuildKeywordsWordLists;
   BuildSectionsWordList;
-  FScriptFunctionsByName := TFunctionDefinitionsByName.Create(TIStringComparer.Ordinal);
+  FScriptFunctionsByName[False] := TFunctionDefinitionsByName.Create(TIStringComparer.Ordinal);
+  FScriptFunctionsByName[True] := TFunctionDefinitionsByName.Create(TIStringComparer.Ordinal);
   BuildScriptLists;
 end;
 
 destructor TInnoSetupStyler.Destroy;
 begin
-  FScriptFunctionsByName.Free;
+  FScriptFunctionsByName[False].Free;
+  FScriptFunctionsByName[True].Free;
   inherited;
 end;
 
@@ -749,14 +761,27 @@ begin
 end;
 
 procedure TInnoSetupStyler.BuildScriptFunctionsLists(
-  const ScriptFuncTable: TScriptTable; const SL: TStringList);
+  const ScriptFuncTable: TScriptTable; const ClassMembers: Boolean;
+  const SL: TStringList);
 begin
   for var ScriptFunc in ScriptFuncTable do begin
     var ScriptFuncWithoutHeader := RemoveScriptFuncHeader(ScriptFunc);
     var ScriptFuncName := ExtractScriptFuncWithoutHeaderName(ScriptFuncWithoutHeader);
-    if ScriptFuncHasParameters(ScriptFunc) then
-      FScriptFunctionsByName.Add(String(ScriptFuncName), ScriptFuncWithoutHeader);
-    AddWordToList(SL, ScriptFuncName, awtScriptFunction);
+    var DoAddWordToList := True;
+    if ScriptFuncHasParameters(ScriptFunc) then begin
+      var Key := String(ScriptFuncName);
+      if not FScriptFunctionsByName[ClassMembers].TryAdd(Key, [ScriptFuncWithoutHeader]) then begin
+        { Function has multiple prototypes }
+        var ScriptFunctions := FScriptFunctionsByName[ClassMembers][Key];
+        var N := Length(ScriptFunctions);
+        SetLength(ScriptFunctions, N+1);
+        ScriptFunctions[N] := ScriptFuncWithoutHeader;
+        FScriptFunctionsByName[ClassMembers][Key] := ScriptFunctions;
+        DoAddWordToList := False; { Already added it when the first prototype was found }
+      end;
+    end;
+    if DoAddWordToList then
+      AddWordToList(SL, ScriptFuncName, awtScriptFunction);
   end;
 end;
 
@@ -868,10 +893,26 @@ begin
   Result := FKeywordsWordList[Section];
 end;
 
-function TInnoSetupStyler.GetScriptFunctionDefinition(Name: String): AnsiString;
+function TInnoSetupStyler.GetScriptFunctionDefinition(const ClassMember: Boolean;
+  const Name: String; const Index: Integer; out Count: Integer): AnsiString;
 begin
-  if not FScriptFunctionsByName.TryGetValue(Name, Result) then
+  var ScriptFunctions: TFunctionDefinitions;
+  if FScriptFunctionsByName[ClassMember].TryGetValue(Name, ScriptFunctions) then begin
+    Count := Length(ScriptFunctions);
+    var ResultIndex := Index;
+    if ResultIndex >= Count then
+      ResultIndex := Count-1;
+    Result := ScriptFunctions[ResultIndex]
+  end else begin
+    Count := 0;
     Result := '';
+  end;
+end;
+
+function TInnoSetupStyler.GetScriptWordList(
+  ClassOrRecordMembers: Boolean): AnsiString;
+begin
+  Result := FScriptWordList[ClassOrRecordMembers];
 end;
 
 class function TInnoSetupStyler.GetSectionFromLineState(

+ 3 - 2
Projects/Src/ScriptFunc.pas

@@ -153,9 +153,10 @@ begin
   else if CompareText(Copy(Result, 1, Length(H2)), H2) = 0 then
     Delete(Result, 1, Length(H2))
   else
-    raise Exception.CreateFmt('Invalid FunctionDefinition: %s', [Result]);
+    raise Exception.CreateFmt('Invalid ScriptFunc: %s', [Result]);
 end;
 
+{ Also present in UIsxclassesParser.pas }
 function ExtractScriptFuncWithoutHeaderName(const ScriptFuncWithoutHeader: AnsiString): AnsiString;
 begin
   Result := ScriptFuncWithoutHeader;
@@ -170,7 +171,7 @@ begin
   if P = 0 then
     P := Pos(C3, Result);
   if P = 0 then
-    raise Exception.CreateFmt('Invalid FunctionDefinitionWithoutHeader: %s', [Result]);
+    raise Exception.CreateFmt('Invalid ScriptFuncWithoutHeader: %s', [Result]);
 
   Delete(Result, P, Maxint);
 end;

+ 3 - 2
whatsnew.htm

@@ -53,8 +53,9 @@ For conditions of distribution and use, see <a href="files/is/license.txt">LICEN
 <ul>
   <li>Added support for Visual Studio Code-style editor shortcuts, like Ctrl+D to Add Next Occurrence, Ctrl+Shift+K to delete a line and Alt+Click to add an additional cursor.<br />To activate this use the <i>Options</i> menu item in the <i>Tools</i> menu to set the new <i>Keys</i> option in the <i>Editor</i> group to <i>Visual Studio Code</i>.<br />The updated <a href="https://jrsoftware.org/ishelp/index.php?topic=compformshortcuts">Compiler IDE Keyboard And Mouse Commands</a> help topic lists all differences with the classic keyboard and mouse shortcuts.</li>
   <li>Added new shortcuts only available if Visual Studio Code-style editor shortcuts have been activated: Shift+Alt+Down to copy line down and Ctrl+] and Ctrl+[ to ident or unindent lines.</li>
-  <li>Implemented parameter hints for all Pascal Scripting support functions for quick reference to the function's parameter names, types, and order. Parameter hints can be invoked manually by pressing Ctrl+Shift+Space or automatically by using the new <i>Invoke parameter hints automatically</i> option which is enabled by default.</li>
-  <li>Added autocompletion support for all Pascal Scripting support functions, types, constants, etcetera. Existing option <i>Invoke autocompletion automatically</i> controls whether the autocompletion suggestions appear automatically or only when invoked manually by pressing Ctrl+Space or Ctrl+I. Does not support autocompletion of class or record members.</li>
+  <li>Added parameter hints for all Pascal Scripting support functions for quick reference to the function's parameter names, types, and order. Parameter hints can be invoked manually by pressing Ctrl+Shift+Space or automatically by using the new <i>Invoke parameter hints automatically</i> option which is enabled by default.</li>
+  <li>Added autocompletion support for all Pascal Scripting support functions, types, constants, etcetera. Existing option <i>Invoke autocompletion automatically</i> controls whether the autocompletion suggestions appear automatically or only when invoked manually by pressing Ctrl+Space or Ctrl+I.</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 object's class.</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>