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 Alternatively, the contents of this file may be used under the terms of the
12 GNU General Public License Version 2 or later (the "GPL"), in which case
13 the provisions of the GPL are applicable instead of those above.
14 If you wish to allow use of your version of this file only under the terms
15 of the GPL and not to allow others to use your version of this file
16 under the MPL, indicate your decision by deleting the provisions above and
17 replace them with the notice and other provisions required by the GPL.
18 If you do not delete the provisions above, a recipient may use your version
19 of this file under either the MPL or the GPL.
20
21 This file was added to the Lazarus branch of SynEdit.
22 The original Author is M Friebe
23 }
24
25 { This unit provide Highlighting for diff files
26 Currently supported formats: Context, Unified
27 //Todo: support original diff
28 }
29
30 unit SynHighlighterDiff;
31
32 {$I SynEdit.inc}
33
34 interface
35
36 uses
37 Classes, Graphics, math,
38 SynEditHighlighter, SynEditHighlighterFoldBase;
39
40 type
41 TtkTokenKind = (tkNull, tkUnknown, tkSpace,
42 // File Header
43 tkFileOrigMark, tkFileNewMark,
44 tkFileOrig, tkFileNew,
45 // Chunk Header
46 tkChunkSeparator,
47 tkChunkMixedMark, tkChunkOrigMark, tkChunkNewMark,
48 tkChunkMixed, tkChunkOrig, tkChunkNew,
49 // Lines
50 tkLineRemovedMark, tkLineAddedMark, tkLineChangedMark, tkLineContextMark,
51 tkLineRemoved, tkLineAdded, tkLineChanged, tkLineContext
52 );
53
54 TRangeState = (rsUnknown,
55 // Context
56 rsCtxFirst,
57 rsCtxUnknown,
58 rsCtxFileOrig, rsCtxFileNew,
59 rsCtxChunkHeader, rsCtxChunkOrig, rsCtxChunkNew,
60 rsCtxLineRemoved, rsCtxLineAdded, rsCtxLineChanged,
61 rsCtxLineContext,
62 rsCtxLast,
63 // Unified
64 rsUniFirst,
65 rsUniUnknown,
66 rsUniFileOrig, rsUniFileNew,
67 rsUniChunkHeader,
68 rsUniLineRemoved, rsUniLineAdded,
69 rsUniLineContext,
70 rsUniLast
71 );
72
73 TDiffCodeFoldBlockType = (
74 cfbtDiffFile,
75 cfbtDiffChunk,
76 cfbtDiffChunkSect,
77 cfbtDiffNone
78 );
79
80 TProcTableProc = procedure of object;
81
82 const
83 CountDiffCodeFoldBlockOffset: Pointer =
84 Pointer(PtrInt(Integer(high(TDiffCodeFoldBlockType))+1));
85
86 type
87
88 { TSynDiffSyn }
89
90 TSynDiffSyn = class(TSynCustomFoldHighlighter)
91 private
92 fRange: TRangeState;
93 fLine: PChar;
94 fLineNumber: Integer;
95 Run: LongInt;
96 fTokenPos: Integer;
97 FTokenID: TtkTokenKind;
98 private
99 fProcTable: array[#0..#255] of TProcTableProc;
100 procedure MakeMethodTables;
101 procedure CRProc;
102 procedure LFProc;
103 procedure NullProc;
104 procedure LineProc;
105 procedure UnknownProc;
106 procedure AsteriskProc;
107 procedure MinusProc;
108 procedure PlusProc;
109 procedure ExclamationProc;
110 procedure AtProc;
111 procedure SpaceProc;
112 private
113 FChunkMarkerAttri: TSynHighlighterAttributes;
114 FChunkMixedAttri: TSynHighlighterAttributes;
115 FChunkNewAttri: TSynHighlighterAttributes;
116 FChunkOldAttri: TSynHighlighterAttributes;
117 FLineAddedAttri: TSynHighlighterAttributes;
118 FLineChangedAttri: TSynHighlighterAttributes;
119 FLineContextAttri: TSynHighlighterAttributes;
120 FLineRemovedAttri: TSynHighlighterAttributes;
121 FNewFileAttri: TSynHighlighterAttributes;
122 FOrigFileAttri: TSynHighlighterAttributes;
123 FSpaceAttri: TSynHighlighterAttributes;
124 FUnknownAttri: TSynHighlighterAttributes;
125 protected
GetSampleSourcenull126 function GetSampleSource : String; override;
127 public
128 constructor Create(AOwner: TComponent); override;
129 destructor Destroy; override;
130
GetTokennull131 function GetToken: String; override;
132 procedure GetTokenEx(out TokenStart: PChar; out TokenLength: integer); override;
GetTokenAttributenull133 function GetTokenAttribute: TSynHighlighterAttributes; override;
GetTokenKindnull134 function GetTokenKind: integer; override;
GetTokenPosnull135 function GetTokenPos: Integer; override;
GetTokenIDnull136 function GetTokenID: TtkTokenKind;
137
138 procedure Next; override;
GetEolnull139 function GetEol: Boolean; override;
140
141 procedure SetLine(const NewValue: String;
142 LineNumber: Integer); override;
GetRangenull143 function GetRange: Pointer; override;
144 procedure SetRange(Value: Pointer); override;
145 procedure ResetRange; override;
146
GetDefaultAttributenull147 function GetDefaultAttribute(Index: integer): TSynHighlighterAttributes; override;
GetLanguageNamenull148 class function GetLanguageName: string; override;
149 protected
150 // folding
151 procedure CreateRootCodeFoldBlock; override;
152
StartDiffCodeFoldBlocknull153 function StartDiffCodeFoldBlock(ABlockType: TDiffCodeFoldBlockType): TSynCustomCodeFoldBlock;
154 procedure EndDiffCodeFoldBlock;
TopDiffCodeFoldBlockTypenull155 function TopDiffCodeFoldBlockType(DownIndex: Integer = 0): TDiffCodeFoldBlockType;
156
GetFoldConfigInstancenull157 function GetFoldConfigInstance(Index: Integer): TSynCustomFoldConfig; override;
GetFoldConfigCountnull158 function GetFoldConfigCount: Integer; override;
GetFoldConfigInternalCountnull159 function GetFoldConfigInternalCount: Integer; override;
160 published
161 property UnknownAttri: TSynHighlighterAttributes read FUnknownAttri write FUnknownAttri;
162 property SpaceAttri: TSynHighlighterAttributes read FSpaceAttri write FSpaceAttri;
163 property OrigFileAttri: TSynHighlighterAttributes read FOrigFileAttri write FOrigFileAttri;
164 property NewFileAttri: TSynHighlighterAttributes read FNewFileAttri write FNewFileAttri;
165 property ChunkMarkerAttri: TSynHighlighterAttributes read FChunkMarkerAttri write FChunkMarkerAttri;
166 property ChunkNewAttri: TSynHighlighterAttributes read FChunkNewAttri write FChunkNewAttri;
167 property ChunkOldAttri: TSynHighlighterAttributes read FChunkOldAttri write FChunkOldAttri;
168 property ChunkMixedAttri: TSynHighlighterAttributes read FChunkMixedAttri write FChunkMixedAttri;
169 property LineAddedAttri: TSynHighlighterAttributes read FLineAddedAttri write FLineAddedAttri;
170 property LineRemovedAttri: TSynHighlighterAttributes read FLineRemovedAttri write FLineRemovedAttri;
171 property LineChangedAttri: TSynHighlighterAttributes read FLineChangedAttri write FLineChangedAttri;
172 property LineContextAttri: TSynHighlighterAttributes read FLineContextAttri write FLineContextAttri;
173 end;
174
175 implementation
176
177 uses
178 SynEditStrConst;
179
180
181 { TSynDiffSyn }
182
183 procedure TSynDiffSyn.MakeMethodTables;
184 var
185 I: Char;
186 begin
187 for I := #0 to #255 do
188 case I of
189 #13: fProcTable[I] := @CRProc;
190 #10: fProcTable[I] := @LFProc;
191 #0: fProcTable[I] := @NullProc;
192 '*': fProcTable[I] := @AsteriskProc;
193 '-': fProcTable[I] := @MinusProc;
194 '+': fProcTable[I] := @PlusProc;
195 '!': fProcTable[I] := @ExclamationProc;
196 '@': fProcTable[I] := @AtProc;
197 ' ': fProcTable[I] := @SpaceProc;
198 else fProcTable[I] := @UnknownProc;
199 end;
200 end;
201
202 procedure TSynDiffSyn.CRProc;
203 begin
204 fTokenID := tkSpace;
205 Inc(Run);
206 if (fLine[Run] = #10) then Inc(Run);
207 end;
208
209 procedure TSynDiffSyn.LFProc;
210 begin
211 fTokenID := tkSpace;
212 inc(Run);
213 end;
214
215 procedure TSynDiffSyn.NullProc;
216 begin
217 fTokenID := tkNull;
218 end;
219
220 procedure TSynDiffSyn.LineProc;
221 var
222 l: Integer;
223 begin
224 case fRange of
225 rsCtxFileOrig, rsUniFileOrig: FTokenID := tkFileOrig;
226 rsCtxFileNew, rsUniFileNew: FTokenID := tkFileNew;
227 rsCtxChunkNew: begin
228 l := length(fLine);
229 if fLine[Run] = '-' then begin
230 FTokenID := tkChunkNewMark;
231 while (Run < l-1) and (fLine[Run] = '-') do inc(Run);
232 end else begin
233 FTokenID := tkChunkNew;
234 while (Run < l-1) and (fLine[Run] <> '-') do inc(Run);
235 end;
236 end;
237 rsCtxChunkOrig: begin
238 l := length(fLine);
239 if fLine[Run] = '*' then begin
240 FTokenID := tkChunkOrigMark;
241 while (Run < l-1) and (fLine[Run] = '*') do inc(Run);
242 end else begin
243 FTokenID := tkChunkOrig;
244 while (Run < l-1) and (fLine[Run] <> '*') do inc(Run);
245 end;
246 end;
247 rsUniChunkHeader: begin
248 l := length(fLine);
249 if fLine[Run] = '@' then begin
250 FTokenID := tkChunkMixedMark;
251 while (Run < l-1) and (fLine[Run] = '@') do inc(Run);
252 end else begin
253 FTokenID := tkChunkMixed;
254 while (Run < l-1) and (fLine[Run] <> '@') do inc(Run);
255 end;
256 end;
257 rsCtxLineRemoved, rsUniLineRemoved: FTokenID := tkLineRemoved;
258 rsCtxLineAdded, rsUniLineAdded: FTokenID := tkLineAdded;
259 rsCtxLineChanged: FTokenID := tkLineChanged;
260 rsCtxLineContext, rsUniLineContext: FTokenID := tkLineContext;
261 else begin
262 FTokenID := tkUnknown;
263 end;
264 end;
265 Run := length(fLine); // #0 NullProc
266 end;
267
268 procedure TSynDiffSyn.UnknownProc;
269 begin
270 if (fRange in [rsCtxFirst..rsCtxLast]) then
271 fRange := rsCtxUnknown
272 else if (fRange in [rsUniFirst..rsUniLast]) then
273 fRange := rsUniUnknown
274 else
275 fRange := rsUnknown;
276 FTokenID := tkUnknown;
277 Run := length(fLine);
278 end;
279
280 procedure TSynDiffSyn.AsteriskProc;
281 var
282 l: Integer;
283 begin
284 (* Could be:
285 *** /path/to/original # orig file (Context Format)
286 *************** # start of chunk (Context Format)
287 *** 10,15 **** # chunk: lines in orig file (Context Format)
288 *)
289 l := length(fLine);
290 if (not (fRange in [rsUnknown, rsCtxFirst..rsCtxLast])) or
291 (l < 4) or (fLine[1] <> '*') or (fLine[2] <> '*')
292 then begin
293 UnknownProc;
294 exit;
295 end;
296
297 if fLine[3] = '*' then begin
298 // ***************
299 fRange := rsCtxChunkHeader;
300 FTokenID := tkChunkSeparator;
301 Run := l;
302 exit;
303 end;
304
305 if fLine[3] = ' ' then begin
306 if fRange in [rsCtxChunkHeader..rsCtxChunkNew] then begin
307 // *** 10,15 ****
308 fRange := rsCtxChunkOrig;
309 FTokenID := tkChunkOrigMark;
310 Run := 3;
311 end
312 else begin
313 // *** /path/to/original
314 fRange := rsCtxFileOrig;
315 FTokenID := tkFileOrigMark;
316 Run := 3;
317 end;
318 end
319 else
320 UnknownProc;
321 end;
322
323 procedure TSynDiffSyn.MinusProc;
324 var
325 l: Integer;
326 begin
327 (* Could be:
328 --- /path/to/new # new file (Context) [usually after *** / path/to/orig]
329 --- 10,15 ---- # chunk: lines in new file (Context)
330 - foo # Removed Line (Context)
331 --- /path/to/original # orig file (Unified) [usually before +++ / path/to/new]
332 -foo # Removed Line (Unified)
333 *)
334
335 l := length(fLine);
336 if (l > 4) and (fLine[1] = '-') and (fLine[2] = '-') and (fLine[3] = ' ') then begin
337 // Todo: this check is unsufficent in Unified format; need to track amount of lines in Chunk
338 if fRange in [rsUnknown, rsUniFirst..rsUniLast] then begin
339 // --- /path/to/original # orig file (Unified)
340 fRange := rsUniFileOrig;
341 FTokenID := tkFileOrigMark;
342 Run := 3;
343 end
344 else if fRange in [rsCtxFileOrig] then begin
345 // --- /path/to/new # new file (Context)
346 fRange := rsCtxFileNew;
347 FTokenID := tkFileNewMark;
348 Run := 3;
349 end
350 else begin
351 // --- 10,15 ---- # new line (Context)
352 fRange := rsCtxChunkNew;
353 FTokenID := tkChunkNewMark;
354 Run := 3;
355 end;
356
357 exit;
358 end;
359
360 if fRange = rsUnknown then begin
361 FTokenID := tkUnknown;
362 Run := l;
363 exit;
364 end;
365
366 if (fRange in [rsCtxFirst..rsCtxLast]) then begin
367 fRange := rsCtxLineRemoved;
368 Run := Min(l, 2);
369 end else begin
370 fRange := rsUniLineRemoved;
371 Run := 1;
372 end;
373 FTokenID := tkLineRemovedMark;
374 end;
375
376 procedure TSynDiffSyn.PlusProc;
377 var
378 l: Integer;
379 begin
380 (* Could be:
381 + foo # Removed Line (Context)
382 +++ /path/to/new # orig file (Unified)
383 +foo # Removed Line (Unified)
384 *)
385
386 l := length(fLine);
387 if (l > 4) and (fLine[1] = '+') and (fLine[2] = '+') and (fLine[3] = ' ') then begin
388 // Todo: this check is unsufficent in Unified format; need to track amount of lines in Chunk
389 if fRange in [rsUnknown, rsUniFirst..rsUniLast] then begin
390 // --- /path/to/new # new file (Unified)
391 fRange := rsUniFileNew;
392 FTokenID := tkFileNewMark;
393 Run := 3;
394 exit;
395 end;
396 end;
397
398 if fRange = rsUnknown then begin
399 FTokenID := tkUnknown;
400 Run := l;
401 exit;
402 end;
403
404 if (fRange in [rsCtxFirst..rsCtxLast]) then begin
405 fRange := rsCtxLineAdded;
406 Run := Min(l, 2);
407 end else begin
408 fRange := rsUniLineAdded;
409 Run := 1;
410 end;
411 FTokenID := tkLineAddedMark;
412 end;
413
414 procedure TSynDiffSyn.ExclamationProc;
415 var
416 l: Integer;
417 begin
418 (* Could be:
419 ! foo # Changed Line (Context)
420 *)
421
422 l := length(fLine);
423 if (fRange in [rsCtxFirst..rsCtxLast]) and (l >= 2) and (fLine[1] = ' ')
424 then begin
425 fRange := rsCtxLineChanged;
426 FTokenID := tkLineChangedMark;
427 Run := Min(l, 2);
428 exit;
429 end;
430
431 UnknownProc;
432 end;
433
434 procedure TSynDiffSyn.AtProc;
435 var
436 l: Integer;
437 begin
438 (* Could be:
439 @@ -1,3 +1,9 @@ # Start of Chunk (Unified)
440 *)
441
442 l := length(fLine);
443 if (fRange in [rsCtxFirst..rsCtxLast]) or
444 (l < 3) or (fLine[1] <> '@') or (fLine[2] <> ' ')
445 then begin
446 UnknownProc;
447 exit;
448 end;
449
450 fRange := rsUniChunkHeader;
451 FTokenID := tkChunkMixedMark;
452 Run := Min(l, 2);
453 end;
454
455 procedure TSynDiffSyn.SpaceProc;
456 begin
457 (* Could be:
458 " foo" # Context Line (Context, Unified)
459 *)
460
461 if fRange = rsUnknown then
462 UnknownProc;
463
464 if (fRange in [rsCtxFirst..rsCtxLast]) then begin
465 fRange := rsCtxLineContext;
466 Run := Min(length(fLine), 2);
467 end else begin
468 fRange := rsUniLineContext;
469 Run := 1;
470 end;
471
472 FTokenID := tkChunkMixedMark;
473 end;
474
GetSampleSourcenull475 function TSynDiffSyn.GetSampleSource: string;
476 begin
477 Result := ''#13#10 +
478 '';
479 end;
480
481 constructor TSynDiffSyn.Create(AOwner: TComponent);
482 begin
483 inherited Create(AOwner);
484
485 FUnknownAttri := TSynHighlighterAttributes.Create(@SYNS_AttrUnknownWord, SYNS_XML_AttrUnknownWord);
486 FUnknownAttri.Style := [fsItalic];
487 AddAttribute(FUnknownAttri);
488
489 FSpaceAttri := TSynHighlighterAttributes.Create(@SYNS_AttrSpace, SYNS_XML_AttrSpace);
490 AddAttribute(FSpaceAttri);
491
492 FOrigFileAttri := TSynHighlighterAttributes.Create(@SYNS_AttrOrigFile, SYNS_XML_AttrOrigFile);
493 FOrigFileAttri.Style := [fsBold];
494 FOrigFileAttri.Background := clRed;
495 AddAttribute(FOrigFileAttri);
496
497 FNewFileAttri := TSynHighlighterAttributes.Create(@SYNS_AttrNewFile, SYNS_XML_AttrNewFile);
498 FNewFileAttri.Style := [fsBold];
499 FNewFileAttri.Background := clGreen;
500 AddAttribute(FNewFileAttri);
501
502 FChunkMarkerAttri := TSynHighlighterAttributes.Create(@SYNS_AttrChunkMarker, SYNS_XML_AttrChunkMarker);
503 FChunkMarkerAttri.Style := [fsBold];
504 AddAttribute(FChunkMarkerAttri);
505
506 FChunkNewAttri := TSynHighlighterAttributes.Create(@SYNS_AttrChunkNew, SYNS_XML_AttrChunkNew);
507 FChunkNewAttri.Style := [fsBold];
508 FChunkNewAttri.Foreground := clGreen;
509 AddAttribute(FChunkNewAttri);
510
511 FChunkOldAttri := TSynHighlighterAttributes.Create(@SYNS_AttrChunkOrig, SYNS_XML_AttrChunkOrig);
512 FChunkOldAttri.Style := [fsBold];
513 FChunkOldAttri.Foreground := clRed;
514 AddAttribute(FChunkOldAttri);
515
516 FChunkMixedAttri := TSynHighlighterAttributes.Create(@SYNS_AttrChunkMixed, SYNS_XML_AttrChunkMixed);
517 FChunkMixedAttri.Style := [fsBold];
518 FChunkMixedAttri.Foreground := clPurple;
519 AddAttribute(FChunkMixedAttri);
520
521 FLineAddedAttri := TSynHighlighterAttributes.Create(@SYNS_AttrLineAdded, SYNS_XML_AttrLineAdded);
522 FLineAddedAttri.Foreground := clGreen;
523 AddAttribute(FLineAddedAttri);
524
525 FLineRemovedAttri := TSynHighlighterAttributes.Create(@SYNS_AttrLineRemoved, SYNS_XML_AttrLineRemoved);
526 FLineRemovedAttri.Foreground := clRed;
527 AddAttribute(FLineRemovedAttri);
528
529 FLineChangedAttri := TSynHighlighterAttributes.Create(@SYNS_AttrLineChanged, SYNS_XML_AttrLineChanged);
530 FLineChangedAttri.Foreground := clPurple;
531 AddAttribute(FLineChangedAttri);
532
533 FLineContextAttri := TSynHighlighterAttributes.Create(@SYNS_AttrLineContext, SYNS_XML_AttrLineContext);
534 AddAttribute(FLineContextAttri);
535
536 SetAttributesOnChange(@DefHighlightChange);
537 MakeMethodTables;
538 fDefaultFilter := '';
539 fRange := rsUnknown;
540 end;
541
542 destructor TSynDiffSyn.Destroy;
543 begin
544 inherited Destroy;
545 end;
546
TSynDiffSyn.GetTokennull547 function TSynDiffSyn.GetToken: String;
548 var
549 Len: LongInt;
550 begin
551 Result := '';
552 Len := Run - fTokenPos;
553 SetString(Result, (FLine + fTokenPos), Len);
554 end;
555
556 procedure TSynDiffSyn.GetTokenEx(out TokenStart: PChar;
557 out TokenLength: integer);
558 begin
559 TokenLength:=Run-fTokenPos;
560 TokenStart:=FLine + fTokenPos;
561 end;
562
GetTokenAttributenull563 function TSynDiffSyn.GetTokenAttribute: TSynHighlighterAttributes;
564 begin
565 case fTokenID of
566 tkNull: Result := FUnknownAttri;
567 tkUnknown: Result := FUnknownAttri;
568 tkSpace: Result := FSpaceAttri;
569 tkFileOrigMark: Result := FOrigFileAttri;
570 tkFileNewMark: Result := FNewFileAttri;
571 tkFileOrig: Result := FOrigFileAttri;
572 tkFileNew: Result := FNewFileAttri;
573 tkChunkSeparator: Result := FChunkMarkerAttri;
574 tkChunkMixedMark: Result := FChunkMixedAttri;
575 tkChunkOrigMark: Result := FChunkOldAttri;
576 tkChunkNewMark: Result := FChunkNewAttri;
577 tkChunkMixed: Result := FChunkMixedAttri;
578 tkChunkOrig: Result := FChunkOldAttri;
579 tkChunkNew: Result := FChunkNewAttri;
580 tkLineRemovedMark: Result := FLineRemovedAttri;
581 tkLineAddedMark: Result := FLineAddedAttri;
582 tkLineChangedMark: Result := FLineChangedAttri;
583 tkLineContextMark: Result := FLineContextAttri;
584 tkLineRemoved: Result := FLineRemovedAttri;
585 tkLineAdded: Result := FLineAddedAttri;
586 tkLineChanged: Result := FLineChangedAttri;
587 tkLineContext: Result := FLineContextAttri;
588 else Result := nil;
589 end;
590 end;
591
GetTokenKindnull592 function TSynDiffSyn.GetTokenKind: integer;
593 begin
594 Result := Ord(fTokenID);
595 end;
596
TSynDiffSyn.GetTokenPosnull597 function TSynDiffSyn.GetTokenPos: Integer;
598 begin
599 Result := fTokenPos;
600 end;
601
GetTokenIDnull602 function TSynDiffSyn.GetTokenID: TtkTokenKind;
603 begin
604 Result := fTokenId;
605 end;
606
607 procedure TSynDiffSyn.Next;
608 var
609 OldRange: TRangeState;
610 begin
611 fTokenPos := Run;
612 if Run > 0 then begin
613 if fLine[Run] = #0 then NullProc
614 else LineProc;
615 end else begin
616 OldRange := fRange;
617 fProcTable[fLine[Run]]();
618
619 if ((fRange in [rsCtxFileOrig, rsCtxFileNew, rsUniFileOrig..rsUniFileNew]) and
620 not (OldRange in [rsCtxFileOrig, rsCtxFileNew, rsUniFileOrig..rsUniFileNew]))
621 then begin
622 while (TopDiffCodeFoldBlockType in [cfbtDiffChunkSect, cfbtDiffChunk, cfbtDiffFile]) do
623 EndDiffCodeFoldBlock;
624 StartDiffCodeFoldBlock(cfbtDiffFile);
625 end;
626
627 if (fRange in [rsCtxChunkHeader, rsUniChunkHeader])
628 then begin
629 while (TopDiffCodeFoldBlockType in [cfbtDiffChunkSect, cfbtDiffChunk]) do
630 EndDiffCodeFoldBlock;
631 StartDiffCodeFoldBlock(cfbtDiffChunk);
632 end;
633
634 if (fRange in [rsCtxChunkOrig, rsCtxChunkNew])
635 then begin
636 if (TopDiffCodeFoldBlockType = cfbtDiffChunkSect) then
637 EndDiffCodeFoldBlock;
638 StartDiffCodeFoldBlock(cfbtDiffChunkSect);
639 end;
640
641
642 end;
643 end;
644
GetEolnull645 function TSynDiffSyn.GetEol: Boolean;
646 begin
647 Result := fTokenId = tkNull;
648 end;
649
650 procedure TSynDiffSyn.SetLine(const NewValue: String;
651 LineNumber: Integer);
652 begin
653 inherited;
654 fLine := PChar(NewValue);
655 Run := 0;
656 fLineNumber := LineNumber;
657 Next;
658 end;
659
TSynDiffSyn.GetRangenull660 function TSynDiffSyn.GetRange: Pointer;
661 begin
662 CodeFoldRange.RangeType:=Pointer(PtrUInt(Integer(fRange)));
663 Result := inherited;
664 end;
665
666 procedure TSynDiffSyn.SetRange(Value: Pointer);
667 begin
668 inherited;
669 fRange := TRangeState(Integer(PtrUInt(CodeFoldRange.RangeType)));
670 end;
671
672 procedure TSynDiffSyn.ResetRange;
673 begin
674 inherited;
675 fRange := rsUnknown;
676 end;
677
GetDefaultAttributenull678 function TSynDiffSyn.GetDefaultAttribute(Index: integer): TSynHighlighterAttributes;
679 begin
680 Result := nil;
681 end;
682
TSynDiffSyn.GetLanguageNamenull683 class function TSynDiffSyn.GetLanguageName: string;
684 begin
685 Result := SYNS_LangDiff;
686 end;
687
688 procedure TSynDiffSyn.CreateRootCodeFoldBlock;
689 begin
690 inherited CreateRootCodeFoldBlock;
691 RootCodeFoldBlock.InitRootBlockType(Pointer(PtrInt(cfbtDiffNone)));
692 end;
693
StartDiffCodeFoldBlocknull694 function TSynDiffSyn.StartDiffCodeFoldBlock(ABlockType: TDiffCodeFoldBlockType): TSynCustomCodeFoldBlock;
695 var
696 FoldBlock: Boolean;
697 p: PtrInt;
698 begin
699 FoldBlock := FFoldConfig[ord(ABlockType)].Enabled;
700 p := 0;
701 if not FoldBlock then
702 p := PtrInt(CountDiffCodeFoldBlockOffset);
703 Result := StartCodeFoldBlock(p + Pointer(PtrInt(ABlockType)), FoldBlock);
704 end;
705
706 procedure TSynDiffSyn.EndDiffCodeFoldBlock;
707 var
708 DecreaseLevel: Boolean;
709 begin
710 DecreaseLevel := TopCodeFoldBlockType < CountDiffCodeFoldBlockOffset;
711 EndCodeFoldBlock(DecreaseLevel);
712 end;
713
TopDiffCodeFoldBlockTypenull714 function TSynDiffSyn.TopDiffCodeFoldBlockType(DownIndex: Integer): TDiffCodeFoldBlockType;
715 var
716 p: Pointer;
717 begin
718 p := TopCodeFoldBlockType(DownIndex);
719 if p >= CountDiffCodeFoldBlockOffset then
720 p := p - PtrUInt(CountDiffCodeFoldBlockOffset);
721 Result := TDiffCodeFoldBlockType(PtrUInt(p));
722 end;
723
GetFoldConfigInstancenull724 function TSynDiffSyn.GetFoldConfigInstance(Index: Integer): TSynCustomFoldConfig;
725 begin
726 Result := inherited GetFoldConfigInstance(Index);
727 Result.Enabled := True;
728 end;
729
GetFoldConfigCountnull730 function TSynDiffSyn.GetFoldConfigCount: Integer;
731 begin
732 // excluded cfbtDiffnone;
733 Result := ord(high(TDiffCodeFoldBlockType)) - ord(low(TDiffCodeFoldBlockType));
734 end;
735
TSynDiffSyn.GetFoldConfigInternalCountnull736 function TSynDiffSyn.GetFoldConfigInternalCount: Integer;
737 begin
738 // include cfbtDiffnone;
739 Result := ord(high(TDiffCodeFoldBlockType)) - ord(low(TDiffCodeFoldBlockType)) + 1;
740 end;
741
742 initialization
743 RegisterPlaceableHighlighter(TSynDiffSyn);
744
745 end.
746