Skip to content

Commit

Permalink
Removed bulk of ISharedService
Browse files Browse the repository at this point in the history
Got the core window / tab management code moved into the `VsVimHost`
layer directly instead of through `ISharedService`

This took _much_ longer than it should have because I ended up
struggling with referencing the non-SDK DLLs. The
`Microsoft.VisualStudio.SDK` package by default will end up forcing many
of the PIA assemblies to be
`<EmbeddedInteropTypes>true</EmbeddedInteropTypes>`.

That works fine within the supported SDK but breaks down once you get to
DLLs like `Microsoft.VisualStudio.Platform.WindowManagement`. That,
appears at least, to uses a standard reference not an embedded one.
Hence it causes a conflict at compile time.

Took me a while to figure out how to suppress the interop type embedding
so that I could add the reference.
  • Loading branch information
jaredpar committed Jul 4, 2021
1 parent 4aa0c0a commit b88d199
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 80 deletions.
Binary file not shown.
8 changes: 8 additions & 0 deletions References/Vs2019/Vs2019.Build.targets
Expand Up @@ -9,9 +9,17 @@

<ItemGroup>
<PackageReference Include="Microsoft.VisualStudio.Sdk" Version="16.0.206" />
<PackageReference Include="Microsoft.VisualStudio.Sdk.EmbedInteropTypes" Version="15.0.36" ExcludeAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Scripting" Version="3.0.0" />
<PackageReference Include="Microsoft.VisualStudio.TextManager.Interop.10.0" Version="16.7.30328.74" />
<PackageReference Include="Microsoft.VSSDK.BuildTools" Version="16.10.1055" Condition="'$(VsVimProjectType)' == 'Vsix'" />

<!--
These are private assemblies and not typically considered as a part of the official VS SDK. But
they are needed for some of the window / tab management code hence are used here -->
<Reference Include="Microsoft.VisualStudio.Platform.WindowManagement, Version=16.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
<Reference Include="Microsoft.VisualStudio.Shell.ViewManager, Version=16.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
<Reference Include="Microsoft.VisualStudio.Diagnostics.Assert, Version=16.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
</ItemGroup>

<ItemGroup Condition="'$(VsVimProjectType)' == 'EditorHost'">
Expand Down
44 changes: 0 additions & 44 deletions Src/VsSpecific/VsSpecific/SharedService.cs
Expand Up @@ -34,50 +34,6 @@ internal void GoToTab(int index)
GetActiveViews()[index].ShowInFront();
}

internal WindowFrameState GetWindowFrameState()
{
var activeView = ViewManager.Instance.ActiveView;
if (activeView == null)
{
return WindowFrameState.Default;
}

var list = GetActiveViews();
var index = list.IndexOf(activeView);
if (index < 0)
{
return WindowFrameState.Default;
}

return new WindowFrameState(index, list.Count);
}

/// <summary>
/// Get the list of View's in the current ViewManager DocumentGroup
/// </summary>
private static List<View> GetActiveViews()
{
var activeView = ViewManager.Instance.ActiveView;
if (activeView == null)
{
return new List<View>();
}

var group = activeView.Parent as DocumentGroup;
if (group == null)
{
return new List<View>();
}

return group.VisibleChildren.OfType<View>().ToList();
}

internal bool IsActiveWindowFrame(IVsWindowFrame vsWindowFrame)
{
var frame = vsWindowFrame as WindowFrame;
return frame != null && frame.FrameView == ViewManager.Instance.ActiveView;
}

#region ISharedService

