* enable previewing on FileNode

* update DocumentManager

* fix compilation

* add "CommonPhysicalViewAttributes = (int)__VSPHYSICALVIEWATTRIBUTES.PVA_SupportsPreview)"

* Go do Definition opens documents in the preview tab

* add System.ValueTuple.dll to .gitignore

* do not show error dialog on single click on missing file

code cleanup

* show "missing file" icon in solution explorer if a file is missing

* don't use IVsRunningDocumentTable4 in DocumentManager to make tests happy

* revert DocumentManager and FileDocumentManager as it's impossible to fix the tests

* fix duplicated tabs

* use TextView logical view kind to open documents in DoDefaultAction instead of erasing one passed outside
This commit is contained in:
Vasily Kirichenko 2017-02-15 03:18:48 +03:00 коммит произвёл Kevin Ransom (msft)
Родитель 17657d28f6
Коммит a1cbffbe86
10 изменённых файлов: 85 добавлений и 74 удалений

2
.gitignore поставляемый
Просмотреть файл

@ -107,3 +107,5 @@ times
source_link.json
.vs/
/VSRelease/net40/bin
System.ValueTuple.dll
tests/fsharpqa/testenv/bin/System.ValueTuple.dll

Двоичные данные
tests/fsharpqa/testenv/bin/System.ValueTuple.dll

Двоичный файл не отображается.

Просмотреть файл

@ -97,7 +97,9 @@ type internal FSharpGoToDefinitionService
let workspace = document.Project.Solution.Workspace
let navigationService = workspace.Services.GetService<IDocumentNavigationService>()
ignore presenters
navigationService.TryNavigateToSpan(workspace, navigableItem.Document.Id, navigableItem.SourceSpan)
// prefer open documents in the preview tab
let options = workspace.Options.WithChangedOption(NavigationOptions.PreferProvisionalTab, true)
navigationService.TryNavigateToSpan(workspace, navigableItem.Document.Id, navigableItem.SourceSpan, options)
// FSROSLYNTODO: potentially display multiple results here
// If GotoDef returns one result then it should try to jump to a discovered location. If it returns multiple results then it should use

Просмотреть файл

@ -7,7 +7,7 @@ using System.Diagnostics;
using System.Globalization;
using System.Runtime.InteropServices;
using System.Security;
using System.Windows;
using System.Windows;
using Microsoft.VisualStudio.OLE.Interop;
using Microsoft.VisualStudio.Shell;
using System.Drawing;
@ -36,7 +36,7 @@ namespace Microsoft.VisualStudio.FSharp.ProjectSystem
return this.node;
}
}
public DocumentManager(HierarchyNode node)
{
this.node = node;
@ -184,7 +184,7 @@ namespace Microsoft.VisualStudio.FSharp.ProjectSystem
return (pvar as string);
}
public void CloseWindowFrame(ref IVsWindowFrame windowFrame)
{
if (windowFrame != null)
@ -336,4 +336,4 @@ namespace Microsoft.VisualStudio.FSharp.ProjectSystem
}
}
}
}
}

Просмотреть файл

