1 {-------------------------------------------------------------------------------
2 The contents of this file are subject to the Mozilla Public License
3 Version 1.1 (the "License"); you may not use this file except in compliance
4 with the License. You may obtain a copy of the License at
5 http://www.mozilla.org/MPL/
6
7 Software distributed under the License is distributed on an "AS IS" basis,
8 WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
9 the specific language governing rights and limitations under the License.
10
11 The Original Code is: SynHighlighterDfm.pas, released 2000-04-14.
12 The Original Code is based on the dmDfmSyn.pas file from the
13 mwEdit component suite by Martin Waldenburg and other developers, the Initial
14 Author of this file is David H. Muir.
15 All Rights Reserved.
16
17 Contributors to the SynEdit and mwEdit projects are listed in the
18 Contributors.txt file.
19
20 Alternatively, the contents of this file may be used under the terms of the
21 GNU General Public License Version 2 or later (the "GPL"), in which case
22 the provisions of the GPL are applicable instead of those above.
23 If you wish to allow use of your version of this file only under the terms
24 of the GPL and not to allow others to use your version of this file
25 under the MPL, indicate your decision by deleting the provisions above and
26 replace them with the notice and other provisions required by the GPL.
27 If you do not delete the provisions above, a recipient may use your version
28 of this file under either the MPL or the GPL.
29
30 $Id$
31
32 You may retrieve the latest version of this file at the SynEdit home page,
33 located at http://SynEdit.SourceForge.net
34
35 Known Issues:
36 -------------------------------------------------------------------------------}
37 {
38 @abstract(Provides a Delphi Form Source highlighter for SynEdit)
39 @author(David Muir <david@loanhead45.freeserve.co.uk>)
40 @created(April 13, 2000)
41 @lastmod(2000-06-23)
42 The SynHighlighterLFM unit provides SynEdit with a Delphi Form Source (.LFM) highlighter.
43 The highlighter formats form source code similar to when forms are viewed as text in the Delphi editor.
44 }
45 unit SynHighlighterLFM;
46
47 {$I SynEdit.inc}
48
49 interface
50
51 uses
52 SysUtils, Classes, FileUtil, Graphics,
53 SynEditTypes, SynEditHighlighter, SynEditHighlighterFoldBase, SynEditStrConst;
54
55 type
56 TtkTokenKind = (tkComment, tkIdentifier, tkKey, tkNull, tkNumber, tkSpace,
57 tkString, tkSymbol, tkUnknown);
58
59 TRangeState = (rsANil, rsComment, rsUnKnown);
60
61 TLfmCodeFoldBlockType = (
62 cfbtLfmObject, // object, inherited, inline
63 cfbtLfmList, // <>
64 cfbtLfmItem, // Item
65 // internal type / no config
66 cfbtLfmNone
67 );
68 TLfmCodeFoldBlockTypes = set of TLfmCodeFoldBlockType;
69
70 TProcTableProc = procedure of object;
71
72 const
73 CountLfmCodeFoldBlockOffset: Pointer =
74 Pointer(PtrInt(Integer(high(TLfmCodeFoldBlockType))+1));
75
76 type
77
78 { TSynLFMSyn }
79
80 TSynLFMSyn = class(TSynCustomFoldHighlighter)
81 private
82 fRange: TRangeState;
83 fLine: PChar;
84 fLineNumber: Integer;
85 fProcTable: array[#0..#255] of TProcTableProc;
86 Run: integer;
87 fTokenPos: Integer;
88 FTokenID: TtkTokenKind;
89 fCommentAttri: TSynHighlighterAttributes;
90 fIdentifierAttri: TSynHighlighterAttributes;
91 fKeyAttri: TSynHighlighterAttributes;
92 fNumberAttri: TSynHighlighterAttributes;
93 fSpaceAttri: TSynHighlighterAttributes;
94 fStringAttri: TSynHighlighterAttributes;
95 fSymbolAttri: TSynHighlighterAttributes;
96 procedure AltProc;
97 procedure AsciiCharProc;
98 procedure BraceCloseProc;
99 procedure BraceOpenProc;
100 procedure CommentProc;
101 procedure CRProc;
102 procedure EndProc;
103 procedure IntegerProc;
104 procedure LFProc;
105 procedure NullProc;
106 procedure NumberProc;
107 procedure ObjectProc;
108 procedure InheritedInlineProc;
109 procedure SpaceProc;
110 procedure StringProc;
111 procedure SymbolProc;
112 procedure UnknownProc;
113 procedure MakeMethodTables;
114 protected
GetIdentCharsnull115 function GetIdentChars: TSynIdentChars; override;
GetSampleSourcenull116 function GetSampleSource: string; override;
117 protected
118 // folding
119 procedure CreateRootCodeFoldBlock; override;
120
StartLfmCodeFoldBlocknull121 function StartLfmCodeFoldBlock
122 (ABlockType: TLfmCodeFoldBlockType): TSynCustomCodeFoldBlock;
123 procedure EndLfmCodeFoldBlock;
TopLfmCodeFoldBlockTypenull124 function TopLfmCodeFoldBlockType(DownIndex: Integer = 0): TLfmCodeFoldBlockType;
125 protected
GetFoldConfigInstancenull126 function GetFoldConfigInstance(Index: Integer): TSynCustomFoldConfig; override;
GetFoldConfigCountnull127 function GetFoldConfigCount: Integer; override;
GetFoldConfigInternalCountnull128 function GetFoldConfigInternalCount: Integer; override;
129 public
GetLanguageNamenull130 class function GetLanguageName: string; override;
131 public
132 constructor Create(AOwner: TComponent); override;
133 destructor Destroy; override;
GetDefaultAttributenull134 function GetDefaultAttribute(Index: integer): TSynHighlighterAttributes;
135 override;
GetEolnull136 function GetEol: Boolean; override;
GetRangenull137 function GetRange: Pointer; override;
GetTokenIDnull138 function GetTokenID: TtkTokenKind;
139 procedure SetLine(const NewValue: String;
140 LineNumber: Integer); override;
GetTokennull141 function GetToken: String; override;
142 procedure GetTokenEx(out TokenStart: PChar; out TokenLength: integer); override;
GetTokenAttributenull143 function GetTokenAttribute: TSynHighlighterAttributes; override;
GetTokenKindnull144 function GetTokenKind: integer; override;
GetTokenPosnull145 function GetTokenPos: Integer; override;
146 procedure Next; override;
147 procedure SetRange(Value: Pointer); override;
148 procedure ResetRange; override;
149 property IdentChars;
150 published
151 property CommentAttri: TSynHighlighterAttributes read fCommentAttri
152 write fCommentAttri;
153 property IdentifierAttri: TSynHighlighterAttributes read fIdentifierAttri
154 write fIdentifierAttri;
155 property KeyAttri: TSynHighlighterAttributes read fKeyAttri write fKeyAttri;
156 property NumberAttri: TSynHighlighterAttributes read fNumberAttri
157 write fNumberAttri;
158 property SpaceAttri: TSynHighlighterAttributes read fSpaceAttri
159 write fSpaceAttri;
160 property StringAttri: TSynHighlighterAttributes read fStringAttri
161 write fStringAttri;
162 end;
163
LoadLFMFile2Stringsnull164 function LoadLFMFile2Strings(const AFile: string; AStrings: TStrings;
165 var WasText: boolean): integer;
SaveStrings2LFMFilenull166 function SaveStrings2LFMFile(AStrings: TStrings; const AFile: string): integer;
167
168 implementation
169
170 { A couple of useful Lazarus Form functions }
171
LoadLFMFile2Stringsnull172 function LoadLFMFile2Strings(const AFile: string; AStrings: TStrings;
173 var WasText: boolean): integer;
174 var
175 Src, Dest: TStream;
176 begin
177 Result := 0;
178 WasText := FALSE;
179 AStrings.Clear;
180 try
181 Src := TFileStream.Create(AFile, fmOpenRead or fmShareDenyWrite);
182 try
183 Dest := TMemoryStream.Create;
184 try
185 ObjectResourceToText(Src, Dest);
186 Dest.Seek(0, soFromBeginning);
187 AStrings.LoadFromStream(Dest);
188 finally
189 Dest.Free;
190 end;
191 finally
192 Src.Free;
193 end;
194 except
195 on E: EInOutError do Result := -E.ErrorCode;
196 else Result := -1;
197 end;
198 end;
199
SaveStrings2LFMFilenull200 function SaveStrings2LFMFile(AStrings: TStrings; const AFile: string): integer;
201 var
202 Src, Dest: TStream;
203 begin
204 Result := 0;
205 try
206 Src := TMemoryStream.Create;
207 try
208 AStrings.SaveToStream(Src);
209 Src.Seek(0, soFromBeginning);
210 Dest := TFileStream.Create(AFile, fmCreate);
211 try
212 ObjectTextToResource(Src, Dest);
213 finally
214 Dest.Free;
215 end;
216 finally
217 Src.Free;
218 end;
219 except
220 on E: EInOutError do Result := -E.ErrorCode;
221 else Result := -1;
222 end;
223 end;
224
225 { TSynLFMSyn }
226
227 procedure TSynLFMSyn.MakeMethodTables;
228 var
229 I: Char;
230 begin
231 for I := #0 to #255 do
232 case I of
233 '#': fProcTable[I] := @AsciiCharProc;
234 '}': fProcTable[I] := @BraceCloseProc;
235 '{': fProcTable[I] := @BraceOpenProc;
236 #13: fProcTable[I] := @CRProc;
237 'A'..'Z', 'a'..'z', '_':
238 if I in ['e', 'E'] then
239 fProcTable[I] := @EndProc
240 else if I in ['o', 'O'] then
241 fProcTable[I] := @ObjectProc
242 else if I in ['i', 'I'] then
243 fProcTable[I] := @InheritedInlineProc
244 else
245 fProcTable[I] := @AltProc;
246 '$': fProcTable[I] := @IntegerProc;
247 #10: fProcTable[I] := @LFProc;
248 #0: fProcTable[I] := @NullProc;
249 '0'..'9': fProcTable[I] := @NumberProc;
250 '(', ')', '/', '=', '<', '>', '.', ',', '[', ']', ':':
251 fProcTable[I] := @SymbolProc;
252 #1..#9, #11, #12, #14..#32: fProcTable[I] := @SpaceProc;
253 #39: fProcTable[I] := @StringProc;
254 else fProcTable[I] := @UnknownProc;
255 end;
256 end;
257
GetFoldConfigInstancenull258 function TSynLFMSyn.GetFoldConfigInstance(Index: Integer): TSynCustomFoldConfig;
259 begin
260 Result := inherited GetFoldConfigInstance(Index);
261 Result.Enabled := True;
262 if TLfmCodeFoldBlockType(Index) in [cfbtLfmObject, cfbtLfmList, cfbtLfmItem] then begin
263 Result.SupportedModes := Result.SupportedModes + [fmMarkup];
264 Result.Modes := Result.Modes + [fmMarkup];
265 end;
266 end;
267
268 constructor TSynLFMSyn.Create(AOwner: TComponent);
269 begin
270 inherited Create(AOwner);
271 fCommentAttri := TSynHighlighterAttributes.Create(@SYNS_AttrComment, SYNS_XML_AttrComment);
272 fCommentAttri.Style := [fsItalic];
273 AddAttribute(fCommentAttri);
274 fIdentifierAttri := TSynHighlighterAttributes.Create(@SYNS_AttrIdentifier, SYNS_XML_AttrIdentifier);
275 AddAttribute(fIdentifierAttri);
276 fKeyAttri := TSynHighlighterAttributes.Create(@SYNS_AttrKey, SYNS_XML_AttrKey);
277 fKeyAttri.Style := [fsBold];
278 AddAttribute(fKeyAttri);
279 fNumberAttri := TSynHighlighterAttributes.Create(@SYNS_AttrNumber, SYNS_XML_AttrNumber);
280 AddAttribute(fNumberAttri);
281 fSpaceAttri := TSynHighlighterAttributes.Create(@SYNS_AttrSpace, SYNS_XML_AttrSpace);
282 AddAttribute(fSpaceAttri);
283 fStringAttri := TSynHighlighterAttributes.Create(@SYNS_AttrString, SYNS_XML_AttrString);
284 AddAttribute(fStringAttri);
285 fSymbolAttri := TSynHighlighterAttributes.Create(@SYNS_AttrSymbol, SYNS_XML_AttrSymbol);
286 AddAttribute(fSymbolAttri);
287 SetAttributesOnChange(@DefHighlightChange);
288 MakeMethodTables;
289 fDefaultFilter := SYNS_FilterLFM;
290 fRange := rsUnknown;
291 end;
292
293 destructor TSynLFMSyn.Destroy;
294 begin
295 inherited Destroy;
296 end;
297
298 procedure TSynLFMSyn.SetLine(const NewValue: String;
299 LineNumber: Integer);
300 begin
301 inherited;
302 fLine := PChar(NewValue);
303 Run := 0;
304 fLineNumber := LineNumber;
305 Next;
306 end;
307
308 procedure TSynLFMSyn.AltProc;
309 begin
310 fTokenID := tkIdentifier;
311 repeat
312 Inc(Run);
313 until not (fLine[Run] in ['_', '0'..'9', 'a'..'z', 'A'..'Z']);
314 end;
315
316 procedure TSynLFMSyn.AsciiCharProc;
317 begin
318 fTokenID := tkString;
319 repeat
320 Inc(Run);
321 until not (fLine[Run] in ['0'..'9']);
322 end;
323
324 procedure TSynLFMSyn.BraceCloseProc;
325 begin
326 inc(Run);
327 fRange := rsUnknown;
328 fTokenId := tkIdentifier;
329 end;
330
331 procedure TSynLFMSyn.BraceOpenProc;
332 begin
333 fRange := rsComment;
334 CommentProc;
335 end;
336
337 procedure TSynLFMSyn.CommentProc;
338 begin
339 fTokenID := tkComment;
340 repeat
341 inc(Run);
342 if fLine[Run] = '}' then begin
343 Inc(Run);
344 fRange := rsUnknown;
345 break;
346 end;
347 until fLine[Run] in [#0, #10, #13];
348 end;
349
350 procedure TSynLFMSyn.CRProc;
351 begin
352 fTokenID := tkSpace;
353 Inc(Run);
354 if (fLine[Run] = #10) then Inc(Run);
355 end;
356
357 procedure TSynLFMSyn.EndProc;
358 begin
359 if (fLine[Run + 1] in ['n', 'N']) and
360 (fLine[Run + 2] in ['d', 'D']) and
361 not (fLine[Run + 3] in ['_', '0'..'9', 'a'..'z', 'A'..'Z'])
362 then begin
363 fTokenID := tkKey;
364 Inc(Run, 3);
365 if (TopLfmCodeFoldBlockType in [cfbtLfmObject, cfbtLfmItem]) then
366 EndLfmCodeFoldBlock;
367 end else
368 AltProc;
369 end;
370
371 procedure TSynLFMSyn.IntegerProc;
372 begin
373 fTokenID := tkNumber;
374 repeat
375 inc(Run);
376 until not (fLine[Run] in ['0'..'9', 'A'..'F', 'a'..'f']);
377 end;
378
379 procedure TSynLFMSyn.LFProc;
380 begin
381 fTokenID := tkSpace;
382 inc(Run);
383 end;
384
385 procedure TSynLFMSyn.NullProc;
386 begin
387 fTokenID := tkNull;
388 end;
389
390 procedure TSynLFMSyn.NumberProc;
391 begin
392 fTokenID := tkNumber;
393 repeat
394 Inc(Run);
395 if fLine[Run] = '.' then begin
396 if fLine[Run + 1] <> '.' then Inc(Run);
397 break;
398 end;
399 until not (fLine[Run] in ['0'..'9', 'e', 'E']);
400 end;
401
402 procedure TSynLFMSyn.ObjectProc;
403 begin
404 if (fLine[Run + 1] in ['b', 'B']) and
405 (fLine[Run + 2] in ['j', 'J']) and
406 (fLine[Run + 3] in ['e', 'E']) and
407 (fLine[Run + 4] in ['c', 'C']) and
408 (fLine[Run + 5] in ['t', 'T']) and
409 not (fLine[Run + 6] in ['_', '0'..'9', 'a'..'z', 'A'..'Z'])
410 then
411 begin
412 fTokenID := tkKey;
413 Inc(Run, 6);
414 StartLfmCodeFoldBlock(cfbtLfmObject);
415 end
416 else
417 AltProc;
418 end;
419
420 procedure TSynLFMSyn.InheritedInlineProc;
421 begin
422 if ((fLine[Run + 1] in ['n', 'N']) and
423 (fLine[Run + 2] in ['h', 'H']) and
424 (fLine[Run + 3] in ['e', 'E']) and
425 (fLine[Run + 4] in ['r', 'R']) and
426 (fLine[Run + 5] in ['i', 'I']) and
427 (fLine[Run + 6] in ['t', 'T']) and
428 (fLine[Run + 7] in ['e', 'E']) and
429 (fLine[Run + 8] in ['d', 'D']) and
430 not (fLine[Run + 9] in ['_', '0'..'9', 'a'..'z', 'A'..'Z']))
431 then
432 begin
433 fTokenID := tkKey;
434 Inc(Run, 9);
435 StartLfmCodeFoldBlock(cfbtLfmObject);
436 end
437 else if ((fLine[Run + 1] in ['n', 'N']) and
438 (fLine[Run + 2] in ['l', 'L']) and
439 (fLine[Run + 3] in ['i', 'I']) and
440 (fLine[Run + 4] in ['n', 'N']) and
441 (fLine[Run + 5] in ['e', 'E']) and
442 not (fLine[Run + 6] in ['_', '0'..'9', 'a'..'z', 'A'..'Z']))
443 then
444 begin
445 fTokenID := tkKey;
446 Inc(Run, 6);
447 StartLfmCodeFoldBlock(cfbtLfmObject);
448 end
449 else if ((fLine[Run + 1] in ['t', 'T']) and
450 (fLine[Run + 2] in ['e', 'E']) and
451 (fLine[Run + 3] in ['m', 'M']) and
452 not (fLine[Run + 4] in ['_', '0'..'9', 'a'..'z', 'A'..'Z']))
453 then
454 begin
455 fTokenID := tkIdentifier;
456 Inc(Run, 4);
457 StartLfmCodeFoldBlock(cfbtLfmItem);
458 end
459 else
460 AltProc;
461 end;
462
463 procedure TSynLFMSyn.SpaceProc;
464 begin
465 fTokenID := tkSpace;
466 repeat
467 Inc(Run);
468 until (fLine[Run] > #32) or (fLine[Run] in [#0, #10, #13]);
469 end;
470
471 procedure TSynLFMSyn.StringProc;
472 begin
473 fTokenID := tkString;
474 repeat
475 Inc(Run);
476 if fLine[Run] = '''' then begin
477 Inc(Run);
478 if fLine[Run] <> '''' then break
479 end;
480 until fLine[Run] in [#0, #10, #13];
481 end;
482
483 procedure TSynLFMSyn.SymbolProc;
484 begin
485
486 inc(Run);
487 fTokenID := tkSymbol;
488 if fLine[Run-1] = '<' then
489 begin
490 StartLfmCodeFoldBlock(cfbtLfmList)
491 end
492 else
493 if (fLine[Run-1] = '>') and (TopLfmCodeFoldBlockType = cfbtLfmList) then
494 EndLfmCodeFoldBlock;
495 end;
496
497 procedure TSynLFMSyn.UnknownProc;
498 begin
499 {$IFDEF SYN_MBCSSUPPORT}
500 if FLine[Run] in LeadBytes then
501 Inc(Run,2)
502 else
503 {$ENDIF}
504 inc(Run);
505 while (fLine[Run] in [#128..#191]) OR // continued utf8 subcode
506 ((fLine[Run]<>#0) and (fProcTable[fLine[Run]] = @UnknownProc)) do inc(Run);
507 fTokenID := tkUnknown;
508 end;
509
510 procedure TSynLFMSyn.Next;
511 begin
512 fTokenPos := Run;
513 if fRange = rsComment then begin
514 if fLine[Run] = #0 then NullProc
515 else CommentProc;
516 end else
517 fProcTable[fLine[Run]]();
518 end;
519
GetDefaultAttributenull520 function TSynLFMSyn.GetDefaultAttribute(Index: integer): TSynHighlighterAttributes;
521 begin
522 case Index of
523 SYN_ATTR_COMMENT: Result := fCommentAttri;
524 SYN_ATTR_IDENTIFIER: Result := fIdentifierAttri;
525 SYN_ATTR_KEYWORD: Result := fKeyAttri;
526 SYN_ATTR_STRING: Result := fStringAttri;
527 SYN_ATTR_WHITESPACE: Result := fSpaceAttri;
528 SYN_ATTR_SYMBOL: Result := fSymbolAttri;
529 SYN_ATTR_NUMBER: Result := fNumberAttri;
530 else
531 Result := nil;
532 end;
533 end;
534
TSynLFMSyn.GetEolnull535 function TSynLFMSyn.GetEol: Boolean;
536 begin
537 Result := fTokenId = tkNull;
538 end;
539
TSynLFMSyn.GetRangenull540 function TSynLFMSyn.GetRange: Pointer;
541 begin
542 CodeFoldRange.RangeType:=Pointer(PtrUInt(Integer(fRange)));
543 Result := inherited;
544 end;
545
GetTokenIDnull546 function TSynLFMSyn.GetTokenID: TtkTokenKind;
547 begin
548 Result := fTokenId;
549 end;
550
GetTokennull551 function TSynLFMSyn.GetToken: String;
552 var
553 Len: LongInt;
554 begin
555 Result := '';
556 Len := Run - fTokenPos;
557 SetString(Result, (FLine + fTokenPos), Len);
558 end;
559
560 procedure TSynLFMSyn.GetTokenEx(out TokenStart: PChar;
561 out TokenLength: integer);
562 begin
563 TokenLength:=Run-fTokenPos;
564 TokenStart:=FLine + fTokenPos;
565 end;
566
GetTokenAttributenull567 function TSynLFMSyn.GetTokenAttribute: TSynHighlighterAttributes;
568 begin
569 case fTokenID of
570 tkComment: Result := fCommentAttri;
571 tkIdentifier: Result := fIdentifierAttri;
572 tkKey: Result := fKeyAttri;
573 tkNumber: Result := fNumberAttri;
574 tkSpace: Result := fSpaceAttri;
575 tkString: Result := fStringAttri;
576 tkSymbol: Result := fSymbolAttri;
577 tkUnknown: Result := fIdentifierAttri;
578 else Result := nil;
579 end;
580 end;
581
GetTokenKindnull582 function TSynLFMSyn.GetTokenKind: integer;
583 begin
584 Result := Ord(fTokenID);
585 end;
586
GetTokenPosnull587 function TSynLFMSyn.GetTokenPos: Integer;
588 begin
589 Result := fTokenPos;
590 end;
591
592 procedure TSynLFMSyn.ResetRange;
593 begin
594 inherited;
595 fRange := rsUnknown;
596 end;
597
598 procedure TSynLFMSyn.SetRange(Value: Pointer);
599 begin
600 inherited;
601 fRange := TRangeState(Integer(PtrUInt(CodeFoldRange.RangeType)));
602 end;
603
GetIdentCharsnull604 function TSynLFMSyn.GetIdentChars: TSynIdentChars;
605 begin
606 Result := TSynValidStringChars;
607 end;
608
TSynLFMSyn.GetLanguageNamenull609 class function TSynLFMSyn.GetLanguageName: string;
610 begin
611 Result := SYNS_LangLFM;
612 end;
613
TSynLFMSyn.GetSampleSourcenull614 function TSynLFMSyn.GetSampleSource: string;
615 begin
616 Result := '{ Delphi/C++ Builder Form Definitions }'#13#10 +
617 'object TestForm: TTestForm'#13#10 +
618 ' Left = 273'#13#10 +
619 ' Top = 103'#13#10 +
620 ' Caption = ''SynEdit sample source'''#13#10 +
621 'end';
622 end; { GetSampleSource }
623
624 procedure TSynLFMSyn.CreateRootCodeFoldBlock;
625 begin
626 inherited CreateRootCodeFoldBlock;
627 RootCodeFoldBlock.InitRootBlockType(Pointer(PtrInt(cfbtLfmNone)));
628 end;
629
TSynLFMSyn.StartLfmCodeFoldBlocknull630 function TSynLFMSyn.StartLfmCodeFoldBlock(ABlockType: TLfmCodeFoldBlockType): TSynCustomCodeFoldBlock;
631 var
632 FoldBlock: Boolean;
633 p: PtrInt;
634 begin
635 FoldBlock := FFoldConfig[ord(ABlockType)].Enabled;
636 p := 0;
637 if not FoldBlock then
638 p := PtrInt(CountLfmCodeFoldBlockOffset);
639 Result := StartCodeFoldBlock(p + Pointer(PtrInt(ABlockType)), FoldBlock);
640 end;
641
642 procedure TSynLFMSyn.EndLfmCodeFoldBlock;
643 var
644 DecreaseLevel: Boolean;
645 begin
646 DecreaseLevel := TopCodeFoldBlockType < CountLfmCodeFoldBlockOffset;
647 EndCodeFoldBlock(DecreaseLevel);
648 end;
649
TSynLFMSyn.TopLfmCodeFoldBlockTypenull650 function TSynLFMSyn.TopLfmCodeFoldBlockType(DownIndex: Integer): TLfmCodeFoldBlockType;
651 var
652 p: Pointer;
653 begin
654 p := TopCodeFoldBlockType(DownIndex);
655 if p >= CountLfmCodeFoldBlockOffset then
656 p := p - PtrUInt(CountLfmCodeFoldBlockOffset);
657 Result := TLfmCodeFoldBlockType(PtrUInt(p));
658 end;
659
TSynLFMSyn.GetFoldConfigCountnull660 function TSynLFMSyn.GetFoldConfigCount: Integer;
661 begin
662 // excluded cfbtLfmNone
663 Result := ord(high(TLfmCodeFoldBlockType)) - ord(low(TLfmCodeFoldBlockType));
664 end;
665
TSynLFMSyn.GetFoldConfigInternalCountnull666 function TSynLFMSyn.GetFoldConfigInternalCount: Integer;
667 begin
668 // include cfbtLfmNone
669 Result := ord(high(TLfmCodeFoldBlockType)) - ord(low(TLfmCodeFoldBlockType)) + 1;
670 end;
671
672 initialization
673 RegisterPlaceableHighlighter(TSynLFMSyn);
674
675 end.
676