IDE: parameter hints: button to add missing parameters

git-svn-id: trunk@30730 -
This commit is contained in:
mattias 2011-05-14 10:49:08 +00:00
parent 29d00b67cf
commit e6c4ffc414
6 changed files with 336 additions and 55 deletions

View File

@ -221,7 +221,7 @@ begin
end; end;
NewCode:=CodeToolBoss.SourceChangeCache.BeautifyCodeOptions.BeautifyStatement( NewCode:=CodeToolBoss.SourceChangeCache.BeautifyCodeOptions.BeautifyStatement(
NewCode,Indent,[bcfDoNotIndentFirstLine]); NewCode,Indent,[bcfDoNotIndentFirstLine],GetPosInLine(Tool.Src,CleanPos));
CodeToolBoss.SourceChangeCache.MainScanner:=Tool.Scanner; CodeToolBoss.SourceChangeCache.MainScanner:=Tool.Scanner;
if not CodeToolBoss.SourceChangeCache.Replace(Gap,Gap,CleanPos,CleanPos,NewCode) if not CodeToolBoss.SourceChangeCache.Replace(Gap,Gap,CleanPos,CleanPos,NewCode)
then begin then begin

View File

@ -32,7 +32,8 @@ interface
uses uses
Classes, SysUtils, LCLProc, LResources, Forms, Controls, Graphics, Dialogs, Classes, SysUtils, LCLProc, LResources, Forms, Controls, Graphics, Dialogs,
ButtonPanel, StdCtrls, ExtCtrls, ButtonPanel, StdCtrls, ExtCtrls,
FileProcs, CodeToolManager, CodeCache, FindDeclarationTool, CodeCompletionTool; FileProcs, CodeToolManager, CodeCache, FindDeclarationTool,
CodeCompletionTool, CodyUtils;
type type
@ -62,6 +63,9 @@ procedure ShowDeclareVariableDialog(Sender: TObject);
var var
CodyDeclareVarDialog: TCodyDeclareVarDialog; CodyDeclareVarDialog: TCodyDeclareVarDialog;
begin begin
// ParseTilCursor(Tool,CleanPos,Node);
dbgs(3);
ShowMessage('Not implemented yet'); ShowMessage('Not implemented yet');
CodyDeclareVarDialog:=TCodyDeclareVarDialog.Create(nil); CodyDeclareVarDialog:=TCodyDeclareVarDialog.Create(nil);
try try

View File

