|
@@ -18,6 +18,8 @@ type
|
|
|
private
|
|
|
CodeCompleteLB : PAdvancedListBox;
|
|
|
RB : PRadioButtons;
|
|
|
+ CB : PCheckBoxes;
|
|
|
+ MinInputL,InputL : PInputLine;
|
|
|
procedure Add;
|
|
|
procedure Edit;
|
|
|
procedure Delete;
|
|
@@ -27,6 +29,8 @@ function FPCompleteCodeWord(const WordS: string; var Text: string): boolean;
|
|
|
|
|
|
procedure InitCodeComplete;
|
|
|
function LoadCodeComplete(var S: TStream): boolean;
|
|
|
+procedure AddStandardUnitsToCodeComplete;
|
|
|
+procedure AddAvailableUnitsToCodeComplete(OnlyStandard : boolean);
|
|
|
function StoreCodeComplete(var S: TStream): boolean;
|
|
|
procedure DoneCodeComplete;
|
|
|
|
|
@@ -35,19 +39,20 @@ type
|
|
|
TCodeCompleteCase = (ccc_unchanged, ccc_lower, ccc_upper, ccc_mixed);
|
|
|
const
|
|
|
CodeCompleteCase : TCodeCompleteCase = ccc_unchanged;
|
|
|
+ UnitsCodeCompleteWords : PCodeCompleteWordList = nil;
|
|
|
|
|
|
procedure RegisterCodeComplete;
|
|
|
|
|
|
implementation
|
|
|
|
|
|
-uses Views,MsgBox,
|
|
|
+uses Views,MsgBox,Validate,
|
|
|
{$ifdef FVISION}
|
|
|
FVConsts,
|
|
|
{$else}
|
|
|
Commands,
|
|
|
{$endif}
|
|
|
- WEditor,
|
|
|
- FPConst,FPString,FPViews;
|
|
|
+ WEditor, FPCompil, FPVars, FPSymbol, BrowCol,
|
|
|
+ App,FPConst,FPString,FPViews;
|
|
|
|
|
|
{$ifndef NOOBJREG}
|
|
|
const
|
|
@@ -61,14 +66,83 @@ const
|
|
|
|
|
|
function FPCompleteCodeWord(const WordS: string; var Text: string): boolean;
|
|
|
var OK: boolean;
|
|
|
- Index: sw_integer;
|
|
|
+ CIndex, Index, i : sw_integer;
|
|
|
+ St, UpWordS : string;
|
|
|
begin
|
|
|
+ if ShowOnlyUnique then
|
|
|
+ UpWordS:=UpCaseStr(WordS);
|
|
|
OK:=Assigned(CodeCompleteWords);
|
|
|
if OK then
|
|
|
begin
|
|
|
- Text:=CodeCompleteWords^.Lookup(WordS,Index);
|
|
|
+ Text:=CodeCompleteWords^.Lookup(WordS,CIndex);
|
|
|
+ OK:=(CIndex<>-1) and (length(Text)<>length(WordS));
|
|
|
+ if OK and ShowOnlyUnique and (CIndex<CodeCompleteWords^.Count-1) then
|
|
|
+ begin
|
|
|
+ St:=PString(CodeCompleteWords^.At(CIndex+1))^;
|
|
|
+ if (UpCaseStr(Copy(St,1,length(WordS)))=UpWordS) then
|
|
|
+ begin
|
|
|
+ if UpCase(st[Length(UpWordS)+1])<>Upcase(Text[Length(UpWordS)+1]) then
|
|
|
+ begin
|
|
|
+ Text:='';
|
|
|
+ FPCompleteCodeWord:=false;
|
|
|
+ exit;
|
|
|
+ end
|
|
|
+ else
|
|
|
+ { only give the common part }
|
|
|
+ begin
|
|
|
+ i:=Length(UpWordS)+1;
|
|
|
+ while (i<=length(st)) and (i<=length(text)) and (UpCase(st[i])=Upcase(Text[i])) do
|
|
|
+ inc(i);
|
|
|
+ SetLength(Text,i-1);
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+ if (ShowOnlyUnique or not OK) and Assigned(UnitsCodeCompleteWords) then
|
|
|
+ begin
|
|
|
+ Text:=UnitsCodeCompleteWords^.Lookup(WordS,Index);
|
|
|
OK:=(Index<>-1) and (length(Text)<>length(WordS));
|
|
|
+ if ShowOnlyUnique and (Index<UnitsCodeCompleteWords^.Count-1) then
|
|
|
+ begin
|
|
|
+ St:=PString(UnitsCodeCompleteWords^.At(Index+1))^;
|
|
|
+ if UpCaseStr(Copy(St,1,length(WordS)))=UpWordS then
|
|
|
+ begin
|
|
|
+ if UpCase(st[Length(UpWordS)+1])<>Upcase(Text[Length(UpWordS)+1]) then
|
|
|
+ begin
|
|
|
+ Text:='';
|
|
|
+ FPCompleteCodeWord:=false;
|
|
|
+ exit;
|
|
|
+ end
|
|
|
+ else
|
|
|
+ { only give the common part }
|
|
|
+ begin
|
|
|
+ i:=Length(UpWordS)+1;
|
|
|
+ while (i<=length(st)) and (i<=length(text)) and (UpCase(st[i])=Upcase(Text[i])) do
|
|
|
+ inc(i);
|
|
|
+ SetLength(Text,i-1);
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
end;
|
|
|
+
|
|
|
+ if ShowOnlyUnique and (Index<>-1) and (CIndex<>-1) then
|
|
|
+ begin
|
|
|
+ St:=PString(CodeCompleteWords^.At(CIndex+1))^;
|
|
|
+ if UpCase(st[Length(UpWordS)+1])<>Upcase(Text[Length(UpWordS)+1]) then
|
|
|
+ begin
|
|
|
+ Text:='';
|
|
|
+ FPCompleteCodeWord:=false;
|
|
|
+ exit;
|
|
|
+ end
|
|
|
+ else
|
|
|
+ { only give the common part }
|
|
|
+ begin
|
|
|
+ i:=Length(UpWordS)+1;
|
|
|
+ while (i<=length(st)) and (i<=length(text)) and (UpCase(st[i])=Upcase(Text[i])) do
|
|
|
+ inc(i);
|
|
|
+ SetLength(Text,i-1);
|
|
|
+ end;
|
|
|
+ end;
|
|
|
if OK=false then Text:=''
|
|
|
else case CodeCompleteCase of
|
|
|
ccc_upper : Text:=UpcaseStr(Text);
|
|
@@ -97,9 +171,89 @@ begin
|
|
|
}
|
|
|
end;
|
|
|
|
|
|
+
|
|
|
+procedure AddAvailableUnitsToCodeComplete(OnlyStandard : boolean);
|
|
|
+
|
|
|
+var
|
|
|
+ I : sw_integer;
|
|
|
+ Overflow: boolean;
|
|
|
+ Level : longint;
|
|
|
+ UpStandardUnits : string;
|
|
|
+
|
|
|
+ procedure InsertInS(P: PSymbol); {$ifndef FPC}far;{$endif}
|
|
|
+
|
|
|
+ procedure InsertItemsInS(P: PSymbolCollection);
|
|
|
+ var I: Sw_integer;
|
|
|
+ begin
|
|
|
+ for I:=0 to P^.Count-1 do
|
|
|
+ InsertInS(P^.At(I));
|
|
|
+ end;
|
|
|
+
|
|
|
+ begin
|
|
|
+ Inc(level);
|
|
|
+ if UnitsCodeCompleteWords^.Count=MaxCollectionSize then
|
|
|
+ begin Overflow:=true; Exit; end;
|
|
|
+ UnitsCodeCompleteWords^.Insert(NewStr(P^.GetName));
|
|
|
+ { this is wrong because it inserted args or locals of proc
|
|
|
+ in the globals list !! PM}
|
|
|
+ if (P^.Items<>nil) and (level=1) and
|
|
|
+ (not OnlyStandard or (Pos(P^.GetName+',',UpStandardUnits)>0)) then
|
|
|
+ InsertItemsInS(P^.Items);
|
|
|
+ Dec(level);
|
|
|
+ end;
|
|
|
+
|
|
|
+begin
|
|
|
+ if OnlyStandard then
|
|
|
+ UpStandardunits:=UpCaseStr(StandardUnits)+',';
|
|
|
+ if IsSymbolInfoAvailable then
|
|
|
+ begin
|
|
|
+ if Assigned(UnitsCodeCompleteWords) then
|
|
|
+ begin
|
|
|
+ Dispose(UnitsCodeCompleteWords,done);
|
|
|
+ UnitsCodeCompleteWords:=nil;
|
|
|
+ end;
|
|
|
+
|
|
|
+ New(UnitsCodeCompleteWords, Init(10,10));
|
|
|
+ level:=0;
|
|
|
+ Overflow:=false;
|
|
|
+ BrowCol.Modules^.ForEach(@InsertInS);
|
|
|
+ { if Overflow then
|
|
|
+ WarningBox(msg_toomanysymbolscantdisplayall,nil); }
|
|
|
+ end;
|
|
|
+end;
|
|
|
+
|
|
|
+procedure AddStandardUnitsToCodeComplete;
|
|
|
+var
|
|
|
+ HiddenSource : PSourceWindow;
|
|
|
+ R : TRect;
|
|
|
+begin
|
|
|
+ Desktop^.GetExtent(R);
|
|
|
+ New(HiddenSource,init(R,''));
|
|
|
+ CompilingHiddenFile:=HiddenSource;
|
|
|
+ { compile a dummy file to get symbol info }
|
|
|
+ with HiddenSource^.Editor^ do
|
|
|
+ begin
|
|
|
+ FileName:='__fp__.pp';
|
|
|
+ if StandardUnits<>'' then
|
|
|
+ begin
|
|
|
+ AddLine('uses');
|
|
|
+ Addline(StandardUnits+';');
|
|
|
+ end;
|
|
|
+ Addline('begin');
|
|
|
+ Addline('end.');
|
|
|
+ SaveFile;
|
|
|
+ end;
|
|
|
+ DoCompile(cCompile);
|
|
|
+ AddAvailableUnitsToCodeComplete(true);
|
|
|
+ { Now add the interface declarations to the Code Complete list }
|
|
|
+ CompilingHiddenFile:=nil;
|
|
|
+ Dispose(HiddenSource,Done);
|
|
|
+end;
|
|
|
+
|
|
|
function LoadCodeComplete(var S: TStream): boolean;
|
|
|
var C: PCodeCompleteWordList;
|
|
|
OK: boolean;
|
|
|
+ StPtr : PString;
|
|
|
begin
|
|
|
New(C, Load(S));
|
|
|
OK:=Assigned(C) and (S.Status=stOk);
|
|
@@ -108,6 +262,14 @@ begin
|
|
|
if Assigned(CodeCompleteWords) then Dispose(CodeCompleteWords, Done);
|
|
|
CodeCompleteWords:=C;
|
|
|
S.Read(CodeCompleteCase,Sizeof(TCodeCompleteCase));
|
|
|
+ S.Read(UseStandardUnitsInCodeComplete,Sizeof(UseStandardUnitsInCodeComplete));
|
|
|
+ S.Read(UseAllUnitsInCodeComplete,Sizeof(UseAllUnitsInCodeComplete));
|
|
|
+ S.Read(ShowOnlyUnique,Sizeof(ShowOnlyUnique));
|
|
|
+ S.Read(CodeCompleteMinLen,Sizeof(CodeCompleteMinLen));
|
|
|
+ StPtr:=S.ReadStr;
|
|
|
+ StandardUnits:=GetStr(StPtr);
|
|
|
+ if assigned(StPtr) then
|
|
|
+ FreeMem(StPtr,Length(StandardUnits)+1);
|
|
|
end
|
|
|
else
|
|
|
if Assigned(C) then
|
|
@@ -123,6 +285,11 @@ begin
|
|
|
begin
|
|
|
CodeCompleteWords^.Store(S);
|
|
|
S.Write(CodeCompleteCase,Sizeof(TCodeCompleteCase));
|
|
|
+ S.Write(UseStandardUnitsInCodeComplete,Sizeof(UseStandardUnitsInCodeComplete));
|
|
|
+ S.Write(UseAllUnitsInCodeComplete,Sizeof(UseAllUnitsInCodeComplete));
|
|
|
+ S.Write(ShowOnlyUnique,Sizeof(ShowOnlyUnique));
|
|
|
+ S.Write(CodeCompleteMinLen,Sizeof(CodeCompleteMinLen));
|
|
|
+ S.WriteStr(@StandardUnits);
|
|
|
OK:=OK and (S.Status=stOK);
|
|
|
end;
|
|
|
StoreCodeComplete:=OK;
|
|
@@ -132,6 +299,11 @@ procedure DoneCodeComplete;
|
|
|
begin
|
|
|
if Assigned(CodeCompleteWords) then Dispose(CodeCompleteWords, Done);
|
|
|
CodeCompleteWords:=nil;
|
|
|
+ if Assigned(UnitsCodeCompleteWords) then
|
|
|
+ begin
|
|
|
+ Dispose(UnitsCodeCompleteWords,done);
|
|
|
+ UnitsCodeCompleteWords:=nil;
|
|
|
+ end;
|
|
|
end;
|
|
|
|
|
|
constructor TCodeCompleteDialog.Init;
|
|
@@ -139,11 +311,13 @@ var R,R2,R3: TRect;
|
|
|
Items: PSItem;
|
|
|
SB: PScrollBar;
|
|
|
begin
|
|
|
- R.Assign(0,0,46,20);
|
|
|
+ R.Assign(0,0,50,22);
|
|
|
inherited Init(R,dialog_codecomplete);
|
|
|
HelpCtx:=hcCodeCompleteOptions;
|
|
|
+
|
|
|
+ { name list dialog }
|
|
|
GetExtent(R); R.Grow(-3,-2); Inc(R.A.Y); R3.Copy(R); Dec(R.B.X,12);
|
|
|
- Dec(R.B.Y,5);
|
|
|
+ Dec(R.B.Y,7);
|
|
|
R2.Copy(R); R2.Move(1,0); R2.A.X:=R2.B.X-1;
|
|
|
New(SB, Init(R2)); Insert(SB);
|
|
|
New(CodeCompleteLB, Init(R,1,SB));
|
|
@@ -151,7 +325,8 @@ begin
|
|
|
R2.Copy(R); R2.Move(0,-1); R2.B.Y:=R2.A.Y+1; Dec(R2.A.X);
|
|
|
Insert(New(PLabel, Init(R2, label_codecomplete_keywords, CodeCompleteLB)));
|
|
|
|
|
|
- R.Copy(R3); R.A.Y:=R.B.Y-4; Dec(R.B.X,14); Inc(R.A.X);
|
|
|
+ { Case choice }
|
|
|
+ R.Copy(R3); Dec(R.B.Y,2); R.A.Y:=R.B.Y-4; Inc(R.A.X); R.B.X:=R.A.X+15;
|
|
|
Items:=NewSItem('Unc~h~anged',
|
|
|
NewSItem('~L~ower',
|
|
|
NewSItem('~U~pper',
|
|
@@ -162,6 +337,38 @@ begin
|
|
|
Insert(New(PLabel, Init(R2, 'Case handling', RB)));
|
|
|
Insert(RB);
|
|
|
|
|
|
+ { Mininum length inputline }
|
|
|
+ R.Copy(R3); R.A.Y:=R.B.Y-7;R.B.Y:=R.A.Y+1; Dec(R.B.X); R.A.X:=R.B.X -5;
|
|
|
+ New(MinInputL, Init(R,5));
|
|
|
+ MinInputL^.SetValidator(New(PRangeValidator, Init(1,255)));
|
|
|
+ Insert(MinInputL);
|
|
|
+ R2.Copy(R); R2.A.X:=20;Dec(R2.B.X,5);
|
|
|
+ Insert(New(PLabel, Init(R2, 'Min. length', MinInputL)));
|
|
|
+
|
|
|
+ { Standard/all units booleans }
|
|
|
+ Items:=nil;
|
|
|
+ Items:=NewSItem('Add standard units', Items);
|
|
|
+ Items:=NewSItem('Add available units', Items);
|
|
|
+ Items:=NewSItem('Show only unique', Items);
|
|
|
+ R.Copy(R3); R.A.Y:=R.B.Y-5;R.B.Y:=R.A.Y+3; Inc(R.A.X,18); Dec(R.B.X);
|
|
|
+ New(CB, Init(R, Items));
|
|
|
+ Insert(CB);
|
|
|
+ R2.Copy(R); R2.Move(0,-1); R2.B.Y:=R2.A.Y+1; Dec(R2.A.X);
|
|
|
+ Insert(New(PLabel, Init(R2, 'Unit handling', CB)));
|
|
|
+ R2.Copy(R); R2.Move(0,-1); R2.B.Y:=R2.A.Y+1;
|
|
|
+ If UseStandardUnitsInCodeComplete then
|
|
|
+ CB^.Press(0);
|
|
|
+ If UseAllUnitsInCodeComplete then
|
|
|
+ CB^.Press(1);
|
|
|
+
|
|
|
+ { Standard unit name boolean }
|
|
|
+ R.Copy(R3); R.A.Y:=R.B.Y-1; Inc(R.A.X); Dec(R.B.X);
|
|
|
+ New(InputL,Init(R,255));
|
|
|
+ Insert(InputL);
|
|
|
+ InputL^.SetValidator(New(PFilterValidator,Init(NumberChars+AlphaChars+[','])));
|
|
|
+ R2.Copy(R); R2.Move(0,-1); R2.B.Y:=R2.A.Y+1; Dec(R2.A.X);R2.B.X:=R2.A.X+25;
|
|
|
+ Insert(New(PLabel, Init(R2, '~S~tandard unit list', InputL)));
|
|
|
+
|
|
|
R.Copy(R3); R.A.X:=R.B.X-10; R.B.Y:=R.A.Y+2;
|
|
|
Insert(New(PButton, Init(R, button_OK, cmOK, bfNormal)));
|
|
|
R.Move(0,2);
|
|
@@ -215,19 +422,37 @@ end;
|
|
|
function TCodeCompleteDialog.Execute: Word;
|
|
|
var R: word;
|
|
|
C: PCodeCompleteWordList;
|
|
|
- I: integer;
|
|
|
+ NewVal, I: integer;
|
|
|
+ NewValStr : string;
|
|
|
begin
|
|
|
New(C, Init(10,20));
|
|
|
if Assigned(CodeCompleteWords) then
|
|
|
for I:=0 to CodeCompleteWords^.Count-1 do
|
|
|
C^.Insert(NewStr(GetStr(CodeCompleteWords^.At(I))));
|
|
|
CodeCompleteLB^.NewList(C);
|
|
|
+ InputL^.SetData(StandardUnits);
|
|
|
+ NewValStr:=IntToStr(CodeCompleteMinLen);
|
|
|
+ MinInputL^.SetData(NewValStr);
|
|
|
R:=inherited Execute;
|
|
|
if R=cmOK then
|
|
|
begin
|
|
|
if Assigned(CodeCompleteWords) then Dispose(CodeCompleteWords, Done);
|
|
|
CodeCompleteWords:=C;
|
|
|
CodeCompleteCase:=TCodeCompleteCase(RB^.Value);
|
|
|
+ UseStandardUnitsInCodeComplete:=CB^.Mark(0);
|
|
|
+ UseAllUnitsInCodeComplete:=CB^.Mark(1);
|
|
|
+ if UseStandardUnitsInCodeComplete and (not UseAllUnitsInCodeComplete or not assigned(UnitsCodeCompleteWords)) and
|
|
|
+ ((StandardUnits<>GetStr(InputL^.Data)) or not assigned(UnitsCodeCompleteWords)) then
|
|
|
+ begin
|
|
|
+ InputL^.GetData(StandardUnits);
|
|
|
+ AddStandardUnitsToCodeComplete;
|
|
|
+ end
|
|
|
+ else
|
|
|
+ InputL^.GetData(StandardUnits);
|
|
|
+ MinInputL^.GetData(NewValStr);
|
|
|
+ NewVal:=StrToInt(NewValStr);
|
|
|
+ if NewVal>0 then
|
|
|
+ CodeCompleteMinLen:=NewVal;
|
|
|
end
|
|
|
else
|
|
|
Dispose(C, Done);
|