Recent

Author Topic: Invite to Colorizing TSynEdit ! {Improving Editor for Editing Complex Codes}  (Read 112052 times)

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 5769
    • wiki
Re: Invite to Colorizing TSynEdit ! {Improving Editor for Editing Complex Codes}
« Reply #120 on: December 16, 2015, 04:58:34 pm »
Last time I checked (a few days ago) you still didn't have working invalidation.

1) add spaces at a line that contains a begin, the vert line moves.
2) place caret 10 lines below
3) hit undo.

But similar with codetools, and linked editors.

You may need to keep a list for all visible lines where you painted, and then on DoTextChanged find the lines that changed and invalidate

Code: Pascal  [Select]
  1.   if EndLine < 0 then exit; //already refreshed by syn
  2.  
Dont worry. Invalidating already invalidated lines is no problem. Synedit catches it in some cases, otherwise the OS handles it as null op.
« Last Edit: December 16, 2015, 05:00:48 pm by Martin_fr »

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 5769
    • wiki
Re: Invite to Colorizing TSynEdit ! {Improving Editor for Editing Complex Codes}
« Reply #121 on: December 16, 2015, 05:13:57 pm »
Quote
I also would reapply that rule into the if-then make if the longest line, over the then,begin and else,begin. whooaa..... :-[
The reason is: I don't really want to fold/unfold at "then" (current rule), instead I want at "if". I believe other people want too.
* Was it a mistake to fold/unfold at "then". ?

yes and no. fold rules may need to be changed. But the current one are there for a reason.

If (and before) they get changed, the testcase (folder test) must contain sufficient tests, that they work in all variations and configs.

To merge the begin/end in the else, a foldblock for the else must be added (terminated by either ";", end, until, ....)

Similar foldblocks for while and others may be needed (and only enabled, if your markup is active / that is if they have sfaOutline, because then it is assumed that a markup is active). Maybe a global switch.... but not important now.

For your test HL that is ok. then again since all is configurable your code needs to do something if they are absent too.



merging doInitNode to pas hl is fine, but it is a completely independent task. so it should not mix with any of the other changes. If there is a stable diff for that then it can be merged.



Quote
Code: Pascal  [Select]
  1.       StartPascalCodeFoldBlock(cfbtCaseElse);
  2.       FTokenIsCaseLabel := True; //<-------------------------------bug
  3.  

Why is it a bug, where does it go wrong?



I look at the latest changes later


Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 5769
    • wiki
Re: Invite to Colorizing TSynEdit ! {Improving Editor for Editing Complex Codes}
« Reply #122 on: December 16, 2015, 06:06:33 pm »
Code: Pascal  [Select]
  1.     if not BlockConfExists then
  2.       act := act + [sfaFold,sfaFoldFold, sfaMarkup, sfaOutline];
  3.  
You will eventually have to add foldconf to any HL that should support this.

x2nie

  • Sr. Member
  • ****
  • Posts: 478
  • Impossible=I don't know the way
    • impossible is nothing - www.x2nie.com
Re: Invite to Colorizing TSynEdit ! {Improving Editor for Editing Complex Codes}
« Reply #123 on: December 17, 2015, 03:45:07 am »
Code: Pascal  [Select]
  1.       StartPascalCodeFoldBlock(cfbtCaseElse);
  2.       FTokenIsCaseLabel := True; //<-------------------------------bug
  3.  

Why is it a bug, where does it go wrong?


The order.
FTokenIsCaseLabel is seemly needed to distinct whether an identifier is a Case's Label or not.
If it NOT set to True, then in DoInitNode the identifier is not related to foldConfig. which is a bug. DoInitNode is called in every StartPascalCodeFoldBlock( ).

The bug is probably not visible, but when using my markup, there is obviously a bug.
.see my complete post, for correction of the order.
« Last Edit: December 17, 2015, 04:03:17 am by x2nie »
When you were logged in, you can see attachments.
Lazarus Trunk @ Windows7 64bit, XP 32bit, Debian under VirtualMachine

x2nie

  • Sr. Member
  • ****
  • Posts: 478
  • Impossible=I don't know the way
    • impossible is nothing - www.x2nie.com
Re: Invite to Colorizing TSynEdit ! {Improving Editor for Editing Complex Codes}
« Reply #124 on: December 17, 2015, 03:52:45 am »
Quote
When you prepare FHighlights, then you know how many outer lines there are. So you can set the colors from the content of FHighlights.
:o You have said it several time, but sorry for my stupid, I don't understand yet either.  Maybe, I should just go forward, forgeting it for now.

Lets start with this one.

If I read your code correctly:

Step 1:
you add all nodes to FHighlights.
First from the current line, then from TLazSynEditNestedFoldsList. As a result the innermost node is at index 0.
You will have to add duplicates at the same x pos, so you can NOT
    if FHighlights.X = x then    exit;
but instead add a flag to this node.

Then before you sort them (SortLeftMostFI), do something like
Code: Pascal  [Select]
  1. a := 0
  2. for i = high(FHighlights) downto 0 do begin// start at the outermost)
  3.   FHighlights[i].color = a mod lenght(colors).
  4.   inc(a)
  5. end
  6.  

And you got your colors. Of course if you want to join 2 lines, do not inc the color.

And that way you do not need any level from the HL at all.

Eureka!
Wow, @Martin, it helped me a lot. It is the missing part that puzzled me in before. Now I know where the sfaOutlineMergeParent info is useful.
When you were logged in, you can see attachments.
Lazarus Trunk @ Windows7 64bit, XP 32bit, Debian under VirtualMachine

x2nie

  • Sr. Member
  • ****
  • Posts: 478
  • Impossible=I don't know the way
    • impossible is nothing - www.x2nie.com
Re: Invite to Colorizing TSynEdit ! {Improving Editor for Editing Complex Codes}
« Reply #125 on: December 18, 2015, 11:06:03 am »
I did, as result, your ideas solves many problem


I introduced many actions as needed. I may add/remove/change later.

  • sfaOutline
    This node will be higlighted by nested color replacing the token color
    Its needed for all node being painted by nested-coloring
    -
  • sfaOutlineKeepColor,
    Direct children should not increase color dept. (But grandchild can.)  e.g. "if","then" any "procedure"
    This way, one statement can be colored by single: if blah then repeat foo until bew else while bar do begin end
    -
  • sfaOutlineMergeParent,
    This node want to decrease current color depth. (But Previous sibling increased) e.g. "except", "finally"
    -
  • sfaOutlineForceIndent,
    Node will temporary ignore sfaOutlineKeep. (Next sibling can.) e.g in NESTED "procedure"
    -
  • sfaOutlineHidden,     
    Node will not painted by nested-coloring, but may increase color (e.g. any "procedure")     
    Without this, nested procedure will be colored by similar color.
    contrary with disabling/excluding fmOutline (which will completely ignored), the node with sfaOutlineHidden will still be calculated.


Code: Pascal  [Select]
  1. sfaOutline,  // This node will be higlighted by nested color replacing the token color
  2. sfaOutlineKeepColor, // Direct children should not increase color dept. (But grandchild can.)  e.g. "if","then" any "procedure"
  3. sfaOutlineMergeParent,// This node want to decrease current color depth. (But Previous sibling increased) e.g. "except", "finally"
  4. sfaOutlineForceIndent, // Node will temporary ignore sfaOutlineKeep. (Next sibling can.) e.g in NESTED "procedure"
  5. sfaOutlineHidden,      // Node will not painted by nested-coloring, but may increase color (e.g. any "procedure")    


I have a little bit problem with closing fold tags.
I am still trying  8-)
When you were logged in, you can see attachments.
Lazarus Trunk @ Windows7 64bit, XP 32bit, Debian under VirtualMachine