@ -100,7 +100,8 @@ type
LastSplitPos: integer; // last position where splitting is allowed LastSplitPos: integer; // last position where splitting is allowed
LastSrcLineStart: integer;// last line start, not added by splitting LastSrcLineStart: integer;// last line start, not added by splitting
CurAtomType, LastAtomType: TAtomType; CurAtomType, LastAtomType: TAtomType;
CurPos, AtomStart, AtomEnd, SrcLen, CurIndent, HiddenIndent: integer; CurPos, AtomStart, AtomEnd, SrcLen: integer;
HiddenIndent: integer; // the next indent is the sum of the current line indent plus HiddenIndent
CommentLvl: integer; CommentLvl: integer;
CommentStartPos: array of integer; CommentStartPos: array of integer;
Src: string; Src: string;
@ -150,7 +151,7 @@ type
function BeautifyStatementLeftAligned(const AStatement: string; function BeautifyStatementLeftAligned(const AStatement: string;
IndentSize: integer): string; IndentSize: integer): string;
function BeautifyStatement(const AStatement: string; IndentSize: integer; function BeautifyStatement(const AStatement: string; IndentSize: integer;
BeautifyFlags: TBeautifyCodeFlags): string; BeautifyFlags: TBeautifyCodeFlags; InsertX: integer = 1): string;
function AddClassAndNameToProc(const AProcCode, AClassName, function AddClassAndNameToProc(const AProcCode, AClassName,
AMethodName: string): string; AMethodName: string): string;
function BeautifyWord(const AWord: string; WordPolicy: TWordPolicy): string; function BeautifyWord(const AWord: string; WordPolicy: TWordPolicy): string;
@ -1532,8 +1533,10 @@ begin
end; end;
function TBeautifyCodeOptions.BeautifyStatement(const AStatement: string; function TBeautifyCodeOptions.BeautifyStatement(const AStatement: string;
IndentSize: integer; BeautifyFlags: TBeautifyCodeFlags): string; IndentSize: integer; BeautifyFlags: TBeautifyCodeFlags; InsertX: integer
var CurAtom: string; ): string;
var
CurAtom: string;
OldIndent: Integer; OldIndent: Integer;
OldAtomStart: LongInt; OldAtomStart: LongInt;
begin begin
@ -1549,17 +1552,21 @@ begin
Src:=AStatement; Src:=AStatement;
SrcLen:=length(Src); SrcLen:=length(Src);
if IndentSize>=LineLength-10 then IndentSize:=LineLength-10; if IndentSize>=LineLength-10 then IndentSize:=LineLength-10;
CurIndent:=IndentSize; if IndentSize<0 then IndentSize:=0;
HiddenIndent:=0; Result:='';
if bcfDoNotIndentFirstLine in CurFlags then begin if (bcfDoNotIndentFirstLine in CurFlags) then begin
Result:=''; HiddenIndent:=IndentSize;
HiddenIndent:=CurIndent; CurLineLen:=0;
end else if InsertX>0 then inc(CurLineLen,InsertX-1);
Result:=GetIndentStr(CurIndent); end else begin
HiddenIndent:=0;
Result:=GetIndentStr(IndentSize);
CurLineLen:=IndentSize;
if InsertX>0 then inc(CurLineLen,InsertX-1);
end;
CurPos:=1; CurPos:=1;
LastSplitPos:=-1; LastSplitPos:=-1;
LastSrcLineStart:=1; LastSrcLineStart:=1;
CurLineLen:=length(Result);
LastAtomType:=atNone; LastAtomType:=atNone;
CommentLvl:=0; CommentLvl:=0;
// read atoms // read atoms

View File

