G'day all, Just for information I've attached some patches I apply to my local tree and use in an application I'm working on.
These are not any form of an example of how to write good code, they are gross hacks that have "evolved" as lazarus has evolved over the last 9 months or so and I adapt them as required as the code changes under me. If anyone finds any of the bits useful, I'm more than happy to clean them up and work with the relative authors to make them acceptable to the general code base. Conversely, I've maintained them in my own tree for 9 months and I'm happy to keep doing so. I'm also very open to suggestions as to how I might achieve my desired results without having to hack the codebase. laz-find.patch : This adds an extra checkbox and set member to the find/replace dialogs to allow selection of "entire scope" as a search parameter. laz-synpatch-005.patch This is a gross hack, but it allows clicking *anywhere* on the grey fold line in the gutter to fold that particular level of routine. I have some procedures that are very long and it's nice to be able to click on that line from the bottom of the procedure and have it fold up on me. laz-synpatch-007.patch This is another gross hack, but in a highlighter I've written I use this to enable me to ensure the remainder of a line is painted in the right background colour. Synedit calls this "GetLineRemainder" routine (if assigned in the highlighter) to get the colour the remainder of the line is to be painted after it has finished painting all its tokens. Without this I was getting odd line remainders when I scrolled often. With this I get perfection every time. laz-synpatch-008.patch And the final gross hack. I store the folded status of each open file in my overall project file. The easy way for me to do this is in a sequential comma delimited list of line numbers that are folded. This routine "DumpFolds" gives me a string which is a comma delimited list of all the lines that are folded. Then when I reload the project I can simply fold those lines in reverse order to get precisely the folds I had previously. On another note, recent work by Martin Friebe and Paul Ishenin has rendered three other gross hacks I've had in my tree irrelevant :) Regards, Brad -- Dolphins are so intelligent that within a few weeks they can train Americans to stand at the edge of the pool and throw them fish.
Common subdirectories: ../lazarus.clean/components/synedit/design and components/synedit/design
Common subdirectories: ../lazarus.clean/components/synedit/languages and components/synedit/languages
Only in ../lazarus.clean/components/synedit/: .svn
diff -u ../lazarus.clean/components/synedit/syneditfoldedview.pp components/synedit/syneditfoldedview.pp
--- ../lazarus.clean/components/synedit/syneditfoldedview.pp 2009-05-03 13:10:49.000000000 +0800
+++ components/synedit/syneditfoldedview.pp 2009-05-03 19:17:43.000000000 +0800
@@ -276,6 +276,7 @@
ColCount : Integer = 1; Skip: Boolean = False);
procedure FoldAtTextIndex(AStartIndex: Integer; ColIndex : Integer = -1; (* Folds at nth TextIndex (all lines in buffer) / 1-based *)
ColCount : Integer = 1; Skip: Boolean = False);
+ procedure FoldBlockAtTextIndex(AStartIndex : Integer);
procedure UnFoldAtLine(AStartLine: Integer; ColIndex : Integer = -1; (* UnFolds at ScreenLine / 0-based *)
ColCount : Integer = 0; Skip: Boolean = False);
procedure UnFoldAtViewPos(AStartPos: Integer; ColIndex : Integer = -1; (* UnFolds at nth visible/unfolded Line / 1-based *)
@@ -1869,6 +1870,26 @@
fOnFoldChanged(AStartIndex);
end;
+procedure TSynEditFoldedView.FoldBlockAtTextIndex(AStartIndex : Integer);
+var
+ i, j, k : Integer;
+ hl: TSynCustomFoldHighlighter;
+begin
+ if not(assigned(FHighLighter) and (FHighLighter is TSynCustomFoldHighlighter))
+ then exit;
+ FHighLighter.CurrentLines := fLines;
+ hl := TSynCustomFoldHighlighter(FHighLighter);
+ i := AStartIndex;
+ j := hl.FoldNestCount(i,1);
+ If j < 1 then
+ Exit;
+ While (i >= 0) and (hl.FoldNestCount(i,1) >= j) do
+ Dec(i);
+ Inc(i);
+ If i >= 0 then
+ FoldAtTextIndex(i);
+end;
+
procedure TSynEditFoldedView.UnFoldAtLine(AStartLine : Integer;
ColIndex : Integer = -1; ColCount : Integer = 0; Skip: Boolean = False);
begin
Only in components/synedit/: syneditfoldedview.pp~
diff -u ../lazarus.clean/components/synedit/synguttercodefolding.pp components/synedit/synguttercodefolding.pp
--- ../lazarus.clean/components/synedit/synguttercodefolding.pp 2009-05-03 13:10:49.000000000 +0800
+++ components/synedit/synguttercodefolding.pp 2009-05-03 19:18:03.000000000 +0800
@@ -182,6 +182,11 @@
if isClick(FExpandedClickConf[sgctFoldAll]) then
FFoldView.FoldAtTextIndex(Line-1, -1, 0);
end;
+ cfContinue :
+ begin
+ if isClick(FExpandedClickConf[sgctFoldOne]) then
+ FFoldView.FoldBlockAtTextIndex(Line-1);
+ end;
end;
end;
Only in components/synedit/: synguttercodefolding.pp~
Only in components/synedit/: units
Only in ../lazarus.clean/components/synedit/design/lib: .svn
Only in ../lazarus.clean/components/synedit/design: .svn
Only in ../lazarus.clean/components/synedit/languages: .svn
Only in ../lazarus.clean/components/synedit/: .svn
diff -ur ../lazarus.clean/components/synedit/synedithighlighter.pp components/synedit/synedithighlighter.pp
--- ../lazarus.clean/components/synedit/synedithighlighter.pp 2009-04-07 07:51:40.000000000 +0800
+++ components/synedit/synedithighlighter.pp 2009-05-03 13:13:51.000000000 +0800
@@ -259,6 +259,7 @@
function GetRange: Pointer; virtual;
function GetToken: String; virtual; abstract;
procedure GetTokenEx(out TokenStart: PChar; out TokenLength: integer); virtual; abstract;
+ function GetLineRemainder: TSynHighlighterAttributes; virtual;
function GetTokenAttribute: TSynHighlighterAttributes; virtual; abstract;
function GetTokenKind: integer; virtual; abstract;
function GetTokenPos: Integer; virtual; abstract;
@@ -1079,6 +1080,11 @@
Result := [#33..#255];
end;
+function TSynCustomHighlighter.GetLineRemainder: TSynHighlighterAttributes;
+begin
+ Result := nil;
+end;
+
procedure TSynCustomHighlighter.SetWordBreakChars(AChars: TSynIdentChars);
begin
fWordBreakChars := AChars;
Only in components/synedit/: synedithighlighter.pp~
Only in components/synedit/: synedithighlighter.pp.orig
Only in components/synedit/: synedithighlighter.pp.rej
diff -ur ../lazarus.clean/components/synedit/synedit.pp components/synedit/synedit.pp
--- ../lazarus.clean/components/synedit/synedit.pp 2009-05-03 13:10:49.000000000 +0800
+++ components/synedit/synedit.pp 2009-05-03 13:14:11.000000000 +0800
@@ -2967,6 +2967,7 @@
FGFold, BGfold, FFfold : TColor;
Sfold: TFontStyles;
tok: TRect;
+ Attr : TSynHighlighterAttributes;
begin
{debugln('PaintHighlightToken A TokenAccu: Len=',dbgs(TokenAccu.Len),
' PhysicalStartPos=',dbgs(TokenAccu.PhysicalStartPos),
@@ -2991,6 +2992,10 @@
if bFillToEOL and (rcToken.Left < rcLine.Right) then begin
eolx := rcToken.Left; // remeber end of actual line, so we can decide to draw the right edge
NextPos := Min(LastCol, TokenAccu.PhysicalEndPos+1);
+ if Assigned(fHighlighter) then
+ Attr := fHighlighter.GetLineRemainder
+ else
+ Attr := nil;
Repeat
MarkupInfo := fMarkupManager.GetMarkupAttributeAtRowCol(FFoldedLinesView.TextIndex[CurLine]+1, NextPos);
NextPos := fMarkupManager.GetNextMarkupColAfterRowCol(FFoldedLinesView.TextIndex[CurLine]+1, NextPos);
@@ -2998,7 +3003,12 @@
with fTextDrawer do
if MarkupInfo = nil
then begin
- SetBackColor(colEditorBG);
+ if Not Assigned(Attr) or (Attr.Background = clNone) then begin
+ SetBackColor(colEditorBG);
+ end
+ else begin
+ SetBackColor(Attr.Background);
+ end
//SetForeColor(TokenAccu.FG); // for underline
//SetStyle(TokenAccu.Style);
end
Only in components/synedit/: synedit.pp~
Only in components/synedit/: synedit.pp.orig
Only in components/synedit/: synedit.pp.rej
Only in components/synedit/: units
Only in ../lazarus.clean/components/synedit/design/lib: .svn
Only in ../lazarus.clean/components/synedit/design: .svn
Only in ../lazarus.clean/components/synedit/languages: .svn
Only in ../lazarus.clean/components/synedit/: .svn
diff -ur ../lazarus.clean/components/synedit/syneditfoldedview.pp components/synedit/syneditfoldedview.pp
--- ../lazarus.clean/components/synedit/syneditfoldedview.pp 2009-05-03 13:10:49.000000000 +0800
+++ components/synedit/syneditfoldedview.pp 2009-05-03 13:15:32.000000000 +0800
@@ -265,6 +265,7 @@
procedure Lock;
procedure UnLock;
procedure debug;
+ function DumpFolds : String;
// Action Fold/Unfold
// ColumnIndex can be negative, to access the highest(-1) availabel, 2nd highest(-2) ...
// With Negative, count points downward
@@ -2304,6 +2305,32 @@
fFoldTree.debug;
end;
+function TSynEditFoldedView.DumpFolds : String;
+var
+ i, tpos, cnt : Integer;
+ node : TSynTextFoldAVLNode;
+begin
+ Result := '';
+ node := fFoldTree.FindFoldForFoldedLine(1, true);
+ // ftopline is not a folded line
+ // so node.FoldedBefore(next node after ftopl) does apply
+ tpos := 1 + node.FoldedBefore;
+ cnt := fLines.Count;
+ i := 0;
+ while tpos < cnt do begin
+ if tpos > cnt then begin
+ end else begin
+ if (node.IsInFold) and (tpos+1 = node.StartLine)
+ then Result := Result+IntToStr(tpos)+',';
+ inc(tpos);
+ if (node.IsInFold) and (tpos >= node.StartLine) then begin
+ tpos := tpos + node.LineCount;
+ node := node.Next;
+ end;
+ end;
+ Inc(i);
+ end;
+end;
end.
Only in components/synedit/: syneditfoldedview.pp.orig
diff -ur ../lazarus.clean/components/synedit/synedit.pp components/synedit/synedit.pp
--- ../lazarus.clean/components/synedit/synedit.pp 2009-05-03 13:10:49.000000000 +0800
+++ components/synedit/synedit.pp 2009-05-03 13:16:29.000000000 +0800
@@ -702,6 +702,7 @@
SelectBrackets, OnlyVisible: Boolean
): TPoint; virtual;
//code fold
+ function GetFolds : String;
procedure CodeFoldAction(iLine: integer); deprecated;
function FindNextUnfoldedLine(iLine: integer; Down: boolean): Integer;
procedure UnfoldAll;
@@ -2734,6 +2735,11 @@
end;
{$IFDEF SYN_LAZARUS}
+function TCustomSynEdit.GetFolds : String;
+begin
+ result := FFoldedLinesView.DumpFolds;
+end;
+
procedure TCustomSynEdit.CodeFoldAction(iLine: integer);
// iLine is 1 based as parameter
begin
Only in components/synedit/: synedit.pp~
Only in components/synedit/: synedit.pp.orig
Only in components/synedit/: synedit.pp.rej
Only in components/synedit/: units
laz-find.patch.gz
Description: GNU Zip compressed data
_______________________________________________ Lazarus mailing list [email protected] http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