x2nie

  • Sr. Member
  • ****
  • Posts: 478
  • Impossible=I don't know the way
    • impossible is nothing - www.x2nie.com
Re: Invite to Colorizing TSynEdit ! {Improving Editor for Editing Complex Codes}
« Reply #126 on: December 19, 2015, 02:13:29 pm »
Hello!  :)


I am very happy with my last modification.
Finally (after 2 days trying), I can connect each closing-tag's color with their pair opening-tag.
It's only can be done if closing tag has indentical BlockType with opening one.


So let make a deal, PAS (and any other) hl should be redesigned (a little bit modification),
because PAS hl seem as sometime closes fold block with unknown block type.
When you were logged in, you can see attachments.
Lazarus Trunk @ Windows7 64bit, XP 32bit, Debian under VirtualMachine

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 5769
    • wiki
Re: Invite to Colorizing TSynEdit ! {Improving Editor for Editing Complex Codes}
« Reply #127 on: December 19, 2015, 03:58:51 pm »
It's only can be done if closing tag has indentical BlockType with opening one.


So let make a deal, PAS (and any other) hl should be redesigned (a little bit modification),
because PAS hl seem as sometime closes fold block with unknown block type.

Example?

This shouldn't be possible. (not if there is valid code).

However closing tags may have 0 size, or NO location:
Code: Pascal  [Select]
  1. procedure foo,
  2. var
  3.   a: boolean;
  4. begin
  5.  
