Sign in Join
Wiki copytemporary

SynEdit Highlighter: what changed

Revision 3 to 4. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
1-For more info on SynEdit go to: [[SynEdit]]\
1+For more info on SynEdit go to: [[SynEdit]]
22Also see [[SynEdit Markup]]
33
4-------------------------------------------------------------------------
4+* * *
55
66# Understanding the SynEdit Highlighter
77
88## SynEdit - Highlighter relationship
99
10-**SynEdit to Highlighter** have an **N to 1** relationship.
10+**SynEdit to Highlighter** have an **N to 1** relationship.
1111
12-- One instance of a Highlighter can serve **N** (many) instances of SynEdits
13-- Each SynEdit only has one Highlighter
14-- But: one text (text-buffer) can have many highlighters, if shared by several SynEdit (each SynEdit will have one HL, but all HL will work on the same document)
12+ * One instance of a Highlighter can serve **N** (many) instances of SynEdits
13+ * Each SynEdit only has one Highlighter
14+ * But: one text (text-buffer) can have many highlighters, if shared by several SynEdit (each SynEdit will have one HL, but all HL will work on the same document)
1515
16-As a result of this:
16+As a result of this:
1717
18-- no Highlighter Instance has a (fixed) reference to the SynEdit.
18+ * no Highlighter Instance has a (fixed) reference to the SynEdit.
1919
20-
2120(Highlighters however keep a list of SynEditTextBuffers to which they are attached)
2221
23-- All data for the Highlighter is (and must be) stored on the SynEdit (actually on the TextBuffer of SynEdit (referred to as "Lines").
22+ * All data for the Highlighter is (and must be) stored on the SynEdit (actually on the TextBuffer of SynEdit (referred to as "Lines").
2423
25-However, before each call to the Highlighter, SynEdit ensures that Highlighter.CurrentLines is set to the current SynEdits Lines. This way the highlighter can access the data whenever needed. The Format of the data storage is determined by the highlighter (TSynCustomHighlighter.AttachToLines).
24+However, before each call to the Highlighter, SynEdit ensures that Highlighter.CurrentLines is set to the current SynEdits Lines. This way the highlighter can access the data whenever needed. The Format of the data storage is determined by the highlighter (TSynCustomHighlighter.AttachToLines).
2625
2726## Scanning and Returning Highlight attributes
2827
29-The Highlighter is expected to work on a per Line base.
28+The Highlighter is expected to work on a per Line base.
3029
31-If any text was modified, SynEdit will call (TSynCustomHighlighter.ScanFrom / Currently called from TSynEdit.ScanFrom) with the line range. The Highlighter should know the state of the previous line.
30+If any text was modified, SynEdit will call (TSynCustomHighlighter.ScanFrom / Currently called from TSynEdit.ScanFrom) with the line range. The Highlighter should know the state of the previous line.
3231
33-If Highlight attributes are required, SynEdit will request them per Line too. SynEdit will loop through individual tokens on a line. This currently happens from nested proc PaintLines in SynEdit.PaintTextLines. It calls TSynCustomHighlighter.StartAtLineIndex, followed by HL.GetTokenEx/HL.GetTokenAttribute for as long as HL.GetEol is false.
32+If Highlight attributes are required, SynEdit will request them per Line too. SynEdit will loop through individual tokens on a line. This currently happens from nested proc PaintLines in SynEdit.PaintTextLines. It calls TSynCustomHighlighter.StartAtLineIndex, followed by HL.GetTokenEx/HL.GetTokenAttribute for as long as HL.GetEol is false.
3433
35-Also the BaseClass for the Highlighter's data (see AttachToLines) is based on per line storage, and SynEdit's TextBuffer (Lines) do maintenance on this data to keep it synchronized. That is: whenever lines of text are inserted or removed, so are entries inserted or removed from the highlighters data (hence it must have one entry per line).
34+Also the BaseClass for the Highlighter's data (see AttachToLines) is based on per line storage, and SynEdit's TextBuffer (Lines) do maintenance on this data to keep it synchronized. That is: whenever lines of text are inserted or removed, so are entries inserted or removed from the highlighters data (hence it must have one entry per line).
3635
37-Usually Highlighters store the end-of-line-status in this field. So if the highlighter is going to work on a line, it will continue with the state-entry from the previous line.
36+Usually Highlighters store the end-of-line-status in this field. So if the highlighter is going to work on a line, it will continue with the state-entry from the previous line.
3837
3938## Folding
4039
41-SynEdit's folding is handled by unit SynEditFoldedView and SynGutterCodeFolding. Highlighters that implement folding are to be based on TSynCustomFoldHighlighter.
42-
43-The basic information for communication between SynEditFoldedView and the HL requires 2 values stored for each line. (Of course the highlighter itself can store more information):
40+SynEdit's folding is handled by unit SynEditFoldedView and SynGutterCodeFolding. Highlighters that implement folding are to be based on TSynCustomFoldHighlighter.
4441
45-- FoldLevel at the end of line
46-- Minimum FoldLevel encountered anywhere on the line
42+The basic information for communication between SynEditFoldedView and the HL requires 2 values stored for each line. (Of course the highlighter itself can store more information):
4743
48-The Foldlevel indicates how many (nested) folds exist. It goes up whenever a fold begins, and down when a fold ends:
44+ * FoldLevel at the end of line
45+ * Minimum FoldLevel encountered anywhere on the line
4946
50-``` pascal
51- EndLvl MinLvl
52- Procedure a; 1 - 0
53- Begin 2 -- 1 -
54- b:= 1; 2 -- 2 --
55- if c > b then begin 3 --- 2 --
56- c:=b; 3 --- 3 ---
57- end else begin 3 --- 2 --
58- b:=c; 3 --- 3 ---
59- end; 2 -- 2 --
60- end; 0 0 // The end closes both: begin and procedure fold
47+The Foldlevel indicates how many (nested) folds exist. It goes up whenever a fold begins, and down when a fold ends:
6148```
62-
63-In the line
64-
65-``` pascal
66- Procedure a; 1 - 0
49+EndLvl MinLvl
50+ Procedure a; 1 - 0
51+ Begin 2 -- 1 -
52+ b:= 1; 2 -- 2 --
53+ if c > b then begin 3 --- 2 --
54+ c:=b; 3 --- 3 ---
55+ end else begin 3 --- 2 --
56+ b:=c; 3 --- 3 ---
57+ end; 2 -- 2 --
58+ end; 0 0 // The end closes both: begin and procedure fold
6759```
6860
69-the MinLvl is 0, because the line started with a Level of 0 (and it never went down / no folds closed). Similar in all lines where there is only an opening fold keyword ("begin").
61+In the line
62+```
63+Procedure a; 1 - 0
64+```
7065
71-But the line
66+the MinLvl is 0, because the line started with a Level of 0 (and it never went down / no folds closed). Similar in all lines where there is only an opening fold keyword ("begin").
7267
73-``` pascal
74- end else begin 3 --- 2 --
68+But the line
7569```
76-
77-starts with a level of 3, and also ends with it (one close, one open). But since it went down first, the minimum level encountered anywhere on the line is 2.
70+end else begin 3 --- 2 --
71+```
7872
79-Without the MinLvl it would not be possible to tell that a fold ends in this line.
73+starts with a level of 3, and also ends with it (one close, one open). But since it went down first, the minimum level encountered anywhere on the line is 2.
8074
81-There is no such thing as a MaxLvl, because folds that start and end on the same line can not be folded anyway. No need to detect them.
75+Without the MinLvl it would not be possible to tell that a fold ends in this line.
8276
83-``` pascal
84- if a then begin b:=1; c:=2; end; // no fold on that line
77+There is no such thing as a MaxLvl, because folds that start and end on the same line can not be folded anyway. No need to detect them.
8578```
86-
87-# Creating a SynEdit Highlighter
88-
89-Since 0.9.31 Revision 35115 the fold-highlighter has changed. Implementing basic folding is now easier.
79+if a then begin b:=1; c:=2; end; // no fold on that line
80+```
9081
91-All Sources can be found in the Lazarus installation directory under:
82+
9283
93-:* Lazarus 2.3 and up: examples\Components\SynEdit\NewHighlighterTutorial
84+# Creating a SynEdit Highlighter
9485
95-:* Lazarus before 2.2.*: examples\SynEdit\NewHighlighterTutorial\\
86+Since 0.9.31 Revision 35115 the fold-highlighter has changed. Implementing basic folding is now easier.
9687
97-The project HighlighterTutorial contains 3 difference example highlighters:
88+All Sources can be found in the Lazarus installation directory under:
9889
99-:* SimpleHl: used in Step 1 below
90+ * Lazarus 2.3 and up: examples\Components\SynEdit\NewHighlighterTutorial
91+ * Lazarus before 2.2.*: examples\SynEdit\NewHighlighterTutorial\
10092
101-:* ContextHl: used in Step 2 below
93+
94+The project HighlighterTutorial contains 3 difference example highlighters:
10295
103-:* FoldHl: used in Step 3 below
96+ * SimpleHl: used in Step 1 below
97+ * ContextHl: used in Step 2 below
98+ * FoldHl: used in Step 3 below
10499
105-SimpleHl and ContextHl will work with 0.9.30 too
100+SimpleHl and ContextHl will work with 0.9.30 too
106101
107-The folding highlighter in action:
102+The folding highlighter in action:
108103
109-![](/wiki-images/a/a2/SynEditFoldingHighlighterDemo.png)
104+[![SynEditFoldingHighlighterDemo.png](/wiki-images/a/a2/SynEditFoldingHighlighterDemo.png)](</File:SynEditFoldingHighlighterDemo.png>)
110105
111106## The Basics: Returning Tokens and Attributes
112107
113-As indicated, the **SimpleHl** unit demonstrates this process.
108+As indicated, the **SimpleHl** unit demonstrates this process.
114109
115110### What it does
116111
117-- It splits each line into words and spaces (or tabs)
118- - The spaces are part of the text, and must be highlighted too
119-- This example allows specifying different colors for
112+ * It splits each line into words and spaces (or tabs)
113+ * The spaces are part of the text, and must be highlighted too
114+ * This example allows specifying different colors for
120115
121-
122-
123116\- text (defaults to not-highlighted)
124117
125118\- spaces (defaults to silver frame)
126119
127120\- words, separated by spaces, that start with a,e,i,o,u (defaults to bold)
128121
129122\- the word "not" (defaults to red background)
130123
131124### How it works
132125
133-- Creation
126+ * Creation
134127
135-The Highlighter creates Attributes that it can return the Words and Spaces.
128+The Highlighter creates Attributes that it can return the Words and Spaces.
136129
137-- SetLine
130+ * SetLine
138131
139-Is called by SynEdit before a line gets painted (or before highlight info is needed)
132+Is called by SynEdit before a line gets painted (or before highlight info is needed)
140133
141-- GetTokenEx, GetTokenAttribute, Next, GetEol
134+ * GetTokenEx, GetTokenAttribute, Next, GetEol
142135
143-Are used by SynEdit to iterate over the Line. Note that the first Token (Word or Spaces) must be ready after SetLine, without a call to Next.
136+Are used by SynEdit to iterate over the Line. Note that the first Token (Word or Spaces) must be ready after SetLine, without a call to Next.
144137
145-[[Important:]] The tokens returned for each line must represent the original line-text, and be returned in the correct order.
138+[[Important:]] The tokens returned for each line must represent the original line-text, and be returned in the correct order.
146139
147-- GetToken, GetTokenPos, GetTokenKind
140+ * GetToken, GetTokenPos, GetTokenKind
148141
149-SynEdit uses them e.g for finding matching brackets. If tokenKind returns different values per Attribute, then brackets only match, if they are of the same kind (e.g. if there was a string attribute, brackets outside a string would not match brackets inside a string).
142+SynEdit uses them e.g for finding matching brackets. If tokenKind returns different values per Attribute, then brackets only match, if they are of the same kind (e.g. if there was a string attribute, brackets outside a string would not match brackets inside a string).
150143
151144### Other notes
152145
153-For readability, the highlighter has no optimization, so it may be very slow on larger texts. Many of the supplied highlighters use hash functions, to find what word (or any group of chars) is.
146+For readability, the highlighter has no optimization, so it may be very slow on larger texts. Many of the supplied highlighters use hash functions, to find what word (or any group of chars) is.
154147
155148## Step 2: Using Ranges
156149
157-As indicated, the **ContextHl** unit demonstrates this process
158-
159-The next example allows content of a line that influences other lines that follow. An example: a "(*" in Pascal makes all following lines a comment until a "*)" is found.
150+As indicated, the **ContextHl** unit demonstrates this process
160151
161-This example extends the **SimpleHl** show above: The tokens -- and ++ (must be surrounded by space or line-begin/end to be a token of their own) will toggle words that start with a,e,i,o,u
152+The next example allows content of a line that influences other lines that follow. An example: a "(*" in Pascal makes all following lines a comment until a "*)" is found.
162153
163-Multiple ++ and -- can be nested. Then for each -- a ++ must be given, before the words highlight again.
154+This example extends the **SimpleHl** show above: The tokens -- and ++ (must be surrounded by space or line-begin/end to be a token of their own) will toggle words that start with a,e,i,o,u
164155
165-Then we extend the scanner. The pre-scan to store the information calls the same functions as the highlighter. It is automatically called, if anything changes. (It is called for all lines below the changed line, until a line returns the same Range-value as it already had)
156+Multiple ++ and -- can be nested. Then for each -- a ++ must be given, before the words highlight again.
166157
167-The current amount of "--" is counted in
158+Then we extend the scanner. The pre-scan to store the information calls the same functions as the highlighter. It is automatically called, if anything changes. (It is called for all lines below the changed line, until a line returns the same Range-value as it already had)
168159
169-``` pascal
170- FCurRange: Integer;
160+The current amount of "--" is counted in
171161```
162+FCurRange: Integer;
163+```
172164
173-The amount is decreased by "++"
165+The amount is decreased by "++"
174166
175-To store the info we use:
167+To store the info we use:
176168
177-GetRange
169+**GetRange**
170+
178171Called after a line is completely scanned, to get the value at the end of the line. The value will be stored.
179172
180-SetRange
173+**SetRange**
174+
181175Called before a line gets scanned. Sets the value stored from the end of the previous line.
182176
183-ResetRange
177+**ResetRange**
178+
184179Called before the 1st line is scanned (as there is no previous line).
185180
186-> **Note:** A scan is triggered by *every* change to a line (every keystroke). It scans the current line, and all lines below, until a line returns the same range that it already had. See: <http://forum.lazarus.freepascal.org/index.php/topic,21727.msg139420.html#msg139420>
181+![Light bulb](https://upload.wikimedia.org/wikipedia/commons/d/d8/Nuvola_apps_ktip.png) **Note:** A scan is triggered by *every* change to a line (every keystroke). It scans the current line, and all lines below, until a line returns the same range that it already had. See: <http://forum.lazarus.freepascal.org/index.php/topic,21727.msg139420.html#msg139420>
187182
188183### Important note on Ranges
189184
190-The purpose of the range is to allow the HL to start scanning in any line. The HL will not never need to look at a previous line. Any information needed to scan the current line can be derived from the ranges value.
191-
192-Example:
185+The purpose of the range is to allow the HL to start scanning in any line. The HL will not never need to look at a previous line. Any information needed to scan the current line can be derived from the ranges value.
193186
194-``` pascal
195- writeln; (*
196- readln;
197- *)
187+Example:
198188```
189+writeln; (*
190+ readln;
191+ *)
192+```
199193
200-when scanning the "readln" the HL knows from the range that it is in a comment, it does not need to look back at previous lines.
194+when scanning the "readln" the HL knows from the range that it is in a comment, it does not need to look back at previous lines.
201195
202-Therefore scanning can start at any line.
196+Therefore scanning can start at any line.
203197
204-This also explains the note in the previous chapter. "until a line returns the same range that it already had". For even if the text of a line was not changed, if the value of the range at the lines start changed, then the scan result will change too.
198+This also explains the note in the previous chapter. "until a line returns the same range that it already had". For even if the text of a line was not changed, if the value of the range at the lines start changed, then the scan result will change too.
205199
206-## Step 3: Add Folding
200+### Objects as Ranges - Incompatible change in 4.99
207201
208-As indicated, the **FoldHl** unit demonstrates this process
202+Using an object as range is possible. Currently this is done by having objects with a lifetime until all Highlighters are destroyed (refcounting may be added later).
209203
210-For the example, the highlighter should fold everything between free-standing "-(-", "-)-".
204+The pointer to any such object can be stored as range. However, pointers stored in the range can get lost. Therefore all objects must be hold in an additional container. This additional container also allows to detect existing objects with equal values to a new object, and allows de-duplication.
211205
212-Change inheritance:
206+
213207
214-``` pascal
215- uses SynEditHighlighterFoldBase;
216- ...
217- TSynDemoHl = class(TSynCustomFoldHighlighter)
218-```
208+#### Up to an including 4.x
219209
220-Change the way range info is stored, since the base class uses it for fold-info:
210+The objects where stored in an avl tree. Objects needed to provide a "Compare" method returning an integer: negative, zero or positive. To allow ordering.
221211
222-``` pascal
223-procedure TSynDemoHl.SetRange(Value: Pointer);
224-begin
225- inherited;
226- FCurRange := PtrInt(CodeFoldRange.RangeType);
227-end;
212+#### 4.99 and up
228213
229-procedure TSynDemoHl.ResetRange;
230-begin
231- inherited;
232- FCurRange := 0;
233-end;
214+See **unit LazEditHighlighterUtils**
234215
235-function TSynDemoHl.GetRange: Pointer;
236-begin
237- CodeFoldRange.RangeType := Pointer(PtrInt(FCurRange));
238- inherited;
239-end;
216+The objects are stored in a TDictionary.
217+
218+ * Compare most return zero (equal) or none-zero (different)
219+ * A method **GetHashCode** must return a hash value, for the dictionary
220+
221+## Step 3: Add Folding
222+
223+As indicated, the **FoldHl** unit demonstrates this process
224+
225+For the example, the highlighter should fold everything between free-standing "-(-", "-)-".
226+
227+Change inheritance:
240228```
229+uses SynEditHighlighterFoldBase;
230+ ...
231+ TSynDemoHl = class(TSynCustomFoldHighlighter)
232+```
241233
242-Now add code to the scanner which tells the highlighter about opening and closing folds:
234+Change the way range info is stored, since the base class uses it for fold-info:
235+```
236+procedure TSynDemoHl.SetRange(Value: Pointer);
237+ begin
238+ inherited;
239+ FCurRange := PtrInt(CodeFoldRange.RangeType);
240+ end;
241+
242+ procedure TSynDemoHl.ResetRange;
243+ begin
244+ inherited;
245+ FCurRange := 0;
246+ end;
247+
248+ function TSynDemoHl.GetRange: Pointer;
249+ begin
250+ CodeFoldRange.RangeType := Pointer(PtrInt(FCurRange));
251+ inherited;
252+ end;
253+```
243254
244-``` pascal
255+Now add code to the scanner which tells the highlighter about opening and closing folds:
256+```
245257procedure TSynDemoHl.FindTokenEnd;
246-begin
247- ...
248-
249- if (FTokenEnd = FTokenPos+1) and (FLineText[FTokenPos] = '[') then
250- StartCodeFoldBlock(nil);
251- if (FTokenEnd = FTokenPos+1) and (FLineText[FTokenPos] = ']') then
252- EndCodeFoldBlock();
253-end;
258+ begin
259+ ...
260+
261+ if (FTokenEnd = FTokenPos+1) and (FLineText[FTokenPos] = '[') then
262+ StartCodeFoldBlock(nil);
263+ if (FTokenEnd = FTokenPos+1) and (FLineText[FTokenPos] = ']') then
264+ EndCodeFoldBlock();
265+ end;
254266```
255267
256-- **For 0.9.30**
268+ * **For 0.9.30**
257269
258-Please see the history of this page, if you are using a 0.9.30 version [[http://wiki.lazarus.freepascal.org/index.php?title=SynEdit Highlighter&amp;oldid=76020]]
270+Please see the history of this page, if you are using a 0.9.30 version [[[1]](<http://wiki.lazarus.freepascal.org/index.php?title=SynEdit_Highlighter&oldid=76020>)]
259271
260272#### More info on StartCodeFoldBlock / EndCodeFoldBlock
261-
262-``` pascal
263- function StartCodeFoldBlock(ABlockType: Pointer; IncreaseLevel: Boolean = true): TSynCustomCodeFoldBlock; virtual;
264273```
274+function StartCodeFoldBlock(ABlockType: Pointer; IncreaseLevel: Boolean = true): TSynCustomCodeFoldBlock; virtual;
275+```
265276
266-ABlockType
267-Can be used to specify an ID for the block.\
277+**ABlockType**
268278
269-The field is not normally used as a pointer (though this is permitted). Normally IDs are a numeric enumeration.\
270-If you have different types of block (e.g. in Pascal: begin/end; repeat/until, ...), and you do not want a block being closed by the wrong keyword ("end" should not close "repeat"), then you can give them IDs:\
271-StartCodeFoldBlock(PtrUInt(1)) // or other numbers\
279+Can be used to specify an ID for the block.
272280
273-IncreaseLevel
274-If set to False, then a block will be inserted that can not be folded.\
275-Blocks like that can be used for internal tracking.
281+The field is not normally used as a pointer (though this is permitted). Normally IDs are a numeric enumeration.
282+If you have different types of block (e.g. in Pascal: begin/end; repeat/until, ...), and you do not want a block being closed by the wrong keyword ("end" should not close "repeat"), then you can give them IDs:
283+**StartCodeFoldBlock(PtrUInt(1))** // or other numbers
276284
277-NOTE: All folds must be nested, they can not overlap. That is, the last opened fold must be closed first.\
278-This refers to the "EndLvl" as shown in "Folding"(1.3) above\
279-Overlaps (like IFDEF and begin in the IDE) can not be done this way.
285+**IncreaseLevel**
280286
281-``` pascal
282- procedure EndCodeFoldBlock(DecreaseLevel: Boolean = True); virtual;
287+If set to False, then a block will be inserted that can not be folded.
288+Blocks like that can be used for internal tracking.
289+
290+NOTE: All folds must be nested, they can not overlap. That is, the last opened fold must be closed first.
291+This refers to the "EndLvl" as shown in "Folding"(1.3) above
292+Overlaps (like IFDEF and begin in the IDE) can not be done this way.
283293```
294+procedure EndCodeFoldBlock(DecreaseLevel: Boolean = True); virtual;
295+```
284296
285-DecreaseLevel
286-This *must* match IncreaseLevel, as it was given on the StartCodeFoldBlock\
297+**DecreaseLevel**
287298
288-True means a fold ends; False means an internal block is ended. If mismatched then folds will either continue, or end early.\
289-TopCodeFoldBlockType can be used to indicate the ID of the innermost open block. One can use different IDs for internal blocks, and use this to set the value.
299+This *must* match IncreaseLevel, as it was given on the StartCodeFoldBlock
290300
291-``` pascal
292- function TopCodeFoldBlockType(DownIndex: Integer = 0): Pointer;
301+True means a fold ends; False means an internal block is ended. If mismatched then folds will either continue, or end early.
302+TopCodeFoldBlockType can be used to indicate the ID of the innermost open block. One can use different IDs for internal blocks, and use this to set the value.
293303```
304+function TopCodeFoldBlockType(DownIndex: Integer = 0): Pointer;
305+```
294306
295-Returns the ID of the innermost block.
307+Returns the ID of the innermost block.
296308
297-DownIndex
309+**DownIndex**
310+
298311can be used to get ID for the other block.
299312
300-DownIndex=1 means the block that is surrounding the innermost.
313+DownIndex=1 means the block that is surrounding the innermost.
301314
302315# Configurable Highlighters (incl. 3rd party)
303316
304317## SynAnySyn
305318
306-A real simple Highlighter. More a reference implementation, than a real life useable Highlighter.
319+A real simple Highlighter. More a reference implementation, than a real life useable Highlighter.
307320
308321## SynUniHighlighter
309322
310-Uses XML-based configurations files. [old official link](http://web.archive.org/web/20090610040212/http://www.delphist.com:80/UniHighlighter.html)
323+Uses XML-based configurations files. [old official link](<http://web.archive.org/web/20090610040212/http://www.delphist.com:80/UniHighlighter.html>)
311324
312325## SynFacilSyn
313326
314327Flexible fully configurable Highlighter. <https://github.com/t-edson/SynFacilSyn>
315328
316329# References
317330
318-Threads on the forum:
331+Threads on the forum:
319332
320-- "Making highligher for C syntaxis" [[http://www.lazarus.freepascal.org/index.php/topic,10260.0.html topic,10260]]
321-- "Creating a Syntax Highlighter" [[http://www.lazarus.freepascal.org/index.php/topic,10959.msg54714 topic,10959.msg54714]]
322-- obtaining highlight for printing [[http://www.lazarus.freepascal.org/index.php/topic,11384.msg57160.html|http://www.lazarus.freepascal.org/index.php/topic,11384.msg57160.html#msg57160 11384.msg57160]]
323-- Some details on ranges, and using objects to store more info [[http://forum.lazarus.freepascal.org/index.php/topic,21727.msg139354.html|http://forum.lazarus.freepascal.org/index.php/topic,21727.msg139354.html#msg139354 topic,21727.msg139354]] and [[http://forum.lazarus.freepascal.org/index.php/topic,21727.msg139419.html|http://forum.lazarus.freepascal.org/index.php/topic,21727.msg139419.html#msg139419 topic,21727.msg139419]]
324-- More on ranges, working copy vs immutable, foldblocks... [[http://forum.lazarus.freepascal.org/index.php/topic,30685.msg195464.html|http://forum.lazarus.freepascal.org/index.php/topic,30685.msg195464.html#msg195464 http://forum.lazarus.freepascal.org/index.php/topic,30685]]
325-- Markup (Highlight) all occurrences of a token (or regex) [[http://forum.lazarus.freepascal.org/index.php?topic=26833 topic=26833]]
326-- Markup and foldinfo: [[http://forum.lazarus.freepascal.org/index.php?topic=30122]]
327-- How to do invalidation in TSynEditMarkup [[http://forum.lazarus.freepascal.org/index.php/topic,30122.msg207931.html|http://forum.lazarus.freepascal.org/index.php/topic,30122.msg207931.html#msg207931]]
333+ * "Making highligher for C syntaxis" [[topic,10260](<http://www.lazarus.freepascal.org/index.php/topic,10260.0.html>)]
334+ * "Creating a Syntax Highlighter" [[topic,10959.msg54714](<http://www.lazarus.freepascal.org/index.php/topic,10959.msg54714>)]
335+ * obtaining highlight for printing [[11384.msg57160](<http://www.lazarus.freepascal.org/index.php/topic,11384.msg57160.html#msg57160>)]
336+ * Some details on ranges, and using objects to store more info [[topic,21727.msg139354](<http://forum.lazarus.freepascal.org/index.php/topic,21727.msg139354.html#msg139354>)] and [[topic,21727.msg139419](<http://forum.lazarus.freepascal.org/index.php/topic,21727.msg139419.html#msg139419>)]
337+ * More on ranges, working copy vs immutable, foldblocks... [[http://forum.lazarus.freepascal.org/index.php/topic,30685](<http://forum.lazarus.freepascal.org/index.php/topic,30685.msg195464.html#msg195464>)]
338+ * Markup (Highlight) all occurrences of a token (or regex) [[topic=26833](<http://forum.lazarus.freepascal.org/index.php?topic=26833>)]
339+ * Markup and foldinfo: [[[2]](<http://forum.lazarus.freepascal.org/index.php?topic=30122>)]
340+ * How to do invalidation in TSynEditMarkup [[[3]](<http://forum.lazarus.freepascal.org/index.php/topic,30122.msg207931.html#msg207931>)]
328341
329-- Folding
330- - "SynEdit - improved highlighters to handle Code Folding?" [[http://www.lazarus.freepascal.org/index.php/topic,7879.0.html topic,7879]]
331- - "SynEdit - Add support code folding for Java" [[http://www.lazarus.freepascal.org/index.php/topic,7338.0.html topic,7338]]
332- - "CodeFolding" Config [[http://www.lazarus.freepascal.org/index.php/topic,11064 topic,11064]]
333- - Fold blocks "end" keyword (end on the line before the next keyword) [[http://forum.lazarus.freepascal.org/index.php/topic,23411.msg139621.html|http://forum.lazarus.freepascal.org/index.php/topic,23411.msg139621.html#msg139621 topic,23411.msg139621]]
334- - Folding selected text from code (user/application code): [[http://forum.lazarus.freepascal.org/index.php/topic,24473.msg147312.html|http://forum.lazarus.freepascal.org/index.php/topic,24473.msg147312.html#msg147312 24473.msg147312]]
335- - Obtaining state of folding (save fold state with session) [[http://forum.lazarus.freepascal.org/index.php?topic=26748 topic=26748]]
342+ * Folding
343+ * "SynEdit - improved highlighters to handle Code Folding?" [[topic,7879](<http://www.lazarus.freepascal.org/index.php/topic,7879.0.html>)]
344+ * "SynEdit - Add support code folding for Java" [[topic,7338](<http://www.lazarus.freepascal.org/index.php/topic,7338.0.html>)]
345+ * "CodeFolding" Config [[topic,11064](<http://www.lazarus.freepascal.org/index.php/topic,11064>)]
346+ * Fold blocks "end" keyword (end on the line before the next keyword) [[topic,23411.msg139621](<http://forum.lazarus.freepascal.org/index.php/topic,23411.msg139621.html#msg139621>)]
347+ * Folding selected text from code (user/application code): [[24473.msg147312](<http://forum.lazarus.freepascal.org/index.php/topic,24473.msg147312.html#msg147312>)]
348+ * Obtaining state of folding (save fold state with session) [[topic=26748](<http://forum.lazarus.freepascal.org/index.php?topic=26748>)]
336349
337350---
338-*From the Free Pascal wiki, page "SynEdit Highlighter", as it stood on 2022-05-04 after a change by Martin, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*
339-Category: SynEdit
351+*From the Free Pascal wiki, page "SynEdit Highlighter", as the Internet Archive kept it on 2025-04-18, last changed on 2025-04-03. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history