@ -37,36 +37,51 @@ unit CodeContextForm;
interface interface
uses uses
Classes, SysUtils, Types, LCLProc, LResources, Forms, Controls, Graphics, Classes, SysUtils, Types, contnrs, LCLProc, LResources, Forms, Controls,
Dialogs, LCLType, LCLIntf, Graphics, Dialogs, LCLType, LCLIntf, Themes, Buttons, SynEdit, SynEditKeyCmds,
SynEdit, SynEditKeyCmds,
BasicCodeTools, KeywordFuncLists, LinkScanner, CodeCache, FindDeclarationTool, BasicCodeTools, KeywordFuncLists, LinkScanner, CodeCache, FindDeclarationTool,
IdentCompletionTool, CodeTree, CodeAtom, PascalParserTool, CodeToolManager, IdentCompletionTool, CodeTree, CodeAtom, PascalParserTool, CodeToolManager,
SrcEditorIntf, SourceChanger, SrcEditorIntf, IDEProcs, LazarusIDEStrConsts;
IDEProcs, LazarusIDEStrConsts;
type type
{ TCodeContextItem }
TCodeContextItem = class
public
Code: string;
Hint: string;
CopyAllButton: TSpeedButton;
destructor Destroy; override;
end;
{ TCodeContextFrm } { TCodeContextFrm }
TCodeContextFrm = class(THintWindow) TCodeContextFrm = class(THintWindow)
procedure ApplicationIdle(Sender: TObject; var Done: Boolean); procedure ApplicationIdle(Sender: TObject; var Done: Boolean);
procedure CopyAllBtnClick(Sender: TObject);
procedure FormCreate(Sender: TObject); procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject); procedure FormDestroy(Sender: TObject);
procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
procedure FormPaint(Sender: TObject); procedure FormPaint(Sender: TObject);
procedure FormUTF8KeyPress(Sender: TObject; var UTF8Key: TUTF8Char); procedure FormUTF8KeyPress(Sender: TObject; var UTF8Key: TUTF8Char);
private private
FHints: TStrings; FHints: TObjectList; // list of TCodeContextItem
FLastParameterIndex: integer; FLastParameterIndex: integer;
FParamListBracketOpenCodeXYPos: TCodeXYPosition; FParamListBracketOpenCodeXYPos: TCodeXYPosition;
FProcNameCodeXYPos: TCodeXYPosition; FProcNameCodeXYPos: TCodeXYPosition;
FSourceEditorTopIndex: integer; FSourceEditorTopIndex: integer;
FBtnWidth: integer;
procedure CreateHints(const CodeContexts: TCodeContextInfo); procedure CreateHints(const CodeContexts: TCodeContextInfo);
procedure ClearMarksInHints; procedure ClearMarksInHints;
function GetHints(Index: integer): TCodeContextItem;
procedure MarkCurrentParameterInHints(ParameterIndex: integer); // 0 based procedure MarkCurrentParameterInHints(ParameterIndex: integer); // 0 based
procedure CalculateHintsBounds(const CodeContexts: TCodeContextInfo); procedure CalculateHintsBounds(const CodeContexts: TCodeContextInfo);
procedure DrawHints(var MaxWidth, MaxHeight: Integer; Draw: boolean); procedure DrawHints(var MaxWidth, MaxHeight: Integer; Draw: boolean);
procedure CompleteParameters(DeclCode: string);
protected
procedure Notification(AComponent: TComponent; Operation: TOperation);
override;
public public
constructor Create(TheOwner: TComponent); override; constructor Create(TheOwner: TComponent); override;
destructor Destroy; override; destructor Destroy; override;
@ -78,6 +93,7 @@ type
read FParamListBracketOpenCodeXYPos; read FParamListBracketOpenCodeXYPos;
property SourceEditorTopIndex: integer read FSourceEditorTopIndex; property SourceEditorTopIndex: integer read FSourceEditorTopIndex;
property LastParameterIndex: integer read FLastParameterIndex; property LastParameterIndex: integer read FLastParameterIndex;
property Hints[Index: integer]: TCodeContextItem read GetHints;
end; end;
var var
@ -86,7 +102,6 @@ var
function ShowCodeContext(Code: TCodeBuffer): boolean; function ShowCodeContext(Code: TCodeBuffer): boolean;
implementation implementation
uses Themes;
type type
TWinControlAccess = class(TWinControl); TWinControlAccess = class(TWinControl);
@ -114,6 +129,14 @@ begin
end; end;
end; end;
{ TCodeContextItem }
destructor TCodeContextItem.Destroy;
begin
FreeAndNil(CopyAllButton);
inherited Destroy;
end;
{ TCodeContextFrm } { TCodeContextFrm }
procedure TCodeContextFrm.ApplicationIdle(Sender: TObject; var Done: Boolean); procedure TCodeContextFrm.ApplicationIdle(Sender: TObject; var Done: Boolean);
@ -122,9 +145,27 @@ begin
UpdateHints; UpdateHints;
end; end;
procedure TCodeContextFrm.CopyAllBtnClick(Sender: TObject);
var
i: LongInt;
Item: TCodeContextItem;
begin
i:=FHints.Count-1;
while (i>=0) do begin
Item:=Hints[i];
if Item.CopyAllButton=Sender then begin
//debugln(['TCodeContextFrm.CopyAllBtnClick Hint="',Item.Code,'"']);
CompleteParameters(Item.Code);
exit;
end;
dec(i);
end;
end;
procedure TCodeContextFrm.FormCreate(Sender: TObject); procedure TCodeContextFrm.FormCreate(Sender: TObject);
begin begin
FHints:=TStringList.Create; FBtnWidth:=16;
FHints:=TObjectList.Create(true);
Application.AddOnIdleHandler(@ApplicationIdle); Application.AddOnIdleHandler(@ApplicationIdle);
end; end;
@ -355,31 +396,35 @@ var
s: String; s: String;
p: Integer; p: Integer;
CurContext: TCodeContextInfoItem; CurContext: TCodeContextInfoItem;
Btn: TSpeedButton;
j: Integer;
Code: String;
Item: TCodeContextItem;
begin begin
FHints.Clear; FHints.Clear;
if (CodeContexts=nil) or (CodeContexts.Count=0) then exit; if (CodeContexts=nil) or (CodeContexts.Count=0) then exit;
for i:=0 to CodeContexts.Count-1 do begin for i:=0 to CodeContexts.Count-1 do begin
CurContext:=CodeContexts[i]; CurContext:=CodeContexts[i];
CurExprType:=CurContext.Expr; CurExprType:=CurContext.Expr;
s:=ExpressionTypeDescNames[CurExprType.Desc]; Code:=ExpressionTypeDescNames[CurExprType.Desc];
if CurExprType.Context.Node<>nil then begin if CurExprType.Context.Node<>nil then begin
CodeNode:=CurExprType.Context.Node; CodeNode:=CurExprType.Context.Node;
CodeTool:=CurExprType.Context.Tool; CodeTool:=CurExprType.Context.Tool;
case CodeNode.Desc of case CodeNode.Desc of
ctnProcedure: ctnProcedure:
begin begin
s:=CodeTool.ExtractProcHead(CodeNode, Code:=CodeTool.ExtractProcHead(CodeNode,
[phpWithVarModifiers,phpWithParameterNames,phpWithDefaultValues, [phpWithVarModifiers,phpWithParameterNames,phpWithDefaultValues,
phpWithResultType]); phpWithResultType]);
end; end;
ctnProperty: ctnProperty:
begin begin
if CodeTool.PropertyNodeHasParamList(CodeNode) then begin if CodeTool.PropertyNodeHasParamList(CodeNode) then begin
s:=CodeTool.ExtractProperty(CodeNode, Code:=CodeTool.ExtractProperty(CodeNode,
[phpWithVarModifiers,phpWithParameterNames,phpWithDefaultValues, [phpWithVarModifiers,phpWithParameterNames,phpWithDefaultValues,
phpWithResultType]); phpWithResultType]);
end else if not CodeTool.PropNodeIsTypeLess(CodeNode) then begin end else if not CodeTool.PropNodeIsTypeLess(CodeNode) then begin
s:=CodeTool.ExtractPropName(CodeNode,false); Code:=CodeTool.ExtractPropName(CodeNode,false);
FindBaseType(CodeTool,CodeNode,s); FindBaseType(CodeTool,CodeNode,s);
end else begin end else begin
// ignore properties without type // ignore properties without type
@ -388,34 +433,52 @@ begin
end; end;
ctnVarDefinition: ctnVarDefinition:
begin begin
s:=CodeTool.ExtractDefinitionName(CodeNode); Code:=CodeTool.ExtractDefinitionName(CodeNode);
if not FindBaseType(CodeTool,CodeNode,s) then if not FindBaseType(CodeTool,CodeNode,Code) then
continue; // ignore normal variables continue; // ignore normal variables
end; end;
end; end;
end else if CurContext.Params<>nil then begin end else if CurContext.Params<>nil then begin
// compiler function // compiler function
s:=CurContext.ProcName+'('+CurContext.Params.DelimitedText+')'; Code:=CurContext.ProcName+'('+CurContext.Params.DelimitedText+')';
if CurContext.ResultType<>'' then if CurContext.ResultType<>'' then
s:=s+':'+CurContext.ResultType; Code:=Code+':'+CurContext.ResultType;
end; end;
// insert spaces // insert spaces
for p:=length(s)-1 downto 1 do begin for p:=length(Code)-1 downto 1 do begin
if (s[p] in [',',';',':']) and (s[p+1]<>' ') then if (Code[p] in [',',';',':']) and (Code[p+1]<>' ') then
System.Insert(' ',s,p+1); System.Insert(' ',Code,p+1);
end; end;
Code:=Trim(Code);
s:=Code;
// mark the mark characters // mark the mark characters
for p:=length(s) downto 1 do for p:=length(s) downto 1 do
if s[p]='\' then if s[p]='\' then
System.Insert('\',s,p+1); System.Insert('\',s,p+1);
s:=Trim(s); // add hint if not already exists
if FHints.IndexOf(s)<0 then j:=FHints.Count-1;
FHints.Add(s); while (j>=0) and (CompareText(Hints[j].Code,Code)<>0) do
dec(j);
if j<0 then begin
Item:=TCodeContextItem.Create;
Item.Code:=Code;
Item.Hint:=s;
Btn:=TSpeedButton.Create(Self);
Item.CopyAllButton:=Btn;
Btn.Name:='CopyAllSpeedButton'+IntToStr(i+1);
Btn.OnClick:=@CopyAllBtnClick;
Btn.Visible:=false;
Btn.Parent:=Self;
FHints.Add(Item);
end;
end;
if FHints.Count=0 then begin
Item:=TCodeContextItem.Create;
Item.Code:='';
Item.Hint:=lisNoHints;
FHints.Add(Item);
end; end;
if FHints.Count=0 then
FHints.Add(lisNoHints);
MarkCurrentParameterInHints(CodeContexts.ParameterIndex-1); MarkCurrentParameterInHints(CodeContexts.ParameterIndex-1);
//DebugLn('TCodeContextFrm.UpdateHints ',FHints.Text);
end; end;
procedure TCodeContextFrm.ClearMarksInHints; procedure TCodeContextFrm.ClearMarksInHints;
@ -424,9 +487,11 @@ var
i: Integer; i: Integer;
s: string; s: string;
p: Integer; p: Integer;
Item: TCodeContextItem;
begin begin
for i:=0 to FHints.Count-1 do begin for i:=0 to FHints.Count-1 do begin
s:=FHints[i]; Item:=Hints[i];
s:=Item.Hint;
p:=1; p:=1;
while p<length(s) do begin while p<length(s) do begin
if s[p]<>'\' then if s[p]<>'\' then
@ -437,10 +502,15 @@ begin
System.Delete(s,p,2); // remove mark System.Delete(s,p,2); // remove mark
end; end;
end; end;
FHints[i]:=s; Item.Hint:=s;
end; end;
end; end;
function TCodeContextFrm.GetHints(Index: integer): TCodeContextItem;
begin
Result:=TCodeContextItem(FHints[Index]);
end;
procedure TCodeContextFrm.MarkCurrentParameterInHints(ParameterIndex: integer); procedure TCodeContextFrm.MarkCurrentParameterInHints(ParameterIndex: integer);
function MarkCurrentParameterInHint(const s: string): string; function MarkCurrentParameterInHint(const s: string): string;
@ -554,11 +624,14 @@ procedure TCodeContextFrm.MarkCurrentParameterInHints(ParameterIndex: integer);
var var
i: Integer; i: Integer;
Item: TCodeContextItem;
begin begin
//DebugLn('TCodeContextFrm.MarkCurrentParameterInHints FLastParameterIndex=',dbgs(FLastParameterIndex),' ParameterIndex=',dbgs(ParameterIndex)); //DebugLn('TCodeContextFrm.MarkCurrentParameterInHints FLastParameterIndex=',dbgs(FLastParameterIndex),' ParameterIndex=',dbgs(ParameterIndex));
ClearMarksInHints; ClearMarksInHints;
for i:=0 to FHints.Count-1 do for i:=0 to FHints.Count-1 do begin
FHints[i]:=MarkCurrentParameterInHint(FHints[i]); Item:=Hints[i];
Item.Hint:=MarkCurrentParameterInHint(Item.Hint);
end;
FLastParameterIndex:=ParameterIndex; FLastParameterIndex:=ParameterIndex;
Invalidate; Invalidate;
end; end;
@ -617,12 +690,12 @@ end;
procedure TCodeContextFrm.DrawHints(var MaxWidth, MaxHeight: Integer; procedure TCodeContextFrm.DrawHints(var MaxWidth, MaxHeight: Integer;
Draw: boolean); Draw: boolean);
var var
HorizontalSpace: Integer; LeftSpace, RightSpace: Integer;
VerticalSpace: Integer; VerticalSpace: Integer;
BackgroundColor, TextGrayColor, TextColor, PenColor: TColor; BackgroundColor, TextGrayColor, TextColor, PenColor: TColor;
TextGrayStyle, TextStyle: TFontStyles; TextGrayStyle, TextStyle: TFontStyles;
procedure DrawHint(const Line: string; var AHintRect: TRect); procedure DrawHint(Index: integer; var AHintRect: TRect);
var var
ATextRect: TRect; ATextRect: TRect;
TokenStart: Integer; TokenStart: Integer;
@ -633,15 +706,25 @@ var
UsedWidth: Integer; // maximum right token position UsedWidth: Integer; // maximum right token position
LineHeight: Integer; // current line height LineHeight: Integer; // current line height
LastTokenEnd: LongInt; LastTokenEnd: LongInt;
Line: string;
Item: TCodeContextItem;
begin begin
ATextRect:=Rect(AHintRect.Left+HorizontalSpace, Item:=Hints[Index];
Line:=Item.Hint;
ATextRect:=Rect(AHintRect.Left+LeftSpace,
AHintRect.Top+VerticalSpace, AHintRect.Top+VerticalSpace,
AHintRect.Right-HorizontalSpace, AHintRect.Right-RightSpace,
AHintRect.Bottom-VerticalSpace); AHintRect.Bottom-VerticalSpace);
UsedWidth:=0; UsedWidth:=0;
LineHeight:=0; LineHeight:=0;
TokenPos:=Point(ATextRect.Left,ATextRect.Top); TokenPos:=Point(ATextRect.Left,ATextRect.Top);
TokenEnd:=1; TokenEnd:=1;
if Draw and (Item.CopyAllButton<>nil) then begin
// move button at end of first line
Item.CopyAllButton.SetBounds(
AHintRect.Right-RightSpace,AHintRect.Top,FBtnWidth,FBtnWidth);
Item.CopyAllButton.Visible:=true;
end;
while (TokenEnd<=length(Line)) do begin while (TokenEnd<=length(Line)) do begin
LastTokenEnd:=TokenEnd; LastTokenEnd:=TokenEnd;
ReadRawNextPascalAtom(Line,TokenEnd,TokenStart); ReadRawNextPascalAtom(Line,TokenEnd,TokenStart);
@ -728,7 +811,7 @@ var
end; end;
if (not Draw) and (UsedWidth>0) then if (not Draw) and (UsedWidth>0) then
AHintRect.Right:=UsedWidth+HorizontalSpace; AHintRect.Right:=UsedWidth+RightSpace;
AHintRect.Bottom:=TokenPos.Y+LineHeight+VerticalSpace; AHintRect.Bottom:=TokenPos.Y+LineHeight+VerticalSpace;
end; end;
@ -749,7 +832,8 @@ begin
TextStyle:=[fsBold]; TextStyle:=[fsBold];
PenColor:=clBlack; PenColor:=clBlack;
end; end;
HorizontalSpace:=2; LeftSpace:=2;
RightSpace:=2+FBtnWidth;
VerticalSpace:=2; VerticalSpace:=2;
if Draw then begin if Draw then begin
@ -767,7 +851,7 @@ begin
for i:=0 to FHints.Count-1 do begin for i:=0 to FHints.Count-1 do begin
if Draw and (NewMaxHeight>=MaxHeight) then break; if Draw and (NewMaxHeight>=MaxHeight) then break;
CurHintRect:=Rect(0,NewMaxHeight,MaxWidth,MaxHeight); CurHintRect:=Rect(0,NewMaxHeight,MaxWidth,MaxHeight);
DrawHint(FHints[i],CurHintRect); DrawHint(i,CurHintRect);
//DebugLn('TCodeContextFrm.DrawHints i=',dbgs(i),' CurTextRect=',dbgs(CurTextRect),' CurRect=',dbgs(CurRect),' s="',s,'"'); //DebugLn('TCodeContextFrm.DrawHints i=',dbgs(i),' CurTextRect=',dbgs(CurTextRect),' CurRect=',dbgs(CurRect),' s="',s,'"');
if CurHintRect.Right>NewMaxWidth then if CurHintRect.Right>NewMaxWidth then
NewMaxWidth:=CurHintRect.Right; NewMaxWidth:=CurHintRect.Right;
@ -776,6 +860,9 @@ begin
// for fractionals add some space // for fractionals add some space
inc(NewMaxWidth,2); inc(NewMaxWidth,2);
inc(NewMaxHeight,2); inc(NewMaxHeight,2);
// add space for the copy all button
inc(NewMaxWidth,16);
if Draw then begin if Draw then begin
// fill rest of form // fill rest of form
if NewMaxHeight<MaxHeight then if NewMaxHeight<MaxHeight then
@ -792,6 +879,189 @@ begin
end; end;
end; end;
procedure TCodeContextFrm.CompleteParameters(DeclCode: string);
// add the parameter names in the source editor
function ReadNextAtom(ASynEdit: TSynEdit; var TokenLine, TokenEnd: integer;
out TokenStart: integer): string;
var
Line: string;
begin
while TokenLine<=ASynEdit.Lines.Count do begin
Line:=ASynEdit.Lines[TokenLine-1];
ReadRawNextPascalAtom(Line,TokenEnd,TokenStart);
if TokenStart<TokenEnd then begin
Result:=copy(Line,TokenStart,TokenEnd-TokenStart);
exit;
end;
inc(TokenLine);
TokenEnd:=1;
end;
TokenStart:=TokenEnd;
Result:='';
end;
procedure AddParameters(ASynEdit: TSynEdit; Y, X: integer; AddComma: boolean;
StartIndex: integer);
var
NewCode: String;
TokenStart: Integer;
BracketLevel: Integer;
ParameterIndex: Integer;
TokenEnd: integer;
LastToken: String;
Indent: LongInt;
begin
TokenEnd:=1;
BracketLevel:=0;
ParameterIndex:=-1;
NewCode:='';
LastToken:='';
repeat
ReadRawNextPascalAtom(DeclCode,TokenEnd,TokenStart);
if TokenEnd=TokenStart then break;
case DeclCode[TokenStart] of
'(','[':
begin
inc(BracketLevel);
if BracketLevel=1 then
ParameterIndex:=0;
end;
')',']':
begin
dec(BracketLevel);
if BracketLevel=0 then begin
// closing bracket found
break;
end;
end;
',',':':
if BracketLevel=1 then begin
if (LastToken<>'') and (IsIdentStartChar[LastToken[1]])
and (ParameterIndex>=StartIndex) then begin
// add parameter
if AddComma then
NewCode:=NewCode+',';
NewCode:=NewCode+LastToken;
AddComma:=true;
end;
if DeclCode[TokenStart]=',' then
inc(ParameterIndex);
end;
';':
if BracketLevel=1 then
inc(ParameterIndex);
else
end;
LastToken:=copy(DeclCode,TokenStart,TokenEnd-TokenStart);
until false;
if NewCode='' then exit;
// format insertion
Indent:=GetLineIndentWithTabs(ASynEdit.Lines[Y-1],X,ASynEdit.TabWidth);
if Y<>FParamListBracketOpenCodeXYPos.Y then
dec(Indent,CodeToolBoss.SourceChangeCache.BeautifyCodeOptions.Indent);
NewCode:=CodeToolBoss.SourceChangeCache.BeautifyCodeOptions.BeautifyStatement(
NewCode,Indent,[],X);
NewCode:=copy(NewCode,Indent+1,length(NewCode));
// insert
ASynEdit.BeginUndoBlock;
ASynEdit.BlockBegin:=Point(X,Y);
ASynEdit.BlockEnd:=Point(X,Y);
ASynEdit.SelText:=NewCode;
ASynEdit.EndUndoBlock;
end;
var
SrcEdit: TSourceEditorInterface;
BracketPos: TPoint;
ASynEdit: TSynEdit;
Line: string;
TokenLine, TokenEnd, TokenStart: LongInt;
LastTokenLine, LastTokenEnd: LongInt;
BracketLevel: Integer;
ParameterIndex: Integer;
Token: String;
LastToken: String;
NeedComma: Boolean;
begin
SrcEdit:=SourceEditorManagerIntf.ActiveEditor;
if (SrcEdit=nil) or (SrcEdit.CodeToolsBuffer<>ProcNameCodeXYPos.Code) then
exit;
BracketPos:=Point(ParamListBracketOpenCodeXYPos.X,
ParamListBracketOpenCodeXYPos.Y);
// find out, if cursor is in procedure call and where
ASynEdit:=SrcEdit.EditorControl as TSynEdit;
Line:=ASynEdit.Lines[BracketPos.Y-1];
if (length(Line)<BracketPos.X) or (not (Line[BracketPos.X] in ['(','[']))
then begin
// bracket lost -> something changed -> hints became invalid
exit;
end;
// parse the code
TokenLine:=BracketPos.Y;
TokenEnd:=BracketPos.X;
//debugln(['TCodeContextFrm.CompleteParameters START BracketPos=',dbgs(BracketPos)]);
TokenStart:=TokenEnd;
BracketLevel:=0;
ParameterIndex:=-1;
Token:='';
repeat
LastTokenLine:=TokenLine;
LastTokenEnd:=TokenEnd;
LastToken:=Token;
Token:=ReadNextAtom(ASynEdit,TokenLine,TokenEnd,TokenStart);
//debugln(['TCodeContextFrm.CompleteParameters Token="',Token,'" ParameterIndex=',ParameterIndex]);
if TokenEnd=TokenStart then break;
case Token[1] of
'(','[':
begin
inc(BracketLevel);
if BracketLevel=1 then
ParameterIndex:=0;
end;
')',']':
begin
dec(BracketLevel);
if BracketLevel=0 then begin
// closing bracket found
NeedComma:=(LastToken<>',') and (LastToken<>'(') and (LastToken<>'[');
if NeedComma then inc(ParameterIndex);
//debugln(['TCodeContextFrm.CompleteParameters y=',LastTokenLine,' x=',LastTokenEnd,' ParameterIndex=',ParameterIndex]);
AddParameters(ASynEdit,LastTokenLine,LastTokenEnd,NeedComma,ParameterIndex);
break;
end;
end;
',':
if BracketLevel=1 then inc(ParameterIndex);
';':
break; // missing close bracket => cursor behind procedure call
else
if IsIdentStartChar[Token[1]] then begin
if CompareIdentifiers(PChar(Token),'end')=0 then
break;// missing close bracket => cursor behind procedure call
end;
end;
until false;
end;
procedure TCodeContextFrm.Notification(AComponent: TComponent;
Operation: TOperation);
var
i: Integer;
begin
inherited Notification(AComponent, Operation);
if Operation=opRemove then
begin
for i:=0 to FHints.Count-1 do
if Hints[i].CopyAllButton=AComponent then
Hints[i].CopyAllButton:=nil;
end;
end;
procedure TCodeContextFrm.Paint; procedure TCodeContextFrm.Paint;
begin begin
FormPaint(Self); FormPaint(Self);

View File

@ -2413,8 +2413,8 @@ begin
if not CodeToolBoss.InitCurCodeTool(Code) then exit; if not CodeToolBoss.InitCurCodeTool(Code) then exit;
try try
// find declaration // find declaration
if not CodeToolBoss.CurCodeTool.FindDeclaration(CursorPos,DefaultFindSmartHintFlags, if not CodeToolBoss.CurCodeTool.FindDeclaration(CursorPos,
CTTool,CTNode,XYPos,aTopLine) DefaultFindSmartHintFlags,CTTool,CTNode,XYPos,aTopLine)
then then
exit; exit;

View File

@ -348,7 +348,7 @@ function TCustomSpeedButton.GetDrawDetails: TThemedElementDetails;
if FState = bsHot then if FState = bsHot then
Result := tbPushButtonHot Result := tbPushButtonHot
else else
Result := tbPushButtonNormal Result := tbPushButtonNormal;
end; end;
function ToolButtonPart: TThemedToolBar; function ToolButtonPart: TThemedToolBar;
@ -364,7 +364,7 @@ function TCustomSpeedButton.GetDrawDetails: TThemedElementDetails;
if FMouseInControl then if FMouseInControl then
Result := ttbButtonCheckedHot Result := ttbButtonCheckedHot
else else
Result := ttbButtonChecked Result := ttbButtonChecked;
end end
else else
begin begin
@ -373,7 +373,7 @@ function TCustomSpeedButton.GetDrawDetails: TThemedElementDetails;
if FState = bsHot then if FState = bsHot then
Result := ttbButtonHot Result := ttbButtonHot
else else
Result := ttbButtonNormal Result := ttbButtonNormal;
end; end;
end; end;
end; end;