@ -17,7 +17,7 @@ using IOleServiceProvider = Microsoft.VisualStudio.OLE.Interop.IServiceProvider;
namespace Microsoft.VisualStudio.FSharp.ProjectSystem
{
[Guid(Constants.FSharpEditorFactoryIdString)]
[ProvideEditorFactory(typeof(FSharpEditorFactory), 101)]
[ProvideEditorFactory(typeof(FSharpEditorFactory), 101, CommonPhysicalViewAttributes = (int)__VSPHYSICALVIEWATTRIBUTES.PVA_SupportsPreview)]
[ProvideEditorExtension(typeof(FSharpEditorFactory), ".fs", 32)]
[ProvideEditorExtension(typeof(FSharpEditorFactory), ".fsi", 32)]
[ProvideEditorExtension(typeof(FSharpEditorFactory), ".fsscript", 32)]

Просмотреть файл

@ -77,7 +77,7 @@ namespace Microsoft.VisualStudio.FSharp.ProjectSystem
{
Guid logicalView = Guid.Empty;
IVsWindowFrame windowFrame = null;
return this.Open(newFile, openWith, logicalView, logicalView, out windowFrame, windowFrameAction);
return this.Open(newFile, openWith, logicalView, out windowFrame, windowFrameAction);
}
/// <summary>
@ -89,7 +89,7 @@ namespace Microsoft.VisualStudio.FSharp.ProjectSystem
/// <param name="frame">A reference to the window frame that is mapped to the file</param>
/// <param name="windowFrameAction">Determine the UI action on the document window</param>
/// <returns>If the method succeeds, it returns S_OK. If it fails, it returns an error code.</returns>
public int Open(bool newFile, bool openWith, Guid logicalView, Guid fallbackLogicalView, out IVsWindowFrame frame, WindowFrameShowAction windowFrameAction)
public int Open(bool newFile, bool openWith, Guid logicalView, out IVsWindowFrame frame, WindowFrameShowAction windowFrameAction)
{
frame = null;
IVsRunningDocumentTable rdt = this.Node.ProjectMgr.Site.GetService(typeof(SVsRunningDocumentTable)) as IVsRunningDocumentTable;
@ -112,11 +112,7 @@ namespace Microsoft.VisualStudio.FSharp.ProjectSystem
try
{
ErrorHandler.ThrowOnFailure(rdt.FindAndLockDocument((uint)flags, path, out ivsHierarchy, out itemid, out docData, out docCookie));
var hr = this.Open(newFile, openWith, ref logicalView, docData, out frame, windowFrameAction);
if (hr != VSConstants.S_OK && fallbackLogicalView != logicalView)
{
ErrorHandler.ThrowOnFailure(this.Open(newFile, openWith, ref fallbackLogicalView, docData, out frame, windowFrameAction));
}
ErrorHandler.ThrowOnFailure(this.Open(newFile, openWith, ref logicalView, docData, out frame, windowFrameAction));
}
catch (COMException e)
{
@ -166,15 +162,12 @@ namespace Microsoft.VisualStudio.FSharp.ProjectSystem
int returnValue = VSConstants.S_OK;
string caption = this.GetOwnerCaption();
string fullPath = this.GetFullPathForDocument();
// Make sure that the file is on disk before we open the editor and display message if not found
if (!((FileNode)this.Node).IsFileOnDisk(true))
{
// Inform clients that we have an invalid item (wrong icon)
this.Node.OnInvalidateItems(this.Node.Parent);
// Bail since we are not able to open the item
// Do not return an error code otherwise an public error message is shown. The scenario for this operation
// Do not return an error code otherwise an internal error message is shown. The scenario for this operation
// normally is already a reaction to a dialog box telling that the item has been removed.
return VSConstants.S_FALSE;
}
@ -186,7 +179,7 @@ namespace Microsoft.VisualStudio.FSharp.ProjectSystem
{
this.Node.ProjectMgr.OnOpenItem(fullPath);
int result = VSConstants.E_FAIL;
if (openWith)
{
result = uiShellOpenDocument.OpenStandardEditor((uint)__VSOSEFLAGS.OSE_UseOpenWithDialog, fullPath, ref logicalView, caption, Node.ProjectMgr.InteropSafeIVsUIHierarchy, this.Node.ID, docDataExisting, serviceProvider, out windowFrame);
@ -197,8 +190,8 @@ namespace Microsoft.VisualStudio.FSharp.ProjectSystem
if (newFile)
{
openFlags |= __VSOSEFLAGS.OSE_OpenAsNewFile;
}
}
//NOTE: we MUST pass the IVsProject in pVsUIHierarchy and the itemid
// of the node being opened, otherwise the debugger doesn't work.
if (editorType != Guid.Empty)
@ -256,4 +249,4 @@ namespace Microsoft.VisualStudio.FSharp.ProjectSystem
return returnValue;
}
}
}
}

Просмотреть файл

