Skip to content

Commit 50036a3

Browse files
committed
Update TextTools, improve white space
1 parent 2684999 commit 50036a3

15 files changed

+354
-287
lines changed

TextTools/Resource1.Designer.cs

Lines changed: 0 additions & 63 deletions
This file was deleted.

TextTools/Resource1.resx

Lines changed: 0 additions & 101 deletions
This file was deleted.

TextTools/TextTools.csproj

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -74,17 +74,16 @@
7474
<WarningLevel>4</WarningLevel>
7575
</PropertyGroup>
7676
<ItemGroup>
77-
<Compile Include="Encoding\PostSaveProcess.cs" />
7877
<Compile Include="Properties\AssemblyInfo.cs" />
79-
<Compile Include="Resource1.Designer.cs">
80-
<AutoGen>True</AutoGen>
81-
<DesignTime>True</DesignTime>
82-
<DependentUpon>Resource1.resx</DependentUpon>
83-
</Compile>
84-
<Compile Include="TrailingWhitespace\RemoveWhiteSpace.cs" />
85-
<Compile Include="TrailingWhitespace\RemoveWhitespaceCommand.cs" />
86-
<Compile Include="TrailingWhitespace\RemoveWhitespaceOnSave.cs" />
87-
<Compile Include="TrailingWhitespace\RemoveWhiteSpaceProvider.cs" />
78+
<Compile Include="TextTools\ClassificationTypes.cs" />
79+
<Compile Include="TextTools\Classifier.cs" />
80+
<Compile Include="TextTools\ClassifierProvider.cs" />
81+
<Compile Include="TextTools\FileHelpers.cs" />
82+
<Compile Include="TextTools\TextTools.cs" />
83+
<Compile Include="TextTools\RemoveWhiteSpace.cs" />
84+
<Compile Include="TextTools\RemoveWhitespaceCommand.cs" />
85+
<Compile Include="TextTools\RemoveWhitespaceOnSave.cs" />
86+
<Compile Include="TextTools\RemoveWhiteSpaceProvider.cs" />
8887
</ItemGroup>
8988
<ItemGroup>
9089
<None Include="Key.snk" />
@@ -94,8 +93,7 @@
9493
</None>
9594
</ItemGroup>
9695
<ItemGroup>
97-
<Content Include="index.html" />
98-
<Content Include="Resources\PostSaveProcess1.ico" />
96+
<Content Include="Resources\TextTools.ico" />
9997
<Content Include="stylesheet.css" />
10098
</ItemGroup>
10199
<ItemGroup>
@@ -315,13 +313,6 @@
315313
<Reference Include="UIAutomationProvider" />
316314
<Reference Include="WindowsBase" />
317315
</ItemGroup>
318-
<ItemGroup>
319-
<EmbeddedResource Include="Resource1.resx">
320-
<Generator>ResXFileCodeGenerator</Generator>
321-
<LastGenOutput>Resource1.Designer.cs</LastGenOutput>
322-
<MergeWithCTO>true</MergeWithCTO>
323-
</EmbeddedResource>
324-
</ItemGroup>
325316
<ItemGroup>
326317
<BootstrapperPackage Include=".NETFramework,Version=v4.5.2">
327318
<Visible>False</Visible>
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
using System.ComponentModel.Composition;
2+
using System.Windows.Media;
3+
using Microsoft.VisualStudio.Text.Classification;
4+
using Microsoft.VisualStudio.Utilities;
5+
6+
namespace TextTools
7+
{
8+
static class TrailingClassificationTypes
9+
{
10+
public const string Whitespace = "TextTools";
11+
12+
[Export, Name(TrailingClassificationTypes.Whitespace)]
13+
public static ClassificationTypeDefinition TextTools { get; set; }
14+
}
15+
16+
[Export(typeof(EditorFormatDefinition))]
17+
[ClassificationType(ClassificationTypeNames = TrailingClassificationTypes.Whitespace)]
18+
[Name(TrailingClassificationTypes.Whitespace)]
19+
[Order(After = Priority.Default)]
20+
[UserVisible(true)]
21+
sealed class TextToolsFormatDefinition : ClassificationFormatDefinition
22+
{
23+
public TextToolsFormatDefinition()
24+
{
25+
BackgroundColor = Color.FromRgb(255, 145, 145);
26+
DisplayName = "Trailing Whitespace";
27+
}
28+
}
29+
}

