diff --git a/components/lazedit/lazedittextattributes.pas b/components/lazedit/lazedittextattributes.pas index 2e393e178e..4fcf33210e 100644 --- a/components/lazedit/lazedittextattributes.pas +++ b/components/lazedit/lazedittextattributes.pas @@ -18,6 +18,7 @@ unit LazEditTextAttributes; {$mode objfpc}{$H+} +{$ModeSwitch advancedrecords} interface @@ -26,10 +27,16 @@ uses type // TODO: TLazEditDisplayTokenBound is not yet supporting wrapped text - The Physical value may change + + { TLazEditDisplayTokenBound } + TLazEditDisplayTokenBound = record Physical: Integer; // 1 based - May be in middle of char Logical: Integer; // 1 based Offset: Integer; // default 0. MultiWidth (e.g. Tab), if token starts in the middle of char + + function HasValue: boolean; inline; + function Init(APhys, ALog: Integer; AnOffs: Integer = 0): boolean; inline; end; @@ -262,6 +269,20 @@ type implementation +{ TLazEditDisplayTokenBound } + +function TLazEditDisplayTokenBound.HasValue: boolean; +begin + Result := (Physical > 0) or (Logical > 0); +end; + +function TLazEditDisplayTokenBound.Init(APhys, ALog: Integer; AnOffs: Integer): boolean; +begin + Physical := APhys; + Logical := ALog; + Offset := AnOffs; +end; + { TLazCustomEditTextAttribute } function TLazCustomEditTextAttribute.GetColor(AnIndex: TLazTextAttributeColor): TColor; diff --git a/components/synedit/lazsyntextarea.pp b/components/synedit/lazsyntextarea.pp index 4acfb46ba4..bcbf6fc17f 100644 --- a/components/synedit/lazsyntextarea.pp +++ b/components/synedit/lazsyntextarea.pp @@ -539,8 +539,10 @@ function TLazSynPaintTokenBreaker.GetNextHighlighterTokenFromView(out ATarget.Style := []; // Font.Style; // currently always cleared end; // ATarget.MergeFinalStyle := True; - ATarget.StartX := AnAttrStartX; - ATarget.EndX := NoEnd; + if not ATarget.StartX.HasValue then + ATarget.StartX := AnAttrStartX; + if not ATarget.EndX.HasValue then + ATarget.EndX := NoEnd; end; function MaybeFetchToken: Boolean; inline; @@ -832,7 +834,8 @@ begin FrameStartPos.Physical := 1 + FCurLinePhysStartOffset; FrameStartPos.Offset := 0; InitSynAttr(FCurViewAttr, FCurViewToken.TokenAttr, FrameStartPos); - FCurViewAttr.EndX := FWrapEndBound; + if not FCurViewAttr.EndX.HasValue then + FCurViewAttr.EndX := FWrapEndBound; ATokenInfo.Attr := FCurViewAttr; end else @@ -983,7 +986,9 @@ begin assert(FCurViewToken.TokenLength >= 0, 'FCurViewToken.TokenLength >= 0'); InitSynAttr(FCurViewAttr, FCurViewToken.TokenAttr, FCurViewCurTokenStartPos); - if FCurViewToken.TokenLength = 0 then + if (FCurViewToken.TokenLength = 0) and + (not ATokenInfo.Attr.EndX.HasValue) + then ATokenInfo.Attr.EndX := ATokenInfo.EndPos; // PhysPos-1; MaybeFetchToken; @@ -1118,7 +1123,9 @@ begin assert(FCurViewToken.TokenLength >= 0, 'FCurViewToken.TokenLength >= 0'); InitSynAttr(FCurViewAttr, FCurViewToken.TokenAttr, FCurViewCurTokenStartPos); - if FCurViewToken.TokenLength = 0 then + if (FCurViewToken.TokenLength = 0) and + (not ATokenInfo.Attr.EndX.HasValue) + then ATokenInfo.Attr.EndX := ATokenInfo.EndPos; // PhysPos-1; MaybeFetchToken; diff --git a/components/synedit/syneditmiscclasses.pp b/components/synedit/syneditmiscclasses.pp index c8afc68466..e6f72a1420 100644 --- a/components/synedit/syneditmiscclasses.pp +++ b/components/synedit/syneditmiscclasses.pp @@ -516,10 +516,10 @@ type FMergeInfos: array [TSynSelectedColorEnum] of TSynSelectedColorMergeInfo; - function IsMatching(ABound1, ABound2: TLazSynDisplayTokenBound): Boolean; + function IsMatching(const ABound1, ABound2: TLazSynDisplayTokenBound): Boolean; function GetFrameSideOrigin(Side: TLazSynBorderSide): TSynFrameEdges; - procedure SetCurrentEndX(AValue: TLazSynDisplayTokenBound); - procedure SetCurrentStartX(AValue: TLazSynDisplayTokenBound); + procedure SetCurrentEndX(const AValue: TLazSynDisplayTokenBound); + procedure SetCurrentStartX(const AValue: TLazSynDisplayTokenBound); protected function GetFrameSideColors(Side: TLazSynBorderSide): TColor; override; function GetFrameSidePriority(Side: TLazSynBorderSide): integer; override; @@ -546,9 +546,9 @@ type procedure InitMergeInfo; // (called automatically) Set all MergeInfo to the start values. After this was called, ay Changes to the color properties are ignored procedure ProcessMergeInfo; // copy the merge result, to the actual color properties procedure CleanupMergeInfo; // free the alpha arrays - procedure Merge(Other: TSynHighlighterAttributesModifier); - procedure Merge(Other: TSynHighlighterAttributesModifier; LeftCol, RightCol: TLazSynDisplayTokenBound); - procedure MergeFrames(Other: TSynHighlighterAttributesModifier; LeftCol, RightCol: TLazSynDisplayTokenBound); + procedure Merge(Other: TLazCustomEditTextAttribute); + procedure Merge(Other: TLazCustomEditTextAttribute; LeftCol, RightCol: TLazSynDisplayTokenBound); + procedure MergeFrames(Other: TLazCustomEditTextAttribute; LeftCol, RightCol: TLazSynDisplayTokenBound); end; { TLazSynSurface } @@ -1034,8 +1034,8 @@ end; { TSynSelectedColorMergeResult } -function TSynSelectedColorMergeResult.IsMatching(ABound1, - ABound2: TLazSynDisplayTokenBound): Boolean; +function TSynSelectedColorMergeResult.IsMatching(const ABound1, ABound2: TLazSynDisplayTokenBound + ): Boolean; begin Result := ( (ABound1.Physical > 0) and (ABound1.Physical = ABound2.Physical) @@ -1100,7 +1100,7 @@ begin else Result := slsSolid; end; -procedure TSynSelectedColorMergeResult.SetCurrentEndX(AValue: TLazSynDisplayTokenBound); +procedure TSynSelectedColorMergeResult.SetCurrentEndX(const AValue: TLazSynDisplayTokenBound); begin //if FCurrentEndX = AValue then Exit; FCurrentEndX := AValue; @@ -1111,7 +1111,7 @@ begin end; end; -procedure TSynSelectedColorMergeResult.SetCurrentStartX(AValue: TLazSynDisplayTokenBound); +procedure TSynSelectedColorMergeResult.SetCurrentStartX(const AValue: TLazSynDisplayTokenBound); begin //if FCurrentStartX = AValue then Exit; FCurrentStartX := AValue; @@ -1373,12 +1373,12 @@ begin FMergeInfoInitialized := False; end; -procedure TSynSelectedColorMergeResult.Merge(Other: TSynHighlighterAttributesModifier); +procedure TSynSelectedColorMergeResult.Merge(Other: TLazCustomEditTextAttribute); begin Merge(Other, StartX, EndX); // always merge frame end; -procedure TSynSelectedColorMergeResult.Merge(Other: TSynHighlighterAttributesModifier; LeftCol, +procedure TSynSelectedColorMergeResult.Merge(Other: TLazCustomEditTextAttribute; LeftCol, RightCol: TLazSynDisplayTokenBound); var sKeep, sSet, sClr, sInv, sInvInv: TFontStyles; @@ -1426,7 +1426,7 @@ begin EndUpdate; end; -procedure TSynSelectedColorMergeResult.MergeFrames(Other: TSynHighlighterAttributesModifier; LeftCol, +procedure TSynSelectedColorMergeResult.MergeFrames(Other: TLazCustomEditTextAttribute; LeftCol, RightCol: TLazSynDisplayTokenBound); //procedure SetSide(ASide: TLazSynBorderSide; ASrc: TSynHighlighterAttributesModifier); @@ -1457,7 +1457,7 @@ procedure TSynSelectedColorMergeResult.MergeFrames(Other: TSynHighlighterAttribu //end; procedure SetSide(AInfoSide: TSynSelectedColorEnum; ASide: TLazSynBorderSide; - ASrc: TSynHighlighterAttributesModifier); + ASrc: TLazCustomEditTextAttribute); begin if (FMergeInfos[AInfoSide].BaseColor <> clNone) and ( (ASrc.FramePriority < FMergeInfos[AInfoSide].BasePriority) or @@ -1481,6 +1481,14 @@ procedure TSynSelectedColorMergeResult.MergeFrames(Other: TSynHighlighterAttribu FFrameSideOrigin[ASide] := ASrc.FrameEdges; end; + function HasFrameBound(AnAttr: TLazCustomEditTextAttribute; const ABnd: TLazSynDisplayTokenBound): boolean; + begin + (* Highlighter Attribs (NON-TSynSelectedColor) did NOT have a StartX/EndX + So theire frames would be drawn at any location + *) + Result := (Other is TSynSelectedColor) or ABnd.HasValue; + end; + begin if not FFrameSidesInitialized then MaybeInitFrameSides; @@ -1492,12 +1500,12 @@ begin case Other.FrameEdges of sfeAround: begin // UpdateOnly, frame keeps behind individual sites - if (not (Other is TSynSelectedColor)) or // always merge, if it has no startx - IsMatching(TSynSelectedColor(Other).StartX, LeftCol) + if (not HasFrameBound(Other, Other.StartX)) or + IsMatching(Other.StartX, LeftCol) then SetSide(sscFrameLeft, bsLeft, Other); - if (not (Other is TSynSelectedColor)) or - IsMatching(TSynSelectedColor(Other).EndX, RightCol) + if (not HasFrameBound(Other, Other.EndX)) or + IsMatching(Other.EndX, RightCol) then SetSide(sscFrameRight, bsRight, Other); SetSide(sscFrameBottom, bsBottom, Other); diff --git a/components/synedit/synhighlighterpas.pp b/components/synedit/synhighlighterpas.pp index 3aa427019d..493b8d4916 100644 --- a/components/synedit/synhighlighterpas.pp +++ b/components/synedit/synhighlighterpas.pp @@ -5724,11 +5724,22 @@ end; function TSynPasSyn.GetTokenAttribute: TSynHighlighterAttributes; +var + x1, x2: Integer; begin case GetTokenID of tkAsm: Result := fAsmAttri; - tkIDEDirective, tkComment: + tkIDEDirective, tkComment: begin Result := fCommentAttri; + //x1 := ToPos(fTokenPos); + //x2 := ToPos(Run); + //FCustomCommentTokenMergedMarkup.SetFrameBoundsLog(x1, x2); + //if not GetTokenIsCommentStart(True) then + // x1 := 1; + //if (not GetTokenIsCommentEnd) then + // x2 := fLineLen; + //Result.SetFrameBoundsLog(x1, x2); + end; tkIdentifier: begin if eaGotoLabel in FTokenExtraAttribs then Result := FGotoLabelAttr @@ -5750,8 +5761,20 @@ end; function TSynPasSyn.GetTokenAttributeEx: TLazCustomEditTextAttribute; var tid: TtkTokenKind; - i: Integer; + i, x1, x2: Integer; + LeftCol, RightCol: TLazSynDisplayTokenBound; attr: TSynHighlighterAttributesModifier; + + procedure InitMergeRes(AMergeRes: TSynSelectedColorMergeResult; AnAttr: TLazCustomEditTextAttribute); + begin + if AnAttr is TSynSelectedColorMergeResult then begin + AMergeRes.Assign(AnAttr); + end + else begin + AMergeRes.Clear; + AMergeRes.Merge(AnAttr, LeftCol, RightCol); + end; + end; begin Result := GetTokenAttribute; if Result = nil then @@ -5759,9 +5782,20 @@ begin tid := GetTokenID; + x1 := ToPos(fTokenPos); + x2 := ToPos(Run); + LeftCol.Init(-1, x1); + RightCol.Init(-1, x2); + if tid in [tkIDEDirective, tkComment] then begin + if not GetTokenIsCommentStart(True) then x1 := 1; + if (not GetTokenIsCommentEnd) then x2 := fLineLen; + Result.SetFrameBoundsLog(x1, x2); + end; + + if tid = tkIDEDirective then begin FCurIDEDirectiveAttri.Assign(FCommentAttri); - FCurIDEDirectiveAttri.Merge(FIDEDirectiveAttri); + FCurIDEDirectiveAttri.Merge(FIDEDirectiveAttri, LeftCol, RightCol); Result := FCurIDEDirectiveAttri; end; @@ -5771,26 +5805,29 @@ begin ) then begin FCurCaseLabelAttri.Assign(Result); - FCurCaseLabelAttri.Merge(FCaseLabelAttri); + FCurCaseLabelAttri.Merge(FCaseLabelAttri, LeftCol, RightCol); Result := FCurCaseLabelAttri; end; if FIsPasDocKey then begin - FCurPasDocAttri.Assign(Result); - FCurPasDocAttri.Merge(fPasDocKeyWordAttri); + InitMergeRes(FCurPasDocAttri, Result); + FCurPasDocAttri.Merge(fPasDocKeyWordAttri, LeftCol, RightCol); Result := FCurPasDocAttri; + Result.SetFrameBoundsLog(x1, x2); end else if FIsPasDocSym then begin - FCurPasDocAttri.Assign(Result); - FCurPasDocAttri.Merge(fPasDocSymbolAttri); + InitMergeRes(FCurPasDocAttri, Result); + FCurPasDocAttri.Merge(fPasDocSymbolAttri, LeftCol, RightCol); Result := FCurPasDocAttri; + Result.SetFrameBoundsLog(x1, x2); end else if FIsPasUnknown then begin - FCurPasDocAttri.Assign(Result); - FCurPasDocAttri.Merge(fPasDocUnknownAttr); + InitMergeRes(FCurPasDocAttri, Result); + FCurPasDocAttri.Merge(fPasDocUnknownAttr, LeftCol, RightCol); Result := FCurPasDocAttri; + Result.SetFrameBoundsLog(x1, x2); end; case FTokenTypeDeclExtraAttrib of @@ -5801,73 +5838,74 @@ begin (PasCodeFoldRange.BracketNestLevel = 0) then begin FCurProcTypeDeclExtraAttr.Assign(Result); - FCurProcTypeDeclExtraAttr.Merge(FProcedureHeaderNameAttr); + FCurProcTypeDeclExtraAttr.Merge(FProcedureHeaderNameAttr, LeftCol, RightCol); Result := FCurProcTypeDeclExtraAttr; end; end; eaPropertyName: begin FCurProcTypeDeclExtraAttr.Assign(Result); - FCurProcTypeDeclExtraAttr.Merge(FPropertyNameAttr); + FCurProcTypeDeclExtraAttr.Merge(FPropertyNameAttr, LeftCol, RightCol); Result := FCurProcTypeDeclExtraAttr; end; eaProcParam: begin FCurProcTypeDeclExtraAttr.Assign(Result); - FCurProcTypeDeclExtraAttr.Merge(FProcedureHeaderParamAttr); + FCurProcTypeDeclExtraAttr.Merge(FProcedureHeaderParamAttr, LeftCol, RightCol); Result := FCurProcTypeDeclExtraAttr; end; eaProcType: begin FCurProcTypeDeclExtraAttr.Assign(Result); - FCurProcTypeDeclExtraAttr.Merge(FProcedureHeaderTypeAttr); + FCurProcTypeDeclExtraAttr.Merge(FProcedureHeaderTypeAttr, LeftCol, RightCol); Result := FCurProcTypeDeclExtraAttr; end; eaProcValue: begin FCurProcTypeDeclExtraAttr.Assign(Result); - FCurProcTypeDeclExtraAttr.Merge(FProcedureHeaderValueAttr); + FCurProcTypeDeclExtraAttr.Merge(FProcedureHeaderValueAttr, LeftCol, RightCol); Result := FCurProcTypeDeclExtraAttr; end; eaProcResult: begin FCurProcTypeDeclExtraAttr.Assign(Result); - FCurProcTypeDeclExtraAttr.Merge(FProcedureHeaderResultAttr); + FCurProcTypeDeclExtraAttr.Merge(FProcedureHeaderResultAttr, LeftCol, RightCol); Result := FCurProcTypeDeclExtraAttr; end; eaDeclVarName: begin FCurProcTypeDeclExtraAttr.Assign(Result); - FCurProcTypeDeclExtraAttr.Merge(FDeclarationVarConstNameAttr); + FCurProcTypeDeclExtraAttr.Merge(FDeclarationVarConstNameAttr, LeftCol, RightCol); Result := FCurProcTypeDeclExtraAttr; end; eaDeclTypeName: begin FCurProcTypeDeclExtraAttr.Assign(Result); - FCurProcTypeDeclExtraAttr.Merge(FDeclarationTypeNameAttr); + FCurProcTypeDeclExtraAttr.Merge(FDeclarationTypeNameAttr, LeftCol, RightCol); Result := FCurProcTypeDeclExtraAttr; end; eaDeclType: begin FCurProcTypeDeclExtraAttr.Assign(Result); - FCurProcTypeDeclExtraAttr.Merge(FDeclarationTypeAttr); + FCurProcTypeDeclExtraAttr.Merge(FDeclarationTypeAttr, LeftCol, RightCol); Result := FCurProcTypeDeclExtraAttr; end; eaDeclValue: begin FCurProcTypeDeclExtraAttr.Assign(Result); - FCurProcTypeDeclExtraAttr.Merge(FDeclarationValueAttr); + FCurProcTypeDeclExtraAttr.Merge(FDeclarationValueAttr, LeftCol, RightCol); Result := FCurProcTypeDeclExtraAttr; end; end; if eaStructMemeber in FTokenExtraAttribs then begin FCurStructMemberExtraAttri.Assign(Result); - FCurStructMemberExtraAttri.Merge(FStructMemberAttr); + FCurStructMemberExtraAttri.Merge(FStructMemberAttr, LeftCol, RightCol); Result := FCurStructMemberExtraAttri; end; - if FCustomTokenMarkup <> nil then begin - FCustomTokenMergedMarkup.Assign(Result); - FCustomTokenMergedMarkup.Merge(FCustomTokenMarkup); - Result := FCustomTokenMergedMarkup; - end; if FCustomCommentTokenMarkup <> nil then begin - FCustomCommentTokenMergedMarkup.Assign(Result); - FCustomCommentTokenMergedMarkup.Merge(FCustomCommentTokenMarkup); + InitMergeRes(FCustomCommentTokenMergedMarkup, Result); + FCustomCommentTokenMarkup.SetFrameBoundsLog(x1, x2); + FCustomCommentTokenMergedMarkup.Merge(FCustomCommentTokenMarkup, LeftCol, RightCol); Result := FCustomCommentTokenMergedMarkup; end; + if FCustomTokenMarkup <> nil then begin + InitMergeRes(FCustomTokenMergedMarkup, Result); + FCustomTokenMergedMarkup.Merge(FCustomTokenMarkup, LeftCol, RightCol); + Result := FCustomTokenMergedMarkup; + end; if (FTokenID = tkSymbol) and (Run - fTokenPos = 1) and (fLine[fTokenPos] in ['(', ')']) then begin @@ -5886,6 +5924,7 @@ begin end; end; + //Result.SetFrameBoundsLog(-1, -1); // TODO: Textdrawer will do its own bounds, so all frames must be cleared while merging end; function TSynPasSyn.GetTokenKind: integer;