Check-in [abecf9f927]
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:The Wide Diff highlighter is done (for now; inline diffs can be done later).
Timelines: family | ancestors | descendants | both | lazarus
Files: files | file ages | folders
SHA1:abecf9f927166164675a1dc13fc881d950477a27
User & Date: tinus 2014-08-07 03:50:33
Context
2014-08-07
04:22
Renamed wide diff highlighter, and added support for writing its attributes. check-in: b42ec8b614 user: tinus tags: lazarus
03:50
The Wide Diff highlighter is done (for now; inline diffs can be done later). check-in: abecf9f927 user: tinus tags: lazarus
2014-08-06
21:11
Bugfix: reset the ColIndex when starting a new line. check-in: e74a31c95f user: tinus tags: lazarus
Changes

Changes to src/a_fileversioninfo.lfm.

714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
    WantTabs = False
    inline SynLeftGutterPartList1: TSynGutterPartList
      object SynGutterMarks1: TSynGutterMarks
        Width = 24
        MouseActions = <>
      end
      object SynGutterLineNumber1: TSynGutterLineNumber
        Width = 22
        Visible = False
        MouseActions = <>
        MarkupInfo.Background = clBtnFace
        MarkupInfo.Foreground = clNone
        MarkupInfo.FrameEdges = sfeAround
        DigitCount = 2
        ShowOnlyLineNumbersMultiplesOf = 1







|







714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
    WantTabs = False
    inline SynLeftGutterPartList1: TSynGutterPartList
      object SynGutterMarks1: TSynGutterMarks
        Width = 24
        MouseActions = <>
      end
      object SynGutterLineNumber1: TSynGutterLineNumber
        Width = 37
        Visible = False
        MouseActions = <>
        MarkupInfo.Background = clBtnFace
        MarkupInfo.Foreground = clNone
        MarkupInfo.FrameEdges = sfeAround
        DigitCount = 2
        ShowOnlyLineNumbersMultiplesOf = 1

Changes to src/a_fileversioninfo.pas.

213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
          synEdit.Highlighter := modHighlighters.shlDiffWide;
        end else begin
          synEdit.Highlighter := modHighlighters.shlDiff;
        end;

        DiffOpts := cDefaultDiffOptions;
        DiffOpts.SideBySide := btnViewDiffWide.Down;
        DiffOpts.Width := (synEdit.CharsInWindow div 2) - 10;
        synEdit.Lines.Text := FFile.GetDiff(@DiffOpts);

        synEdit.Gutter.Parts.ByClass[TSynGutterLineNumber, 0].Visible := False;

      end else if btnViewAnnotate.Down then begin
        synEdit.Highlighter := nil;
        synEdit.Lines.Text := FFile.GetAnnotated();







|







213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
          synEdit.Highlighter := modHighlighters.shlDiffWide;
        end else begin
          synEdit.Highlighter := modHighlighters.shlDiff;
        end;

        DiffOpts := cDefaultDiffOptions;
        DiffOpts.SideBySide := btnViewDiffWide.Down;
        DiffOpts.Width := (synEdit.CharsInWindow div 2) - 9;
        synEdit.Lines.Text := FFile.GetDiff(@DiffOpts);

        synEdit.Gutter.Parts.ByClass[TSynGutterLineNumber, 0].Visible := False;

      end else if btnViewAnnotate.Down then begin
        synEdit.Highlighter := nil;
        synEdit.Lines.Text := FFile.GetAnnotated();

Changes to src/synhighlighterdiffwide.pas.

95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
...
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
...
154
155
156
157
158
159
160
161
162
163
164

165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189

190
191
192
193



194
195
196
197
198
199
200
...
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230





231
232
233
234
235
236
237
238
239
240



241
242
243
244
245
246



























247