The var block just ends. there is no keyword for that.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 5769
    • wiki
Re: Invite to Colorizing TSynEdit ! {Improving Editor for Editing Complex Codes}
« Reply #128 on: December 19, 2015, 05:05:42 pm »
Also for this you can use the foldlevel.

if the foldlevel is equal (using it's value only for comparison with other foldlevel) then that is the closing tag. 

If the level is less, then the block was already closed.

EDIT: verify it is in the same fold group too
« Last Edit: December 19, 2015, 05:43:50 pm by Martin_fr »

x2nie

  • Sr. Member
  • ****
  • Posts: 478
  • Impossible=I don't know the way
    • impossible is nothing - www.x2nie.com
Re: Invite to Colorizing TSynEdit ! {Improving Editor for Editing Complex Codes}
« Reply #129 on: December 19, 2015, 07:08:21 pm »
It's only can be done if closing tag has indentical BlockType with opening one.


So let make a deal, PAS (and any other) hl should be redesigned (a little bit modification),
because PAS hl seem as sometime closes fold block with unknown block type.
This shouldn't be possible. (not if there is valid code).

However closing tags may have 0 size, or NO location:
Code: Pascal  [Select]
  1. procedure foo,
  2. var
  3.   a: boolean;
  4. begin
  5.  
The var block just ends. there is no keyword for that.

Even "var" fold block has closing-fold-block. Yeah, the size is maybe zero.
But my current code depends too-much on the very-identical BlockType between open~close tag.


Let's make it clear.
* The original PAS HL (I didn't touch) implements it's own version of InitNode,StartPascalBlock,EndPascalBlock...
so it yet able to fill the correct blocktype.
* But once it needed to obey the changes made in the base class, it's will NOT have opportunity to tell what's the BlockType of closing tag.
It is because the definitions :
StartCodeFoldBlock(p+Pointer(PtrInt(ABlockType)), FoldBlock));
EndCodeFoldBlock(DecreaseLevel);

Okay, if I can't trust the FoldBlockType (because it may difficult to do / too muuch changes needed), i will try to believe in FoldGroup.
Yes, I also worry/confusing about similar block level of inner contents of between {$IFDEF}... & {$ELSE}....
« Last Edit: December 19, 2015, 07:10:48 pm by x2nie »
When you were logged in, you can see attachments.
Lazarus Trunk @ Windows7 64bit, XP 32bit, Debian under VirtualMachine

x2nie

  • Sr. Member
  • ****
  • Posts: 478
  • Impossible=I don't know the way
    • impossible is nothing - www.x2nie.com
Re: Invite to Colorizing TSynEdit ! {Improving Editor for Editing Complex Codes}
« Reply #130 on: December 20, 2015, 05:01:20 am »
anyway, my markup slowdown when scroll at about 4000 lines.
I test using GR32.pas ( has 6500 lines).
But it fast enough at earlier lines ( < 1000 ) using the same file
When you were logged in, you can see attachments.
Lazarus Trunk @ Windows7 64bit, XP 32bit, Debian under VirtualMachine

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 5769
    • wiki
Re: Invite to Colorizing TSynEdit ! {Improving Editor for Editing Complex Codes}
« Reply #131 on: December 20, 2015, 05:13:11 am »
Quote
The original PAS HL (I didn't touch) implements it's own version of InitNode,StartPascalBlock,EndPascalBlock...

Then for now it keeps its own. That can be independently reviewed later.

Quote
anyway, my markup slowdown when scroll at about 4000 lines.
I test using GR32.pas ( has 6500 lines).
But it fast enough at earlier lines ( < 1000 ) using the same file

I might look at it, but later.
I will be travelling. I'll be online but with limited time, and limited access to sources etc.


x2nie

  • Sr. Member
  • ****
  • Posts: 478
  • Impossible=I don't know the way
    • impossible is nothing - www.x2nie.com
Re: Invite to Colorizing TSynEdit ! {Improving Editor for Editing Complex Codes}
« Reply #132 on: December 21, 2015, 03:58:52 am »
anyway, my markup slowdown when scroll at about 4000 lines.
I test using GR32.pas ( has 6500 lines).
But it fast enough at earlier lines ( < 1000 ) using the same file


I got it!
Finding parent + grandpa in TLazSynEditNestedFoldsList, will always continue until the most top the "unit" keyword (root of folds, at first line ) founded !
And it is repeated for each line in my markup class.  :'( (it's not my fault, its default behaviour of NestedFoldLIst).
Anyway, It (find till "unit") is not required by another markup (such as triplet WordGroup markup).


Actually my markup didn't require it (find till "unit") either. Because the first fold to be colored is "procedure".
But naturally TLazSynEditNestedFoldsList will not stop until first  (#zero ) grand parent fold reached.
Yes obviously there are not used grand parents : "unit", "interface", "implementation".
That is why my markup was slowing down: repeat searching the "unit" for each visible line.


---
I have a quick solution: stop search the grand parent when the "procedure" keyword is just reached.
This way, will make my markup only work in Pascal Highlighter, or may need some complex configuration for other HL.


But, you have had another solution: to cache the finding parent in NestedFoldList class.
This way will keep markup independent for any HL.
Using cache will speedup finding root, because of reusing the founded grand parent instead of actual repeated finding.


I think the second (yours) solution is far better.
but,well, my internal problem is TLazSynEditNestedFoldsList just too complex for my brain.
No worry, I am creating my own NestedFold getter class. It will be easier for me when create new class with that everything is under control.
Anther reason is I also hate the ReleaseReference + AddReference (aliens) things.  >:D
It's far better to use Create + Free. Which are common and predicable behavior.



Overall, have a nice day @Martin_fr. Have a nice trip !
I most probably send you pictures rather than ask to check the source code.
Thanks
When you were logged in, you can see attachments.
Lazarus Trunk @ Windows7 64bit, XP 32bit, Debian under VirtualMachine

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 5769
    • wiki
Re: Invite to Colorizing TSynEdit ! {Improving Editor for Editing Complex Codes}
« Reply #133 on: December 21, 2015, 04:01:38 am »
Quote
I got it!
Finding parent + grandpa in TLazSynEditNestedFoldsList, will always continue until the most top the "unit" keyword (root of folds, at first line ) founded !

I have several ideas how to fix that. But dont have the time now, so later.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 5769
    • wiki
Re: Invite to Colorizing TSynEdit ! {Improving Editor for Editing Complex Codes}
« Reply #134 on: December 21, 2015, 04:06:39 am »
Quote
I got it!
Finding parent + grandpa in TLazSynEditNestedFoldsList, will always continue until the most top the "unit" keyword (root of folds, at first line ) founded !

I have several ideas how to fix that. But dont have the time now, so later.

edit:
Quote
I have a quick solution: stop search the grand parent when the "procedure" keyword is just reached.
This way, will make my markup only work in Pascal Highlighter, or may need some complex configuration for other HL.

add virtual (pas needs to override to return correct) method to foldblock to return fold-type, then look up fold conf, and look at modes. then you can go up foldblocks to see if you need to scan.

---------
remember last line, and if line increased by one, use the data you have. (EndMarkup to clear cache)

Also if min-level equals last lines end level, then nothing changes on a line.

----------
I rewrite in more detail at some time



----
Quote
Anther reason is I also hate the ReleaseReference + AddReference (aliens) things.  >:D
It's far better to use Create + Free. Which are common and predicable behavior.
compile with assert enabled.

I explain the background on them later
« Last Edit: December 21, 2015, 04:08:12 am by Martin_fr »