@ -92,6 +92,7 @@ namespace Microsoft.VisualStudio.FSharp.ProjectSystem
return caption;
}
}
public override int ImageIndex
{
get
@ -466,16 +467,16 @@ namespace Microsoft.VisualStudio.FSharp.ProjectSystem
switch ((VsCommands)cmd)
{
case VsCommands.ViewCode:
return ((FileDocumentManager)this.GetDocumentManager()).Open(false, false, VSConstants.LOGVIEWID_Code, VSConstants.LOGVIEWID_Code, out windowFrame, WindowFrameShowAction.Show);
return ((FileDocumentManager)this.GetDocumentManager()).Open(false, false, VSConstants.LOGVIEWID_Code, out windowFrame, WindowFrameShowAction.Show);
case VsCommands.ViewForm:
return ((FileDocumentManager)this.GetDocumentManager()).Open(false, false, VSConstants.LOGVIEWID_Designer, VSConstants.LOGVIEWID_Designer, out windowFrame, WindowFrameShowAction.Show);
return ((FileDocumentManager)this.GetDocumentManager()).Open(false, false, VSConstants.LOGVIEWID_Designer, out windowFrame, WindowFrameShowAction.Show);
case VsCommands.Open:
return ((FileDocumentManager)this.GetDocumentManager()).Open(false, false, WindowFrameShowAction.Show);
case VsCommands.OpenWith:
return ((FileDocumentManager)this.GetDocumentManager()).Open(false, true, VSConstants.LOGVIEWID_UserChooseView, VSConstants.LOGVIEWID_UserChooseView, out windowFrame, WindowFrameShowAction.Show);
return ((FileDocumentManager)this.GetDocumentManager()).Open(false, true, VSConstants.LOGVIEWID_UserChooseView, out windowFrame, WindowFrameShowAction.Show);
}
}
@ -1070,5 +1071,10 @@ namespace Microsoft.VisualStudio.FSharp.ProjectSystem
}
return childNodes;
}
public override __VSPROVISIONALVIEWINGSTATUS ProvisionalViewingStatus =>
IsFileOnDisk(false)
? __VSPROVISIONALVIEWINGSTATUS.PVS_Enabled
: __VSPROVISIONALVIEWINGSTATUS.PVS_Disabled;
}
}
}

Просмотреть файл

@ -797,6 +797,12 @@ namespace Microsoft.VisualStudio.FSharp.ProjectSystem
result = this.ProjectMgr.GetProjectProperty("TargetPlatformIdentifier");
}
if (propId == (int)__VSHPROPID5.VSHPROPID_ProvisionalViewingStatus)
{
// Indicates that the node support previewing
result = ProvisionalViewingStatus;
}
#if DEBUG
if (propId != LastTracedProperty)
{
@ -3287,5 +3293,7 @@ namespace Microsoft.VisualStudio.FSharp.ProjectSystem
{
throw new NotImplementedException();
}
public virtual __VSPROVISIONALVIEWINGSTATUS ProvisionalViewingStatus => __VSPROVISIONALVIEWINGSTATUS.PVS_Disabled;
}
}

Просмотреть файл