248
249
250
251
252
253
254
255
  FTokenPos := 1;
  FTokenLength := 0;
  FTokenStyle := hsUnknown;

  SetLength(FColDefs, 0);
  FColIndex := 0;
  for hs := Low(THighlightStyle) to High(THighlightStyle) do begin
    //StyleName := GetEnumName(TypeInfo(THighlightStyle), Ord(hs));
    //StyleName := Copy(StyleName, 3, Length(StyleName));
    StyleName := 'Style' + IntToStr(Ord(hs));
    Attr := AddSpecialAttribute(StyleName, StyleName);
    FStyles[hs] := Attr;
    case hs of
      hsUnknown: begin
        Attr.Style := [fsItalic];
      end;
      hsHeader: begin
................................................................................
      hsDivider: begin
        Attr.Style := [fsBold];
        Attr.Foreground := clBlue;
      end;
      hsSpace, hsContent: begin
      end;
      hsLineNumber: begin
        Attr.Background := clGray;
        Attr.Foreground := clWhite;
      end;
      hsMarkerAdded: begin
        Attr.Foreground := clGreen;
      end;
      hsMarkerEdited: begin
        Attr.Foreground := clNavy;
      end;
      hsMarkerDeleted: begin
        Attr.Foreground := clRed;
      end;
      hsContentAdded: begin
        //Attr.Background := TColor($99FF99); // TODO
      end;
      hsContentEdited: begin
        //Attr.Background := TColor($FF9999); // TODO
      end;
      hsContentDeleted: begin
        //Attr.Background := TColor($9999FF); // TODO
      end;
    end;
  end;
end;

destructor TSynHighlighterDiffWide.Destroy;
begin
................................................................................
  Result := FStyles[AIndex];
end;

procedure TSynHighlighterDiffWide.SetToken(const StartPos, ALength: Integer;
                                            const Style: THighlightStyle);
begin
  FTokenPos := StartPos; // FTokenPos is 1-based
  if ALength < 0 then
    FTokenLength := Length(FLineText) - FTokenPos + 1
  else
    FTokenLength := ALength;

  FTokenStyle := Style;
end;
procedure TSynHighlighterDiffWide.SetToken(const ColDef: PHSColDef);
begin
  SetToken(ColDef^.Start, ColDef^.Length, ColDef^.Style);
end;

procedure TSynHighlighterDiffWide.SetLine(const NewValue: String;
  LineNumber: Integer);
var
  ColIndex: Integer;
  { - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - }
  procedure ResetColDefs(const Length: Integer);
  begin
    SetLength(FColDefs, Length);
    ColIndex := 0;
  end;
  { - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - }
  function AddColDef(const Length: Integer; const Style: THighlightStyle): Integer;
  begin
    Result := ColIndex;
    if ColIndex = 0 then
      FColDefs[Result].Start := 1
    else
      FColDefs[Result].Start := FColDefs[Result - 1].Start + FColDefs[Result - 1].Length;

    FColDefs[Result].Style := Style;
    Inc(ColIndex);
  end;
  { - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - }



begin
  inherited SetLine(NewValue, LineNumber);
  FLineText := NewValue;
  FLineIndex := LineNumber;
  if Length(NewValue) = 0 then begin
    FLineType := #0;
    SetToken(1, -1, hsUnknown);
................................................................................
  end;
  // keep track of the type of line we're on
  FLineType := NewValue[1];
  case NewValue[1] of
    '=': begin // header
      // Determine the content width
      FContentWidth := (Length(FLineText) - 1) div 2 - 8;
      ResetColDefs(8);
      AddColDef(5, hsLineNumber);
      AddColDef(2, hsSpace);
      AddColDef(FContentWidth, hsContent);
      AddColDef(1, hsSpace);
      AddColDef(1, hsMarkerEdited);
      AddColDef(1, hsSpace);
      AddColDef(5, hsLineNumber);
      AddColDef(2, hsSpace);
      AddColDef(FContentWidth, hsContent);
      // set the token to the entire line, and set the styler to HeaderAttri
      SetToken(1, -1, hsHeader);
    end;
    '.': begin // divider
      // set the token to the entire line, and set the styler to DividerAttri
      SetToken(1, -1, hsDivider);
    end;
    ' ', '0'..'9': begin // a diff line
      FLineType := ' ';
      // set the token to the first 5 chars, and set the styler to LineNumberAttri
      FColIndex := 0;
      SetToken(1, 5, hsLineNumber);





    end;
    else begin // unknown
      FLineType := '?';
      // set the token to the entire line, and set the styler to UnknownAttri
      SetToken(1, -1, hsUnknown);
    end;
  end;
