Recent

Author Topic: How can i configure outlines using SynFacilSyn  (Read 5258 times)

llutti

  • New Member
  • *
  • Posts: 23
How can i configure outlines using SynFacilSyn
« on: January 30, 2018, 06:12:58 pm »
Firstly, congratulations Edson for your work in SynFacilSyn.

I'm tried to use your component, but I want to active the outline option (new option in Lazarus 1.8).

It's possible? Can you give me any tips on how to do this?

best regards,

Luciano
       

Edson

  • Hero Member
  • *****
  • Posts: 1296
Re: How can i configure outlines using SynFacilSyn
« Reply #1 on: January 30, 2018, 09:30:41 pm »
SynFacilSyn was developed prior to the Outline option in SynEdit and it doesn't consider to implement this option.

Honestly I don't know how the Outline was implemented. If it is at the level of Markups, it is not work of SynFacilSyn, but if it's part of the highlighter maybe in could be activated in SynFacilSyn too.

I will check it later. I'm afraid of, like many other features of SynEdit, it's not documented at all.
Lazarus 2.2.6 - FPC 3.2.2 - x86_64-win64 on Windows 10

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 9754
  • Debugger - SynEdit - and more
    • wiki
Re: How can i configure outlines using SynFacilSyn
« Reply #2 on: January 30, 2018, 10:43:48 pm »
The highlighter needs to mark the (fold) nodes that should be outlined.

this is done by
1) adding outline to the foldconfig for the node's type.

2) when node info is collected (search for)
   if IsCollectingNodeInfo then begin
    CollectingNodeInfoList.Add(node);
adding sfaOutline to Node.FoldAction


Edson

  • Hero Member
  • *****
  • Posts: 1296
Re: How can i configure outlines using SynFacilSyn
« Reply #3 on: January 31, 2018, 12:53:55 am »
Hi Martin.

Do you mean I need to implement FoldConfig (override GetFoldConfigInstance, GetFoldConfigCount and GetFoldConfigInternalCount) in my highlighter to be able to use the Outline feature?

If so, it will be complicated because SynfacilSyn use his own "FoldConfig" structure.
Lazarus 2.2.6 - FPC 3.2.2 - x86_64-win64 on Windows 10

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 9754
  • Debugger - SynEdit - and more
    • wiki
Re: How can i configure outlines using SynFacilSyn
« Reply #4 on: January 31, 2018, 01:20:51 am »
I am not 100% sure. The markup was written by Pascal, and though I went through it, I can not remember all things from the top of my head.

A quick search shows that the module does NOT access FoldConfig. It uses the info returned by
   InitFoldNodeInfo

IIRC that would actually be the way it should be... But not sure, if guaranteed to stay like this. But probably will. But if it ever changes, then all you need is to provide read only structures.

For this to work you must inherit from TSynCustomFoldHighlighter. And that also relies on FoldConfig.
See TSynCustomFoldHighlighter.CollectNodeInfo

For now you can override CollectNodeInfo, and collect the nodes yourself, setting the markup flags as needed.

But TSynCustomFoldHighlighter may in future have more code relying on FoldConfig.

----------------
CollectNodeInfo is also used for folding.

Some basic folding may work without it (not sure how much, and not guaranteed). But try the fold gutter popup menu. IIRC this will display wrong info, if fold node info is missing.


llutti

  • New Member
  • *
  • Posts: 23
Re: How can i configure outlines using SynFacilSyn
« Reply #5 on: January 31, 2018, 10:46:47 am »
Hi,
 
  In my owne Highligther I have implement the outline option, just override the procedure "DoInitNode" and when it's necessary add then "sfaOutlineKeepLevel" in the "FoldAction".

Code: Pascal  [Select][+][-]
  1. procedure TSynLCHighlighter.DoInitNode(var Node: TSynFoldNodeInfo;
  2.   FinishingABlock: Boolean; ABlockType: Pointer; aActions: TSynFoldActions;
  3.   AIsFold: Boolean);
  4. begin
  5.   inherited DoInitNode(Node, FinishingABlock, ABlockType, aActions, AIsFold);
  6.  
  7.   if not FAtLineStart then
  8.   begin
  9.     Node.FoldAction := Node.FoldAction - [sfaFoldHide];
  10.   end;
  11.  
  12.   if  (ABlockType <> nil)
  13.   and (TLCCodeFoldBlockType(PtrUInt(ABlockType)) = cfbtLCInicioFim) then
  14.   begin
  15.     Include( Node.FoldAction, sfaOutlineKeepLevel);
  16.   end;  
  17. end;
  18.  

   Regard's

Luciano

Edson

  • Hero Member
  • *****
  • Posts: 1296