@ -2151,26 +2151,28 @@ namespace rec Microsoft.VisualStudio.FSharp.ProjectSystem
base.Dispose(disposing)
override x.ImageIndex =
if (x.IsFormSubType) then
int32 ProjectNode.ImageName.WindowsForm
elif (FSharpProjectNode.IsFSharpCodeFileIconwise(x.FileName)) then
FSharpProjectNode.ImageOffset + int32 FSharpImageName.FsFile
elif (FSharpProjectNode.IsFSharpSignatureFileIconwise(x.FileName)) then
FSharpProjectNode.ImageOffset + int32 FSharpImageName.FsiFile
elif (FSharpProjectNode.IsFSharpScriptFileIconwise(x.FileName)) then
FSharpProjectNode.ImageOffset + int32 FSharpImageName.FsxFile
else
base.ImageIndex
// Check if the file is there.
if not (x.CanShowDefaultIcon()) then
int ProjectNode.ImageName.MissingFile
elif x.IsFormSubType then
int ProjectNode.ImageName.WindowsForm
elif (FSharpProjectNode.IsFSharpCodeFileIconwise(x.FileName)) then
FSharpProjectNode.ImageOffset + int FSharpImageName.FsFile
elif (FSharpProjectNode.IsFSharpSignatureFileIconwise(x.FileName)) then
FSharpProjectNode.ImageOffset + int FSharpImageName.FsiFile
elif (FSharpProjectNode.IsFSharpScriptFileIconwise(x.FileName)) then
FSharpProjectNode.ImageOffset + int FSharpImageName.FsxFile
else
base.ImageIndex
/// Open a file depending on the SubType property associated with the file item in the project file
override x.DoDefaultAction() =
let manager = (x.GetDocumentManager() :?> FileDocumentManager)
Debug.Assert(manager <> null, "Could not get the FileDocumentManager")
let viewGuid = (if x.IsFormSubType then VSConstants.LOGVIEWID_Designer else VSConstants.LOGVIEWID_Primary)
let fallbackViewGuid = (if x.IsFormSubType then VSConstants.LOGVIEWID_Primary else VSConstants.LOGVIEWID_Designer)
let viewGuid = (if x.IsFormSubType then VSConstants.LOGVIEWID_Designer else VSConstants.LOGVIEWID_TextView)
let mutable frame : IVsWindowFrame = null
manager.Open(false, false, viewGuid, fallbackViewGuid, &frame, WindowFrameShowAction.Show) |> ignore
manager.Open(false, false, viewGuid, &frame, WindowFrameShowAction.Show) |> ignore
/// In solution explorer, move the last of my siblings to just above me, return the moved FSharpFileNode
static member MoveLastToAbove(target : HierarchyNode, root : FSharpProjectNode) : FSharpFileNode =

Просмотреть файл