end;

procedure TSynHighlighterDiffWide.Next;



begin
  if FLineType = ' ' then begin
    // TODO: linenum[5], space[2], content[FContentWidth], space[1], marker[1], space[1], linenum[5], space[2], content[FContentWidth]
    Inc(FColIndex);
    if FColIndex < Length(FColDefs) then begin
      SetToken(@FColDefs[FColIndex]);



























    end else begin



      SetToken(Length(FLineText) + 1, 0, hsSpace);
    end;
  end else begin
    SetToken(Length(FLineText) + 1, 0, hsSpace);
  end;
end;

function TSynHighlighterDiffWide.GetEol: Boolean;







|
|
<







 







|
|











|


|


|







 







|

|

>









<
<




<


|






>

<


>
>
>







 







|
|
|
|
|
|
|
|
|
|












>
>
>
>
>










>
>
>





|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
|







95
96
97
98
99
100
101
102
103

104
105
106
107
108
109
110
...
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
...
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173


174
175
176
177

178
179
180
181
182
183
184
185
186
187
188

189
190
191
192
193
194
195
196
197
198
199
200
...
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
  FTokenPos := 1;
  FTokenLength := 0;
  FTokenStyle := hsUnknown;

  SetLength(FColDefs, 0);
  FColIndex := 0;
  for hs := Low(THighlightStyle) to High(THighlightStyle) do begin
    StyleName := GetEnumName(TypeInfo(THighlightStyle), Ord(hs));
    StyleName := Copy(StyleName, 3, Length(StyleName));

    Attr := AddSpecialAttribute(StyleName, StyleName);
    FStyles[hs] := Attr;
    case hs of
      hsUnknown: begin
        Attr.Style := [fsItalic];
      end;
      hsHeader: begin
................................................................................
      hsDivider: begin
        Attr.Style := [fsBold];
        Attr.Foreground := clBlue;
      end;
      hsSpace, hsContent: begin
      end;
      hsLineNumber: begin
        Attr.Background := clBtnFace; // clGray;
        Attr.Foreground := clBtnText; // clWhite;
      end;
      hsMarkerAdded: begin
        Attr.Foreground := clGreen;
      end;
      hsMarkerEdited: begin
        Attr.Foreground := clNavy;
      end;
      hsMarkerDeleted: begin
        Attr.Foreground := clRed;
      end;
      hsContentAdded: begin
        Attr.Background := TColor($C0FFC0);
      end;
      hsContentEdited: begin
        Attr.Background := TColor($FFC0C0);
      end;
      hsContentDeleted: begin
        Attr.Background := TColor($C0C0FF);
      end;
    end;
  end;
end;

destructor TSynHighlighterDiffWide.Destroy;
begin
................................................................................
  Result := FStyles[AIndex];
end;

procedure TSynHighlighterDiffWide.SetToken(const StartPos, ALength: Integer;
                                            const Style: THighlightStyle);
begin
  FTokenPos := StartPos; // FTokenPos is 1-based
  if (ALength < 0) or (FTokenPos + ALength > Length(FLineText)) then begin
    FTokenLength := Length(FLineText) - FTokenPos + 1
  end else begin
    FTokenLength := ALength;
  end;
  FTokenStyle := Style;
end;
procedure TSynHighlighterDiffWide.SetToken(const ColDef: PHSColDef);
begin
  SetToken(ColDef^.Start, ColDef^.Length, ColDef^.Style);
end;

procedure TSynHighlighterDiffWide.SetLine(const NewValue: String;
  LineNumber: Integer);


  { - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - }
  procedure ResetColDefs(const Length: Integer);
  begin
    SetLength(FColDefs, Length);

  end;
  { - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - }
  function AddColDef(const ColIndex, Length: Integer; const Style: THighlightStyle): Integer;
  begin
    Result := ColIndex;
    if ColIndex = 0 then
      FColDefs[Result].Start := 1
    else
      FColDefs[Result].Start := FColDefs[Result - 1].Start + FColDefs[Result - 1].Length;
    FColDefs[Result].Length := Length;
    FColDefs[Result].Style := Style;

  end;
  { - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - }
