implemented tab completion for word and identifier completion

git-svn-id: trunk@5031 -
This commit is contained in:
mattias 2004-01-08 22:15:39 +00:00
parent f8cac4fbb4
commit 2a402038bb
6 changed files with 192 additions and 27 deletions

View File

@ -159,6 +159,7 @@ type
function CreateIdentifier(const Ident: string): PChar;
function StartUpAtomInFrontIs(const s: string): boolean;
function StartUpAtomBehindIs(const s: string): boolean;
function CompletePrefix(const OldPrefix: string): string;
public
property Context: TFindContext read FContext write FContext;
property ContextFlags: TIdentifierListContextFlags
@ -577,6 +578,41 @@ begin
Result:=StartContext.Tool.FreeUpAtomIs(StartAtomBehind,s);
end;
function TIdentifierList.CompletePrefix(const OldPrefix: string): string;
// search all identifiers beginning with Prefix
// and return the biggest prefix of all of them
var
AnAVLNode: TAVLTreeNode;
CurItem: TIdentifierListItem;
FoundFirst: Boolean;
SamePos: Integer;
begin
Result:=Prefix;
FoundFirst:=false;
AnAVLNode:=FItems.FindLowest;
while AnAVLNode<>nil do begin
CurItem:=TIdentifierListItem(AnAVLNode.Data);
if (CurItem.Identifier<>nil)
and ComparePrefixIdent(PChar(Prefix),CurItem.Identifier) then begin
if not FoundFirst then begin
Result:=GetIdentifier(CurItem.Identifier);
FoundFirst:=true;
end else begin
SamePos:=length(Prefix);
while (SamePos<length(Result))
and (UpChars[CurItem.Identifier[SamePos]]=UpChars[Result[SamePos+1]])
do
inc(SamePos);
if SamePos<length(Result) then begin
Result:=copy(Result,1,SamePos);
if length(Result)=length(Prefix) then exit;
end;
end;
end;
AnAVLNode:=FItems.FindSuccessor(AnAVLNode);
end;
end;
{ TIdentCompletionTool }
function TIdentCompletionTool.CollectAllIdentifiers(

View File

@ -79,6 +79,7 @@ type
FAnsi: boolean;
{$IFDEF SYN_LAZARUS}
FOnSearchPosition:TSynBaseCompletionSearchPosition;
FOnKeyCompletePrefix: TNotifyEvent;
FTextColor: TColor;
FTextSelectedColor: TColor;
{$ENDIF}
@ -125,6 +126,7 @@ type
property FontHeight:integer read FFontHeight write SetFontHeight;
property OnSearchPosition:TSynBaseCompletionSearchPosition
read FOnSearchPosition write FOnSearchPosition;
property OnKeyCompletePrefix: TNotifyEvent read FOnKeyCompletePrefix write FOnKeyCompletePrefix;
property TextColor: TColor read FTextColor write FTextColor;
property TextSelectedColor: TColor
read FTextSelectedColor write FTextSelectedColor;
@ -165,6 +167,8 @@ type
procedure SetFontHeight(NewFontHeight :integer);
function GetOnSearchPosition:TSynBaseCompletionSearchPosition;
procedure SetOnSearchPosition(NewValue :TSynBaseCompletionSearchPosition);
function GetOnKeyCompletePrefix: TNotifyEvent;
procedure SetOnKeyCompletePrefix(const AValue: TNotifyEvent);
{$ENDIF}
public
constructor Create(AOwner: TComponent); override;
@ -192,6 +196,8 @@ type
property FontHeight: integer read GetFontHeight write SetFontHeight;
property OnSearchPosition: TSynBaseCompletionSearchPosition
read GetOnSearchPosition write SetOnSearchPosition;
property OnKeyCompletePrefix: TNotifyEvent read GetOnKeyCompletePrefix
write SetOnKeyCompletePrefix;
{$ENDIF}
property ClSelect: TColor read GetClSelect write SetClSelect;
property AnsiStrings: boolean read SFAnsi write RFAnsi;
@ -372,6 +378,13 @@ begin
if Assigned(OnKeyDelete) then OnKeyDelete(Self);
CurrentString := Copy(CurrentString, 1, Length(CurrentString) - 1);
end;
{$IFDEF SYN_LAZARUS}
VK_TAB:
begin
if Assigned(OnKeyCompletePrefix) then OnKeyCompletePrefix(Self);
Key:=VK_UNKNOWN;
end;
{$ENDIF}
end;
{$ifdef SYN_LAZARUS}
Invalidate;
@ -385,7 +398,7 @@ begin
if Assigned(OnKeyPress) then
OnKeyPress(self, Key);
{$ifdef SYN_LAZARUS}
if Key in [#33..'z'] then
if Key in [#33..#255] then
CurrentString := CurrentString + key;
{$else}
CurrentString := CurrentString + key;
@ -661,6 +674,16 @@ procedure TSynBaseCompletion.SetOnSearchPosition(
begin
Form.OnSearchPosition:=NewValue;
end;
function TSynBaseCompletion.GetOnKeyCompletePrefix: TNotifyEvent;
begin
Result:=Form.OnKeyCompletePrefix;
end;
procedure TSynBaseCompletion.SetOnKeyCompletePrefix(const AValue: TNotifyEvent);
begin
Form.OnKeyCompletePrefix:=AValue;
end;
{$ENDIF}
procedure TSynBaseCompletion.Execute(s: string; x, y: integer);

View File

@ -2253,7 +2253,7 @@ procedure TEnvironmentOptionsDialog.SetupFormEditorPage(Page: integer);
Parent:=GridGroupBox;
Left:=GridColorButton.Left+GridColorButton.Width+5;
Top:=GridColorButton.Top+2;
Width:=80;
Width:=100;
Caption:=dlgGridColor;
end;
@ -2274,7 +2274,7 @@ procedure TEnvironmentOptionsDialog.SetupFormEditorPage(Page: integer);
Parent:=GridGroupBox;
Left:=ShowGridCheckBox.Left;
Top:=SnapToGridCheckBox.Top+SnapToGridCheckBox.Height+5;
Width:=80;
Width:=100;
Caption:=dlgGridX;
end;

View File

@ -432,7 +432,8 @@ type
procedure ccComplete(var Value: ansistring; Shift: TShiftState);
function OnSynCompletionPaintItem(const AKey: string; ACanvas: TCanvas;
X, Y: integer; ItemSelected: boolean; Index: integer): boolean;
procedure OnSynCompletionSearchPosition(var APosition:integer);
procedure OnSynCompletionSearchPosition(var APosition: integer);
procedure OnSynCompletionCompletePrefix(Sender : TObject);
procedure DeactivateCompletionForm;
procedure InitIdentCompletion(S: TStrings);
@ -554,7 +555,7 @@ type
procedure OnCodeTemplateTokenNotFound(Sender: TObject; AToken: string;
AnEditor: TCustomSynEdit; var Index:integer);
procedure OnWordCompletionGetSource(
var Source:TStrings; SourceIndex:integer);
var Source: TStrings; SourceIndex: integer);
function Empty: boolean;
property FormEditor : TFormEditor read FFormEditor write FFormEditor;
@ -654,13 +655,13 @@ var
// aCompletion:
// The component controlling the completion form. It is created on demand
// and killed when the IDE ends.
aCompletion : TSynCompletion;
aCompletion: TSynCompletion;
// CurCompletionControl contains aCompletion whenever the completion form is
// active
CurCompletionControl : TSynBaseCompletion;
CurCompletionControl : TSynCompletion;
CurrentCompletionType: TCompletionType;
IdentCompletionTimer : TTimer;
AWordCompletion : TWordCompletion;
AWordCompletion: TWordCompletion;
GotoDialog : TfrmGoto;
@ -2114,6 +2115,7 @@ begin
OnCodeCompletion := @ccComplete;
OnPaintItem:=@OnSynCompletionPaintItem;
OnSearchPosition:=@OnSynCompletionSearchPosition;
OnKeyCompletePrefix:=@OnSynCompletionCompletePrefix;
ShortCut:=Menus.ShortCut(VK_UNKNOWN,[]);
end;
@ -2215,8 +2217,8 @@ begin
Result:=true;
end;
procedure TSourceNotebook.OnWordCompletionGetSource(var Source:TStrings;
SourceIndex:integer);
procedure TSourceNotebook.OnWordCompletionGetSource(var Source: TStrings;
SourceIndex: integer);
var TempEditor: TSourceEditor;
i:integer;
begin
@ -2272,7 +2274,7 @@ begin
SL:=TStringList.Create;
try
for i:=0 to ItemCnt-1 do
SL.Add('Dummy');
SL.Add('Dummy'); // these entries are not shown
CurCompletionControl.ItemList:=SL;
finally
SL.Free;
@ -2306,7 +2308,7 @@ begin
CurStr:=CurCompletionControl.CurrentString;
SL:=TStringList.Create;
try
aWordCompletion.GetWordList(SL, CurStr, false, 30);
aWordCompletion.GetWordList(SL, CurStr, false, 100);
CurCompletionControl.ItemList:=SL;
finally
SL.Free;
@ -2316,6 +2318,47 @@ begin
end;
end;
procedure TSourceNotebook.OnSynCompletionCompletePrefix(Sender: TObject);
var
OldPrefix: String;
NewPrefix: String;
SL: TStringList;
AddPrefix: String;
begin
if CurCompletionControl=nil then exit;
OldPrefix:=CurCompletionControl.CurrentString;
NewPrefix:=OldPrefix;
case CurrentCompletionType of
ctIdentCompletion:
begin
NewPrefix:=CodeToolBoss.IdentifierList.CompletePrefix(OldPrefix);
end;
ctWordCompletion:
begin
aWordCompletion.CompletePrefix(OldPrefix,NewPrefix,false);
end;
end;
if NewPrefix<>OldPrefix then begin
AddPrefix:=copy(NewPrefix,length(OldPrefix)+1,length(NewPrefix));
CurCompletionControl.Editor.SelText:=AddPrefix;
CurCompletionControl.Editor.CaretXY:=
CurCompletionControl.Editor.BlockBegin;
SL:=TStringList.Create;
try
aWordCompletion.GetWordList(SL, NewPrefix, false, 100);
CurCompletionControl.ItemList:=SL;
finally
SL.Free;
end;
CurCompletionControl.CurrentString:=NewPrefix;
end;
end;
procedure TSourceNotebook.DeactivateCompletionForm;
begin
CurCompletionControl.Deactivate;
@ -2587,7 +2630,7 @@ var
NewStr: String;
ActiveEditor: TSynEdit;
Begin
CurCompletionControl := TSynBaseCompletion(Sender);
CurCompletionControl := Sender as TSynCompletion;
S := TStringList.Create;
Prefix := CurCompletionControl.CurrentString;
ActiveEditor:=GetActiveSE.EditorComponent;

View File

@ -37,17 +37,21 @@ type
FOnGetSource:TWordCompletionGetSource;
function GetWordBufferCapacity:integer;
procedure SetWordBufferCapacity(NewCapacity: integer);
function CaseInsensitiveIndexOf(const AWord:string):integer;
function CaseInsensitiveIndexOf(const AWord: string):integer;
function CaseSensitiveIndexOf(const AWord: string):integer;
public
constructor Create;
destructor Destroy; override;
procedure AddWord(const AWord:string);
property WordBufferCapacity:integer
read GetWordBufferCapacity write SetWordBufferCapacity;
procedure GetWordList(AWordList:TStrings; const Prefix:String;
CaseSensitive:boolean; MaxResults:integer);
procedure CompletePrefix(const Prefix: string; var CompletedPrefix: string;
CaseSensitive:boolean);
public
property OnGetSource:TWordCompletionGetSource
read FOnGetSource write FOnGetSource;
constructor Create;
destructor Destroy; override;
end;
implementation
@ -90,7 +94,7 @@ var i, j, Line, x, PrefixLen, MaxHash, LineLen: integer;
Hash:=0;
a:=1;
while (a<=length(ALowWord)) and (a<20) do begin
inc(Hash,ord(ALowWord[a]) and $3f);
inc(Hash,ord(ALowWord[a]) and $7f);
inc(a);
end;
Hash:=(Hash*137) mod MaxHash;
@ -128,7 +132,7 @@ begin
if CaseSensitive then begin
if copy(NewWord,1,PrefixLen)=Prefix then
Add(NewWord);
end else if uppercase(copy(NewWord,1,PrefixLen))=UpPrefix then begin
end else if CompareText(copy(NewWord,1,PrefixLen),UpPrefix)=0 then begin
if NewWord<>Prefix then
Add(NewWord)
end;
@ -193,6 +197,51 @@ begin
end;
end;
procedure TWordCompletion.CompletePrefix(const Prefix: string;
var CompletedPrefix: string; CaseSensitive: boolean);
var
WordList: TStringList;
s: string;
SamePos: Integer;
MaxPos: Integer;
i: Integer;
begin
CompletedPrefix:=Prefix;
WordList:=TStringList.Create;
try
// fetch all words with Prefix
GetWordList(WordList,Prefix,CaseSensitive,10000);
if WordList.Count=0 then exit;
// find the biggest prefix of all available words
CompletedPrefix:=WordList[0];
for i:=1 to WordList.Count-1 do begin
// stop, when it can't get shorter
if CompletedPrefix=Prefix then exit;
s:=WordList[i];
if length(s)<length(Prefix) then continue;
// count same
SamePos:=0;
MaxPos:=length(s);
if MaxPos>length(CompletedPrefix) then MaxPos:=length(CompletedPrefix);
while (SamePos<MaxPos) do begin
if CaseSensitive then begin
if s[SamePos+1]<>CompletedPrefix[SamePos+1] then
break;
end else begin
if upcase(s[SamePos+1])<>upcase(CompletedPrefix[SamePos+1]) then
break;
end;
inc(SamePos);
end;
if SamePos<length(Prefix) then continue;
if SamePos<length(CompletedPrefix) then
CompletedPrefix:=copy(CompletedPrefix,1,SamePos);
end;
finally
WordList.Free;
end;
end;
constructor TWordCompletion.Create;
begin
inherited Create;
@ -235,7 +284,7 @@ end;
procedure TWordCompletion.AddWord(const AWord:string);
var OldIndex:integer;
begin
OldIndex:=FWordBuffer.IndexOf(AWord);
OldIndex:=CaseSensitiveIndexOf(AWord);
if OldIndex>=0 then begin
// move word to the top
FWordBuffer.Move(OldIndex,FWordBuffer.Count-1);
@ -248,11 +297,16 @@ begin
end;
function TWordCompletion.CaseInsensitiveIndexOf(const AWord:string):integer;
var LowWord: string;
begin
LowWord:=lowercase(AWord);
Result:=FWordBuffer.Count-1;
while (Result>=0) and (lowercase(FWordBuffer[Result])<>LowWord) do
while (Result>=0) and (CompareText(FWordBuffer[Result],AWord)<>0) do
dec(Result);
end;
function TWordCompletion.CaseSensitiveIndexOf(const AWord: string): integer;
begin
Result:=FWordBuffer.Count-1;
while (Result>=0) and (FWordBuffer[Result]<>AWord) do
dec(Result);
end;

View File

@ -1,15 +1,24 @@
#!/usr/bin/env bash
# Wrapper for the strip command
#
# Author: Mattias Gaertner
#
# Normally just calls strip with the same parameters. Special files, which can
# not be stripped are skipped
# The redhat rpm scripts try to strip files, that can't be stripped.
# This wrapper simply skips some files.
set -e
#set -x
Params=$@
#echo "SMART STRIP $Params"
# The last parameter is the file
for p in $Params; do
File=$p
done
echo $File | grep -q '\bpalmos\b' || strip $PARAMS
echo $File | grep -q '\bpalmos\b' && exit
echo $File | grep -q '\.a$' && exit
strip $Params
# end.