@ -29,6 +29,39 @@
<GeneratePkgDefFile>true</GeneratePkgDefFile>
<IncludePkgdefInVSIXContainer>true</IncludePkgdefInVSIXContainer>
</PropertyGroup>
<Import Project="$(FSharpSourcesRoot)\FSharpSource.targets" />
<Import Project="$(FSharpSourcesRoot)\..\vsintegration\vsintegration.targets" />
<Import Project="$(VsSDKInstall)\Microsoft.VsSDK.targets" />
<PropertyGroup>
<BuildingProject>true</BuildingProject>
<BuildDependsOn>VSCTCompile;CopyCtoFile;$(BuildDependsOn)</BuildDependsOn>
</PropertyGroup>
<Target Name="CopyCtoFile">
<Copy SourceFiles="@(VSCTCompile->'$(IntermediateOutputPath)%(FileName).cto')" DestinationFiles="@(VSCTCompile->'ctofiles\%(FileName).cto')" />
</Target>
<PropertyGroup>
<Win32Resource>$(IntermediateOutputPath)\ProjectResources.rc.res</Win32Resource>
</PropertyGroup>
<Target Name="BeforeBuild">
<Exec Command="&quot;$(ProgramFiles)\Windows Kits\8.1\bin\x86\rc.exe&quot; /fo $(IntermediateOutputPath)$(RCResourceFile).res $(RCResourceFile)" Condition="Exists('$(ProgramFiles)\Windows Kits\8.1\bin\x86\rc.exe')" />
<Exec Command="&quot;$(ProgramFiles)\Windows Kits\10\bin\x86\rc.exe&quot; /fo $(IntermediateOutputPath)$(RCResourceFile).res $(RCResourceFile)" Condition="Exists('$(ProgramFiles)\Windows Kits\10\bin\x86\rc.exe')" />
</Target>
<Target Name="GatherBinariesToBeSigned" AfterTargets="Localize" Condition="'$(UseGatherBinaries)' == 'true'">
<ItemGroup>
<BinariesToBeSigned Include="$(OutDir)$(AssemblyName).dll" />
<BinariesToBeSigned Include="$(OutDir)localize\**\$(AssemblyName).resources.dll" />
<FilesToSign Include="@(BinariesToBeSigned)">
<Authenticode>Microsoft</Authenticode>
<StrongName>StrongName</StrongName>
</FilesToSign>
</ItemGroup>
</Target>
<Target Name="CopyLocalizationResources" BeforeTargets="Localize">
<ItemGroup>
<LocalizationResources Include="MenusAndCommands.vsct" />
</ItemGroup>
<Copy SourceFiles="@(LocalizationResources)" DestinationFiles="@(LocalizationResources->'$(OutDir)%(Filename)%(Extension)')" />
</Target>
<ItemGroup>
<FilesToLocalize Include="$(OutDir)$(AssemblyName).dll">
<TranslationFile>$(FSharpSourcesRoot)\..\loc\lcl\{Lang}\$(AssemblyName).dll.lcl</TranslationFile>
@ -44,8 +77,6 @@
<Link>FSharp.ProjectSystem.FSharp.dll</Link>
<Parser>210</Parser>
</FilesToLocalize>
</ItemGroup>
<ItemGroup>
<VSCTCompile Include="MenusAndCommands.vsct" />
<EmbeddedResource Include="VSPackage.resx">
<MergeWithCTO>true</MergeWithCTO>
@ -161,37 +192,4 @@
<Name>FSharp.Core</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(FSharpSourcesRoot)\FSharpSource.targets" />
<Import Project="$(FSharpSourcesRoot)\..\vsintegration\vsintegration.targets" />
<Import Project="$(VsSDKInstall)\Microsoft.VsSDK.targets" />
<PropertyGroup>
<BuildingProject>true</BuildingProject>
<BuildDependsOn>VSCTCompile;CopyCtoFile;$(BuildDependsOn)</BuildDependsOn>
</PropertyGroup>
<Target Name="CopyCtoFile">
<Copy SourceFiles="@(VSCTCompile->'$(IntermediateOutputPath)%(FileName).cto')" DestinationFiles="@(VSCTCompile->'ctofiles\%(FileName).cto')" />
</Target>
<PropertyGroup>
<Win32Resource>$(IntermediateOutputPath)\ProjectResources.rc.res</Win32Resource>
</PropertyGroup>
<Target Name="BeforeBuild">
<Exec Command="&quot;$(ProgramFiles)\Windows Kits\8.1\bin\x86\rc.exe&quot; /fo $(IntermediateOutputPath)$(RCResourceFile).res $(RCResourceFile)" Condition="Exists('$(ProgramFiles)\Windows Kits\8.1\bin\x86\rc.exe')" />
<Exec Command="&quot;$(ProgramFiles)\Windows Kits\10\bin\x86\rc.exe&quot; /fo $(IntermediateOutputPath)$(RCResourceFile).res $(RCResourceFile)" Condition="Exists('$(ProgramFiles)\Windows Kits\10\bin\x86\rc.exe')" />
</Target>
<Target Name="GatherBinariesToBeSigned" AfterTargets="Localize" Condition="'$(UseGatherBinaries)' == 'true'">
<ItemGroup>
<BinariesToBeSigned Include="$(OutDir)$(AssemblyName).dll" />
<BinariesToBeSigned Include="$(OutDir)localize\**\$(AssemblyName).resources.dll" />
<FilesToSign Include="@(BinariesToBeSigned)">
<Authenticode>Microsoft</Authenticode>
<StrongName>StrongName</StrongName>
</FilesToSign>
</ItemGroup>
</Target>
<Target Name="CopyLocalizationResources" BeforeTargets="Localize">
<ItemGroup>
<LocalizationResources Include="MenusAndCommands.vsct" />
</ItemGroup>
<Copy SourceFiles="@(LocalizationResources)" DestinationFiles="@(LocalizationResources->'$(OutDir)%(Filename)%(Extension)')" />
</Target>
</Project>