Skip to content

Latest commit

 

History

History
89 lines (71 loc) · 3.2 KB

CodeFolding.md

File metadata and controls

89 lines (71 loc) · 3.2 KB

Code folding support

Introduction

This pull request adds code folding support for SynEdit. It blends well with the Synedit highligting infrastructure and provides fast and efficient code folding that can cope with files with tens of thousands of lines without lags.

Converting existing highlighters

To support code folding a Highlighter must inherit from TSynCustomCodeFoldingHighlighter and implement one abstact procedure

ScanForFoldRanges(FoldRanges: TSynFoldRanges;
LinesToScan: TStrings; FromLine: Integer; ToLine: Integer);

For each line, ScanForFoldRanges needs to call one of the following:

FoldRanges.StartFoldRange
FoldRanges.StopFoldRange
FoldRanges.NoFoldInfo

ScanForFoldRanges is called after the standard highlighter scanning has taken place so one can use the Range information stored inside LinesToScan, which is a TSynEditStringList, to avoid duplicating effort.

Initally two hightlighters have been converted SynHighlighterJScript and SynHighlighterPython, to serve as examples of adding code folding support to brace-based and indentation-based languagges.

Alternatively, code folding support can be provided just by implementing the SynEdit OnScanForFoldRangesEvent event.

Demo of Coding Folding

A Folding demo has been added that demonstrates the use of the JScript and Python highlighters as well as the use of the OnScanForFoldRangesEvent event to support code folding in C++ files.

Synedit Commants and Shortcuts

The following commands have been added: ecFoldAll, ecUnfoldAll, ecFoldNearest, ecUnfoldNearest, ecFoldLevel1, ecFoldLevel2, ecFoldLevel3,, ecUnfoldLevel1, ecUnfoldLevel2, ecUnfoldLevel3, ecFoldRegions, ecUnfoldRegions.

The default customisable shortcuts are:

AddKey(ecFoldAll, VK_OEM_MINUS, [ssCtrl, ssShift]);   //- _
AddKey(ecUnfoldAll,  VK_OEM_PLUS, [ssCtrl, ssShift]); //= +
AddKey(ecFoldNearest, VK_OEM_2, [ssCtrl]);  // Divide //'/'
AddKey(ecUnfoldNearest, VK_OEM_2, [ssCtrl, ssShift]);
AddKey(ecFoldLevel1, ord('K'), [ssCtrl], Ord('1'), [ssCtrl]);
AddKey(ecFoldLevel2, ord('K'), [ssCtrl], Ord('2'), [ssCtrl]);
AddKey(ecFoldLevel3, ord('K'), [ssCtrl], Ord('3'), [ssCtrl]);
AddKey(ecUnfoldLevel1, ord('K'), [ssCtrl, ssShift], Ord('1'), [ssCtrl,
ssShift]);
AddKey(ecUnfoldLevel2, ord('K'), [ssCtrl, ssShift], Ord('2'), [ssCtrl,
ssShift]);
AddKey(ecUnfoldLevel3, ord('K'), [ssCtrl, ssShift], Ord('3'), [ssCtrl,
ssShift]);

Limitations

  • Code folding can not be used simultaneously with Wordwrap. Synedit takes care of that.

  • The code uses generic collections, so it cannot be used with Delphi versions prior to Delphi 2009.

Improvements

Although the code folding infrastructure is fairly complete, improvements can be made in providing the user with more painting options (folding hints etc.)

Technical details

The main code folding structure is TSynFoldRanges in SynEditCodefolding.pas. It contains a public TList<TSynFoldRange> (sorted by starting line numbers). This list is used by Synedit to paint the gutter and lines, fold and unfold ranges etc. Internally, TSynFoldRange maintains a TList<TLineFoldInfo> that is modified during scanning. The TList<TSynFoldRange> is reconstructed from the TList<TLineFoldInfo> only when it is necessary.