TextTools/TextTools/Classifier.cs

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Threading.Tasks;
4+
using System.Windows.Threading;
5+
using Microsoft.VisualStudio.Text;
6+
using Microsoft.VisualStudio.Text.Classification;
7+
using Microsoft.VisualStudio.Text.Editor;
8+
using Microsoft.VisualStudio.Text.Projection;
9+
10+
namespace TextTools
11+
{
12+
internal class TrailingClassifier : IClassifier
13+
{
14+
private readonly IClassificationType _whitespace;
15+
private IWpfTextView _view;
16+
private readonly ITextBuffer _buffer;
17+
private ITrackingSpan _span;
18+
private SnapshotPoint _caret, _lastCaret;
19+
private static readonly IList<ClassificationSpan> _empty = new List<ClassificationSpan>();
20+
21+
public TrailingClassifier(IClassificationTypeRegistryService registry, ITextBuffer buffer)
22+
{
23+
_whitespace = registry.GetClassificationType(TrailingClassificationTypes.Whitespace);
24+
_buffer = buffer;
25+
_buffer.Changed += OnSomethingChanged;
26+
}
27+
28+
public IList<ClassificationSpan> GetClassificationSpans(SnapshotSpan span)
29+
{
30+
if (span.IsEmpty || _view == null)
31+
return _empty;
32+
33+
IList<ClassificationSpan> list = new List<ClassificationSpan>();
34+
ITextSnapshotLine line = span.Snapshot.GetLineFromPosition(span.Start.Position);
35+
36+
if (_caret > 0 && (line.Extent.Contains(_caret.Position) || line.Extent.End.Position == _caret.Position))
37+
{
38+
_span = span.Snapshot.CreateTrackingSpan(line.Extent, SpanTrackingMode.EdgeExclusive);
39+
return _empty;
40+
}
41+
42+
if (span.Snapshot.TextBuffer is IProjectionBuffer projection)
43+
{
44+
SnapshotPoint point = projection.CurrentSnapshot.MapToSourceSnapshot(line.Start + line.Length);
45+
ITextSnapshotLine basePoint = point.Snapshot.GetLineFromPosition(point.Position);
46+
47+
if (basePoint.Length > line.Length)
48+
return _empty;
49+
}
50+
51+
string text = line.GetText();
52+
string trimmed = text.TrimEnd();
53+
int diff = text.Length - trimmed.Length;
54+
55+
if (diff > 0)
56+
{
57+
var ss = new SnapshotSpan(span.Snapshot, line.Start + line.Length - diff, diff);
58+
list.Add(new ClassificationSpan(ss, _whitespace));
59+
}
60+
61+
return list;
62+
}
63+
64+
65+
public async Task SetTextViewAsync(IWpfTextView view)
66+
{
67+
if (_view != null)
68+
return;
69+
70+
// Delay to allow Add Any File extension to place the caret
71+
await Task.Delay(100);
72+
if (_view == null)
73+
{
74+
_view = view;
75+
_view.Caret.PositionChanged += OnSomethingChanged;
76+
_view.Closed += OnViewClosed;
77+
UpdateCaret();
78+
}
79+
}
80+
81+
private void OnViewClosed(object sender, EventArgs e)
82+
{
83+
var view = (ITextView)sender;
84+
view.Closed -= OnViewClosed;
85+
view.Caret.PositionChanged -= OnSomethingChanged;
86+
87+
if (_buffer != null)
88+
_buffer.Changed -= OnSomethingChanged;
89+
}
90+
91+
private void OnSomethingChanged(object sender, EventArgs e)
92+
{
93+
Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() =>
94+
{
95+
UpdateCaret();
96+
97+
if (_span != null)
98+
OnClassificationChanged(_span);
99+
100+
}), DispatcherPriority.ApplicationIdle, null);
101+
}
102+
103+
private void UpdateCaret()
104+
{
105+
if (_view == null)
106+
return;
107+
108+
_lastCaret = _caret;
109+
SnapshotPoint position = _view.Caret.Position.BufferPosition;
110+
111+
if (position == 0)
112+
return;
113+
114+
if (_view.TextBuffer is IProjectionBuffer projection && position <= _view.TextBuffer.CurrentSnapshot.Length)
115+
{
116+
_caret = projection.CurrentSnapshot.MapToSourceSnapshot(position.Position);
117+
return;
118+
}
119+
120+
_caret = position;
121+
return;
122+
}
123+
124+
private void OnClassificationChanged(ITrackingSpan span)
125+
{
126+
if ((_caret == 0 || _caret != _lastCaret) && ClassificationChanged != null)
127+
{
128+
ClassificationChanged(this, new ClassificationChangedEventArgs(span.GetSpan(span.TextBuffer.CurrentSnapshot)));
129+
_span = null;
130+
}
131+
}
132+
133+
public event EventHandler<ClassificationChangedEventArgs> ClassificationChanged;
134+
}
135+
}

0 commit comments

Comments
 (0)