Add EditorSettings management to workspaces.
- Built a design where there's a singleton `EditorSettingsManager` that handles the "current" settings state in the world. When it detects that settings have changed via an update method being called it dispatches a `Changed` event. - Exposed editor settings on the document tracker. When the editor settings change the document tracker dispatches to any listeners that its context has changed. - Added tests to validate all the various settings management. #1718
This commit is contained in:
parent
212d97e511
commit
fb8aff12f1
|
|
@ -0,0 +1,54 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Microsoft.CodeAnalysis.Razor.Editor
|
||||||
|
{
|
||||||
|
internal class DefaultEditorSettingsManager : EditorSettingsManager
|
||||||
|
{
|
||||||
|
public override event EventHandler<EditorSettingsChangedEventArgs> Changed;
|
||||||
|
|
||||||
|
private readonly object SettingsAccessorLock = new object();
|
||||||
|
private EditorSettings _settings;
|
||||||
|
|
||||||
|
public DefaultEditorSettingsManager()
|
||||||
|
{
|
||||||
|
_settings = EditorSettings.Default;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override EditorSettings Current
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
lock (SettingsAccessorLock)
|
||||||
|
{
|
||||||
|
return _settings;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Update(EditorSettings updatedSettings)
|
||||||
|
{
|
||||||
|
if (updatedSettings == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(updatedSettings));
|
||||||
|
}
|
||||||
|
|
||||||
|
lock (SettingsAccessorLock)
|
||||||
|
{
|
||||||
|
if (!_settings.Equals(updatedSettings))
|
||||||
|
{
|
||||||
|
_settings = updatedSettings;
|
||||||
|
OnChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnChanged()
|
||||||
|
{
|
||||||
|
var args = new EditorSettingsChangedEventArgs(Current);
|
||||||
|
Changed?.Invoke(this, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Composition;
|
||||||
|
using Microsoft.CodeAnalysis.Host;
|
||||||
|
using Microsoft.CodeAnalysis.Host.Mef;
|
||||||
|
|
||||||
|
namespace Microsoft.CodeAnalysis.Razor.Editor
|
||||||
|
{
|
||||||
|
[Shared]
|
||||||
|
[ExportLanguageServiceFactory(typeof(EditorSettingsManager), RazorLanguage.Name)]
|
||||||
|
internal class DefaultEditorSettingsManagerFactory : ILanguageServiceFactory
|
||||||
|
{
|
||||||
|
public ILanguageService CreateLanguageService(HostLanguageServices languageServices)
|
||||||
|
{
|
||||||
|
if (languageServices == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(languageServices));
|
||||||
|
}
|
||||||
|
|
||||||
|
return new DefaultEditorSettingsManager();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
// Copyright(c) .NET Foundation.All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using Microsoft.Extensions.Internal;
|
||||||
|
|
||||||
|
namespace Microsoft.CodeAnalysis.Razor.Editor
|
||||||
|
{
|
||||||
|
public sealed class EditorSettings : IEquatable<EditorSettings>
|
||||||
|
{
|
||||||
|
public static readonly EditorSettings Default = new EditorSettings(indentWithTabs: false, indentSize: 4);
|
||||||
|
|
||||||
|
public EditorSettings(bool indentWithTabs, int indentSize)
|
||||||
|
{
|
||||||
|
if (indentSize < 0)
|
||||||
|
{
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(indentSize));
|
||||||
|
}
|
||||||
|
|
||||||
|
IndentWithTabs = indentWithTabs;
|
||||||
|
IndentSize = indentSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IndentWithTabs { get; }
|
||||||
|
|
||||||
|
public int IndentSize { get; }
|
||||||
|
|
||||||
|
public bool Equals(EditorSettings other)
|
||||||
|
{
|
||||||
|
if (other == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return IndentWithTabs == other.IndentWithTabs &&
|
||||||
|
IndentSize == other.IndentSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Equals(object other)
|
||||||
|
{
|
||||||
|
return Equals(other as EditorSettings);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
var combiner = HashCodeCombiner.Start();
|
||||||
|
combiner.Add(IndentWithTabs);
|
||||||
|
combiner.Add(IndentSize);
|
||||||
|
|
||||||
|
return combiner.CombinedHash;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Microsoft.CodeAnalysis.Razor.Editor
|
||||||
|
{
|
||||||
|
public sealed class EditorSettingsChangedEventArgs : EventArgs
|
||||||
|
{
|
||||||
|
public EditorSettingsChangedEventArgs(EditorSettings settings)
|
||||||
|
{
|
||||||
|
Settings = settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EditorSettings Settings { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using Microsoft.CodeAnalysis.Host;
|
||||||
|
|
||||||
|
namespace Microsoft.CodeAnalysis.Razor.Editor
|
||||||
|
{
|
||||||
|
public abstract class EditorSettingsManager : ILanguageService
|
||||||
|
{
|
||||||
|
public abstract event EventHandler<EditorSettingsChangedEventArgs> Changed;
|
||||||
|
|
||||||
|
public abstract EditorSettings Current { get; }
|
||||||
|
|
||||||
|
public abstract void Update(EditorSettings updateSettings);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -10,6 +10,8 @@ using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Razor.Language;
|
using Microsoft.AspNetCore.Razor.Language;
|
||||||
using Microsoft.AspNetCore.Razor.Language.Legacy;
|
using Microsoft.AspNetCore.Razor.Language.Legacy;
|
||||||
using Microsoft.CodeAnalysis.Razor;
|
using Microsoft.CodeAnalysis.Razor;
|
||||||
|
using Microsoft.CodeAnalysis.Razor.Editor;
|
||||||
|
using Microsoft.CodeAnalysis.Razor.ProjectSystem;
|
||||||
using Microsoft.VisualStudio.Language.Intellisense;
|
using Microsoft.VisualStudio.Language.Intellisense;
|
||||||
using Microsoft.VisualStudio.Text;
|
using Microsoft.VisualStudio.Text;
|
||||||
using ITextBuffer = Microsoft.VisualStudio.Text.ITextBuffer;
|
using ITextBuffer = Microsoft.VisualStudio.Text.ITextBuffer;
|
||||||
|
|
@ -376,21 +378,25 @@ namespace Microsoft.VisualStudio.Editor.Razor
|
||||||
|
|
||||||
private void ConfigureTemplateEngine(IRazorEngineBuilder builder)
|
private void ConfigureTemplateEngine(IRazorEngineBuilder builder)
|
||||||
{
|
{
|
||||||
builder.Features.Add(new VisualStudioParserOptionsFeature());
|
builder.Features.Add(new VisualStudioParserOptionsFeature(_documentTracker.EditorSettings));
|
||||||
builder.Features.Add(new VisualStudioTagHelperFeature(TextBuffer));
|
builder.Features.Add(new VisualStudioTagHelperFeature(TextBuffer));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// This class will cease to be useful once we harvest/monitor settings from the editor.
|
|
||||||
/// </summary>
|
|
||||||
private class VisualStudioParserOptionsFeature : RazorEngineFeatureBase, IConfigureRazorCodeGenerationOptionsFeature
|
private class VisualStudioParserOptionsFeature : RazorEngineFeatureBase, IConfigureRazorCodeGenerationOptionsFeature
|
||||||
{
|
{
|
||||||
|
private readonly EditorSettings _settings;
|
||||||
|
|
||||||
|
public VisualStudioParserOptionsFeature(EditorSettings settings)
|
||||||
|
{
|
||||||
|
_settings = settings;
|
||||||
|
}
|
||||||
|
|
||||||
public int Order { get; set; }
|
public int Order { get; set; }
|
||||||
|
|
||||||
public void Configure(RazorCodeGenerationOptionsBuilder options)
|
public void Configure(RazorCodeGenerationOptionsBuilder options)
|
||||||
{
|
{
|
||||||
options.IndentSize = 4;
|
options.IndentSize = _settings.IndentSize;
|
||||||
options.IndentWithTabs = false;
|
options.IndentWithTabs = _settings.IndentWithTabs;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Microsoft.CodeAnalysis;
|
using Microsoft.CodeAnalysis;
|
||||||
|
using Microsoft.CodeAnalysis.Razor.Editor;
|
||||||
using Microsoft.CodeAnalysis.Razor.ProjectSystem;
|
using Microsoft.CodeAnalysis.Razor.ProjectSystem;
|
||||||
using Microsoft.VisualStudio.Text;
|
using Microsoft.VisualStudio.Text;
|
||||||
using Microsoft.VisualStudio.Text.Editor;
|
using Microsoft.VisualStudio.Text.Editor;
|
||||||
|
|
@ -16,6 +17,8 @@ namespace Microsoft.VisualStudio.Editor.Razor
|
||||||
|
|
||||||
internal abstract ProjectExtensibilityConfiguration Configuration { get; }
|
internal abstract ProjectExtensibilityConfiguration Configuration { get; }
|
||||||
|
|
||||||
|
public abstract EditorSettings EditorSettings { get; }
|
||||||
|
|
||||||
public abstract bool IsSupportedProject { get; }
|
public abstract bool IsSupportedProject { get; }
|
||||||
|
|
||||||
public abstract string FilePath { get; }
|
public abstract string FilePath { get; }
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Microsoft.CodeAnalysis;
|
using Microsoft.CodeAnalysis;
|
||||||
using Microsoft.CodeAnalysis.Razor;
|
using Microsoft.CodeAnalysis.Razor;
|
||||||
|
using Microsoft.CodeAnalysis.Razor.Editor;
|
||||||
using Microsoft.CodeAnalysis.Razor.ProjectSystem;
|
using Microsoft.CodeAnalysis.Razor.ProjectSystem;
|
||||||
using Microsoft.VisualStudio.Editor.Razor;
|
using Microsoft.VisualStudio.Editor.Razor;
|
||||||
using Microsoft.VisualStudio.Shell.Interop;
|
using Microsoft.VisualStudio.Shell.Interop;
|
||||||
|
|
@ -17,6 +18,7 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor.Editor
|
||||||
{
|
{
|
||||||
private readonly string _filePath;
|
private readonly string _filePath;
|
||||||
private readonly ProjectSnapshotManager _projectManager;
|
private readonly ProjectSnapshotManager _projectManager;
|
||||||
|
private readonly EditorSettingsManager _editorSettingsManager;
|
||||||
private readonly TextBufferProjectService _projectService;
|
private readonly TextBufferProjectService _projectService;
|
||||||
private readonly ITextBuffer _textBuffer;
|
private readonly ITextBuffer _textBuffer;
|
||||||
private readonly List<ITextView> _textViews;
|
private readonly List<ITextView> _textViews;
|
||||||
|
|
@ -31,6 +33,7 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor.Editor
|
||||||
string filePath,
|
string filePath,
|
||||||
ProjectSnapshotManager projectManager,
|
ProjectSnapshotManager projectManager,
|
||||||
TextBufferProjectService projectService,
|
TextBufferProjectService projectService,
|
||||||
|
EditorSettingsManager editorSettingsManager,
|
||||||
Workspace workspace,
|
Workspace workspace,
|
||||||
ITextBuffer textBuffer)
|
ITextBuffer textBuffer)
|
||||||
{
|
{
|
||||||
|
|
@ -49,6 +52,11 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor.Editor
|
||||||
throw new ArgumentNullException(nameof(projectService));
|
throw new ArgumentNullException(nameof(projectService));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (editorSettingsManager == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(editorSettingsManager));
|
||||||
|
}
|
||||||
|
|
||||||
if (workspace == null)
|
if (workspace == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException(nameof(workspace));
|
throw new ArgumentNullException(nameof(workspace));
|
||||||
|
|
@ -62,6 +70,7 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor.Editor
|
||||||
_filePath = filePath;
|
_filePath = filePath;
|
||||||
_projectManager = projectManager;
|
_projectManager = projectManager;
|
||||||
_projectService = projectService;
|
_projectService = projectService;
|
||||||
|
_editorSettingsManager = editorSettingsManager;
|
||||||
_textBuffer = textBuffer;
|
_textBuffer = textBuffer;
|
||||||
_workspace = workspace; // For now we assume that the workspace is the always default VS workspace.
|
_workspace = workspace; // For now we assume that the workspace is the always default VS workspace.
|
||||||
|
|
||||||
|
|
@ -70,6 +79,8 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor.Editor
|
||||||
|
|
||||||
internal override ProjectExtensibilityConfiguration Configuration => _project.Configuration;
|
internal override ProjectExtensibilityConfiguration Configuration => _project.Configuration;
|
||||||
|
|
||||||
|
public override EditorSettings EditorSettings => _editorSettingsManager.Current;
|
||||||
|
|
||||||
public override bool IsSupportedProject => _isSupportedProject;
|
public override bool IsSupportedProject => _isSupportedProject;
|
||||||
|
|
||||||
public override Project Project => _workspace.CurrentSolution.GetProject(_project.UnderlyingProject.Id);
|
public override Project Project => _workspace.CurrentSolution.GetProject(_project.UnderlyingProject.Id);
|
||||||
|
|
@ -163,6 +174,7 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor.Editor
|
||||||
_projectPath = projectPath;
|
_projectPath = projectPath;
|
||||||
_project = _projectManager.GetProjectWithFilePath(projectPath);
|
_project = _projectManager.GetProjectWithFilePath(projectPath);
|
||||||
_projectManager.Changed += ProjectManager_Changed;
|
_projectManager.Changed += ProjectManager_Changed;
|
||||||
|
_editorSettingsManager.Changed += EditorSettingsManager_Changed;
|
||||||
|
|
||||||
OnContextChanged(_project);
|
OnContextChanged(_project);
|
||||||
}
|
}
|
||||||
|
|
@ -170,6 +182,7 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor.Editor
|
||||||
private void Unsubscribe()
|
private void Unsubscribe()
|
||||||
{
|
{
|
||||||
_projectManager.Changed -= ProjectManager_Changed;
|
_projectManager.Changed -= ProjectManager_Changed;
|
||||||
|
_editorSettingsManager.Changed -= EditorSettingsManager_Changed;
|
||||||
|
|
||||||
// Detached from project.
|
// Detached from project.
|
||||||
_isSupportedProject = false;
|
_isSupportedProject = false;
|
||||||
|
|
@ -196,5 +209,11 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor.Editor
|
||||||
OnContextChanged(e.Project);
|
OnContextChanged(e.Project);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Internal for testing
|
||||||
|
internal void EditorSettingsManager_Changed(object sender, EditorSettingsChangedEventArgs args)
|
||||||
|
{
|
||||||
|
OnContextChanged(_project);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ using System.ComponentModel.Composition;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using Microsoft.CodeAnalysis;
|
using Microsoft.CodeAnalysis;
|
||||||
using Microsoft.CodeAnalysis.Razor;
|
using Microsoft.CodeAnalysis.Razor;
|
||||||
|
using Microsoft.CodeAnalysis.Razor.Editor;
|
||||||
using Microsoft.CodeAnalysis.Razor.ProjectSystem;
|
using Microsoft.CodeAnalysis.Razor.ProjectSystem;
|
||||||
using Microsoft.VisualStudio.Editor.Razor;
|
using Microsoft.VisualStudio.Editor.Razor;
|
||||||
using Microsoft.VisualStudio.Text;
|
using Microsoft.VisualStudio.Text;
|
||||||
|
|
@ -21,6 +22,7 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor.Editor
|
||||||
private readonly Workspace _workspace;
|
private readonly Workspace _workspace;
|
||||||
private readonly ForegroundDispatcher _foregroundDispatcher;
|
private readonly ForegroundDispatcher _foregroundDispatcher;
|
||||||
private readonly ProjectSnapshotManager _projectManager;
|
private readonly ProjectSnapshotManager _projectManager;
|
||||||
|
private readonly EditorSettingsManager _editorSettingsManager;
|
||||||
|
|
||||||
[ImportingConstructor]
|
[ImportingConstructor]
|
||||||
public DefaultVisualStudioDocumentTrackerFactory(
|
public DefaultVisualStudioDocumentTrackerFactory(
|
||||||
|
|
@ -48,7 +50,9 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor.Editor
|
||||||
_workspace = workspace;
|
_workspace = workspace;
|
||||||
|
|
||||||
_foregroundDispatcher = workspace.Services.GetRequiredService<ForegroundDispatcher>();
|
_foregroundDispatcher = workspace.Services.GetRequiredService<ForegroundDispatcher>();
|
||||||
_projectManager = workspace.Services.GetLanguageServices(RazorLanguage.Name).GetRequiredService<ProjectSnapshotManager>();
|
var razorLanguageServices = workspace.Services.GetLanguageServices(RazorLanguage.Name);
|
||||||
|
_projectManager = razorLanguageServices.GetRequiredService<ProjectSnapshotManager>();
|
||||||
|
_editorSettingsManager = razorLanguageServices.GetRequiredService<EditorSettingsManager>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override VisualStudioDocumentTracker Create(ITextBuffer textBuffer)
|
public override VisualStudioDocumentTracker Create(ITextBuffer textBuffer)
|
||||||
|
|
@ -65,7 +69,7 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor.Editor
|
||||||
}
|
}
|
||||||
|
|
||||||
var filePath = textDocument.FilePath;
|
var filePath = textDocument.FilePath;
|
||||||
var tracker = new DefaultVisualStudioDocumentTracker(filePath, _projectManager, _projectService, _workspace, textBuffer);
|
var tracker = new DefaultVisualStudioDocumentTracker(filePath, _projectManager, _projectService, _editorSettingsManager, _workspace, textBuffer);
|
||||||
|
|
||||||
return tracker;
|
return tracker;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,60 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Microsoft.CodeAnalysis.Razor.Editor
|
||||||
|
{
|
||||||
|
public class DefaultEditorSettingsManagerTest
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public void InitialSettingsAreDefault()
|
||||||
|
{
|
||||||
|
// Act
|
||||||
|
var manager = new DefaultEditorSettingsManager();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(EditorSettings.Default, manager.Current);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Update_TriggersChangedIfEditorSettingsAreDifferent()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var manager = new DefaultEditorSettingsManager();
|
||||||
|
var called = false;
|
||||||
|
manager.Changed += (caller, args) =>
|
||||||
|
{
|
||||||
|
called = true;
|
||||||
|
};
|
||||||
|
var settings = new EditorSettings(indentWithTabs: true, indentSize: 7);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
manager.Update(settings);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.True(called);
|
||||||
|
Assert.Equal(settings, manager.Current);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Update_DoesNotTriggerChangedIfEditorSettingsAreSame()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var manager = new DefaultEditorSettingsManager();
|
||||||
|
var called = false;
|
||||||
|
manager.Changed += (caller, args) =>
|
||||||
|
{
|
||||||
|
called = true;
|
||||||
|
};
|
||||||
|
var originalSettings = manager.Current;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
manager.Update(EditorSettings.Default);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.False(called);
|
||||||
|
Assert.Same(originalSettings, manager.Current);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Microsoft.CodeAnalysis;
|
using Microsoft.CodeAnalysis;
|
||||||
using Microsoft.CodeAnalysis.Razor;
|
using Microsoft.CodeAnalysis.Razor;
|
||||||
|
using Microsoft.CodeAnalysis.Razor.Editor;
|
||||||
using Microsoft.CodeAnalysis.Razor.ProjectSystem;
|
using Microsoft.CodeAnalysis.Razor.ProjectSystem;
|
||||||
using Microsoft.VisualStudio.Shell.Interop;
|
using Microsoft.VisualStudio.Shell.Interop;
|
||||||
using Microsoft.VisualStudio.Text;
|
using Microsoft.VisualStudio.Text;
|
||||||
|
|
@ -29,13 +30,33 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor.Editor
|
||||||
s.IsSupportedProject(It.IsAny<IVsHierarchy>()) == true &&
|
s.IsSupportedProject(It.IsAny<IVsHierarchy>()) == true &&
|
||||||
s.GetProjectPath(It.IsAny<IVsHierarchy>()) == "C:/Some/Path/TestProject.csproj");
|
s.GetProjectPath(It.IsAny<IVsHierarchy>()) == "C:/Some/Path/TestProject.csproj");
|
||||||
|
|
||||||
|
private EditorSettingsManager EditorSettingsManager => new DefaultEditorSettingsManager();
|
||||||
|
|
||||||
private Workspace Workspace => new AdhocWorkspace();
|
private Workspace Workspace => new AdhocWorkspace();
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void EditorSettingsManager_Changed_TriggersContextChanged()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var documentTracker = new DefaultVisualStudioDocumentTracker(FilePath, ProjectManager, ProjectService, EditorSettingsManager, Workspace, TextBuffer);
|
||||||
|
var called = false;
|
||||||
|
documentTracker.ContextChanged += (sender, args) =>
|
||||||
|
{
|
||||||
|
called = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
documentTracker.EditorSettingsManager_Changed(null, null);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.True(called);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void AddTextView_AddsToTextViewCollection()
|
public void AddTextView_AddsToTextViewCollection()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var documentTracker = new DefaultVisualStudioDocumentTracker(FilePath, ProjectManager, ProjectService, Workspace, TextBuffer);
|
var documentTracker = new DefaultVisualStudioDocumentTracker(FilePath, ProjectManager, ProjectService, EditorSettingsManager, Workspace, TextBuffer);
|
||||||
var textView = Mock.Of<ITextView>();
|
var textView = Mock.Of<ITextView>();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
|
|
@ -49,7 +70,7 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor.Editor
|
||||||
public void AddTextView_SubscribesAfterFirstTextViewAdded()
|
public void AddTextView_SubscribesAfterFirstTextViewAdded()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var documentTracker = new DefaultVisualStudioDocumentTracker(FilePath, ProjectManager, ProjectService, Workspace, TextBuffer);
|
var documentTracker = new DefaultVisualStudioDocumentTracker(FilePath, ProjectManager, ProjectService, EditorSettingsManager, Workspace, TextBuffer);
|
||||||
var textView = Mock.Of<ITextView>();
|
var textView = Mock.Of<ITextView>();
|
||||||
|
|
||||||
// Assert - 1
|
// Assert - 1
|
||||||
|
|
@ -66,7 +87,7 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor.Editor
|
||||||
public void AddTextView_DoesNotAddDuplicateTextViews()
|
public void AddTextView_DoesNotAddDuplicateTextViews()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var documentTracker = new DefaultVisualStudioDocumentTracker(FilePath, ProjectManager, ProjectService, Workspace, TextBuffer);
|
var documentTracker = new DefaultVisualStudioDocumentTracker(FilePath, ProjectManager, ProjectService, EditorSettingsManager, Workspace, TextBuffer);
|
||||||
var textView = Mock.Of<ITextView>();
|
var textView = Mock.Of<ITextView>();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
|
|
@ -81,7 +102,7 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor.Editor
|
||||||
public void AddTextView_AddsMultipleTextViewsToCollection()
|
public void AddTextView_AddsMultipleTextViewsToCollection()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var documentTracker = new DefaultVisualStudioDocumentTracker(FilePath, ProjectManager, ProjectService, Workspace, TextBuffer);
|
var documentTracker = new DefaultVisualStudioDocumentTracker(FilePath, ProjectManager, ProjectService, EditorSettingsManager, Workspace, TextBuffer);
|
||||||
var textView1 = Mock.Of<ITextView>();
|
var textView1 = Mock.Of<ITextView>();
|
||||||
var textView2 = Mock.Of<ITextView>();
|
var textView2 = Mock.Of<ITextView>();
|
||||||
|
|
||||||
|
|
@ -100,7 +121,7 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor.Editor
|
||||||
public void RemoveTextView_RemovesTextViewFromCollection_SingleItem()
|
public void RemoveTextView_RemovesTextViewFromCollection_SingleItem()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var documentTracker = new DefaultVisualStudioDocumentTracker(FilePath, ProjectManager, ProjectService, Workspace, TextBuffer);
|
var documentTracker = new DefaultVisualStudioDocumentTracker(FilePath, ProjectManager, ProjectService, EditorSettingsManager, Workspace, TextBuffer);
|
||||||
var textView = Mock.Of<ITextView>();
|
var textView = Mock.Of<ITextView>();
|
||||||
documentTracker.AddTextView(textView);
|
documentTracker.AddTextView(textView);
|
||||||
|
|
||||||
|
|
@ -115,7 +136,7 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor.Editor
|
||||||
public void RemoveTextView_RemovesTextViewFromCollection_MultipleItems()
|
public void RemoveTextView_RemovesTextViewFromCollection_MultipleItems()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var documentTracker = new DefaultVisualStudioDocumentTracker(FilePath, ProjectManager, ProjectService, Workspace, TextBuffer);
|
var documentTracker = new DefaultVisualStudioDocumentTracker(FilePath, ProjectManager, ProjectService, EditorSettingsManager, Workspace, TextBuffer);
|
||||||
var textView1 = Mock.Of<ITextView>();
|
var textView1 = Mock.Of<ITextView>();
|
||||||
var textView2 = Mock.Of<ITextView>();
|
var textView2 = Mock.Of<ITextView>();
|
||||||
var textView3 = Mock.Of<ITextView>();
|
var textView3 = Mock.Of<ITextView>();
|
||||||
|
|
@ -137,7 +158,7 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor.Editor
|
||||||
public void RemoveTextView_NoopsWhenRemovingTextViewNotInCollection()
|
public void RemoveTextView_NoopsWhenRemovingTextViewNotInCollection()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var documentTracker = new DefaultVisualStudioDocumentTracker(FilePath, ProjectManager, ProjectService, Workspace, TextBuffer);
|
var documentTracker = new DefaultVisualStudioDocumentTracker(FilePath, ProjectManager, ProjectService, EditorSettingsManager, Workspace, TextBuffer);
|
||||||
var textView1 = Mock.Of<ITextView>();
|
var textView1 = Mock.Of<ITextView>();
|
||||||
documentTracker.AddTextView(textView1);
|
documentTracker.AddTextView(textView1);
|
||||||
var textView2 = Mock.Of<ITextView>();
|
var textView2 = Mock.Of<ITextView>();
|
||||||
|
|
@ -153,7 +174,7 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor.Editor
|
||||||
public void RemoveTextView_UnsubscribesAfterLastTextViewRemoved()
|
public void RemoveTextView_UnsubscribesAfterLastTextViewRemoved()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var documentTracker = new DefaultVisualStudioDocumentTracker(FilePath, ProjectManager, ProjectService, Workspace, TextBuffer);
|
var documentTracker = new DefaultVisualStudioDocumentTracker(FilePath, ProjectManager, ProjectService, EditorSettingsManager, Workspace, TextBuffer);
|
||||||
var textView1 = Mock.Of<ITextView>();
|
var textView1 = Mock.Of<ITextView>();
|
||||||
var textView2 = Mock.Of<ITextView>();
|
var textView2 = Mock.Of<ITextView>();
|
||||||
documentTracker.AddTextView(textView1);
|
documentTracker.AddTextView(textView1);
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using Microsoft.CodeAnalysis;
|
using Microsoft.CodeAnalysis;
|
||||||
using Microsoft.CodeAnalysis.Razor;
|
using Microsoft.CodeAnalysis.Razor;
|
||||||
|
using Microsoft.CodeAnalysis.Razor.Editor;
|
||||||
using Microsoft.CodeAnalysis.Razor.ProjectSystem;
|
using Microsoft.CodeAnalysis.Razor.ProjectSystem;
|
||||||
using Microsoft.VisualStudio.Editor.Razor;
|
using Microsoft.VisualStudio.Editor.Razor;
|
||||||
using Microsoft.VisualStudio.Shell.Interop;
|
using Microsoft.VisualStudio.Shell.Interop;
|
||||||
|
|
@ -25,6 +26,8 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor.Editor
|
||||||
s.IsSupportedProject(It.IsAny<IVsHierarchy>()) == true &&
|
s.IsSupportedProject(It.IsAny<IVsHierarchy>()) == true &&
|
||||||
s.GetProjectPath(It.IsAny<IVsHierarchy>()) == "C:/Some/Path/TestProject.csproj");
|
s.GetProjectPath(It.IsAny<IVsHierarchy>()) == "C:/Some/Path/TestProject.csproj");
|
||||||
|
|
||||||
|
private EditorSettingsManager EditorSettingsManager => new DefaultEditorSettingsManager();
|
||||||
|
|
||||||
private Workspace Workspace { get; } = new AdhocWorkspace();
|
private Workspace Workspace { get; } = new AdhocWorkspace();
|
||||||
|
|
||||||
private IContentType RazorContentType { get; } = Mock.Of<IContentType>(c => c.IsOfType(RazorLanguage.ContentType) == true);
|
private IContentType RazorContentType { get; } = Mock.Of<IContentType>(c => c.IsOfType(RazorLanguage.ContentType) == true);
|
||||||
|
|
@ -56,12 +59,12 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor.Editor
|
||||||
{
|
{
|
||||||
Mock.Of<ITextBuffer>(b => b.ContentType == RazorContentType && b.Properties == new PropertyCollection()),
|
Mock.Of<ITextBuffer>(b => b.ContentType == RazorContentType && b.Properties == new PropertyCollection()),
|
||||||
};
|
};
|
||||||
VisualStudioDocumentTracker documentTracker = new DefaultVisualStudioDocumentTracker("AFile", ProjectManager, ProjectService, Workspace, buffers[0]);
|
VisualStudioDocumentTracker documentTracker = new DefaultVisualStudioDocumentTracker("AFile", ProjectManager, ProjectService, EditorSettingsManager, Workspace, buffers[0]);
|
||||||
var editorFactoryService = Mock.Of<RazorEditorFactoryService>(factoryService => factoryService.TryGetDocumentTracker(It.IsAny<ITextBuffer>(), out documentTracker) == true);
|
var editorFactoryService = Mock.Of<RazorEditorFactoryService>(factoryService => factoryService.TryGetDocumentTracker(It.IsAny<ITextBuffer>(), out documentTracker) == true);
|
||||||
var factory = new RazorTextViewConnectionListener(Dispatcher, editorFactoryService, Workspace);
|
var textViewListener = new RazorTextViewConnectionListener(Dispatcher, editorFactoryService, Workspace);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
factory.SubjectBuffersConnected(textView, ConnectionReason.BufferGraphChange, buffers);
|
textViewListener.SubjectBuffersConnected(textView, ConnectionReason.BufferGraphChange, buffers);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Collection(documentTracker.TextViews, v => Assert.Same(v, textView));
|
Assert.Collection(documentTracker.TextViews, v => Assert.Same(v, textView));
|
||||||
|
|
@ -81,19 +84,19 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor.Editor
|
||||||
};
|
};
|
||||||
|
|
||||||
// Preload the buffer's properties with a tracker, so it's like we've already tracked this one.
|
// Preload the buffer's properties with a tracker, so it's like we've already tracked this one.
|
||||||
var tracker = new DefaultVisualStudioDocumentTracker("C:/File/Path/To/Tracker1.cshtml", ProjectManager, ProjectService, Workspace, buffers[0]);
|
var tracker = new DefaultVisualStudioDocumentTracker("C:/File/Path/To/Tracker1.cshtml", ProjectManager, ProjectService, EditorSettingsManager, Workspace, buffers[0]);
|
||||||
tracker.AddTextView(textView1);
|
tracker.AddTextView(textView1);
|
||||||
tracker.AddTextView(textView2);
|
tracker.AddTextView(textView2);
|
||||||
buffers[0].Properties.AddProperty(typeof(VisualStudioDocumentTracker), tracker);
|
buffers[0].Properties.AddProperty(typeof(VisualStudioDocumentTracker), tracker);
|
||||||
|
|
||||||
tracker = new DefaultVisualStudioDocumentTracker("C:/File/Path/To/Tracker1.cshtml", ProjectManager, ProjectService, Workspace, buffers[1]);
|
tracker = new DefaultVisualStudioDocumentTracker("C:/File/Path/To/Tracker1.cshtml", ProjectManager, ProjectService, EditorSettingsManager, Workspace, buffers[1]);
|
||||||
tracker.AddTextView(textView1);
|
tracker.AddTextView(textView1);
|
||||||
tracker.AddTextView(textView2);
|
tracker.AddTextView(textView2);
|
||||||
buffers[1].Properties.AddProperty(typeof(VisualStudioDocumentTracker), tracker);
|
buffers[1].Properties.AddProperty(typeof(VisualStudioDocumentTracker), tracker);
|
||||||
var factory = new RazorTextViewConnectionListener(Dispatcher, Mock.Of<RazorEditorFactoryService>(), Workspace);
|
var textViewListener = new RazorTextViewConnectionListener(Dispatcher, Mock.Of<RazorEditorFactoryService>(), Workspace);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
factory.SubjectBuffersDisconnected(textView2, ConnectionReason.BufferGraphChange, buffers);
|
textViewListener.SubjectBuffersDisconnected(textView2, ConnectionReason.BufferGraphChange, buffers);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
tracker = buffers[0].Properties.GetProperty<DefaultVisualStudioDocumentTracker>(typeof(VisualStudioDocumentTracker));
|
tracker = buffers[0].Properties.GetProperty<DefaultVisualStudioDocumentTracker>(typeof(VisualStudioDocumentTracker));
|
||||||
|
|
@ -107,7 +110,7 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor.Editor
|
||||||
public void SubjectBuffersDisconnected_ForAnyTextBufferWithoutTracker_DoesNothing()
|
public void SubjectBuffersDisconnected_ForAnyTextBufferWithoutTracker_DoesNothing()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var factory = new RazorTextViewConnectionListener(Dispatcher, Mock.Of<RazorEditorFactoryService>(), Workspace);
|
var textViewListener = new RazorTextViewConnectionListener(Dispatcher, Mock.Of<RazorEditorFactoryService>(), Workspace);
|
||||||
|
|
||||||
var textView = Mock.Of<IWpfTextView>();
|
var textView = Mock.Of<IWpfTextView>();
|
||||||
|
|
||||||
|
|
@ -117,7 +120,7 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor.Editor
|
||||||
};
|
};
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
factory.SubjectBuffersDisconnected(textView, ConnectionReason.BufferGraphChange, buffers);
|
textViewListener.SubjectBuffersDisconnected(textView, ConnectionReason.BufferGraphChange, buffers);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.False(buffers[0].Properties.ContainsProperty(typeof(VisualStudioDocumentTracker)));
|
Assert.False(buffers[0].Properties.ContainsProperty(typeof(VisualStudioDocumentTracker)));
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue