-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 31f9c99
Showing
12 changed files
with
467 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
*/bin/ | ||
*/obj/ | ||
*.csproj.user | ||
*.suo |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
|
||
Microsoft Visual Studio Solution File, Format Version 11.00 | ||
# Visual Studio 2010 | ||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GherkinEditor", "GherkinEditor\GherkinEditor.csproj", "{143F9E01-3B98-4F8B-B170-1A14B2742111}" | ||
EndProject | ||
Global | ||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
Debug|Any CPU = Debug|Any CPU | ||
Release|Any CPU = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
{143F9E01-3B98-4F8B-B170-1A14B2742111}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{143F9E01-3B98-4F8B-B170-1A14B2742111}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{143F9E01-3B98-4F8B-B170-1A14B2742111}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{143F9E01-3B98-4F8B-B170-1A14B2742111}.Release|Any CPU.Build.0 = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(SolutionProperties) = preSolution | ||
HideSolutionNode = FALSE | ||
EndGlobalSection | ||
EndGlobal |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.ComponentModel.Composition; | ||
using Microsoft.VisualStudio.Utilities; | ||
using Microsoft.VisualStudio.Text.Classification; | ||
using System.Windows.Media; | ||
|
||
namespace GherkinEditor | ||
{ | ||
internal static class GherkinClassificationDefinitions | ||
{ | ||
[Export] | ||
[Name("feature")] | ||
internal static ClassificationTypeDefinition featureClassificationDefinition = null; | ||
|
||
[Export] | ||
[Name("feature.scenario")] | ||
[BaseDefinition("feature")] | ||
internal static ClassificationTypeDefinition scenarioDefinition = null; | ||
|
||
[Export(typeof(EditorFormatDefinition))] | ||
[ClassificationType(ClassificationTypeNames = "feature.scenario")] | ||
[Name("feature.scenario")] | ||
internal sealed class ScenarioFormat : ClassificationFormatDefinition | ||
{ | ||
public ScenarioFormat() | ||
{ | ||
ForegroundColor = Colors.Blue; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using Microsoft.VisualStudio.Text.Classification; | ||
using Microsoft.VisualStudio.Text; | ||
|
||
namespace GherkinEditor | ||
{ | ||
public class GherkinClassifier : IClassifier | ||
{ | ||
private IClassificationTypeRegistryService _classificationTypeRegistry; | ||
|
||
internal GherkinClassifier(IClassificationTypeRegistryService registry) | ||
{ | ||
_classificationTypeRegistry = registry; | ||
} | ||
|
||
#pragma warning disable 67 | ||
public event EventHandler<ClassificationChangedEventArgs> ClassificationChanged; | ||
#pragma warning restore 67 | ||
|
||
public IList<ClassificationSpan> GetClassificationSpans(SnapshotSpan span) | ||
{ | ||
var snapshot = span.Snapshot; | ||
var spans = new List<ClassificationSpan>(); | ||
|
||
if (snapshot.Length == 0) | ||
{ | ||
return spans; | ||
} | ||
foreach (var line in snapshot.Lines) | ||
{ | ||
var index = -1; | ||
var text = line.GetText(); | ||
if ((index = text.IndexOf("Scenario:")) != -1) | ||
{ | ||
var type = _classificationTypeRegistry.GetClassificationType("feature.scenario"); | ||
spans.Add(new ClassificationSpan(new SnapshotSpan(snapshot, line.Start.Position + index, 8), type)); | ||
} | ||
} | ||
return spans; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.ComponentModel.Composition; | ||
using Microsoft.VisualStudio.Text.Classification; | ||
using Microsoft.VisualStudio.Utilities; | ||
using Microsoft.VisualStudio.Text; | ||
|
||
namespace GherkinEditor | ||
{ | ||
[Export(typeof(IClassifierProvider))] | ||
[ContentType("feature")] | ||
internal class GherkinClassifierProvider : IClassifierProvider | ||
{ | ||
[Import] | ||
internal IClassificationTypeRegistryService ClassificationRegistry = null; | ||
|
||
private static GherkinClassifier gherkinClassifier; | ||
|
||
public IClassifier GetClassifier(ITextBuffer textBuffer) | ||
{ | ||
if (gherkinClassifier == null) | ||
{ | ||
gherkinClassifier = new GherkinClassifier(ClassificationRegistry); | ||
} | ||
return gherkinClassifier; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.ComponentModel.Composition; | ||
using Microsoft.VisualStudio.Utilities; | ||
|
||
namespace GherkinEditor | ||
{ | ||
internal static class GherkinContentDefinition | ||
{ | ||
[Export] | ||
[Name("feature")] | ||
[BaseDefinition("text")] | ||
internal static ContentTypeDefinition featureContentTypeDefinition = null; | ||
|
||
[Export] | ||
[FileExtension(".feature")] | ||
[ContentType("feature")] | ||
internal static FileExtensionToContentTypeDefinition featureFileExtensionDefinition = null; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | ||
<PropertyGroup> | ||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> | ||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> | ||
<SchemaVersion>2.0</SchemaVersion> | ||
<ProjectTypeGuids>{82b43b9b-a64c-4715-b499-d71e9ca2bd60};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> | ||
<ProjectGuid>{143F9E01-3B98-4F8B-B170-1A14B2742111}</ProjectGuid> | ||
<OutputType>Library</OutputType> | ||
<AppDesignerFolder>Properties</AppDesignerFolder> | ||
<RootNamespace>GherkinEditor</RootNamespace> | ||
<AssemblyName>GherkinEditor</AssemblyName> | ||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion> | ||
<GeneratePkgDefFile>false</GeneratePkgDefFile> | ||
<!-- | ||
<IncludeAssemblyInVSIXContainer>false</IncludeAssemblyInVSIXContainer> | ||
<IncludeDebugSymbolsInVSIXContainer>false</IncludeDebugSymbolsInVSIXContainer> | ||
<IncludeDebugSymbolsInLocalVSIXDeployment>false</IncludeDebugSymbolsInLocalVSIXDeployment> | ||
<CopyBuildOutputToOutputDirectory>false</CopyBuildOutputToOutputDirectory> | ||
<CopyOutputSymbolsToOutputDirectory>false</CopyOutputSymbolsToOutputDirectory> | ||
--> | ||
</PropertyGroup> | ||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> | ||
<DebugSymbols>true</DebugSymbols> | ||
<DebugType>full</DebugType> | ||
<Optimize>false</Optimize> | ||
<OutputPath>bin\Debug\</OutputPath> | ||
<DefineConstants>DEBUG;TRACE</DefineConstants> | ||
<ErrorReport>prompt</ErrorReport> | ||
<WarningLevel>4</WarningLevel> | ||
</PropertyGroup> | ||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> | ||
<DebugType>pdbonly</DebugType> | ||
<Optimize>true</Optimize> | ||
<OutputPath>bin\Release\</OutputPath> | ||
<DefineConstants>TRACE</DefineConstants> | ||
<ErrorReport>prompt</ErrorReport> | ||
<WarningLevel>4</WarningLevel> | ||
</PropertyGroup> | ||
<ItemGroup> | ||
<Compile Include="GherkinClassificationDefinitions.cs" /> | ||
<Compile Include="GherkinClassifier.cs" /> | ||
<Compile Include="GherkinClassifierProvider.cs" /> | ||
<Compile Include="GherkinContentDefinition.cs" /> | ||
<Compile Include="GherkinOutlineTagger.cs" /> | ||
<Compile Include="GherkinOutlineTaggerProvider.cs" /> | ||
<Compile Include="Properties\AssemblyInfo.cs" /> | ||
<Compile Include="Region.cs" /> | ||
</ItemGroup> | ||
<ItemGroup> | ||
<None Include="source.extension.vsixmanifest"> | ||
<SubType>Designer</SubType> | ||
</None> | ||
</ItemGroup> | ||
<ItemGroup> | ||
<Reference Include="Microsoft.VisualStudio.CoreUtility, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" /> | ||
<Reference Include="Microsoft.VisualStudio.Text.Data, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" /> | ||
<Reference Include="Microsoft.VisualStudio.Text.Logic, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" /> | ||
<Reference Include="Microsoft.VisualStudio.Text.UI, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" /> | ||
<Reference Include="Microsoft.VisualStudio.Text.UI.Wpf, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" /> | ||
<Reference Include="PresentationCore" /> | ||
<Reference Include="System" /> | ||
<Reference Include="System.ComponentModel.Composition" /> | ||
</ItemGroup> | ||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> | ||
<Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\VSSDK\Microsoft.VsSDK.targets" /> | ||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. | ||
Other similar extension points exist, see Microsoft.Common.targets. | ||
<Target Name="BeforeBuild"> | ||
</Target> | ||
<Target Name="AfterBuild"> | ||
</Target> | ||
--> | ||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using Microsoft.VisualStudio.Text.Tagging; | ||
using Microsoft.VisualStudio.Text; | ||
|
||
namespace GherkinEditor | ||
{ | ||
internal sealed class GherkinOutlineTagger : ITagger<IOutliningRegionTag> | ||
{ | ||
private readonly string[] _startHide = { "Scenario:", "Feature:", "Background:" }; | ||
private ITextBuffer _buffer; | ||
private ITextSnapshot _snapshot; | ||
private List<Region> _regions; | ||
|
||
public GherkinOutlineTagger(ITextBuffer buffer) | ||
{ | ||
_buffer = buffer; | ||
_snapshot = buffer.CurrentSnapshot; | ||
_regions = new List<Region>(); | ||
ReParse(); | ||
buffer.Changed += BufferChanged; | ||
} | ||
|
||
void BufferChanged(object sender, TextContentChangedEventArgs e) | ||
{ | ||
if (e.After != _buffer.CurrentSnapshot) | ||
{ | ||
return; | ||
} | ||
ReParse(); | ||
} | ||
|
||
private void ReParse() | ||
{ | ||
var newSnapshot = _buffer.CurrentSnapshot; | ||
var newRegions = new List<Region>(); | ||
|
||
Region currentRegion = null; | ||
var lastNonEmptyLine = 0; | ||
|
||
foreach (var line in newSnapshot.Lines) | ||
{ | ||
var text = line.GetText().Trim(); | ||
|
||
if (_startHide.Any(s => text.StartsWith(s))) | ||
{ | ||
if (currentRegion != null) | ||
{ | ||
currentRegion.EndLine = lastNonEmptyLine; | ||
currentRegion.Hover = newSnapshot.GetText(AsSnapshotSpan(currentRegion, newSnapshot)); | ||
newRegions.Add(currentRegion); | ||
} | ||
currentRegion = new Region | ||
{ | ||
Text = text, | ||
StartLine = line.LineNumber | ||
}; | ||
} | ||
else if (line.GetLineBreakText().Length == 0) | ||
{ | ||
if (currentRegion != null) | ||
{ | ||
var end = (text.Length > 0) ? lastNonEmptyLine + 1 : lastNonEmptyLine; | ||
currentRegion.EndLine = end; | ||
currentRegion.Hover = newSnapshot.GetText(AsSnapshotSpan(currentRegion, newSnapshot)); | ||
newRegions.Add(currentRegion); | ||
} | ||
} | ||
if (text.Length > 0) | ||
{ | ||
lastNonEmptyLine = line.LineNumber; | ||
} | ||
} | ||
|
||
var oldSpans = new List<Span>(_regions.Select(r => AsSnapshotSpan(r, _snapshot) | ||
.TranslateTo(newSnapshot, SpanTrackingMode.EdgeExclusive) | ||
.Span)); | ||
var newSpans = new List<Span>(newRegions.Select(r => AsSnapshotSpan(r, newSnapshot).Span)); | ||
var oldSpanCol = new NormalizedSpanCollection(oldSpans); | ||
var newSpanCol = new NormalizedSpanCollection(newSpans); | ||
var removed = NormalizedSpanCollection.Difference(oldSpanCol, newSpanCol); | ||
var added = NormalizedSpanCollection.Difference(newSpanCol, oldSpanCol); | ||
|
||
var changeStart = int.MaxValue; | ||
var changeEnd = -1; | ||
|
||
if (removed.Count > 0) | ||
{ | ||
changeStart = removed[0].Start; | ||
changeEnd = removed[removed.Count - 1].End; | ||
} | ||
|
||
if (added.Count > 0) | ||
{ | ||
changeStart = Math.Min(changeStart, added[0].Start); | ||
changeEnd = Math.Max(changeEnd, added[added.Count - 1].End); | ||
} | ||
|
||
_snapshot = newSnapshot; | ||
_regions = newRegions; | ||
|
||
if (changeStart <= changeEnd) | ||
{ | ||
if (TagsChanged != null) | ||
{ | ||
TagsChanged(this, new SnapshotSpanEventArgs(new SnapshotSpan(_snapshot, Span.FromBounds(changeStart, changeEnd)))); | ||
} | ||
} | ||
} | ||
|
||
private static SnapshotSpan AsSnapshotSpan(Region region, ITextSnapshot snapshot) | ||
{ | ||
var startLine = snapshot.GetLineFromLineNumber(region.StartLine); | ||
var endLine = snapshot.GetLineFromLineNumber(region.EndLine); | ||
return new SnapshotSpan(startLine.Start, endLine.End); | ||
} | ||
|
||
public IEnumerable<ITagSpan<IOutliningRegionTag>> GetTags(NormalizedSnapshotSpanCollection spans) | ||
{ | ||
if (spans.Count == 0) | ||
{ | ||
yield break; | ||
} | ||
var currentRegions = _regions; | ||
var currentSnapshot = _snapshot; | ||
var entire = new SnapshotSpan(spans[0].Start, spans[spans.Count - 1].End) | ||
.TranslateTo(currentSnapshot, SpanTrackingMode.EdgeExclusive); | ||
var startLineNo = entire.Start.GetContainingLine().LineNumber; | ||
var endLineNo = entire.End.GetContainingLine().LineNumber; | ||
foreach (var region in currentRegions) | ||
{ | ||
if (region.StartLine <= endLineNo && region.EndLine >= startLineNo) | ||
{ | ||
var startLine = currentSnapshot.GetLineFromLineNumber(region.StartLine); | ||
var endLine = currentSnapshot.GetLineFromLineNumber(region.EndLine); | ||
yield return new TagSpan<IOutliningRegionTag>( | ||
new SnapshotSpan(startLine.Start, endLine.End), | ||
new OutliningRegionTag(false, false, region.Text, region.Hover)); | ||
} | ||
} | ||
} | ||
|
||
public event EventHandler<SnapshotSpanEventArgs> TagsChanged; | ||
} | ||
} |
Oops, something went wrong.