-
Notifications
You must be signed in to change notification settings - Fork 0
/
BraceBlockContextSource.cs
142 lines (126 loc) · 3.84 KB
/
BraceBlockContextSource.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
135
136
137
138
139
140
141
142
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Adornments;
using Microsoft.VisualStudio.Text.Editor;
using Microsoft.VisualStudio.Text.Tagging;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace BraceProvider
{
class BraceBlockContextSource : IBlockContextSource
{
private ITextBuffer _buffer;
public BraceBlockContextSource(ITextBuffer buffer)
{
_buffer = buffer;
}
public async Task<IBlockContext> GetBlockContextAsync(IBlockTag blockTag, ITextView view, CancellationToken token)
{
IBlockContext bc = null;
await Task.Run(() => {
if (view.TextBuffer == _buffer)
{
object context = CreateContext(blockTag, view);
bc = new BraceBlockContext(blockTag, view, context);
}
});
return bc;
}
private object CreateContext(IBlockTag blockTag, ITextView view)
{
IBlockTag tempTag = blockTag;
Stack<IBlockTag> stack = new Stack<IBlockTag>();
while (true)
{
if (tempTag.Level == -1)
break;
stack.Push(tempTag);
if (tempTag.Level != 0)
{
tempTag = tempTag.Parent;
}
}
int indent = 0;
StringBuilder builder = new StringBuilder();
while (true)
{
tempTag = stack.Pop();
builder.Append(GetStatement(tempTag));
indent += 1;
if (stack.Count != 0)
{
builder.Append('\r');
builder.Append(' ', indent);
}
else
break;
}
return builder.ToString();
}
private string GetStatement(IBlockTag tag)
{
// Handle the two separate cases:
// public void Foo() {
// |
//
// public void Bar()
// {
// |
int lineNumber = _buffer.CurrentSnapshot.GetLineNumberFromPosition(tag.Span.Start.Position);
ITextSnapshotLine line = _buffer.CurrentSnapshot.GetLineFromLineNumber(lineNumber);
if (FirstNonWhitespace(line))
{
line = _buffer.CurrentSnapshot.GetLineFromLineNumber(lineNumber - 1);
}
return line.GetText();
}
// returns true if the line starts with '{' (and isn't the statement), false otherwise
private bool FirstNonWhitespace(ITextSnapshotLine line)
{
int i = line.Start;
while (i < line.End)
{
char c = line.Snapshot[i];
if (!char.IsWhiteSpace(c))
{
if (c == '{')
return true;
else
return false;
}
i++;
}
return false;
}
public void Dispose()
{
throw new NotImplementedException();
}
}
class BraceBlockContext : IBlockContext
{
private object _content;
private IBlockTag _tag;
private ITextView _view;
public BraceBlockContext(IBlockTag tag, ITextView view, object content)
{
_tag = tag;
_view = view;
_content = content;
}
public object Content
{
get { return _content; }
}
public IBlockTag BlockTag
{
get { return _tag; }
}
public ITextView TextView
{
get { return _view; }
}
}
}