var
  sContent: string;
  Spaces: Integer;
begin
  inherited SetLine(NewValue, LineNumber);
  FLineText := NewValue;
  FLineIndex := LineNumber;
  if Length(NewValue) = 0 then begin
    FLineType := #0;
    SetToken(1, -1, hsUnknown);
................................................................................
  end;
  // keep track of the type of line we're on
  FLineType := NewValue[1];
  case NewValue[1] of
    '=': begin // header
      // Determine the content width
      FContentWidth := (Length(FLineText) - 1) div 2 - 8;
      ResetColDefs(9);
      AddColDef(0, 5, hsLineNumber);
      AddColDef(1, 2, hsSpace);
      AddColDef(2, FContentWidth, hsContent);
      AddColDef(3, 1, hsSpace);
      AddColDef(4, 1, hsMarkerEdited);
      AddColDef(5, 1, hsSpace);
      AddColDef(6, 5, hsLineNumber);
      AddColDef(7, 2, hsSpace);
      AddColDef(8, FContentWidth, hsContent);
      // set the token to the entire line, and set the styler to HeaderAttri
      SetToken(1, -1, hsHeader);
    end;
    '.': begin // divider
      // set the token to the entire line, and set the styler to DividerAttri
      SetToken(1, -1, hsDivider);
    end;
    ' ', '0'..'9': begin // a diff line
      FLineType := ' ';
      // set the token to the first 5 chars, and set the styler to LineNumberAttri
      FColIndex := 0;
      SetToken(1, 5, hsLineNumber);
      // Trim the left-side content
      sContent := TrimRight(Copy(FLineText, FColDefs[2].Start, FContentWidth));
      FColDefs[2].Length := Length(sContent);
      FColDefs[3].Start := FColDefs[2].Start + FColDefs[2].Length;
      FColDefs[3].Length := (FContentWidth - Length(sContent)) + 1;
    end;
    else begin // unknown
      FLineType := '?';
      // set the token to the entire line, and set the styler to UnknownAttri
      SetToken(1, -1, hsUnknown);
    end;
  end;
end;

procedure TSynHighlighterDiffWide.Next;
var
  ColDef: PHSColDef;
  Style: THighlightStyle;
begin
  if FLineType = ' ' then begin
    // TODO: linenum[5], space[2], content[FContentWidth], space[1], marker[1], space[1], linenum[5], space[2], content[FContentWidth]
    Inc(FColIndex);
    if FColIndex < Length(FColDefs) then begin
      ColDef := @FColDefs[FColIndex];
      if ColDef^.Style = hsContent then begin
        Style := ColDef^.Style;
        case FLineText[5+2+FContentWidth+1+1] of
          '<': begin
            if FColIndex < (Length(FColDefs) div 2) then
              Style := hsContentDeleted;
          end;
          '>': begin
            if FColIndex > (Length(FColDefs) div 2) then
              Style := hsContentAdded;
          end;
          '|': begin
            Style := hsContentEdited;
          end;
        end;
        SetToken(ColDef^.Start, ColDef^.Length, Style);
      end else if ColDef^.Style = hsMarkerEdited then begin
        Style := ColDef^.Style;
        case FLineText[5+2+FContentWidth+1+1] of
          '<': begin
            Style := hsMarkerDeleted;
          end;
          '>': begin
            Style := hsMarkerAdded;
          end;
        end;
        SetToken(ColDef^.Start, ColDef^.Length, Style);
      end else begin
        SetToken(ColDef);
      end;
    end else begin
      SetToken(Length(FLineText) + 1, 0, hsUnknown);
    end;
  end else begin
    SetToken(Length(FLineText) + 1, 0, hsSpace);
  end;
end;

function TSynHighlighterDiffWide.GetEol: Boolean;