-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathOutputLineRender.cs
134 lines (120 loc) · 4.21 KB
/
OutputLineRender.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
namespace FindInFiles {
internal sealed class OutputLineRender {
private readonly RichTextBox richTextBox;
private static readonly string MarkerPath = "\u200C"; // zero width non-joiner
private static readonly string MarkerLine = "\u200D"; // zero width joiner
private int visibleDelta = 0;
public OutputLineRender(RichTextBox richTextBox) {
this.richTextBox = richTextBox;
}
public Font Font {
get { return richTextBox.Font; }
set {
var current = richTextBox.Font;
if (value == current || (value.Name == current.Name && value.Style == current.Style && value.Size == current.Size)) {
return; // highlighting is lost when change font
}
richTextBox.Font = value;
}
}
public void Invalidate() {
richTextBox.Invalidate();
}
public void Clear() {
richTextBox.Clear();
}
public int Reset() {
var page = (int)(richTextBox.Height / richTextBox.GetLineHeight());
page = Math.Max(page, 5);
visibleDelta = page * 2;
richTextBox.Clear();
return page;
}
public void AppendText(string text, Color color) {
richTextBox.SelectionStart = richTextBox.TextLength;
richTextBox.SelectionColor = color;
richTextBox.SelectedText = text;
}
public void RenderOutput(IList<OutputLine> lines) {
var visible = richTextBox.Focused;
if (!visible) {
var last = richTextBox.GetLineFromCharIndex(-1);
if (last < visibleDelta) {
visible = true;
} else {
var top = richTextBox.GetLineFromCharIndex(richTextBox.GetCharIndexFromPosition(new Point(1, 1)));
visible = last - top < visibleDelta;
}
}
richTextBox.SetRedraw(false);
foreach (var line in lines) {
switch (line.LineType) {
case OutputLineType.Path:
AppendText($"{MarkerPath}{line.Text}{Environment.NewLine}", Color.Blue);
break;
case OutputLineType.Match:
AddMatchLine(line.Number, line.Text, line.Matches);
break;
case OutputLineType.Context:
AddContextLine(line.Number, line.Text);
break;
default:
AppendText($"{line.Text}{Environment.NewLine}", Color.Gray);
break;
}
}
richTextBox.SetRedraw(true);
if (visible) {
richTextBox.Invalidate();
}
}
private void AddContextLine(int number, string? line) {
AppendText($"{number}{MarkerLine}-", Color.Olive);
line = Util.RemoveLineEnding(line);
var padding = (line.Length == 0) ? "" : " ";
AppendText($"{padding}{line}{Environment.NewLine}", SystemColors.WindowText);
}
private void AddMatchLine(int number, string? line, MatchTextRange[]? matches) {
AppendText($"{number}{MarkerLine}:", Color.Green);
line = Util.RemoveLineEnding(line);
var padding = (line.Length == 0) ? "" : " ";
var docOffset = richTextBox.TextLength + padding.Length;
AppendText($"{padding}{line}{Environment.NewLine}", SystemColors.WindowText);
if (matches == null) {
return;
}
foreach (var match in matches) {
richTextBox.Select(match.Start + docOffset, match.Length);
richTextBox.SelectionColor = Color.Red;
if (match.Space) {
richTextBox.SelectionBackColor = Color.Green;
}
}
}
public void StartEditor() {
// line number is wrong when word wrap is enabled
var start = richTextBox.GetFirstCharIndexOfCurrentLine();
var lineno = richTextBox.GetLineFromCharIndex(start);
if (lineno < 1) {
return;
}
var end = richTextBox.GetFirstCharIndexFromLine(lineno + 1);
end = richTextBox.Find(MarkerLine, start, end, RichTextBoxFinds.MatchCase | RichTextBoxFinds.NoHighlight);
if (end > start) {
var text = richTextBox.GetTextRange(start, end);
if (int.TryParse(text, out var num)) {
var column = start + text.Length + 2;
start = richTextBox.Find(MarkerPath, 0, start, RichTextBoxFinds.MatchCase | RichTextBoxFinds.Reverse | RichTextBoxFinds.NoHighlight);
if (start >= 0) {
++start;
lineno = richTextBox.GetLineFromCharIndex(start);
end = richTextBox.GetFirstCharIndexFromLine(lineno + 1);
text = richTextBox.GetTextRange(start, end).Trim();
column = richTextBox.SelectionStart - column;
Util.StartEditor(text, num, column);
}
}
}
}
}
}