mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-27 17:00:31 +02:00
implemented search for existing class completion comments
git-svn-id: trunk@7522 -
This commit is contained in:
parent
cad5a68f98
commit
612ad985f5
@ -1707,28 +1707,34 @@ function TCodeCompletionCodeTool.InsertClassHeaderComment: boolean;
|
|||||||
var
|
var
|
||||||
ClassNode: TCodeTreeNode;
|
ClassNode: TCodeTreeNode;
|
||||||
ClassIdentifierNode: TCodeTreeNode;
|
ClassIdentifierNode: TCodeTreeNode;
|
||||||
NonSpacePos: LongInt;
|
|
||||||
Code: String;
|
Code: String;
|
||||||
InsertPos: LongInt;
|
InsertPos: LongInt;
|
||||||
Indent: LongInt;
|
Indent: LongInt;
|
||||||
|
StartPos, CommentStart, CommentEnd: TCodeXYPosition;
|
||||||
begin
|
begin
|
||||||
Result:=true;
|
Result:=true;
|
||||||
if not ASourceChangeCache.BeautifyCodeOptions.ClassHeaderComments then exit;
|
if not ASourceChangeCache.BeautifyCodeOptions.ClassHeaderComments then exit;
|
||||||
// check if there is already a comment in front of the class
|
// check if there is already a comment in front of the class
|
||||||
|
|
||||||
|
// find the start of the class (the position in front of the class name)
|
||||||
ClassNode:=CodeCompleteClassNode;
|
ClassNode:=CodeCompleteClassNode;
|
||||||
if ClassNode=nil then exit;
|
if ClassNode=nil then exit;
|
||||||
ClassIdentifierNode:=ClassNode.Parent;
|
ClassIdentifierNode:=ClassNode.Parent;
|
||||||
if ClassIdentifierNode=nil then exit;
|
if ClassIdentifierNode=nil then exit;
|
||||||
NonSpacePos:=FindPrevNonSpace(Src,ClassIdentifierNode.StartPos-1);
|
if not CleanPosToCaret(ClassIdentifierNode.StartPos,StartPos) then exit;
|
||||||
if IsCommentEnd(Src,NonSpacePos) then begin
|
Code:=ExtractIdentifier(ClassIdentifierNode.StartPos);
|
||||||
// there is already a comment in front
|
|
||||||
|
// check if there is already a comment in front
|
||||||
|
if FindCommentInFront(StartPos,Code,false,true,false,false,true,
|
||||||
|
CommentStart,CommentEnd)
|
||||||
|
then
|
||||||
|
// comment already exists
|
||||||
exit;
|
exit;
|
||||||
end;
|
|
||||||
// insert comment in front
|
// insert comment in front
|
||||||
InsertPos:=ClassIdentifierNode.StartPos;
|
InsertPos:=ClassIdentifierNode.StartPos;
|
||||||
Indent:=GetLineIndent(Src,InsertPos);
|
Indent:=GetLineIndent(Src,InsertPos);
|
||||||
Code:=GetIndentStr(Indent)
|
Code:=GetIndentStr(Indent)+'{ '+Code+' }';
|
||||||
+'{ '+ExtractIdentifier(ClassIdentifierNode.StartPos)+' }';
|
|
||||||
ASourceChangeCache.Replace(gtEmptyLine,gtEmptyLine,
|
ASourceChangeCache.Replace(gtEmptyLine,gtEmptyLine,
|
||||||
InsertPos,InsertPos,Code);
|
InsertPos,InsertPos,Code);
|
||||||
end;
|
end;
|
||||||
@ -1981,14 +1987,28 @@ var
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
procedure InsertClassMethodsComment;
|
procedure InsertClassMethodsComment;
|
||||||
|
var
|
||||||
|
Code: String;
|
||||||
|
InsertXYPos, CommentStart, CommentEnd: TCodeXYPosition;
|
||||||
begin
|
begin
|
||||||
// insert class comment
|
// insert class comment
|
||||||
if ClassProcs.Count>0 then begin
|
if ClassProcs.Count=0 then exit;
|
||||||
ClassStartComment:=GetIndentStr(Indent)
|
// find the start of the class (the position in front of the class name)
|
||||||
+'{ '+ExtractClassName(FCodeCompleteClassNode,false)+' }';
|
if not CleanPosToCaret(InsertPos,InsertXYPos) then exit;
|
||||||
ASourceChangeCache.Replace(gtEmptyLine,gtEmptyLine,InsertPos,InsertPos,
|
|
||||||
ClassStartComment);
|
Code:=ExtractClassName(CodeCompleteClassNode,false);
|
||||||
|
// check if there is already a comment in front
|
||||||
|
if FindCommentInFront(InsertXYPos,Code,false,true,false,false,true,
|
||||||
|
CommentStart,CommentEnd)
|
||||||
|
then begin
|
||||||
|
// comment already exists
|
||||||
|
exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
ClassStartComment:=GetIndentStr(Indent)
|
||||||
|
+'{ '+ExtractClassName(CodeCompleteClassNode,false)+' }';
|
||||||
|
ASourceChangeCache.Replace(gtEmptyLine,gtEmptyLine,InsertPos,InsertPos,
|
||||||
|
ClassStartComment);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
@ -223,6 +223,7 @@ type
|
|||||||
procedure MoveCursorToCleanPos(ACleanPos: PChar);
|
procedure MoveCursorToCleanPos(ACleanPos: PChar);
|
||||||
procedure MoveCursorToAtomPos(const AnAtomPos: TAtomPosition);
|
procedure MoveCursorToAtomPos(const AnAtomPos: TAtomPosition);
|
||||||
procedure MoveCursorToNearestAtom(ACleanPos: integer);
|
procedure MoveCursorToNearestAtom(ACleanPos: integer);
|
||||||
|
procedure MoveCursorToLastNodeAtom(ANode: TCodeTreeNode);
|
||||||
function IsPCharInSrc(ACleanPos: PChar): boolean;
|
function IsPCharInSrc(ACleanPos: PChar): boolean;
|
||||||
procedure MoveHybridCursorToPos(DirtyPos: PChar);
|
procedure MoveHybridCursorToPos(DirtyPos: PChar);
|
||||||
function GetHybridCursorStart: integer;
|
function GetHybridCursorStart: integer;
|
||||||
@ -1776,6 +1777,19 @@ begin
|
|||||||
MoveCursorToCleanPos(BestPos);
|
MoveCursorToCleanPos(BestPos);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TCustomCodeTool.MoveCursorToLastNodeAtom(ANode: TCodeTreeNode);
|
||||||
|
var
|
||||||
|
BestPos: LongInt;
|
||||||
|
begin
|
||||||
|
MoveCursorToNodeStart(ANode);
|
||||||
|
BestPos:=CurPos.StartPos;
|
||||||
|
while (CurPos.EndPos<=ANode.EndPos) and (CurPos.StartPos<=SrcLen) do begin
|
||||||
|
BestPos:=CurPos.StartPos;
|
||||||
|
ReadNextAtom;
|
||||||
|
end;
|
||||||
|
MoveCursorToCleanPos(BestPos);
|
||||||
|
end;
|
||||||
|
|
||||||
function TCustomCodeTool.IsPCharInSrc(ACleanPos: PChar): boolean;
|
function TCustomCodeTool.IsPCharInSrc(ACleanPos: PChar): boolean;
|
||||||
var NewPos: integer;
|
var NewPos: integer;
|
||||||
begin
|
begin
|
||||||
|
@ -170,7 +170,7 @@ type
|
|||||||
function FindFormAncestor(const UpperClassName: string;
|
function FindFormAncestor(const UpperClassName: string;
|
||||||
var AncestorClassName: string): boolean;
|
var AncestorClassName: string): boolean;
|
||||||
|
|
||||||
// form components
|
// published variables
|
||||||
function FindPublishedVariable(const UpperClassName, UpperVarName: string;
|
function FindPublishedVariable(const UpperClassName, UpperVarName: string;
|
||||||
ExceptionOnClassNotFound: boolean): TCodeTreeNode;
|
ExceptionOnClassNotFound: boolean): TCodeTreeNode;
|
||||||
function AddPublishedVariable(const UpperClassName,VarName, VarType: string;
|
function AddPublishedVariable(const UpperClassName,VarName, VarType: string;
|
||||||
@ -258,6 +258,12 @@ type
|
|||||||
function GetIDEDirectives(DirectiveList: TStrings): boolean;
|
function GetIDEDirectives(DirectiveList: TStrings): boolean;
|
||||||
function SetIDEDirectives(DirectiveList: TStrings;
|
function SetIDEDirectives(DirectiveList: TStrings;
|
||||||
SourceChangeCache: TSourceChangeCache): boolean;
|
SourceChangeCache: TSourceChangeCache): boolean;
|
||||||
|
|
||||||
|
// comments
|
||||||
|
function FindCommentInFront(const StartPos: TCodeXYPosition;
|
||||||
|
const CommentText: string; InvokeBuildTree, SearchInParentNode,
|
||||||
|
WithCommentBounds, CaseSensitive, IgnoreSpaces: boolean;
|
||||||
|
out CommentStart, CommentEnd: TCodeXYPosition): boolean;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -3163,6 +3169,186 @@ begin
|
|||||||
Result:=true;
|
Result:=true;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TStandardCodeTool.FindCommentInFront(const StartPos: TCodeXYPosition;
|
||||||
|
const CommentText: string;
|
||||||
|
InvokeBuildTree, SearchInParentNode, WithCommentBounds, CaseSensitive,
|
||||||
|
IgnoreSpaces: boolean;
|
||||||
|
out CommentStart, CommentEnd: TCodeXYPosition): boolean;
|
||||||
|
// searches a comment in front.
|
||||||
|
var
|
||||||
|
FoundStartPos: LongInt;
|
||||||
|
FoundEndPos: LongInt;
|
||||||
|
|
||||||
|
procedure CompareComment(StartPos, EndPos: integer);
|
||||||
|
var
|
||||||
|
Found: LongInt;
|
||||||
|
CompareStartPos: LongInt;
|
||||||
|
CompareEndPos: LongInt;
|
||||||
|
begin
|
||||||
|
//debugln('CompareComment "',copy(Src,StartPos,EndPos-StartPos),'"');
|
||||||
|
|
||||||
|
CompareStartPos:=StartPos;
|
||||||
|
CompareEndPos:=EndPos;
|
||||||
|
if not WithCommentBounds then begin
|
||||||
|
// chomp comment boundaries
|
||||||
|
case Src[CompareStartPos] of
|
||||||
|
'/','(': inc(CompareStartPos,2);
|
||||||
|
'{': inc(CompareStartPos,1);
|
||||||
|
end;
|
||||||
|
case Src[CompareEndPos-1] of
|
||||||
|
'}': dec(CompareEndPos);
|
||||||
|
')': dec(CompareEndPos,2);
|
||||||
|
#10,#13:
|
||||||
|
begin
|
||||||
|
dec(CompareEndPos);
|
||||||
|
if (Src[CompareEndPos-1] in [#10,#13])
|
||||||
|
and (Src[CompareEndPos-1]<>Src[CompareEndPos]) then
|
||||||
|
dec(CompareEndPos);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
if IgnoreSpaces then begin
|
||||||
|
//debugln('Compare: "',copy(Src,CompareStartPos,CompareEndPos-CompareStartPos),'"',
|
||||||
|
// ' "',CommentText,'"');
|
||||||
|
Found:=CompareTextIgnoringSpace(
|
||||||
|
@Src[CompareStartPos],CompareEndPos-CompareStartPos,
|
||||||
|
@CommentText[1],length(CommentText),
|
||||||
|
CaseSensitive);
|
||||||
|
end else begin
|
||||||
|
Found:=CompareText(@Src[CompareStartPos],CompareEndPos-CompareStartPos,
|
||||||
|
@CommentText[1],length(CommentText),
|
||||||
|
CaseSensitive);
|
||||||
|
end;
|
||||||
|
if Found=0 then begin
|
||||||
|
FoundStartPos:=StartPos;
|
||||||
|
FoundEndPos:=EndPos;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
CleanCursorPos: integer;
|
||||||
|
ANode: TCodeTreeNode;
|
||||||
|
PrevNode: TCodeTreeNode;
|
||||||
|
p: LongInt;
|
||||||
|
CommentLvl: Integer;
|
||||||
|
CommentStartPos: LongInt;
|
||||||
|
begin
|
||||||
|
Result:=false;
|
||||||
|
if CommentText='' then exit;
|
||||||
|
|
||||||
|
{debugln('TStandardCodeTool.FindCommentInFront A CommentText="',CommentText,'" ',
|
||||||
|
' InvokeBuildTree='+dbgs(InvokeBuildTree),
|
||||||
|
' SearchInParentNode='+dbgs(SearchInParentNode),
|
||||||
|
' WithCommentBounds='+dbgs(WithCommentBounds),
|
||||||
|
' CaseSensitive='+dbgs(CaseSensitive),
|
||||||
|
' IgnoreSpaces='+dbgs(IgnoreSpaces));}
|
||||||
|
|
||||||
|
// parse source and find clean positions
|
||||||
|
if InvokeBuildTree then
|
||||||
|
BuildTreeAndGetCleanPos(trAll,StartPos,CleanCursorPos,[])
|
||||||
|
else
|
||||||
|
if CaretToCleanPos(StartPos,CleanCursorPos)<>0 then
|
||||||
|
exit;
|
||||||
|
|
||||||
|
// find node
|
||||||
|
ANode:=FindDeepestNodeAtPos(CleanCursorPos,true);
|
||||||
|
if (ANode=nil) then exit;
|
||||||
|
|
||||||
|
if SearchInParentNode and (ANode.Parent<>nil) then
|
||||||
|
ANode:=ANode.Parent;
|
||||||
|
{ find end of last atom in front of node
|
||||||
|
for example:
|
||||||
|
uses classes;
|
||||||
|
|
||||||
|
// Comment
|
||||||
|
type
|
||||||
|
|
||||||
|
If ANode is the 'type' block, the position after the semicolon is searched
|
||||||
|
}
|
||||||
|
PrevNode:=ANode.Prior;
|
||||||
|
if PrevNode<>nil then begin
|
||||||
|
MoveCursorToLastNodeAtom(PrevNode);
|
||||||
|
end else begin
|
||||||
|
MoveCursorToCleanPos(ANode.StartPos);
|
||||||
|
end;
|
||||||
|
|
||||||
|
//debugln('TStandardCodeTool.FindCommentInFront B Area="',copy(Src,CurPos.StartPos,CleanCursorPos-CurPos.StartPos),'"');
|
||||||
|
|
||||||
|
FoundStartPos:=-1;
|
||||||
|
repeat
|
||||||
|
p:=CurPos.EndPos;
|
||||||
|
//debugln('TStandardCodeTool.FindCommentInFront Atom=',GetAtom);
|
||||||
|
|
||||||
|
// read space and comment till next atom
|
||||||
|
CommentLvl:=0;
|
||||||
|
while true do begin
|
||||||
|
case Src[p] of
|
||||||
|
#0:
|
||||||
|
if p>SrcLen then
|
||||||
|
break
|
||||||
|
else
|
||||||
|
inc(p);
|
||||||
|
#1..#32:
|
||||||
|
inc(p);
|
||||||
|
'{': // pascal comment
|
||||||
|
begin
|
||||||
|
CommentLvl:=1;
|
||||||
|
CommentStartPos:=p;
|
||||||
|
inc(p);
|
||||||
|
while true do begin
|
||||||
|
case Src[p] of
|
||||||
|
#0: if p>SrcLen then break;
|
||||||
|
'{': if Scanner.NestedComments then inc(CommentLvl);
|
||||||
|
'}':
|
||||||
|
begin
|
||||||
|
dec(CommentLvl);
|
||||||
|
if CommentLvl=0 then break;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
inc(p);
|
||||||
|
end;
|
||||||
|
inc(p);
|
||||||
|
CompareComment(CommentStartPos,p);
|
||||||
|
end;
|
||||||
|
'/': // Delphi comment
|
||||||
|
if (Src[p+1]<>'/') then begin
|
||||||
|
break;
|
||||||
|
end else begin
|
||||||
|
CommentStartPos:=p;
|
||||||
|
inc(p,2);
|
||||||
|
while (not (Src[p] in [#10,#13,#0])) do
|
||||||
|
inc(p);
|
||||||
|
inc(p);
|
||||||
|
if (p<=SrcLen) and (Src[p] in [#10,#13])
|
||||||
|
and (Src[p-1]<>Src[p]) then
|
||||||
|
inc(p);
|
||||||
|
CompareComment(CommentStartPos,p);
|
||||||
|
end;
|
||||||
|
'(': // old turbo pascal comment
|
||||||
|
if (Src[p+1]<>'*') then begin
|
||||||
|
break;
|
||||||
|
end else begin
|
||||||
|
CommentStartPos:=p;
|
||||||
|
inc(p,3);
|
||||||
|
while (p<=SrcLen)
|
||||||
|
and ((Src[p-1]<>'*') or (Src[p]<>')')) do
|
||||||
|
inc(p);
|
||||||
|
inc(p);
|
||||||
|
CompareComment(CommentStartPos,p);
|
||||||
|
end;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
ReadNextAtom;
|
||||||
|
until (CurPos.EndPos>=CleanCursorPos) or (CurPos.EndPos>=SrcLen);
|
||||||
|
|
||||||
|
Result:=(FoundStartPos>=1)
|
||||||
|
and CleanPosToCaret(FoundStartPos,CommentStart)
|
||||||
|
and CleanPosToCaret(FoundEndPos,CommentEnd);
|
||||||
|
end;
|
||||||
|
|
||||||
function TStandardCodeTool.GatherResourceStringsWithValue(
|
function TStandardCodeTool.GatherResourceStringsWithValue(
|
||||||
const CursorPos: TCodeXYPosition; const StringValue: string;
|
const CursorPos: TCodeXYPosition; const StringValue: string;
|
||||||
PositionList: TCodeXYPositions): boolean;
|
PositionList: TCodeXYPositions): boolean;
|
||||||
|
Loading…
Reference in New Issue
Block a user