Re: How can i configure outlines using SynFacilSyn
« Reply #6 on: January 31, 2018, 03:43:25 pm »
Hi,
 
  In my owne Highligther I have implement the outline option, just override the procedure "DoInitNode" and when it's necessary add then "sfaOutlineKeepLevel" in the "FoldAction".


Good. Maybe you can propose a patch to SynFacilSyn to implement Outlines.
Lazarus 2.2.6 - FPC 3.2.2 - x86_64-win64 on Windows 10

llutti

  • New Member
  • *
  • Posts: 23
Re: How can i configure outlines using SynFacilSyn
« Reply #7 on: January 31, 2018, 05:22:55 pm »
Hi Edson,

   I'll come to study "SynEditSyn" a bit more and propose the necessary changes to add the "outline" option.

   Regards,

Luciano

Edson

  • Hero Member
  • *****
  • Posts: 1296
Re: How can i configure outlines using SynFacilSyn
« Reply #8 on: January 31, 2018, 06:29:10 pm »
OK. If you have any question about SynFacilSyn, just ask. As a first aid you can read the technical documentation in https://github.com/t-edson/SynFacilSyn/tree/1.20/Docs

There is too, a copy of a Documentation I made about SynEdit, in spanish (La Biblia del SynEdit - Rev7.pdf).
Lazarus 2.2.6 - FPC 3.2.2 - x86_64-win64 on Windows 10

llutti

  • New Member
  • *
  • Posts: 23
Re: How can i configure outlines using SynFacilSyn
« Reply #9 on: February 01, 2018, 02:23:40 pm »
Hi,

    I was able to activate the outline option by simply calling the CollectNodeInfo procedure in the start / stop block procedures in the unit SynFacilHighlighter.

   It's possible make better, but this is the start.

    Those are the procedures I changed (the changes are marked with comment llutti at the end of line):

Code: Pascal  [Select][+][-]
  1. procedure TSynFacilSyn.StartBlock(ABlockType: Pointer; IncreaseLevel: Boolean); inline;
  2. //Procedimiento general para abrir un bloque en el resaltador
  3. begin
  4. //  StartCodeFoldBlock(ABlockType, IncreaseLevel);
  5.  
  6.   if IsCollectingNodeInfo then // llutti
  7.   begin // llutti
  8.     CollectNodeInfo(False, ABlockType, IncreaseLevel); // llutti
  9.   end; // llutti
  10.  
  11.   CodeFoldRange.Add(ABlockType, IncreaseLevel);
  12. end;
  13.  

Code: Pascal  [Select][+][-]
  1. procedure TSynFacilSyn.EndBlock(DecreaseLevel: Boolean); inline;
  2. //Procedimiento general para cerrar un bloque en el resaltador
  3. var // llutti
  4.   BlockType: Pointer; // llutti
  5. begin
  6. //  EndCodeFoldBlock(DecreaseLevel);
  7.  
  8.   BlockType := TopCodeFoldBlockType; // llutti
  9.   if IsCollectingNodeInfo then // llutti
  10.   begin // llutti
  11.     CollectNodeInfo(True, BlockType, DecreaseLevel); // llutti
  12.   end; // llutti
  13.  
  14.   CodeFoldRange.Pop(DecreaseLevel);
  15. end;
  16.  

Code: Pascal  [Select][+][-]
  1. procedure TSynFacilSyn.StartBlockAndFirstSec(const blk, firstSec: TfaSynBlock);
  2. {Abre un bloque TfaSynBlock, verifica si tiene una primera sección para abrir.}
  3. var Cancel: boolean;
  4. begin
  5.   Cancel := false;
  6.   if blk.OnBeforeOpen<>nil then blk.OnBeforeOpen(blk, Cancel);
  7.   if Cancel then exit;
  8.  
  9.   if IsCollectingNodeInfo then // llutti
  10.   begin // llutti
  11.     CollectNodeInfo(False, blk, blk.showFold); // llutti
  12.   end; // llutti
  13.  
  14.   CodeFoldRange.Add(blk, blk.showFold);
  15.  
  16.   //verifica si hay primera sección para abrir
  17.   if firstSec <> nil then
  18.   begin // llutti
  19.     if IsCollectingNodeInfo then // llutti
  20.     begin // llutti
  21.       CollectNodeInfo(False, firstSec, firstSec.showFold); // llutti
  22.     end; // llutti
  23.  
  24.     CodeFoldRange.Add(firstSec, firstSec.showFold);
  25.   end; // llutti
  26. end;
  27.  

