From 7febec25fb90eb57aae4fb20602a71865b692fea Mon Sep 17 00:00:00 2001 From: Basile Burg Date: Sat, 17 Sep 2016 09:15:53 +0200 Subject: [PATCH] completion, put last item in front for further usage + dont store completion kind literally --- src/ce_dcd.pas | 41 ++++++++++++++-------------- src/ce_interfaces.pas | 21 +++++++++++++++ src/ce_synmemo.pas | 62 ++++++++++++++++++++++++++++++++++--------- 3 files changed, 91 insertions(+), 33 deletions(-) diff --git a/src/ce_dcd.pas b/src/ce_dcd.pas index 17ef0e02..4205b8c4 100644 --- a/src/ce_dcd.pas +++ b/src/ce_dcd.pas @@ -407,6 +407,7 @@ var i: Integer; kind: Char; item: string; + kindObj: TObject; begin if not fAvailable then exit; if not fServerListening then exit; @@ -436,28 +437,28 @@ begin kind := item[item.length]; setLength(item, item.length-2); case kind of - 'c': item += ' (class) '; - 'i': item += ' (interface) '; - 's': item += ' (struct) '; - 'u': item += ' (union) '; - 'v': item += ' (variable) '; - 'm': item += ' (member) '; - 'k': item += ' (reserved word) '; - 'f': item += ' (function) '; - 'g': item += ' (enum) '; - 'e': item += ' (enum member) '; - 'P': item += ' (package) '; - 'M': item += ' (module) '; - 'a': item += ' (array) '; - 'A': item += ' (associative array)'; - 'l': item += ' (alias) '; - 't': item += ' (template) '; - 'T': item += ' (mixin) '; + 'c': kindObj := TObject(PtrUint(dckClass)); + 'i': kindObj := TObject(PtrUint(dckInterface)); + 's': kindObj := TObject(PtrUint(dckStruct)); + 'u': kindObj := TObject(PtrUint(dckUnion)); + 'v': kindObj := TObject(PtrUint(dckVariable)); + 'm': kindObj := TObject(PtrUint(dckMember)); + 'k': kindObj := TObject(PtrUint(dckReserved)); + 'f': kindObj := TObject(PtrUint(dckFunction)); + 'g': kindObj := TObject(PtrUint(dckEnum)); + 'e': kindObj := TObject(PtrUint(dckEnum_member)); + 'P': kindObj := TObject(PtrUint(dckPackage)); + 'M': kindObj := TObject(PtrUint(dckModule)); + 'a': kindObj := TObject(PtrUint(dckArray)); + 'A': kindObj := TObject(PtrUint(dckAA)); + 'l': kindObj := TObject(PtrUint(dckAlias)); + 't': kindObj := TObject(PtrUint(dckTemplate)); + 'T': kindObj := TObject(PtrUint(dckMixin)); // see https://github.com/Hackerpilot/dsymbol/blob/master/src/dsymbol/symbol.d#L47 - '*', '?': continue; // internal DCD stuff, said not to happen but actually it did - // https://github.com/Hackerpilot/DCD/issues/261 + // internal DCD stuff, Should not to happen...report bug if it does. + '*', '?': continue; end; - list.Add(item); + list.AddObject(item, kindObj); end; end; diff --git a/src/ce_interfaces.pas b/src/ce_interfaces.pas index ea621b86..77e293f0 100644 --- a/src/ce_interfaces.pas +++ b/src/ce_interfaces.pas @@ -373,6 +373,27 @@ type end; + TDCDCompletionKind = ( + dckClass, + dckInterface, + dckStruct, + dckUnion, + dckVariable, + dckMember, + dckReserved, + dckFunction, + dckEnum, + dckEnum_member, + dckPackage, + dckModule, + dckArray, + dckAA, + dckAlias, + dckTemplate, + dckMixin + ); + + { subject primitives: diff --git a/src/ce_synmemo.pas b/src/ce_synmemo.pas index ab913ba2..25854d77 100644 --- a/src/ce_synmemo.pas +++ b/src/ce_synmemo.pas @@ -170,6 +170,7 @@ type fSortDialog: TSortDialog; fModuleTokFound: boolean; fHasModuleDeclaration: boolean; + fLastCompletion: string; procedure decCallTipsLvl; procedure setMatchOpts(value: TIdentifierMatchOptions); function getMouseBytePosition: Integer; @@ -326,7 +327,28 @@ var implementation uses - ce_interfaces, ce_staticmacro, ce_dcd, SynEditHighlighterFoldBase, ce_lcldragdrop; + ce_interfaces, ce_dcd, ce_staticmacro, SynEditHighlighterFoldBase, ce_lcldragdrop; + +const + DcdCompletionKindStrings: array[TDCDCompletionKind] of string = ( + ' (class) ', + ' (interface) ', + ' (struct) ', + ' (union) ', + ' (variable) ', + ' (member) ', + ' (reserved word) ', + ' (function) ', + ' (enum) ', + ' (enum member) ', + ' (package) ', + ' (module) ', + ' (array) ', + ' (associative array)', + ' (alias) ', + ' (template) ', + ' (mixin) ' + ); function TCEEditorHintWindow.CalcHintRect(MaxWidth: Integer; const AHint: String; AData: Pointer): TRect; begin @@ -1820,12 +1842,26 @@ begin end; procedure TCESynMemo.getCompletionList; +var + i: integer; + o: TObject; begin if not DcdWrapper.available then exit; // fCompletion.Position := 0; fCompletion.ItemList.Clear; DcdWrapper.getComplAtCursor(fCompletion.ItemList); + if fLastCompletion.isNotEmpty then + begin + i := fCompletion.ItemList.IndexOf(fLastCompletion); + if i <> -1 then + begin + o := fCompletion.ItemList.Objects[i]; + fCompletion.ItemList.Delete(i); + fCompletion.ItemList.InsertObject(0, fLastCompletion, o); + end + else fLastCompletion:= ''; + end; end; procedure TCESynMemo.completionCodeCompletion(var value: string; @@ -1835,28 +1871,28 @@ begin if KeyChar = '.' then value := '.' else - // warning: '20' depends on ce_dcd, case knd of, string literals length - value := value[1..value.length-20]; + fLastCompletion := value; end; function TCESynMemo.completionItemPaint(const AKey: string; ACanvas: TCanvas;X, Y: integer; Selected: boolean; Index: integer): boolean; var - lft, rgt: string; + knd: string; len: Integer; begin - // empty items can be produced if completion list is too long - if aKey.isEmpty then exit(true); - // otherwise always at least 20 chars but... - // ... '20' depends on ce_dcd, case knd of, string literals length result := true; - lft := AKey[1 .. AKey.length-20]; - rgt := AKey[AKey.length-19 .. AKey.length]; + // empty items can be produced if completion list is too long + if aKey.isEmpty then + exit; + {$PUSH} {$Warnings OFF} {$Hints OFF} + knd := DcdCompletionKindStrings[TDCDCompletionKind( + PtrUInt(fCompletion.ItemList.Objects[index]))]; + {$POP} ACanvas.Font.Style := [fsBold]; - len := ACanvas.TextExtent(lft).cx; - ACanvas.TextOut(2 + X , Y, lft); + len := ACanvas.TextExtent(aKey).cx; + ACanvas.TextOut(2 + X , Y, aKey); ACanvas.Font.Style := [fsItalic]; - ACanvas.TextOut(2 + X + len + 2, Y, rgt); + ACanvas.TextOut(2 + X + len + 2, Y, knd); end; procedure TCESynMemo.AutoDotTimerEvent(sender: TObject);