diff --git a/Projects/Simba/framescript.pas b/Projects/Simba/framescript.pas index e5d240e..00585d8 100644 --- a/Projects/Simba/framescript.pas +++ b/Projects/Simba/framescript.pas @@ -27,8 +27,8 @@ unit framescript; interface uses - Classes, SysUtils, FileUtil, LResources, Forms, SynHighlighterPas, SynEdit, SynEditMarkupHighAll, - mmlpsthread,ComCtrls, SynEditKeyCmds, LCLType,MufasaBase, SynEditMarkupSpecialLine, Graphics, Controls, SynEditStrConst, + Classes, SysUtils, FileUtil, LResources, Forms, SynHighlighterPas, SynEdit, SynEditMarkupHighAll, + mmlpsthread,ComCtrls, SynEditKeyCmds, LCLType,MufasaBase, SynEditMarkupSpecialLine, Graphics, Controls, SynEditStrConst, v_ideCodeInsight, v_ideCodeParser, CastaliaPasLexTypes, CastaliaSimplePasPar, SynEditHighlighter,synedittextbase,SynPluginSyncroEdit; const ecCodeCompletion = ecUserFirst; @@ -106,10 +106,11 @@ begin Start := Start + Offset; sp := Start - 1; ep := Start - 1; - s := e.Lines[e.CaretY - 1]; + if (e.CaretY <= 0) or (e.CaretY > e.Lines.Count) then + s := '' + else + s := e.Lines[e.CaretY - 1]; l := Length(s); - //if (sp > l) then - // Dec(sp); if (sp < 1) or (sp > l) or (not (s[sp] in ['a'..'z', 'A'..'Z', '0'..'9', '_'])) then begin @@ -124,7 +125,10 @@ begin while (ep >= 1) and (ep < l) and (s[ep + 1] in ['a'..'z', 'A'..'Z', '0'..'9', '_']) do Inc(ep); - Result := Copy(s, sp, ep - sp + 1); + if (ep > l) then + Result := '' + else + Result := Copy(s, sp, ep - sp + 1); end; function PosToCaretXY(e : TSynEdit; pos : integer) : TPoint; @@ -141,7 +145,8 @@ begin loop := 0; count := 0; Lines := e.Lines; - while (loop < Lines.Count) and (count + llen(Lines[loop]) < pos) do begin + while (loop < Lines.Count) and (count + llen(Lines[loop]) < pos) do + begin count := count + llen(Lines[loop]); inc(loop); end; @@ -333,7 +338,7 @@ var d: TDeclaration; dd: TDeclaration; begin - if (Command = ecCodeCompletion) and ((not SynEdit.GetHighlighterAttriAtRowCol(SynEdit.CaretXY, s, Attri)) or + if (Command = ecCodeCompletion) and ((not SynEdit.GetHighlighterAttriAtRowCol(Point(SynEdit.CaretX - 1, SynEdit.CaretY), s, Attri)) or ((Attri.Name <> SYNS_AttrComment) and (Attri.name <> SYNS_AttrString) and (Attri.name <> SYNS_AttrDirective))) then begin mp := TCodeInsight.Create; @@ -348,17 +353,18 @@ begin InsertList.Sorted := True; Synedit.Lines.SaveToStream(ms); - try Filter := WordAtCaret(Synedit, sp, ep); SimbaForm.CodeCompletionStart := Point(sp, Synedit.CaretY); - //mp.Run(ms, nil, Synedit.SelStart + (ep - Synedit.CaretX) - 1); - s := SynEdit.Lines[SynEdit.Carety-1]; - if ep > length(s) then //We are outside the real text, go back to the last char - mp.Run(ms, nil, Synedit.SelStart - ep + length(s)) + if (SynEdit.CaretY <= 0) or (SynEdit.CaretY > SynEdit.Lines.Count) then + s := '' else - mp.Run(ms, nil, Synedit.SelStart + (ep - Synedit.CaretX) - 1); + s := SynEdit.Lines[SynEdit.Carety - 1]; + if ep > length(s) then //We are outside the real text, go back to the last char + mp.Run(ms, nil, Synedit.SelStart + (Length(s) - Synedit.CaretX) + 1) + else + mp.Run(ms, nil, Synedit.SelStart + (ep - Synedit.CaretX)); s := mp.GetExpressionAtPos; if (s <> '') then @@ -373,7 +379,6 @@ begin if (Data <> nil) then //If showing automatically if (s <> '') and ((mp.DeclarationAtPos <> nil) and ((mp.DeclarationAtPos is TciCompoundStatement) or mp.DeclarationAtPos.HasOwnerClass(TciCompoundStatement, d, True))) then Data := nil; - if (Data = nil) then begin mp.FillSynCompletionProposal(ItemList, InsertList, s); @@ -387,8 +392,10 @@ begin ItemList.Free; InsertList.Free; end; - end; - if command = ecCodeHints then + end + + else if (Command = ecCodeHints) and ((not SynEdit.GetHighlighterAttriAtRowCol(Point(SynEdit.CaretX - 1, SynEdit.CaretY), s, Attri)) or + ((Attri.Name <> SYNS_AttrComment) and (Attri.name <> SYNS_AttrString) and (Attri.name <> SYNS_AttrDirective))) then begin if SimbaForm.ParamHint.Visible = true then SimbaForm.ParamHint.hide; @@ -401,26 +408,29 @@ begin synedit.Lines.SaveToStream(ms); try Synedit.GetWordBoundsAtRowCol(Synedit.CaretXY, sp, ep); - s := SynEdit.Lines[SynEdit.Carety-1]; + if (SynEDit.CaretY <= 0) or (SynEdit.CaretY > SynEdit.Lines.Count) then + s := '' + else + s := SynEdit.Lines[SynEdit.CaretY - 1]; if ep > length(s) then //We are outside the real text, go back to the last char - mp.Run(ms, nil, Synedit.SelStart - ep + length(s), True) + mp.Run(ms, nil, Synedit.SelStart + (Length(s) - Synedit.CaretX), True) else mp.Run(ms, nil, Synedit.SelStart + (ep - Synedit.CaretX) - 1, True); - bcc := 1;bck := 0;cc := 0; - s := mp.GetExpressionAtPos(bcc, bck, cc,posi, true); - bracketpos := posi + length(s); - cc := LastDelimiter('(',s); + bcc := 1;bck := 0;cc := 0; + s := mp.GetExpressionAtPos(bcc, bck, cc, ep, posi, bracketpos, true); + if (posi = -1) then + posi := SynEdit.SelStart + (SynEdit.CaretX - sp); + if (bracketpos = -1) then + bracketpos := posi + length(s); + + cc := LastDelimiter('(', s); if cc > 0 then - begin; - bracketpos := cc + posi; delete(s, cc, length(s) - cc + 1); - end; - cc := LastDelimiter('.',s); - if cc > 0 then - posi := posi + cc; + d := mp.FindVarBase(s); dd := nil; + //Find the declaration -> For example if one uses var x : TNotifyEvent.. //You have to get the owner of x, to find the declaration of TNotifyEvent etc.. while (d <> nil) and (d <> dd) and (d.Owner <> nil) and (not ((d is TciProcedureDeclaration) or (d.Owner is TciProcedureDeclaration))) do @@ -444,10 +454,10 @@ begin if (not (d is TciProcedureDeclaration)) and (d.Owner is TciProcedureDeclaration) then d := d.Owner; if (TciProcedureDeclaration(d).Params <> '') then - SimbaForm.ParamHint.Show(PosToCaretXY(synedit,posi + 1), PosToCaretXY(synedit,bracketpos), + SimbaForm.ParamHint.Show(PosToCaretXY(synedit,posi), PosToCaretXY(synedit,bracketpos), TciProcedureDeclaration(d), synedit,mp) else - FormWriteln(''); + mDebugLn(''); end; except on e : exception do diff --git a/Units/Misc/v_autocompleteform.pas b/Units/Misc/v_autocompleteform.pas index 37b6141..4cbc270 100644 --- a/Units/Misc/v_autocompleteform.pas +++ b/Units/Misc/v_autocompleteform.pas @@ -586,21 +586,25 @@ begin; exit; if endpos.y < beginpos.y then exit; + if beginpos.y < 0 then + exit; if endpos.y >= strings.Count then exit; if beginpos.x > length(strings[beginpos.y]) then exit; - if endpos.x > (length(strings[endpos.y])+1) then + if endpos.x > (length(strings[endpos.y]) + 1) then exit; if EndPos.y = beginpos.y then begin - result := copy(strings[beginpos.y],beginpos.x, endpos.x - beginpos.x); + result := copy(strings[beginpos.y], beginpos.x, endpos.x - beginpos.x + 1); + //ShowMessage(Result); exit; end; result := copy(strings[beginpos.y],beginpos.x, length(strings[beginpos.y]) - beginpos.x + 1); for i := beginpos.y + 1 to endpos.y-1 do result := result + strings[i]; - result := result + copy(strings[endpos.y],0,endpos.x-1); //Position <> count! + result := result + copy(strings[endpos.y], 1, endpos.x - 1); //Position <> count! + //ShowMessage(Result); end; function TParamHint.PrepareParamString(out Str: string; out MustHide : boolean): Integer; @@ -797,12 +801,15 @@ begin if not Assigned(FSynEdit) then exit; if FSynEdit.Focused = false then //No focus, hide this hint - exit; //Exits to the finally statement ;) - CursorXY := FSynEdit.LogicalCaretXY; - if (CursorXY.x <= FBracketPoint.x) and (CursorXY.y <= FBracketPoint.y) then //Cursor moved in front of the bracket + exit; //Exits to the finally statement ;) + CursorXY := FSynEdit.CaretXY; + if (CursorXY.y < FBracketPoint.y) or ((CursorXY.x <= FBracketPoint.x) and (CursorXY.y <= FBracketPoint.y)) then //Cursor moved in front of the bracket exit; - Line:=FSynEdit.Lines[FBracketPoint.Y-1]; - if (length(Line) FSynEdit.Lines.Count) then + Line := '' + else + Line:=FSynEdit.Lines[FBracketPoint.Y - 1]; + if (FBracketPoint.X > length(Line)) or (not (Line[FBracketPoint.X] in ['(','['])) then exit; if PrepareParamString(Line,MustHide) = LastParameterIndex then exit @@ -820,6 +827,7 @@ begin FreeAndNil(Fmp); FDecl := nil; FSynEdit := nil; + LastParameterIndex := -1; end; procedure TParamHint.DrawHints(var MaxWidth, MaxHeight: Integer; diff --git a/Units/Misc/v_ideCodeInsight.pas b/Units/Misc/v_ideCodeInsight.pas index c6a76f3..19e974a 100644 --- a/Units/Misc/v_ideCodeInsight.pas +++ b/Units/Misc/v_ideCodeInsight.pas @@ -54,7 +54,7 @@ type function GetFuncType(FuncName, FuncClass: string; out Decl: TDeclaration; Return: TVarBase): Boolean; function FindStruct(s: string; out Decl: TDeclaration; Return: TVarBase; var ArrayCount: Integer): Boolean; public - function GetExpressionAtPos(var BraceCount, BracketCount, CommaCount: Integer; out sp : Integer; IgnoreBrackets: Boolean = False): string; overload; + function GetExpressionAtPos(var BraceCount, BracketCount, CommaCount: Integer; out sp, ssp, bp: Integer; IgnoreBrackets: Boolean = False): string; overload; function GetExpressionAtPos(var BraceCount, BracketCount, CommaCount: Integer; IgnoreBrackets: Boolean = False): string; overload; function GetExpressionAtPos: string; overload; function FindVarBase(s: string; GetStruct: Boolean = False; Return: TVarBase = vbName): TDeclaration; @@ -618,7 +618,7 @@ begin end; end; -function TCodeInsight.GetExpressionAtPos(var BraceCount, BracketCount, CommaCount: Integer; out sp: Integer; IgnoreBrackets: Boolean): string; +function TCodeInsight.GetExpressionAtPos(var BraceCount, BracketCount, CommaCount: Integer; out sp, ssp, bp: Integer; IgnoreBrackets: Boolean): string; var i, StartPos, EndPos, Dif: Integer; s: string; @@ -628,6 +628,9 @@ var begin Result := ''; d := nil; + sp := -1; + ssp := -1; + bp := -1; if (fDeclarationAtPos = nil) or (fDeclarationAtPos is TciJunk) or (not ( @@ -656,71 +659,83 @@ begin StartPos := EndPos; LastWasDot := False; - while (StartPos > 0) do - begin - if (BraceCount = 0) and ((BracketCount = 0) or IgnoreBrackets) and (s[StartPos] in ['a'..'z', 'A'..'Z', '0'..'9', '_']) then - {nothing} - else if (BraceCount = 0) and ((BracketCount = 0) or IgnoreBrackets) and (s[StartPos] in [#10, #11, #13, #32]) then + if (StartPos <= Length(s)) then + while (StartPos > 0) do begin - i := StartPos; - Dec(StartPos); - while (StartPos > 0) and (s[StartPos] in [#10, #11, #13, #32]) do - Dec(StartPos); - if (StartPos > 0) and (not ((LastWasDot and (s[StartPos] in ['a'..'z', 'A'..'Z', '0'..'9', '_', ']', ')'])) or ((not LastWasDot) and (s[StartPos] = '.')))) then + if (BraceCount = 0) and ((BracketCount = 0) or IgnoreBrackets) and (s[StartPos] in ['a'..'z', 'A'..'Z', '0'..'9', '_']) then + {nothing} + else if (BraceCount = 0) and ((BracketCount = 0) or IgnoreBrackets) and (s[StartPos] in [#10, #11, #13, #32]) then begin - StartPos := i - BracketCount - BraceCount; + i := StartPos; + Dec(StartPos); + while (StartPos > 0) and (s[StartPos] in [#10, #11, #13, #32]) do + Dec(StartPos); + if (StartPos > 0) and (not ((LastWasDot and (s[StartPos] in ['a'..'z', 'A'..'Z', '0'..'9', '_', ']', ')'])) or ((not LastWasDot) and (s[StartPos] = '.')))) then + begin + StartPos := i - BracketCount - BraceCount; + if (ssp = -1) then ssp := StartPos; + Break; + end; + Inc(StartPos); + end + else if (s[StartPos] = '.') then + begin + if (ssp = -1) then ssp := StartPos; + LastWasDot := True; + Dec(StartPos); + Continue; + end + else if (s[StartPos] = ']') then + Inc(BracketCount) + else if (s[StartPos] = '[') then + begin + Dec(BracketCount); + LastWasDot := True; + Dec(StartPos); + Continue; + end + else if (s[StartPos] = ')') then + Inc(BraceCount) + else if (s[StartPos] = '(') then + begin + Dec(BraceCount); + LastWasDot := True; + Dec(StartPos); + if (BraceCount = 0) then + bp := StartPos; + Continue; + end + else if (BraceCount = 1) and (BracketCount = 0) and (s[StartPos] = ',') then + Inc(CommaCount) + else if (BraceCount = 0) and ((BracketCount = 0) or IgnoreBrackets) then + Break; + + if (BraceCount < 0) or ((BracketCount < 0) and (not IgnoreBrackets)) then + begin + Dec(StartPos, BraceCount); + Dec(StartPos, BracketCount); Break; end; - Inc(StartPos); - end - else if (s[StartPos] = '.') then - begin - LastWasDot := True; - Dec(StartPos); - Continue; - end - else if (s[StartPos] = ']') then - Inc(BracketCount) - else if (s[StartPos] = '[') then - begin - Dec(BracketCount); - LastWasDot := True; - Dec(StartPos); - Continue; - end - else if (s[StartPos] = ')') then - Inc(BraceCount) - else if (s[StartPos] = '(') then - begin - Dec(BraceCount); - LastWasDot := True; - Dec(StartPos); - Continue; - end - else if (BraceCount = 1) and (BracketCount = 0) and (s[StartPos] = ',') then - Inc(CommaCount) - else if (BraceCount = 0) and ((BracketCount = 0) or IgnoreBrackets) then - Break; - if (BraceCount < 0) or ((BracketCount < 0) and (not IgnoreBrackets)) then - begin - Dec(StartPos, BraceCount); - Dec(StartPos, BracketCount); - Break; + LastWasDot := False; + Dec(StartPos); end; - - LastWasDot := False; - Dec(StartPos); - end; - sp := StartPos + d.StartPos + Dif; - Result := CompressWhiteSpace(Copy(s, StartPos + 1, EndPos - StartPos)); + if (ssp = -1) then ssp := StartPos; + if (bp = -1) then bp := EndPos; + sp := StartPos + d.StartPos + Dif + 1; + ssp := ssp + d.StartPos + Dif + 1; + bp := bp + d.StartPos + Dif + 1; + if (EndPos > Length(s)) then + Result := '' + else + Result := CompressWhiteSpace(Copy(s, StartPos + 1, EndPos - StartPos - 1)); end; function TCodeInsight.GetExpressionAtPos(var BraceCount, BracketCount, CommaCount: Integer; IgnoreBrackets: Boolean = False): string; var - sp : integer; + sp, ssp, bp: integer; begin - result := GetExpressionAtPos(bracecount,bracketcount,commacount,sp,ignorebrackets); + result := GetExpressionAtPos(bracecount,bracketcount,commacount,sp,ssp,bp,ignorebrackets); end; function TCodeInsight.GetExpressionAtPos: string; diff --git a/Units/Misc/v_ideCodeParser.pas b/Units/Misc/v_ideCodeParser.pas index bf300bc..3cdfb4d 100644 --- a/Units/Misc/v_ideCodeParser.pas +++ b/Units/Misc/v_ideCodeParser.pas @@ -812,12 +812,20 @@ begin end; function TciProcedureDeclaration.GetName: TciProcedureName; +var + d: TDeclaration; begin if (fName <> nil) then Result := fName else begin fName := TciProcedureName(fItems.GetFirstItemOfClass(TciProcedureName)); + if (fName = nil) and (HasOwnerClass(TciClassField, d, True)) then + fName := TciProcedureName(d.Items.GetFirstItemOfClass(TciFieldName)); + if (fName = nil) and (HasOwnerClass(TciVarDeclaration, d, True)) then + fName := TciProcedureName(d.Items.GetFirstItemOfClass(TciVarName)); + if (fName = nil) and (HasOwnerClass(TciTypeDeclaration, d, True)) then + fName := TciProcedureName(d.Items.GetFirstItemOfClass(TciTypeName)); Result := fName; end; end;