WindowFrameState ISharedService.GetWindowFrameState()
Expand Down
18 changes: 0 additions & 18 deletions Src/VsVimShared/ISharedService.cs
Expand Up @@ -32,24 +32,6 @@ public WindowFrameState(int activeWindowFrameIndex, int windowFrameCount)
/// </summary>
public interface ISharedService
{
/// <summary>
/// Is this the active IVsWindow frame which has focus? This method is used during macro
/// running and hence must account for view changes which occur during a macro run. Say by the
/// macro containing the 'gt' command. Unfortunately these don't fully process through Visual
/// Studio until the next UI thread pump so we instead have to go straight to the view controller
/// </summary>
bool IsActiveWindowFrame(IVsWindowFrame vsWindowFrame);

/// <summary>
/// Get the state of the active tab group in Visual Studio
/// </summary>
WindowFrameState GetWindowFrameState();

/// <summary>
/// Go to the tab with the specified index
/// </summary>
void GoToTab(int index);

/// <summary>
/// Run C# Script.
/// </summary>
Expand Down
Expand Up @@ -12,20 +12,6 @@ internal sealed class DefaultSharedServiceFactory : ISharedServiceVersionFactory
{
private sealed class DefaultSharedService : ISharedService
{
WindowFrameState ISharedService.GetWindowFrameState()
{
return WindowFrameState.Default;
}

void ISharedService.GoToTab(int index)
{
}

bool ISharedService.IsActiveWindowFrame(IVsWindowFrame vsWindowFrame)
{
return false;
}

void ISharedService.RunCSharpScript(IVimBuffer vimBuffer, CallInfo callInfo, bool createEachTime)
{
vimBuffer.VimBufferData.StatusUtil.OnError("csx not supported");
Expand Down
88 changes: 84 additions & 4 deletions Src/VsVimShared/VsVimHost.cs
Expand Up @@ -25,6 +25,14 @@
using System.Diagnostics;
using Vim.Interpreter;

#if VS_SPECIFIC_2019
using Microsoft.VisualStudio.Platform.WindowManagement;
using Microsoft.VisualStudio.PlatformUI.Shell;
#elif VS_SPECIFIC_2015 || VS_SPECIFIC_2017
#else
#error Unsupported configuration
#endif

namespace Vim.VisualStudio
{
/// <summary>
Expand Down Expand Up @@ -295,7 +303,7 @@ public override bool IsUndoRedoExpected

public override int TabCount
{
get { return _sharedService.GetWindowFrameState().WindowFrameCount; }
get { return GetWindowFrameState().WindowFrameCount; }
}

public override bool UseDefaultCaret
Expand Down Expand Up @@ -732,14 +740,86 @@ public override int GetTabIndex(ITextView textView)
{
// TODO: Should look for the actual index instead of assuming this is called on the
// active ITextView. They may not actually be equal
var windowFrameState = _sharedService.GetWindowFrameState();
var windowFrameState = GetWindowFrameState();
return windowFrameState.ActiveWindowFrameIndex;
}

#if VS_SPECIFIC_2019

/// <summary>
/// Get the state of the active tab group in Visual Studio
/// </summary>
public override void GoToTab(int index)
{
GetActiveViews()[index].ShowInFront();
// TODO_SHARED: consider changing underlying code to be gt and gT specific so the primary
// case can use VS commands like Window.NextTab instead of relying on the non-SDK shell code
}

internal WindowFrameState GetWindowFrameState()
{
var activeView = ViewManager.Instance.ActiveView;
if (activeView == null)
{
return WindowFrameState.Default;
}

var list = GetActiveViews();
var index = list.IndexOf(activeView);
if (index < 0)
{
return WindowFrameState.Default;
}

return new WindowFrameState(index, list.Count);
}

/// <summary>
/// Get the list of View's in the current ViewManager DocumentGroup
/// </summary>
private static List<View> GetActiveViews()
{
var activeView = ViewManager.Instance.ActiveView;
if (activeView == null)
{
return new List<View>();
}

var group = activeView.Parent as DocumentGroup;
if (group == null)
{
return new List<View>();
}

return group.VisibleChildren.OfType<View>().ToList();
}

/// <summary>
/// Is this the active IVsWindow frame which has focus? This method is used during macro
/// running and hence must account for view changes which occur during a macro run. Say by the
/// macro containing the 'gt' command. Unfortunately these don't fully process through Visual
/// Studio until the next UI thread pump so we instead have to go straight to the view controller
/// </summary>
internal bool IsActiveWindowFrame(IVsWindowFrame vsWindowFrame)
{
var frame = vsWindowFrame as WindowFrame;
return frame != null && frame.FrameView == ViewManager.Instance.ActiveView;
}

#elif VS_SPECIFIC_2015 || VS_SPECIFIC_2017
internal WindowFrameState GetWindowFrameState() => WindowFrameState.Default;

// TODO_SHARED: consider calling into IWpfTextView and checking if it's focused or
// maybe through IVsTextManager.GetActiveView
internal bool IsActiveWindowFrame(IVsWindowFrame vsWindowFrame) => false;

public override void GoToTab(int index)
{
_sharedService.GoToTab(index);
// TODO_SHARED: possibly this should error?
}
#else
#error Unsupported configuration
#endif

/// <summary>
/// Open the window for the specified list
Expand Down Expand Up @@ -987,7 +1067,7 @@ public override bool TryGetFocusedTextView(out ITextView textView)
return false;
}

var activeWindowFrame = result.Value.FirstOrDefault(_sharedService.IsActiveWindowFrame);
var activeWindowFrame = result.Value.FirstOrDefault(IsActiveWindowFrame);
if (activeWindowFrame == null)
{
textView = null;
Expand Down

0 comments on commit b88d199

Please sign in to comment.