Code: Pascal  [Select][+][-]
  1. procedure TSynFacilSyn.StartBlockFa(const blk: TfaSynBlock);
  2. {Abre un bloque TfaSynBlock.}
  3. var Cancel: boolean;
  4. begin
  5.   Cancel := false;
  6.   if blk.OnBeforeOpen<>nil then blk.OnBeforeOpen(blk, Cancel);
  7.   if Cancel then exit;
  8.  
  9.   if IsCollectingNodeInfo then // llutti
  10.   begin // llutti
  11.     CollectNodeInfo(False, blk, blk.showFold); // llutti
  12.   end; // llutti
  13.  
  14.   CodeFoldRange.Add(blk, blk.showFold);
  15. end;
  16.  

Code: Pascal  [Select][+][-]
  1. procedure TSynFacilSyn.EndBlockFa(const blk: TfaSynBlock);
  2. {Cierra un bloque TfaSynBlock. El parámetro blk, no debería ser necesario, puesto que
  3. se supone que siemprer se cerrará el último abierto.}
  4. var
  5.   Cancel: boolean;
  6.   BlockType: Pointer; // llutti
  7. begin
  8.   Cancel := false;
  9.   if blk.OnBeforeClose<>nil then blk.OnBeforeClose(blk, Cancel);
  10.   if Cancel then exit;
  11.  
  12.   BlockType := TopCodeFoldBlockType; // llutti
  13.   if IsCollectingNodeInfo then // llutti
  14.   begin // llutti
  15.     CollectNodeInfo(True, BlockType, blk.showFold); // llutti
  16.   end; // llutti
  17.  
  18.   CodeFoldRange.Pop(blk.showFold);
  19. end;  
  20.  

  Regards

Luciano

   
« Last Edit: February 01, 2018, 02:28:17 pm by llutti »

Edson

  • Hero Member
  • *****
  • Posts: 1296
Re: How can i configure outlines using SynFacilSyn
« Reply #10 on: February 02, 2018, 02:47:18 am »
Hi,
    I was able to activate the outline option by simply calling the CollectNodeInfo procedure in the start / stop block procedures in the unit SynFacilHighlighter.
   It's possible make better, but this is the start.
    Those are the procedures I changed (the changes are marked with comment llutti at the end of line):

Hi llutti.

I have updated these procedures but I don't see the outline in a text. Do I need to activate some flag?
Lazarus 2.2.6 - FPC 3.2.2 - x86_64-win64 on Windows 10

llutti

  • New Member
  • *
  • Posts: 23
Re: How can i configure outlines using SynFacilSyn
« Reply #11 on: February 02, 2018, 10:27:12 am »
Hi Edson,

  Yes, you need to add the Fold Colors Markup like this:

Code: Pascal  [Select][+][-]
  1. synEdit1.MarkupManager.AddMarkUp(TSynEditMarkupFoldColors.Create(synEdit1));
  2.  

  Regards,

Luciano

Edson

  • Hero Member
  • *****
  • Posts: 1296
Re: How can i configure outlines using SynFacilSyn
« Reply #12 on: February 02, 2018, 04:28:00 pm »
OK. It works.

There are some strange cases when activated the markup and the outline with some syntax definition, but I guess it's the way SynFacilSyn works and Markups are defined. I guess the Markups are designed to work with Pascalish syntax.

It needs to be studied in more detail.
Lazarus 2.2.6 - FPC 3.2.2 - x86_64-win64 on Windows 10

llutti

  • New Member
  • *
  • Posts: 23
Re: How can i configure outlines using SynFacilSyn
« Reply #13 on: February 02, 2018, 04:56:05 pm »
Hi,

 Great news.

 Really, this markup has various types different the configuration. In Pascal HL has all (I think) configurate.

 I think the better way to adapt the SynFacilSyn now it's custom the procedure CollectNodeInfo and/or DoInitNode, because this procedure is where the markup is configurate.

  The Pascal HL has the configuration in DoInitNode. See the code:

Code: Pascal  [Select][+][-]
  1. procedure TSynPasSyn.DoInitNode(var Node: TSynFoldNodeInfo;
  2.   FinishingABlock: Boolean; ABlockType: Pointer; aActions: TSynFoldActions;
  3.   AIsFold: Boolean);
  4. var
  5.   PasBlockType: TPascalCodeFoldBlockType;
  6.   EndOffs: Integer;
  7.   OneLine: Boolean;
  8. begin
  9.   PasBlockType := TPascalCodeFoldBlockType(PtrUint(ABlockType));
  10.  
  11.   if FinishingABlock then
  12.     EndOffs := -1
  13.   else
  14.     EndOffs := +1;
  15.   //inherited DoInitNode(Node, FinishingABlock, ABlockType, aActions, AIsFold);
  16.   aActions := aActions + [sfaMultiLine];
  17.  
  18.   if (not FinishingABlock) and  (ABlockType <> nil) then begin
  19.     if (PasBlockType in [cfbtIfThen,cfbtForDo,cfbtWhileDo,cfbtWithDo,cfbtIfElse]) then
  20.       //Include( aActions, sfaOutlineKeepLevelOnSameLine);
  21.       Include( aActions, sfaOutlineKeepLevel);
  22.  
  23.     //if (PasBlockType in [cfbtIfElse]) then
  24.     //  Include( aActions, sfaOutlineMergeLevelOnWrongCol);
  25.  
  26.     if (PasBlockType in [cfbtClassSection]) then
  27.       Include( aActions, sfaOutlineMergeParent);
  28.  
  29.     if (PasBlockType in [cfbtProcedure]) then
  30.       aActions := aActions + [sfaOutlineKeepLevel,sfaOutlineNoColor];
  31.  
  32.     //if (PasBlockType in [cfbtProcedure]) and (InProcLevel > 0) then //nested
  33.     //  aActions := aActions + [sfaOutlineForceIndent];
  34.  
  35.     if (PasBlockType in [cfbtExcept]) then
  36.       Include( aActions, sfaOutlineMergeParent);
  37.  
  38.    // if (PasBlockType in [cfbtIfThen, cfbtClass,cfbtRecord]) then
  39.     //  aActions := aActions + [sfaOutlineNoLine];
  40.   end;
  41.  
  42.   Node.LineIndex := LineIndex;
  43.   Node.LogXStart := Run;
  44.   Node.LogXEnd := Run + fStringLen;
  45.   Node.FoldType := Pointer({%H-}PtrInt(ABlockType)); //Pointer(PtrUInt(PasBlockType));
  46.   Node.FoldTypeCompatible := Pointer(PtrUInt(PascalFoldTypeCompatibility[PasBlockType]));
  47.   Node.FoldAction := aActions;
  48.   case PasBlockType of
  49.     cfbtRegion:
  50.       begin
  51.         node.FoldGroup := FOLDGROUP_REGION;
  52.         if AIsFold then
  53.           Node.FoldLvlStart := FSynPasRangeInfo.EndLevelRegion
  54.         else
  55.           Node.FoldLvlStart := 0;
  56.         Node.NestLvlStart := FSynPasRangeInfo.EndLevelRegion;
  57.         OneLine := FinishingABlock and (Node.FoldLvlStart > FSynPasRangeInfo.MinLevelRegion);
  58.       end;
  59.     cfbtIfDef:
  60.       begin
  61.         node.FoldGroup := FOLDGROUP_IFDEF;
  62.         if AIsFold then
  63.           Node.FoldLvlStart := FSynPasRangeInfo.EndLevelIfDef
  64.         else
  65.           Node.FoldLvlStart := 0;
  66.         Node.NestLvlStart := FSynPasRangeInfo.EndLevelIfDef;
  67.         OneLine := FinishingABlock and (Node.FoldLvlStart > FSynPasRangeInfo.MinLevelIfDef);
  68.       end;
  69.     else
  70.       begin
  71.         //inherited DoInitNode(Node, FinishingABlock, ABlockType, aActions, AIsFold);
  72.         node.FoldGroup := FOLDGROUP_PASCAL;
  73.         if AIsFold then begin
  74.           Node.FoldLvlStart := PasCodeFoldRange.CodeFoldStackSize;
  75.           Node.NestLvlStart := PasCodeFoldRange.NestFoldStackSize;
  76.           OneLine := FinishingABlock and (Node.FoldLvlStart > PasCodeFoldRange.MinimumCodeFoldBlockLevel); // MinimumCodeFoldBlockLevel);
  77.         end else begin
  78.           Node.FoldLvlStart := PasCodeFoldRange.NestFoldStackSize; // CodeFoldStackSize; ? but fails test // Todo: zero?
  79.           Node.NestLvlStart := PasCodeFoldRange.NestFoldStackSize;
  80.           OneLine := FinishingABlock and (Node.NestLvlStart > PasCodeFoldRange.MinimumNestFoldBlockLevel); // MinimumCodeFoldBlockLevel);
  81.         end;
  82.       end;
  83.   end;
  84.   Node.NestLvlEnd := Node.NestLvlStart + EndOffs;
  85.   if not (sfaFold in aActions) then
  86.     EndOffs := 0;
  87.   Node.FoldLvlEnd := Node.FoldLvlStart + EndOffs;
  88.   if OneLine then  // find opening node
  89.     RepairSingleLineNode(Node);
  90. end;
  91.  

  Regards

  Luciano

 

TinyPortal © 2005-2018