提交 db7a842f 编写于 作者: T Tomáš Matoušek 提交者: GitHub

Remove Interactive Window (#13143)

上级 1e55ad19
......@@ -117,8 +117,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CSharpScriptingTest", "src\
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InteractiveFeatures", "src\Interactive\Features\InteractiveFeatures.csproj", "{8E2A252E-A140-45A6-A81A-2652996EA589}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InteractiveWindow", "src\InteractiveWindow\Editor\InteractiveWindow.csproj", "{01E9BD68-0339-4A13-B42F-A3CA84D164F3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CSharpEditorServicesTest", "src\EditorFeatures\CSharpTest\CSharpEditorServicesTest.csproj", "{AC2BCEFB-9298-4621-AC48-1FF5E639E48D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CSharpEditorServicesTest2", "src\EditorFeatures\CSharpTest2\CSharpEditorServicesTest2.csproj", "{16E93074-4252-466C-89A3-3B905ABAF779}"
......@@ -143,10 +141,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "csi", "src\Interactive\csi\
EndProject
Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "vbi", "src\Interactive\vbi\vbi.vbproj", "{6E62A0FF-D0DC-4109-9131-AB8E60CDFF7B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InteractiveWindowTest", "src\InteractiveWindow\EditorTest\InteractiveWindowTest.csproj", "{7F3CB45E-4993-4FA4-8D6A-C2DFFED2DFC3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VisualStudioInteractiveWindow", "src\InteractiveWindow\VisualStudio\VisualStudioInteractiveWindow.csproj", "{20BB6FAC-44D2-4D76-ABFE-0C1E163A1A4F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServicesVisualStudio", "src\VisualStudio\Core\Def\ServicesVisualStudio.csproj", "{86FD5B9A-4FA0-4B10-B59F-CFAF077A859C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServicesVisualStudioImpl", "src\VisualStudio\Core\Impl\ServicesVisualStudioImpl.csproj", "{C0E80510-4FBE-4B0C-AF2C-4F473787722C}"
......@@ -1420,26 +1414,6 @@ Global
{8E2A252E-A140-45A6-A81A-2652996EA589}.Release|x64.Build.0 = Release|Any CPU
{8E2A252E-A140-45A6-A81A-2652996EA589}.Release|x86.ActiveCfg = Release|Any CPU
{8E2A252E-A140-45A6-A81A-2652996EA589}.Release|x86.Build.0 = Release|Any CPU
{01E9BD68-0339-4A13-B42F-A3CA84D164F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{01E9BD68-0339-4A13-B42F-A3CA84D164F3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{01E9BD68-0339-4A13-B42F-A3CA84D164F3}.Debug|ARM.ActiveCfg = Debug|Any CPU
{01E9BD68-0339-4A13-B42F-A3CA84D164F3}.Debug|ARM.Build.0 = Debug|Any CPU
{01E9BD68-0339-4A13-B42F-A3CA84D164F3}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{01E9BD68-0339-4A13-B42F-A3CA84D164F3}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{01E9BD68-0339-4A13-B42F-A3CA84D164F3}.Debug|x64.ActiveCfg = Debug|Any CPU
{01E9BD68-0339-4A13-B42F-A3CA84D164F3}.Debug|x64.Build.0 = Debug|Any CPU
{01E9BD68-0339-4A13-B42F-A3CA84D164F3}.Debug|x86.ActiveCfg = Debug|Any CPU
{01E9BD68-0339-4A13-B42F-A3CA84D164F3}.Debug|x86.Build.0 = Debug|Any CPU
{01E9BD68-0339-4A13-B42F-A3CA84D164F3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{01E9BD68-0339-4A13-B42F-A3CA84D164F3}.Release|Any CPU.Build.0 = Release|Any CPU
{01E9BD68-0339-4A13-B42F-A3CA84D164F3}.Release|ARM.ActiveCfg = Release|Any CPU
{01E9BD68-0339-4A13-B42F-A3CA84D164F3}.Release|ARM.Build.0 = Release|Any CPU
{01E9BD68-0339-4A13-B42F-A3CA84D164F3}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{01E9BD68-0339-4A13-B42F-A3CA84D164F3}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{01E9BD68-0339-4A13-B42F-A3CA84D164F3}.Release|x64.ActiveCfg = Release|Any CPU
{01E9BD68-0339-4A13-B42F-A3CA84D164F3}.Release|x64.Build.0 = Release|Any CPU
{01E9BD68-0339-4A13-B42F-A3CA84D164F3}.Release|x86.ActiveCfg = Release|Any CPU
{01E9BD68-0339-4A13-B42F-A3CA84D164F3}.Release|x86.Build.0 = Release|Any CPU
{AC2BCEFB-9298-4621-AC48-1FF5E639E48D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AC2BCEFB-9298-4621-AC48-1FF5E639E48D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AC2BCEFB-9298-4621-AC48-1FF5E639E48D}.Debug|ARM.ActiveCfg = Debug|Any CPU
......@@ -1674,46 +1648,6 @@ Global
{6E62A0FF-D0DC-4109-9131-AB8E60CDFF7B}.Release|x64.Build.0 = Release|Any CPU
{6E62A0FF-D0DC-4109-9131-AB8E60CDFF7B}.Release|x86.ActiveCfg = Release|Any CPU
{6E62A0FF-D0DC-4109-9131-AB8E60CDFF7B}.Release|x86.Build.0 = Release|Any CPU
{7F3CB45E-4993-4FA4-8D6A-C2DFFED2DFC3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7F3CB45E-4993-4FA4-8D6A-C2DFFED2DFC3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7F3CB45E-4993-4FA4-8D6A-C2DFFED2DFC3}.Debug|ARM.ActiveCfg = Debug|Any CPU
{7F3CB45E-4993-4FA4-8D6A-C2DFFED2DFC3}.Debug|ARM.Build.0 = Debug|Any CPU
{7F3CB45E-4993-4FA4-8D6A-C2DFFED2DFC3}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{7F3CB45E-4993-4FA4-8D6A-C2DFFED2DFC3}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{7F3CB45E-4993-4FA4-8D6A-C2DFFED2DFC3}.Debug|x64.ActiveCfg = Debug|Any CPU
{7F3CB45E-4993-4FA4-8D6A-C2DFFED2DFC3}.Debug|x64.Build.0 = Debug|Any CPU
{7F3CB45E-4993-4FA4-8D6A-C2DFFED2DFC3}.Debug|x86.ActiveCfg = Debug|Any CPU
{7F3CB45E-4993-4FA4-8D6A-C2DFFED2DFC3}.Debug|x86.Build.0 = Debug|Any CPU
{7F3CB45E-4993-4FA4-8D6A-C2DFFED2DFC3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7F3CB45E-4993-4FA4-8D6A-C2DFFED2DFC3}.Release|Any CPU.Build.0 = Release|Any CPU
{7F3CB45E-4993-4FA4-8D6A-C2DFFED2DFC3}.Release|ARM.ActiveCfg = Release|Any CPU
{7F3CB45E-4993-4FA4-8D6A-C2DFFED2DFC3}.Release|ARM.Build.0 = Release|Any CPU
{7F3CB45E-4993-4FA4-8D6A-C2DFFED2DFC3}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{7F3CB45E-4993-4FA4-8D6A-C2DFFED2DFC3}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{7F3CB45E-4993-4FA4-8D6A-C2DFFED2DFC3}.Release|x64.ActiveCfg = Release|Any CPU
{7F3CB45E-4993-4FA4-8D6A-C2DFFED2DFC3}.Release|x64.Build.0 = Release|Any CPU
{7F3CB45E-4993-4FA4-8D6A-C2DFFED2DFC3}.Release|x86.ActiveCfg = Release|Any CPU
{7F3CB45E-4993-4FA4-8D6A-C2DFFED2DFC3}.Release|x86.Build.0 = Release|Any CPU
{20BB6FAC-44D2-4D76-ABFE-0C1E163A1A4F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{20BB6FAC-44D2-4D76-ABFE-0C1E163A1A4F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{20BB6FAC-44D2-4D76-ABFE-0C1E163A1A4F}.Debug|ARM.ActiveCfg = Debug|Any CPU
{20BB6FAC-44D2-4D76-ABFE-0C1E163A1A4F}.Debug|ARM.Build.0 = Debug|Any CPU
{20BB6FAC-44D2-4D76-ABFE-0C1E163A1A4F}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{20BB6FAC-44D2-4D76-ABFE-0C1E163A1A4F}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{20BB6FAC-44D2-4D76-ABFE-0C1E163A1A4F}.Debug|x64.ActiveCfg = Debug|Any CPU
{20BB6FAC-44D2-4D76-ABFE-0C1E163A1A4F}.Debug|x64.Build.0 = Debug|Any CPU
{20BB6FAC-44D2-4D76-ABFE-0C1E163A1A4F}.Debug|x86.ActiveCfg = Debug|Any CPU
{20BB6FAC-44D2-4D76-ABFE-0C1E163A1A4F}.Debug|x86.Build.0 = Debug|Any CPU
{20BB6FAC-44D2-4D76-ABFE-0C1E163A1A4F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{20BB6FAC-44D2-4D76-ABFE-0C1E163A1A4F}.Release|Any CPU.Build.0 = Release|Any CPU
{20BB6FAC-44D2-4D76-ABFE-0C1E163A1A4F}.Release|ARM.ActiveCfg = Release|Any CPU
{20BB6FAC-44D2-4D76-ABFE-0C1E163A1A4F}.Release|ARM.Build.0 = Release|Any CPU
{20BB6FAC-44D2-4D76-ABFE-0C1E163A1A4F}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{20BB6FAC-44D2-4D76-ABFE-0C1E163A1A4F}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{20BB6FAC-44D2-4D76-ABFE-0C1E163A1A4F}.Release|x64.ActiveCfg = Release|Any CPU
{20BB6FAC-44D2-4D76-ABFE-0C1E163A1A4F}.Release|x64.Build.0 = Release|Any CPU
{20BB6FAC-44D2-4D76-ABFE-0C1E163A1A4F}.Release|x86.ActiveCfg = Release|Any CPU
{20BB6FAC-44D2-4D76-ABFE-0C1E163A1A4F}.Release|x86.Build.0 = Release|Any CPU
{86FD5B9A-4FA0-4B10-B59F-CFAF077A859C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{86FD5B9A-4FA0-4B10-B59F-CFAF077A859C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{86FD5B9A-4FA0-4B10-B59F-CFAF077A859C}.Debug|ARM.ActiveCfg = Debug|Any CPU
......@@ -3233,7 +3167,6 @@ Global
{066F0DBD-C46C-4C20-AFEC-99829A172625} = {38940C5F-97FD-4B2A-B2CD-C4E4EF601B05}
{2DAE4406-7A89-4B5F-95C3-BC5422CE47CE} = {38940C5F-97FD-4B2A-B2CD-C4E4EF601B05}
{8E2A252E-A140-45A6-A81A-2652996EA589} = {2491A9B9-C0A8-49EE-9077-A32DE76E1E94}
{01E9BD68-0339-4A13-B42F-A3CA84D164F3} = {999FBDA2-33DA-4F74-B957-03AC72CCE5EC}
{AC2BCEFB-9298-4621-AC48-1FF5E639E48D} = {EE97CB90-33BB-4F3A-9B3D-69375DEC6AC6}
{16E93074-4252-466C-89A3-3B905ABAF779} = {EE97CB90-33BB-4F3A-9B3D-69375DEC6AC6}
{8CEE3609-A5A9-4A9B-86D7-33118F5D6B33} = {EE97CB90-33BB-4F3A-9B3D-69375DEC6AC6}
......@@ -3246,8 +3179,6 @@ Global
{8CEE3609-A5A9-4A9B-86D7-33118F5D6B34} = {5CA5F70E-0FDB-467B-B22C-3CD5994F0087}
{14118347-ED06-4608-9C45-18228273C712} = {5CA5F70E-0FDB-467B-B22C-3CD5994F0087}
{6E62A0FF-D0DC-4109-9131-AB8E60CDFF7B} = {5CA5F70E-0FDB-467B-B22C-3CD5994F0087}
{7F3CB45E-4993-4FA4-8D6A-C2DFFED2DFC3} = {999FBDA2-33DA-4F74-B957-03AC72CCE5EC}
{20BB6FAC-44D2-4D76-ABFE-0C1E163A1A4F} = {999FBDA2-33DA-4F74-B957-03AC72CCE5EC}
{86FD5B9A-4FA0-4B10-B59F-CFAF077A859C} = {8DBA5174-B0AA-4561-82B1-A46607697753}
{C0E80510-4FBE-4B0C-AF2C-4F473787722C} = {8DBA5174-B0AA-4561-82B1-A46607697753}
{7BE3DEEB-87F8-4E15-9C21-4F94B0B1C2D6} = {8DBA5174-B0AA-4561-82B1-A46607697753}
......
......@@ -37,7 +37,6 @@
"Microsoft.DiaSymReader.PortablePdb.dll",
"Microsoft.VisualStudio.CSharp.Repl.dll",
"Microsoft.VisualStudio.InteractiveServices.dll",
"Microsoft.VisualStudio.InteractiveWindow.dll",
"Microsoft.VisualStudio.LanguageServices.CSharp.dll",
"Microsoft.VisualStudio.LanguageServices.dll",
"Microsoft.VisualStudio.LanguageServices.Implementation.dll",
......@@ -46,7 +45,6 @@
"Microsoft.VisualStudio.LanguageServices.VisualBasic.dll",
"Microsoft.VisualStudio.LanguageServices.Xaml.dll",
"Microsoft.VisualStudio.VisualBasic.Repl.dll",
"Microsoft.VisualStudio.VsInteractiveWindow.dll",
"Pdb2Xml.exe",
"Roslyn.Compilers.Extension.dll",
"Roslyn.Hosting.Diagnostics.dll",
......@@ -90,7 +88,6 @@
"strongName": null,
"values": [
"ExpressionEvaluatorPackage.vsix",
"Microsoft.VisualStudio.VsInteractiveWindow.vsix",
"Roslyn.Compilers.Extension.vsix",
"Roslyn.Deployment.Full.vsix",
"Roslyn.Deployment.Full.Next.vsix",
......
......@@ -44,13 +44,6 @@
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
<IncludeOutputGroupsInVSIX>VSIXContainerProjectOutputGroup%3b</IncludeOutputGroupsInVSIX>
</ProjectReference>
<ProjectReference Include="..\InteractiveWindow\VisualStudio\VisualStudioInteractiveWindow.csproj">
<Project>{20BB6FAC-44D2-4D76-ABFE-0C1E163A1A4F}</Project>
<Name>VisualStudioInteractiveWindow</Name>
<VSIXSubPath>Vsixes</VSIXSubPath>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
<IncludeOutputGroupsInVSIX>VSIXContainerProjectOutputGroup%3b</IncludeOutputGroupsInVSIX>
</ProjectReference>
<ProjectReference Include="..\VisualStudio\SetupInteractive\VisualStudioSetupInteractive.csproj">
<Project>{C467FEFA-337D-4705-BB5A-BDF41A555FDC}</Project>
<Name>VisualStudioSetupInteractive</Name>
......@@ -74,4 +67,4 @@
</ProjectReference>
</ItemGroup>
<Import Project="..\..\build\Targets\VSL.Imports.targets" />
</Project>
</Project>
\ No newline at end of file
......@@ -29,15 +29,6 @@
Location="|VisualStudioSetup;VSIXContainerProjectOutputGroup|"
Id="|VisualStudioSetup;VSIXIdentifierProjectOutputGroup|" />
<Dependency d:ProjectName="VisualStudioInteractiveWindow"
DisplayName="|VisualStudioInteractiveWindow;VSIXNameProjectOutputGroup|"
Version="[|%CurrentProject%;GetBuildVersion|,)"
d:Source="Project"
d:InstallSource="Embed"
d:VsixSubPath="Vsixes"
Location="|VisualStudioInteractiveWindow;VSIXContainerProjectOutputGroup|"
Id="|VisualStudioInteractiveWindow;VSIXIdentifierProjectOutputGroup|" />
<Dependency d:ProjectName="VisualStudioInteractiveComponents"
DisplayName="|VisualStudioInteractiveComponents;VSIXNameProjectOutputGroup|"
Version="[|%CurrentProject%;GetBuildVersion|,)"
......
......@@ -51,10 +51,6 @@
<Project>{8E2A252E-A140-45A6-A81A-2652996EA589}</Project>
<Name>InteractiveFeatures</Name>
</ProjectReference>
<ProjectReference Include="..\..\InteractiveWindow\Editor\InteractiveWindow.csproj">
<Project>{01E9BD68-0339-4A13-B42F-A3CA84D164F3}</Project>
<Name>InteractiveWindow</Name>
</ProjectReference>
<ProjectReference Include="..\..\EditorFeatures\Text\TextEditorFeatures.csproj">
<Project>{18F5FBB8-7570-4412-8CC7-0A86FF13B7BA}</Project>
<Name>TextEditorFeatures</Name>
......
......@@ -4,6 +4,10 @@
"version": "14.3.25407",
"suppressParent": "all"
},
"RoslynDependencies.Microsoft.VisualStudio.Text.Internal": {
"version": "14.3.25407",
"suppressParent": "all"
},
"RoslynDependencies.Microsoft.VisualStudio.Language.CallHierarchy": {
"version": "14.3.25407",
"suppressParent": "all"
......
......@@ -51,10 +51,6 @@
<Project>{8E2A252E-A140-45A6-A81A-2652996EA589}</Project>
<Name>InteractiveFeatures</Name>
</ProjectReference>
<ProjectReference Include="..\..\InteractiveWindow\Editor\InteractiveWindow.csproj">
<Project>{01E9BD68-0339-4A13-B42F-A3CA84D164F3}</Project>
<Name>InteractiveWindow</Name>
</ProjectReference>
<ProjectReference Include="..\..\EditorFeatures\Text\TextEditorFeatures.csproj">
<Project>{18F5FBB8-7570-4412-8CC7-0A86FF13B7BA}</Project>
<Name>TextEditorFeatures</Name>
......
......@@ -40,10 +40,6 @@
<Project>{18F5FBB8-7570-4412-8CC7-0A86FF13B7BA}</Project>
<Name>TextEditorFeatures</Name>
</ProjectReference>
<ProjectReference Include="..\..\InteractiveWindow\Editor\InteractiveWindow.csproj">
<Project>{01E9BD68-0339-4A13-B42F-A3CA84D164F3}</Project>
<Name>InteractiveWindow</Name>
</ProjectReference>
</ItemGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
......
{
"dependencies": {
"System.Collections.Immutable": "1.2.0",
"Microsoft.VisualStudio.InteractiveWindow": {
"version": "2.0.0-beta5-60820-04",
"suppressParent": "all"
},
"RoslynDependencies.Microsoft.VisualStudio.Text.Internal": {
"version": "14.3.25407",
"suppressParent": "all"
},
"RoslynDependencies.Microsoft.VisualStudio.Language.CallHierarchy": {
"version": "14.3.25407",
"suppressParent": "all"
......@@ -9,6 +17,10 @@
"version": "14.3.25407",
"suppressParent": "all"
},
"Microsoft.VisualStudio.Language.StandardClassification": {
"version": "14.3.25407",
"suppressParent": "all"
},
"Microsoft.VisualStudio.Language.Intellisense": {
"version": "14.3.25407",
"suppressParent": "all"
......
......@@ -43,11 +43,6 @@
<Project>{18F5FBB8-7570-4412-8CC7-0A86FF13B7BA}</Project>
<Name>TextEditorFeatures</Name>
</ProjectReference>
<ProjectReference Include="..\..\InteractiveWindow\Editor\InteractiveWindow.csproj">
<Project>{01E9BD68-0339-4A13-B42F-A3CA84D164F3}</Project>
<Name>InteractiveWindow</Name>
<Aliases>InteractiveWindow</Aliases>
</ProjectReference>
</ItemGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
......
......@@ -87,10 +87,6 @@
<Project>{8E2A252E-A140-45A6-A81A-2652996EA589}</Project>
<Name>InteractiveFeatures</Name>
</ProjectReference>
<ProjectReference Include="..\..\InteractiveWindow\Editor\InteractiveWindow.csproj">
<Project>{01E9BD68-0339-4A13-B42F-A3CA84D164F3}</Project>
<Name>InteractiveWindow</Name>
</ProjectReference>
<ProjectReference Include="..\..\EditorFeatures\Text\TextEditorFeatures.csproj">
<Project>{18F5FBB8-7570-4412-8CC7-0A86FF13B7BA}</Project>
<Name>TextEditorFeatures</Name>
......
......@@ -7,6 +7,10 @@
"version": "14.3.25407",
"suppressParent": "all"
},
"RoslynDependencies.Microsoft.VisualStudio.Text.Internal" : {
"version": "14.3.25407",
"suppressParent": "all"
},
"RoslynDependencies.Microsoft.VisualStudio.Language.CallHierarchy": {
"version": "14.3.25407",
"suppressParent": "all"
......@@ -15,6 +19,10 @@
"version": "14.3.25407",
"suppressParent": "all"
},
"Microsoft.VisualStudio.Language.StandardClassification": {
"version": "14.3.25407",
"suppressParent": "all"
},
"Microsoft.VisualStudio.Text.UI": {
"version": "14.3.25407",
"suppressParent": "all"
......
......@@ -25,10 +25,6 @@
<Project>{2523D0E6-DF32-4A3E-8AE0-A19BFFAE2EF6}</Project>
<Name>BasicCodeAnalysis</Name>
</ProjectReference>
<ProjectReference Include="..\..\InteractiveWindow\Editor\InteractiveWindow.csproj">
<Project>{01e9bd68-0339-4a13-b42f-a3ca84d164f3}</Project>
<Name>InteractiveWindow</Name>
</ProjectReference>
<ProjectReference Include="..\..\Interactive\EditorFeatures\Core\InteractiveEditorFeatures.csproj">
<Project>{92412d1a-0f23-45b5-b196-58839c524917}</Project>
<Name>InteractiveEditorFeatures</Name>
......
{
"dependencies": {
"Microsoft.VisualStudio.InteractiveWindow": {
"version": "2.0.0-beta5-60820-04",
"suppressParent": "all"
},
"Microsoft.VisualStudio.Language.Intellisense": {
"version": "14.3.25407",
"suppressParent": "all"
},
"RoslynDependencies.Microsoft.VisualStudio.Text.Internal": {
"version": "14.3.25407",
"suppressParent": "all"
},
"RoslynDependencies.Microsoft.VisualStudio.Language.CallHierarchy": {
"version": "14.3.25407",
"suppressParent": "all"
......
......@@ -12,10 +12,18 @@
"version": "14.2.19-pre",
"suppressParent": "all"
},
"RoslynDependencies.Microsoft.VisualStudio.Text.Internal": {
"version": "14.3.25407",
"suppressParent": "all"
},
"RoslynDependencies.Microsoft.VisualStudio.Platform.VSEditor": {
"version": "14.3.25407",
"suppressParent": "all"
},
"Microsoft.VisualStudio.Language.StandardClassification" : {
"version": "14.3.25407",
"suppressParent": "all"
},
"Microsoft.VisualStudio.Language.Intellisense": {
"version": "14.3.25407",
"suppressParent": "all"
......
......@@ -4,6 +4,10 @@
"version": "14.3.25407",
"suppressParent": "all"
},
"RoslynDependencies.Microsoft.VisualStudio.Text.Internal": {
"version": "14.3.25407",
"suppressParent": "all"
},
"RoslynDependencies.Microsoft.VisualStudio.Language.NavigateTo.Interfaces": {
"version": "14.3.25407",
"suppressParent": "all"
......
......@@ -52,10 +52,6 @@
<Project>{8E2A252E-A140-45A6-A81A-2652996EA589}</Project>
<Name>InteractiveFeatures</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\InteractiveWindow\Editor\InteractiveWindow.csproj">
<Project>{01E9BD68-0339-4A13-B42F-A3CA84D164F3}</Project>
<Name>InteractiveWindow</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\EditorFeatures\Text\TextEditorFeatures.csproj">
<Project>{18F5FBB8-7570-4412-8CC7-0A86FF13B7BA}</Project>
<Name>TextEditorFeatures</Name>
......
{
"dependencies": {
"Microsoft.VisualStudio.InteractiveWindow": {
"version": "2.0.0-beta5-60820-04",
"suppressParent": "all"
},
"Microsoft.VisualStudio.Text.UI.Wpf": {
"version": "14.3.25407",
"suppressParent": "all"
......
......@@ -41,10 +41,6 @@
<Project>{8E2A252E-A140-45A6-A81A-2652996EA589}</Project>
<Name>InteractiveFeatures</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\InteractiveWindow\Editor\InteractiveWindow.csproj">
<Project>{01E9BD68-0339-4A13-B42F-A3CA84D164F3}</Project>
<Name>InteractiveWindow</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\EditorFeatures\Text\TextEditorFeatures.csproj">
<Project>{18F5FBB8-7570-4412-8CC7-0A86FF13B7BA}</Project>
<Name>TextEditorFeatures</Name>
......
{
"dependencies": {
"Microsoft.VisualStudio.InteractiveWindow": {
"version": "2.0.0-beta5-60820-04",
"suppressParent": "all"
},
"Microsoft.VisualStudio.Language.Intellisense": {
"version": "14.3.25407",
"suppressParent": "all"
......@@ -7,6 +11,10 @@
"Microsoft.VisualStudio.Editor": {
"version": "14.3.25407",
"suppressParent": "all"
},
"Microsoft.VisualStudio.Language.StandardClassification": {
"version": "14.3.25407",
"suppressParent": "all"
}
},
"frameworks": {
......
......@@ -19,10 +19,6 @@
<Project>{2523D0E6-DF32-4A3E-8AE0-A19BFFAE2EF6}</Project>
<Name>BasicCodeAnalysis</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\InteractiveWindow\Editor\InteractiveWindow.csproj">
<Project>{01e9bd68-0339-4a13-b42f-a3ca84d164f3}</Project>
<Name>InteractiveWindow</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\Scripting\VisualBasic\BasicScripting.vbproj">
<Project>{3E7DEA65-317B-4F43-A25D-62F18D96CFD7}</Project>
<Name>BasicScripting</Name>
......
{
"dependencies": {
"Microsoft.VisualStudio.InteractiveWindow": {
"version": "2.0.0-beta5-60820-04",
"suppressParent": "all"
},
"Microsoft.VisualStudio.Text.UI": {
"version": "14.3.25407",
"suppressParent": "all"
......
// Copyright (c) Microsoft. 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.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Text;
namespace Microsoft.VisualStudio.InteractiveWindow
{
/// <summary>
/// REPL session buffer: input, output, or prompt.
/// </summary>
[DataContract]
internal struct BufferBlock
{
[DataMember(Name = "kind")]
internal readonly ReplSpanKind Kind;
[DataMember(Name = "content")]
internal readonly string Content;
internal BufferBlock(ReplSpanKind kind, string content)
{
Kind = kind;
Content = content;
}
internal static string Serialize(BufferBlock[] blocks)
{
var serializer = new DataContractJsonSerializer(typeof(BufferBlock[]));
using (var stream = new MemoryStream())
{
serializer.WriteObject(stream, blocks);
return Encoding.UTF8.GetString(stream.GetBuffer(), 0, (int)stream.Length);
}
}
/// <exception cref="InvalidDataException" />
internal static BufferBlock[] Deserialize(string str)
{
var serializer = new DataContractJsonSerializer(typeof(BufferBlock[]));
try
{
var bytes = Encoding.UTF8.GetBytes(str);
using (var stream = new MemoryStream(bytes))
{
var obj = serializer.ReadObject(stream);
return (BufferBlock[])obj;
}
}
catch (Exception e)
{
throw new InvalidDataException(e.Message, e);
}
}
}
}
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#if TODO
using System.ComponentModel.Composition;
using System.Reflection;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows.Media.Imaging;
namespace Microsoft.VisualStudio.InteractiveWindow {
[Export(typeof(IInteractiveWindowCommand))]
internal sealed class CancelExecutionCommand : InteractiveWindowCommand {
public override Task<ExecutionResult> Execute(IInteractiveWindow window, string arguments) {
window.AbortCommand();
return ExecutionResult.Succeeded;
}
public override string Description {
get { return "Stops execution of the current command."; }
}
public override object ButtonContent {
get {
var image = new BitmapImage();
image.BeginInit();
image.StreamSource = Assembly.GetExecutingAssembly().GetManifestResourceStream("Microsoft.VisualStudio.Resources.CancelEvaluation.gif");
image.EndInit();
var res = new Image();
res.Source = image;
res.Width = res.Height = 16;
return res;
}
}
}
}
#endif
\ No newline at end of file
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.ComponentModel.Composition;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Microsoft.VisualStudio.InteractiveWindow.Commands
{
[Export(typeof(IInteractiveWindowCommand))]
internal sealed class ClearScreenCommand : InteractiveWindowCommand
{
public override Task<ExecutionResult> Execute(IInteractiveWindow window, string arguments)
{
window.Operations.ClearView();
return ExecutionResult.Succeeded;
}
public override string Description
{
get { return InteractiveWindowResources.ClearScreenCommandDescription; }
}
public override IEnumerable<string> Names
{
get { yield return "cls"; yield return "clear"; }
}
}
}
// Copyright (c) Microsoft. 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.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.Language.StandardClassification;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Classification;
namespace Microsoft.VisualStudio.InteractiveWindow.Commands
{
internal sealed class CommandClassifier : IClassifier
{
private readonly IStandardClassificationService _registry;
private readonly IInteractiveWindowCommands _commands;
public CommandClassifier(IStandardClassificationService registry, IInteractiveWindowCommands commands)
{
_registry = registry;
_commands = commands;
}
public IList<ClassificationSpan> GetClassificationSpans(SnapshotSpan span)
{
return _commands.Classify(span).ToArray();
}
#pragma warning disable 67 // unused event
// This event gets raised if a non-text change would affect the classification in some way,
// for example typing /* would cause the classification to change in C# without directly
// affecting the span.
public event EventHandler<ClassificationChangedEventArgs> ClassificationChanged;
#pragma warning restore 67
}
}
\ No newline at end of file
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.ComponentModel.Composition;
using Microsoft.VisualStudio.Language.StandardClassification;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Classification;
using Microsoft.VisualStudio.Text.Editor;
using Microsoft.VisualStudio.Utilities;
namespace Microsoft.VisualStudio.InteractiveWindow.Commands
{
[Export(typeof(IClassifierProvider))]
[ContentType(PredefinedInteractiveCommandsContentTypes.InteractiveCommandContentTypeName)]
internal sealed class CommandClassifierProvider : IClassifierProvider
{
[Import]
public IStandardClassificationService ClassificationRegistry { get; set; }
public IClassifier GetClassifier(ITextBuffer textBuffer)
{
var commands = textBuffer.GetInteractiveWindow().GetInteractiveCommands();
if (commands != null)
{
return new CommandClassifier(ClassificationRegistry, commands);
}
return null;
}
}
}
// Copyright (c) Microsoft. 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.Collections.Generic;
using System.ComponentModel.Composition;
using System.Threading.Tasks;
namespace Microsoft.VisualStudio.InteractiveWindow.Commands
{
[Export(typeof(IInteractiveWindowCommand))]
internal sealed class HelpReplCommand : InteractiveWindowCommand
{
internal const string CommandName = "help";
public override string Description
{
get { return InteractiveWindowResources.HelpCommandDescription; }
}
public override IEnumerable<string> Names
{
get { yield return CommandName; }
}
public override string CommandLine
{
get { return InteractiveWindowResources.CommandNamePlaceholder; }
}
public override Task<ExecutionResult> Execute(IInteractiveWindow window, string arguments)
{
string commandName;
IInteractiveWindowCommand command;
if (!ParseArguments(window, arguments, out commandName, out command))
{
window.ErrorOutputWriter.WriteLine(string.Format(InteractiveWindowResources.UnknownCommand, commandName));
ReportInvalidArguments(window);
return ExecutionResult.Failed;
}
var commands = (IInteractiveWindowCommands)window.Properties[typeof(IInteractiveWindowCommands)];
if (command != null)
{
commands.DisplayCommandHelp(command);
}
else
{
commands.DisplayHelp();
}
return ExecutionResult.Succeeded;
}
private static readonly char[] s_whitespaceChars = new[] { '\r', '\n', ' ', '\t' };
private bool ParseArguments(IInteractiveWindow window, string arguments, out string commandName, out IInteractiveWindowCommand command)
{
string name = arguments.Split(s_whitespaceChars)[0];
if (name.Length == 0)
{
command = null;
commandName = null;
return true;
}
var commands = window.GetInteractiveCommands();
string prefix = commands.CommandPrefix;
// display help on a particular command:
command = commands[name];
if (command == null && name.StartsWith(prefix, StringComparison.Ordinal))
{
name = name.Substring(prefix.Length);
command = commands[name];
}
commandName = name;
return command != null;
}
}
}
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.VisualStudio.Language.StandardClassification;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Classification;
namespace Microsoft.VisualStudio.InteractiveWindow.Commands
{
/// <summary>
/// Represents a command which can be run from a REPL window.
///
/// This interface is a MEF contract and can be implemented and exported to add commands to the REPL window.
/// </summary>
public interface IInteractiveWindowCommand
{
/// <summary>
/// Asynchronously executes the command with specified arguments and calls back the given completion when finished.
/// </summary>
/// <param name="window">The interactive window.</param>
/// <param name="arguments">Command arguments.</param>
/// <returns>The task that completes the execution.</returns>
Task<ExecutionResult> Execute(IInteractiveWindow window, string arguments);
/// <summary>
/// Gets a brief (ideally single-line) description of the REPL command which is displayed when the user asks for help.
/// </summary>
string Description
{
get;
}
/// <summary>
/// A single line parameters listing, or null if the command doesn't take any parameters. For example, "[on|off]".
/// </summary>
string CommandLine
{
get;
}
/// <summary>
/// Gets detailed description of the command usage.
/// </summary>
/// <remarks>
/// Returns a sequence of lines.
/// </remarks>
IEnumerable<string> DetailedDescription
{
get;
}
/// <summary>
/// Parameter name and description for parameters of the command.
/// </summary>
IEnumerable<KeyValuePair<string, string>> ParametersDescription
{
get;
}
/// <summary>
/// The name of the command. May not contain any whitespace characters.
/// </summary>
IEnumerable<string> Names
{
get;
}
/// <summary>
/// Provides classification for command arguments.
/// </summary>
IEnumerable<ClassificationSpan> ClassifyArguments(ITextSnapshot snapshot, Span argumentsSpan, Span spanToClassify);
}
}
// Copyright (c) Microsoft. 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.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Classification;
namespace Microsoft.VisualStudio.InteractiveWindow.Commands
{
/// <summary>
/// Provides handling of meta-commands in the interactive window. Instances can be
/// created using the <see cref="IInteractiveWindowCommandsFactory"/> service.
/// </summary>
public interface IInteractiveWindowCommands
{
/// <summary>
/// Checks to see if the current input is in command mode (it is prefixed with the
/// command prefix).
/// </summary>
bool InCommand
{
get;
}
/// <summary>
/// Gets the prefix which is used for interactive window commands.
/// </summary>
string CommandPrefix { get; }
/// <summary>
/// Attempts to execute the command and returns the execution result.
///
/// Returns null if the current command is unrecognized.
/// </summary>
/// <returns></returns>
Task<ExecutionResult> TryExecuteCommand();
/// <summary>
/// Gets the registered list of commands that this IInteractiveWindowCommands was created with.
/// </summary>
/// <returns></returns>
IEnumerable<IInteractiveWindowCommand> GetCommands();
/// <summary>
/// Gets an individual command by name.
/// </summary>
IInteractiveWindowCommand this[string name]
{
get;
}
/// <summary>
/// Displays help into the interactive window for the specified command.
/// </summary>
void DisplayCommandHelp(IInteractiveWindowCommand command);
/// <summary>
/// Displays usage information in the interactive window for the specified command.
/// </summary>
void DisplayCommandUsage(IInteractiveWindowCommand command, TextWriter writer, bool displayDetails);
/// <summary>
/// Displays help for all of the available commands.
/// </summary>
void DisplayHelp();
/// <summary>
/// Classifies the specified command snapshot.
/// </summary>
IEnumerable<ClassificationSpan> Classify(SnapshotSpan span);
}
}
// Copyright (c) Microsoft. 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.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Microsoft.VisualStudio.InteractiveWindow.Commands
{
/// <summary>
/// Creates an <see cref="IInteractiveWindowCommands"/> which handles updating the context type for the command type,
/// classification of commands, and execution of commands.
/// </summary>
/// <remarks>
/// Engines need to use this interface to respond to checks if code can be executed and to
/// execute text when in a command mode.
///
/// The commands that are available for this interactive window are provided at creation time
/// along with the prefix which commands should be prefaced with.
/// </remarks>
public interface IInteractiveWindowCommandsFactory
{
/// <summary>
/// Creates the IInteractiveCommands instance.
/// </summary>
IInteractiveWindowCommands CreateInteractiveCommands(IInteractiveWindow window, string prefix, IEnumerable<IInteractiveWindowCommand> commands);
}
}
// Copyright (c) Microsoft. 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.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.VisualStudio.Language.StandardClassification;
using Microsoft.VisualStudio.Utilities;
namespace Microsoft.VisualStudio.InteractiveWindow.Commands
{
[Export(typeof(IInteractiveWindowCommandsFactory))]
internal class InteractiveCommandsFactory : IInteractiveWindowCommandsFactory
{
private readonly IContentTypeRegistryService _contentTypeRegistry;
private readonly IStandardClassificationService _standardClassification;
[ImportingConstructor]
public InteractiveCommandsFactory(IContentTypeRegistryService contentTypeRegistry, IStandardClassificationService classification)
{
_contentTypeRegistry = contentTypeRegistry;
_standardClassification = classification;
}
public IInteractiveWindowCommands CreateInteractiveCommands(IInteractiveWindow window, string prefix, IEnumerable<IInteractiveWindowCommand> commands)
{
return new Commands(window, prefix, commands.ToArray(), _contentTypeRegistry, _standardClassification);
}
}
}
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Classification;
using Microsoft.VisualStudio.Utilities;
namespace Microsoft.VisualStudio.InteractiveWindow.Commands
{
/// <summary>
/// Represents a command which can be run from a REPL window.
///
/// This interface is a MEF contract and can be implemented and exported to add commands to the REPL window.
/// </summary>
[ContentType(PredefinedInteractiveCommandsContentTypes.InteractiveCommandContentTypeName)]
internal abstract class InteractiveWindowCommand : IInteractiveWindowCommand
{
public abstract Task<ExecutionResult> Execute(IInteractiveWindow window, string arguments);
public abstract string Description { get; }
public abstract IEnumerable<string> Names { get; }
public virtual IEnumerable<ClassificationSpan> ClassifyArguments(ITextSnapshot snapshot, Span argumentsSpan, Span spanToClassify)
{
return Enumerable.Empty<ClassificationSpan>();
}
public virtual string CommandLine
{
get { return null; }
}
public virtual IEnumerable<string> DetailedDescription
{
get { return null; }
}
public virtual IEnumerable<KeyValuePair<string, string>> ParametersDescription
{
get { return null; }
}
protected void ReportInvalidArguments(IInteractiveWindow window)
{
var commands = (IInteractiveWindowCommands)window.Properties[typeof(IInteractiveWindowCommands)];
commands.DisplayCommandUsage(this, window.ErrorOutputWriter, displayDetails: false);
}
}
}
// Copyright (c) Microsoft. 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.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Microsoft.VisualStudio.InteractiveWindow.Commands
{
public static class InteractiveWindowCommandExtensions
{
/// <summary>
/// Gets the IInteractiveWindowCommands instance for the current interactive window if one is defined.
///
/// Returns null if the interactive commands have not been created for this window.
/// </summary>
public static IInteractiveWindowCommands GetInteractiveCommands(this IInteractiveWindow window)
{
IInteractiveWindowCommands commands;
if (window.Properties.TryGetProperty(typeof(IInteractiveWindowCommands), out commands))
{
return commands;
}
return null;
}
}
}
// Copyright (c) Microsoft. 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.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.VisualStudio.Language.StandardClassification;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Classification;
using Microsoft.VisualStudio.Utilities;
namespace Microsoft.VisualStudio.InteractiveWindow.Commands
{
internal sealed class Commands : IInteractiveWindowCommands
{
private const string _commandSeparator = ", ";
private readonly Dictionary<string, IInteractiveWindowCommand> _commands;
private readonly int _maxCommandNameLength;
private readonly IInteractiveWindow _window;
private readonly IContentType _commandContentType;
private readonly IStandardClassificationService _classificationRegistry;
private IContentType _languageContentType;
private ITextBuffer _previousBuffer;
public string CommandPrefix { get; set; }
public bool InCommand
{
get
{
return _window.CurrentLanguageBuffer.ContentType == _commandContentType;
}
}
internal Commands(IInteractiveWindow window, string prefix, IEnumerable<IInteractiveWindowCommand> commands, IContentTypeRegistryService contentTypeRegistry = null, IStandardClassificationService classificationRegistry = null)
{
CommandPrefix = prefix;
_window = window;
Dictionary<string, IInteractiveWindowCommand> commandsDict = new Dictionary<string, IInteractiveWindowCommand>();
foreach (var command in commands)
{
int length = 0;
foreach (var name in command.Names)
{
if (commandsDict.ContainsKey(name))
{
throw new InvalidOperationException(string.Format(InteractiveWindowResources.DuplicateCommand, string.Join(_commandSeparator, command.Names)));
}
if (length != 0)
{
length += _commandSeparator.Length;
}
// plus the length of `#` for display purpose
length += name.Length + 1;
commandsDict[name] = command;
}
if (length == 0)
{
throw new InvalidOperationException(string.Format(InteractiveWindowResources.MissingCommandName, command.GetType().Name));
}
_maxCommandNameLength = Math.Max(_maxCommandNameLength, length);
}
_commands = commandsDict;
_classificationRegistry = classificationRegistry;
if (contentTypeRegistry != null)
{
_commandContentType = contentTypeRegistry.GetContentType(PredefinedInteractiveCommandsContentTypes.InteractiveCommandContentTypeName);
}
if (window != null)
{
window.SubmissionBufferAdded += Window_SubmissionBufferAdded;
window.Properties[typeof(IInteractiveWindowCommands)] = this;
}
}
private void Window_SubmissionBufferAdded(object sender, SubmissionBufferAddedEventArgs e)
{
if (_previousBuffer != null)
{
_previousBuffer.Changed -= NewBufferChanged;
}
_languageContentType = e.NewBuffer.ContentType;
e.NewBuffer.Changed += NewBufferChanged;
_previousBuffer = e.NewBuffer;
}
private void NewBufferChanged(object sender, TextContentChangedEventArgs e)
{
bool isCommand = IsCommand(e.After.GetExtent());
ITextBuffer buffer = e.After.TextBuffer;
IContentType contentType = buffer.ContentType;
IContentType newContentType = null;
if (contentType == _languageContentType)
{
if (isCommand)
{
newContentType = _commandContentType;
}
}
else
{
if (!isCommand)
{
newContentType = _languageContentType;
}
}
if (newContentType != null)
{
buffer.ChangeContentType(newContentType, editTag: null);
}
}
internal bool IsCommand(SnapshotSpan span)
{
SnapshotSpan prefixSpan, commandSpan, argumentsSpan;
return TryParseCommand(span, out prefixSpan, out commandSpan, out argumentsSpan) != null;
}
internal IInteractiveWindowCommand TryParseCommand(SnapshotSpan span, out SnapshotSpan prefixSpan, out SnapshotSpan commandSpan, out SnapshotSpan argumentsSpan)
{
string prefix = CommandPrefix;
SnapshotSpan trimmed = span.TrimStart();
if (!trimmed.StartsWith(prefix))
{
prefixSpan = commandSpan = argumentsSpan = default(SnapshotSpan);
return null;
}
prefixSpan = trimmed.SubSpan(0, prefix.Length);
var nameAndArgs = trimmed.SubSpan(prefix.Length).TrimStart();
SnapshotPoint nameEnd = nameAndArgs.IndexOfAnyWhiteSpace() ?? span.End;
commandSpan = new SnapshotSpan(span.Snapshot, Span.FromBounds(nameAndArgs.Start.Position, nameEnd.Position));
argumentsSpan = new SnapshotSpan(span.Snapshot, Span.FromBounds(nameEnd.Position, span.End.Position)).Trim();
return this[commandSpan.GetText()];
}
public IInteractiveWindowCommand this[string name]
{
get
{
IInteractiveWindowCommand command;
_commands.TryGetValue(name, out command);
return command;
}
}
public IEnumerable<IInteractiveWindowCommand> GetCommands()
{
return _commands.Values;
}
internal IEnumerable<string> Help()
{
// The magic number `19` here is calculated based on how the description is dispayed for other help entries to keep the texts aligned
// (As of now other help entries include REPL commands and script derectives, both have manually formatted help description strings.
string format = "{0,-" + Math.Max(19, _maxCommandNameLength) + "} {1}";
return _commands.GroupBy(entry => entry.Value).
Select(group => string.Format(format, string.Join(_commandSeparator, group.Key.Names.Select(s => CommandPrefix + s)), group.Key.Description)).
OrderBy(line => line);
}
public IEnumerable<ClassificationSpan> Classify(SnapshotSpan span)
{
SnapshotSpan prefixSpan, commandSpan, argumentsSpan;
var command = TryParseCommand(span.Snapshot.GetExtent(), out prefixSpan, out commandSpan, out argumentsSpan);
if (command == null)
{
yield break;
}
if (span.OverlapsWith(prefixSpan))
{
yield return Classification(span.Snapshot, prefixSpan, _classificationRegistry.Keyword);
}
if (span.OverlapsWith(commandSpan))
{
yield return Classification(span.Snapshot, commandSpan, _classificationRegistry.Keyword);
}
if (argumentsSpan.Length > 0)
{
foreach (var classifiedSpan in command.ClassifyArguments(span.Snapshot, argumentsSpan.Span, span.Span))
{
yield return classifiedSpan;
}
}
}
private ClassificationSpan Classification(ITextSnapshot snapshot, Span span, IClassificationType classificationType)
{
return new ClassificationSpan(new SnapshotSpan(snapshot, span), classificationType);
}
/// <returns>
/// Null if parsing fails, the result of execution otherwise.
/// </returns>
public Task<ExecutionResult> TryExecuteCommand()
{
var span = _window.CurrentLanguageBuffer.CurrentSnapshot.GetExtent();
SnapshotSpan prefixSpan, commandSpan, argumentsSpan;
var command = TryParseCommand(span, out prefixSpan, out commandSpan, out argumentsSpan);
if (command == null)
{
return null;
}
return ExecuteCommandAsync(command, argumentsSpan.GetText());
}
private async Task<ExecutionResult> ExecuteCommandAsync(IInteractiveWindowCommand command, string arguments)
{
try
{
return await command.Execute(_window, arguments).ConfigureAwait(false);
}
catch (Exception e)
{
_window.ErrorOutputWriter.WriteLine(InteractiveWindowResources.CommandFailed, command.Names.First(), e.Message);
return ExecutionResult.Failure;
}
}
private const string HelpIndent = " ";
private static readonly string[] s_CSVBScriptDirectives = new[]
{
"#r " + InteractiveWindowResources.RefHelp,
"#load " + InteractiveWindowResources.LoadHelp
};
private static readonly string[] s_shortcutDescriptions = new[]
{
"Enter " + InteractiveWindowResources.EnterHelp,
"Ctrl-Enter " + InteractiveWindowResources.CtrlEnterHelp1,
" " + InteractiveWindowResources.CtrlEnterHelp2,
"Shift-Enter " + InteractiveWindowResources.ShiftEnterHelp,
"Escape " + InteractiveWindowResources.EscapeHelp,
"Alt-UpArrow " + InteractiveWindowResources.AltUpArrowHelp,
"Alt-DownArrow " + InteractiveWindowResources.AltDownArrowHelp,
"Ctrl-Alt-UpArrow " + InteractiveWindowResources.CtrlAltUpArrowHelp,
"Ctrl-Alt-DownArrow " + InteractiveWindowResources.CtrlAltDownArrowHelp,
"Ctrl-K, Ctrl-Enter " + InteractiveWindowResources.CtrlKCtrlEnterHelp,
"Ctrl-E, Ctrl-Enter " + InteractiveWindowResources.CtrlECtrlEnterHelp,
"Ctrl-A " + InteractiveWindowResources.CtrlAHelp
};
private static readonly string[] s_shortcutDescriptionsSmartUpDown = new[]
{
"UpArrow " + InteractiveWindowResources.UpArrowHelp1,
" " + InteractiveWindowResources.UpArrowHelp2,
"DownArrow " + InteractiveWindowResources.DownArrowHelp1,
" " + InteractiveWindowResources.DownArrowHelp2
};
internal string ShortcutDescriptions
{
get
{
var sb = new StringBuilder();
foreach (var line in s_shortcutDescriptions)
{
sb.Append(HelpIndent + line + "\r\n");
}
if (UseSmartUpDown)
{
foreach (var line in s_shortcutDescriptionsSmartUpDown)
{
sb.Append(HelpIndent + line + "\r\n");
}
}
return sb.ToString();
}
}
public void DisplayHelp()
{
_window.WriteLine(InteractiveWindowResources.KeyboardShortcuts);
_window.Write(ShortcutDescriptions);
_window.WriteLine(InteractiveWindowResources.ReplCommands);
foreach (var line in Help())
{
_window.Write(HelpIndent);
_window.WriteLine(line);
}
// Hack: Display script directives only in CS/VB interactive window
// TODO: https://github.com/dotnet/roslyn/issues/6441
var evaluatorTypeName = _window.Evaluator.GetType().Name;
if (evaluatorTypeName == "CSharpInteractiveEvaluator" ||
evaluatorTypeName == "VisualBasicInteractiveEvaluator")
{
_window.WriteLine(InteractiveWindowResources.CSVBScriptDirectives);
foreach (var line in s_CSVBScriptDirectives)
{
_window.Write(HelpIndent);
_window.WriteLine(line);
}
}
}
public void DisplayCommandUsage(IInteractiveWindowCommand command, TextWriter writer, bool displayDetails)
{
if (displayDetails)
{
writer.WriteLine(command.Description);
writer.WriteLine(string.Empty);
}
writer.WriteLine(InteractiveWindowResources.Usage);
writer.Write(HelpIndent);
writer.Write(CommandPrefix);
writer.Write(string.Join(_commandSeparator + CommandPrefix, command.Names));
string commandLine = command.CommandLine;
if (commandLine != null)
{
writer.Write(" ");
writer.Write(commandLine);
}
if (displayDetails)
{
writer.WriteLine(string.Empty);
var paramsDesc = command.ParametersDescription;
if (paramsDesc != null && paramsDesc.Any())
{
writer.WriteLine(string.Empty);
writer.WriteLine(InteractiveWindowResources.Parameters);
int maxParamNameLength = paramsDesc.Max(entry => entry.Key.Length);
string paramHelpLineFormat = HelpIndent + "{0,-" + maxParamNameLength + "} {1}";
foreach (var paramDesc in paramsDesc)
{
writer.WriteLine(string.Format(paramHelpLineFormat, paramDesc.Key, paramDesc.Value));
}
}
IEnumerable<string> details = command.DetailedDescription;
if (details != null && details.Any())
{
writer.WriteLine(string.Empty);
foreach (var line in details)
{
writer.WriteLine(line);
}
}
}
}
public void DisplayCommandHelp(IInteractiveWindowCommand command)
{
DisplayCommandUsage(command, _window.OutputWriter, displayDetails: true);
}
private bool UseSmartUpDown => _window.TextView.Options.GetOptionValue(InteractiveWindowOptions.SmartUpDown);
}
}
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.ComponentModel.Composition;
using Microsoft.VisualStudio.Utilities;
#pragma warning disable CS0649 // field is not assigned to
namespace Microsoft.VisualStudio.InteractiveWindow.Commands
{
public static class PredefinedInteractiveCommandsContentTypes
{
public const string InteractiveCommandContentTypeName = "Interactive Command";
[Export, Name(InteractiveCommandContentTypeName), BaseDefinition("code")]
internal static readonly ContentTypeDefinition InteractiveCommandContentTypeDefinition;
}
}
// Copyright (c) Microsoft. 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.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel.Composition;
using System.Threading.Tasks;
using Microsoft.VisualStudio.Language.StandardClassification;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Classification;
namespace Microsoft.VisualStudio.InteractiveWindow.Commands
{
[Export(typeof(IInteractiveWindowCommand))]
internal sealed class ResetCommand : InteractiveWindowCommand
{
private const string CommandName = "reset";
private const string NoConfigParameterName = "noconfig";
private static readonly int s_noConfigParameterNameLength = NoConfigParameterName.Length;
private readonly IStandardClassificationService _registry;
[ImportingConstructor]
public ResetCommand(IStandardClassificationService registry)
{
_registry = registry;
}
public override string Description
{
get { return InteractiveWindowResources.ResetCommandDescription; }
}
public override IEnumerable<string> Names
{
get { yield return CommandName; }
}
public override string CommandLine
{
get { return "[" + NoConfigParameterName + "]"; }
}
public override IEnumerable<KeyValuePair<string, string>> ParametersDescription
{
get
{
yield return new KeyValuePair<string, string>(NoConfigParameterName, InteractiveWindowResources.ResetCommandParametersDescription);
}
}
public override Task<ExecutionResult> Execute(IInteractiveWindow window, string arguments)
{
bool initialize;
if (!TryParseArguments(arguments, out initialize))
{
ReportInvalidArguments(window);
return ExecutionResult.Failed;
}
return window.Operations.ResetAsync(initialize);
}
public override IEnumerable<ClassificationSpan> ClassifyArguments(ITextSnapshot snapshot, Span argumentsSpan, Span spanToClassify)
{
string arguments = snapshot.GetText(argumentsSpan);
int argumentsStart = argumentsSpan.Start;
foreach (var pos in GetNoConfigPositions(arguments))
{
var snapshotSpan = new SnapshotSpan(snapshot, new Span(argumentsStart + pos, s_noConfigParameterNameLength));
yield return new ClassificationSpan(snapshotSpan, _registry.Keyword);
}
}
/// <remarks>
/// Internal for testing.
/// </remarks>
internal static IEnumerable<int> GetNoConfigPositions(string arguments)
{
int startIndex = 0;
while (true)
{
int index = arguments.IndexOf(NoConfigParameterName, startIndex, StringComparison.Ordinal);
if (index < 0) yield break;
if ((index == 0 || char.IsWhiteSpace(arguments[index - 1])) &&
(index + s_noConfigParameterNameLength == arguments.Length || char.IsWhiteSpace(arguments[index + s_noConfigParameterNameLength])))
{
yield return index;
}
startIndex = index + s_noConfigParameterNameLength;
}
}
/// <remarks>
/// Internal for testing.
/// </remarks>
internal static bool TryParseArguments(string arguments, out bool initialize)
{
var trimmed = arguments.Trim();
if (trimmed.Length == 0)
{
initialize = true;
return true;
}
else if (string.Equals(trimmed, NoConfigParameterName, StringComparison.Ordinal))
{
initialize = false;
return true;
}
initialize = false;
return false;
}
}
}
// Copyright (c) Microsoft. 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.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.Utilities;
namespace Microsoft.VisualStudio.InteractiveWindow
{
internal class ContentTypeMetadata
{
public IEnumerable<string> ContentTypes { get; }
public ContentTypeMetadata(IDictionary<string, object> data)
{
this.ContentTypes = (IEnumerable<string>)data["ContentTypes"];
}
}
internal static class ContentTypeMetadataHelpers
{
public static T OfContentType<T>(
this IEnumerable<Lazy<T, ContentTypeMetadata>> exports,
IContentType contentType,
IContentTypeRegistryService contentTypeRegistry)
{
return (from export in exports
from exportedContentTypeName in export.Metadata.ContentTypes
let exportedContentType = contentTypeRegistry.GetContentType(exportedContentTypeName)
where exportedContentType.IsOfType(contentType.TypeName)
select export.Value).SingleOrDefault();
}
}
}
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Diagnostics;
using Microsoft.VisualStudio.Text;
namespace Microsoft.VisualStudio.InteractiveWindow
{
/// <summary>
/// This is a custom span which is like an EdgeInclusive span. We need a custom span because elision buffers
/// do not allow EdgeInclusive unless it spans the entire buffer. We create snippets of our language spans
/// and these are initially zero length. When we insert at the beginning of these we'll end up keeping the
/// span zero length if we're just EdgePositive tracking.
/// </summary>
[DebuggerDisplay("{GetDebuggerDisplay(), nq}")]
internal sealed class CustomTrackingSpan : ITrackingSpan
{
private readonly ITrackingPoint _start;
private readonly ITrackingPoint _end;
public CustomTrackingSpan(ITextSnapshot snapshot, Span span, bool canAppend = false)
{
_start = snapshot.CreateTrackingPoint(span.Start, PointTrackingMode.Negative);
_end = snapshot.CreateTrackingPoint(span.End, canAppend ? PointTrackingMode.Positive : PointTrackingMode.Negative);
}
#region ITrackingSpan Members
public SnapshotPoint GetEndPoint(ITextSnapshot snapshot)
{
return _end.GetPoint(snapshot);
}
public Span GetSpan(ITextVersion version)
{
return Span.FromBounds(_start.GetPosition(version), _end.GetPosition(version));
}
public SnapshotSpan GetSpan(ITextSnapshot snapshot)
{
return new SnapshotSpan(snapshot, Span.FromBounds(_start.GetPoint(snapshot), _end.GetPoint(snapshot)));
}
public SnapshotPoint GetStartPoint(ITextSnapshot snapshot)
{
return _start.GetPoint(snapshot);
}
public string GetText(ITextSnapshot snapshot)
{
return GetSpan(snapshot).GetText();
}
public ITextBuffer TextBuffer
{
get { return _start.TextBuffer; }
}
public TrackingFidelityMode TrackingFidelity
{
get { return TrackingFidelityMode.Forward; }
}
public SpanTrackingMode TrackingMode
{
get { return SpanTrackingMode.Custom; }
}
#endregion
private string GetDebuggerDisplay()
{
return "CustomSpan: " + GetSpan(_start.TextBuffer.CurrentSnapshot).ToString();
}
}
}
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Threading.Tasks;
namespace Microsoft.VisualStudio.InteractiveWindow
{
/// <summary>
/// The result of command execution.
/// </summary>
public struct ExecutionResult
{
public static readonly ExecutionResult Success = new ExecutionResult(true);
public static readonly ExecutionResult Failure = new ExecutionResult(false);
public static readonly Task<ExecutionResult> Succeeded = Task.FromResult(Success);
public static readonly Task<ExecutionResult> Failed = Task.FromResult(Failure);
private readonly bool _isSuccessful;
public ExecutionResult(bool isSuccessful)
{
_isSuccessful = isSuccessful;
}
public bool IsSuccessful
{
get
{
return _isSuccessful;
}
}
}
}
\ No newline at end of file
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Diagnostics;
using Microsoft.VisualStudio.Text;
namespace Microsoft.VisualStudio.InteractiveWindow
{
internal class History
{
internal sealed class Entry
{
/// <summary>
/// The cached text of this entry, which may exist if we've detached from the span.
/// </summary>
private string _cachedText;
/// <summary>
/// The span of the original submission of this text.
/// </summary>
private SnapshotSpan? _originalSpan;
public bool Command { get; set; }
public bool Failed { get; set; }
public SnapshotSpan? OriginalSpan { get { return _originalSpan; } }
public string Text
{
get
{
if (_cachedText != null)
{
return _cachedText;
}
return _originalSpan.Value.GetText();
}
}
internal void ForgetOriginalBuffer()
{
if (_originalSpan.HasValue)
{
_cachedText = _originalSpan.Value.GetText();
_originalSpan = null;
}
}
public Entry(SnapshotSpan span)
{
_originalSpan = span;
}
}
private readonly List<Entry> _history;
private readonly int _maxLength;
private int _current;
private bool _live;
internal string UncommittedInput { get; set; }
internal History()
: this(maxLength: 50)
{
}
internal History(int maxLength)
{
_maxLength = maxLength;
_current = -1;
_history = new List<Entry>();
}
internal void Clear()
{
_current = -1;
_live = false;
_history.Clear();
}
internal void ForgetOriginalBuffers()
{
foreach (var entry in _history)
{
entry.ForgetOriginalBuffer();
}
}
internal int MaxLength
{
get { return _maxLength; }
}
internal int Length
{
get { return _history.Count; }
}
internal IEnumerable<Entry> Items
{
get { return _history; }
}
internal Entry Last
{
get
{
if (_history.Count > 0)
{
return _history[_history.Count - 1];
}
else
{
return null;
}
}
}
internal void Add(SnapshotSpan span)
{
var entry = new Entry(span);
var text = span.GetText();
_live = false;
if (Length == 0 || Last.Text != text)
{
_history.Add(entry);
}
//If text at current location in history is not the same as the text you are adding then
//new command was typed and submitted while navigating history. In this case the _current
//gets reset.
if (_history[(_current == -1) ? Length - 1 : _current].Text != text)
{
_current = -1;
}
if (Length > MaxLength)
{
_history.RemoveAt(0);
if (_current > 0)
{
_current--;
}
}
}
internal Entry GetNext(string pattern)
{
var next = MoveNext(pattern);
if (next == null)
{
// if we hit the end of history list, reset _current to stop navigating history.
_current = -1;
}
return next;
}
internal Entry GetPrevious(string pattern)
{
var startPos = _current;
Entry next;
next = MovePrevious(pattern);
if (next == null)
{
_current = startPos;
return null;
}
return next;
}
private Entry MoveNext(string pattern)
{
if (Length == 0) return null;
bool wasCurrentUninitialized = (_current == -1);
// if current in un-initialized then we are not navigating history yet so
// there is no next entry.
if (wasCurrentUninitialized) return null;
//indicates that history search/navigation is in progress
_live = true;
_current++;
for (; _current < Length; _current++)
{
Entry entry;
if (TryMatch(pattern, out entry)) return entry;
}
return null;
}
private Entry MovePrevious(string pattern)
{
if (Length == 0) return null;
bool wasLive = _live;
//indicates that history search/navigation is in progress
_live = true;
bool wasCurrentUninitialized = (_current == -1);
// if current in un-initialized then we are not navigating history yet so
// current needs to be set to last entry before navigating previous.
if (wasCurrentUninitialized)
{
_current = Length - 1;
Entry entry;
if (TryMatch(pattern, out entry)) return entry;
}
bool patternEmpty = string.IsNullOrWhiteSpace(pattern);
if (!wasLive && patternEmpty)
{
//return the current entry again ( handles case up, up, enter, up)
Entry entry;
if (TryMatch(pattern, out entry)) return entry;
}
for (_current--; _current >= 0; _current--)
{
Entry entry;
if (TryMatch(pattern, out entry)) return entry;
}
return null;
}
private bool TryMatch(string pattern, out Entry entry)
{
bool patternEmpty = string.IsNullOrWhiteSpace(pattern);
var tmpEntry = _history[_current];
if (patternEmpty || Matches(tmpEntry.Text, pattern))
{
entry = tmpEntry;
return true;
}
else
{
entry = null;
return false;
}
}
private static bool Matches(string entry, string pattern)
{
return entry.Contains(pattern);
}
}
}
// Copyright (c) Microsoft. 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.Threading.Tasks;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Editor;
using Microsoft.VisualStudio.Utilities;
namespace Microsoft.VisualStudio.InteractiveWindow
{
/// <summary>
/// Implements an evaluator for a specific REPL implementation. The evaluator is provided to the
/// REPL implementation by the IInteractiveEngineProvider interface.
/// </summary>
public interface IInteractiveEvaluator : IDisposable
{
/// <summary>
/// Gets or sets Interactive Window the engine is currently attached to.
/// </summary>
IInteractiveWindow CurrentWindow { get; set; }
/// <summary>
/// Initializes the interactive session.
/// </summary>
/// <returns>Task that completes the initialization.</returns>
Task<ExecutionResult> InitializeAsync();
/// <summary>
/// Re-starts the interpreter. Usually this closes the current process (if alive) and starts
/// a new interpreter.
/// </summary>
/// <returns>Task that completes reset and initialization of the new process.</returns>
Task<ExecutionResult> ResetAsync(bool initialize = true);
// Parsing and Execution
/// <summary>
/// Returns true if the text can be executed. Used to determine if there is a whole statement entered
/// in the REPL window.
/// </summary>
bool CanExecuteCode(string text);
/// <summary>
/// Asynchronously executes the specified text.
/// </summary>
/// <param name="text">The code snippet to execute.</param>
/// <returns>Task that completes the execution.</returns>
Task<ExecutionResult> ExecuteCodeAsync(string text);
/// <summary>
/// Formats the contents of the clipboard in a manner reasonable for the language. Returns null if the
/// current clipboard cannot be formatted.
///
/// </summary>
/// <remarks>
/// By default if the clipboard contains text it will be pasted. The language can format
/// additional forms here - for example CSV data can be formatted in a language compatible
/// manner.
/// </remarks>
string FormatClipboard();
/// <summary>
/// Aborts the current running command.
/// </summary>
void AbortExecution();
/// <summary>
/// Retrieves the prompt string.
/// </summary>
/// <returns>The prompt string.</returns>
string GetPrompt();
}
}
// Copyright (c) Microsoft. 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.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using System.Windows;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Editor;
using Microsoft.VisualStudio.Text.Operations;
using Microsoft.VisualStudio.Utilities;
namespace Microsoft.VisualStudio.InteractiveWindow
{
/// <summary>
/// An implementation of a Read Eval Print Loop Window for iteratively developing code.
///
/// Instances of the repl window can be created by using MEF to import the IInteractiveWindowProvider interface.
/// </summary>
public interface IInteractiveWindow : IDisposable, IPropertyOwner
{
/// <summary>
/// Gets the text view which the interactive window is running and writing output to.
/// </summary>
IWpfTextView TextView
{
get;
}
/// <summary>
/// Gets the current language buffer.
/// </summary>
ITextBuffer CurrentLanguageBuffer
{
get;
}
/// <summary>
/// Gets the output editor buffer.
/// </summary>
ITextBuffer OutputBuffer
{
get;
}
/// <summary>
/// The language evaluator used in Repl Window
/// </summary>
IInteractiveEvaluator Evaluator
{
get;
}
/// <summary>
/// Initializes the execution environment and shows the initial prompt.
/// </summary>
/// <returns>Returns a started task that finishes as soon as the initialization completes.</returns>
Task<ExecutionResult> InitializeAsync();
/// <summary>
/// Closes the underlying text view.
/// </summary>
void Close();
/// <summary>
/// Insert the specified text to the active code buffer at the current caret position.
/// </summary>
/// <param name="text">Text to insert.</param>
/// <remarks>
/// Overwrites the current selection.
///
/// If the REPL is in the middle of code execution the text is inserted at the end of a pending input buffer.
/// When the REPL is ready for input the pending input is inserted into the active code input.
/// </remarks>
void InsertCode(string text);
/// <summary>
/// Submits a sequence of inputs one by one.
/// </summary>
/// <param name="inputs">
/// Code snippets or REPL commands to submit.
/// </param>
/// <remarks>
/// Enqueues given code snippets for submission at the earliest time the REPL is prepared to
/// accept submissions. Any submissions are postponed until execution of the current
/// submission (if there is any) is finished or aborted.
///
/// The REPL processes the given inputs one by one creating a prompt, input span and possibly output span for each input.
/// This method may be reentered if any of the inputs evaluates to a command that invokes this method.
/// </remarks>
Task SubmitAsync(IEnumerable<string> inputs);
/// <summary>
/// Output writer.
///
/// REVIEW: Remove, other people can wrap Write APIS
/// </summary>
TextWriter OutputWriter
{
get;
}
/// <summary>
/// Error output writer.
///
/// REVIEW: Remove, other people can wrap Write APIS
/// </summary>
TextWriter ErrorOutputWriter
{
get;
}
/// <summary>
/// Writes string followed by a line break into the output buffer.
/// </summary>
/// <param name="text">Text to write. Might be null.</param>
/// <returns>
/// The offset in the output subject buffer where the text is inserted and the length of the inserted text including the line break.
/// </returns>
/// <remarks>
/// Note that the text might not be written to the editor buffer immediately but be buffered.
/// The returned offsets might thus be beyond the current length of the editor buffer.
/// </remarks>
Span WriteLine(string text);
/// <summary>
/// Writes a line into the output buffer.
/// </summary>
/// <param name="text">Text to write. Might be null.</param>
/// <returns>
/// The offset in the output subject buffer where the text is inserted.
/// </returns>
/// <remarks>
/// Note that the text might not be written to the editor buffer immediately but be buffered.
/// The returned offset might thus be beyond the current length of the editor buffer.
/// </remarks>
Span Write(string text);
/// <summary>
/// Writes string followed by a line break into the error buffer.
/// </summary>
/// <param name="text">Text to write. Might be null.</param>
/// <returns>
/// The offset in the output subject buffer where the text is inserted and the length of the inserted text including the line break.
/// </returns>
/// <remarks>
/// Note that the text might not be written to the editor buffer immediately but be buffered.
/// The returned offsets might thus be beyond the current length of the editor buffer.
/// </remarks>
Span WriteErrorLine(string text);
/// <summary>
/// Writes a line into the error buffer.
/// </summary>
/// <param name="text">Text to write. Might be null.</param>
/// <returns>
/// The offset in the output subject buffer where the text is inserted.
/// </returns>
/// <remarks>
/// Note that the text might not be written to the editor buffer immediately but be buffered.
/// The returned offset might thus be beyond the current length of the editor buffer.
/// </remarks>
Span WriteError(string text);
/// <summary>
/// Writes a UI object to the REPL window.
/// </summary>
/// <remarks>
/// Flushes all text previously written to the output buffer before the element is inserted.
/// </remarks>
void Write(UIElement element);
void FlushOutput();
/// <summary>
/// Reads input from the REPL window.
/// </summary>
/// <returns>The entered input or null if cancelled.</returns>
TextReader ReadStandardInput();
/// <summary>
/// Event triggered when the REPL is ready to accept input.
/// </summary>
/// <remarks>
/// Called on the UI thread.
/// </remarks>
event Action ReadyForInput;
event EventHandler<SubmissionBufferAddedEventArgs> SubmissionBufferAdded;
/// <summary>
/// True if there is currently an input being executed.
/// </summary>
///
/// <remarks>
/// This value can only be reliably queried on the UI thread, otherwise the value
/// is transient.
/// </remarks>
bool IsRunning
{
get;
}
/// <summary>
/// True if the interactive evaluator is currently resetting.
/// </summary>
///
/// <remarks>
/// This value can only be reliably queried on the UI thread, otherwise the value
/// is transient.
/// </remarks>
bool IsResetting
{
get;
}
/// <summary>
/// True if the interactive evaluator is currently resetting.
/// </summary>
///
/// <remarks>
/// This value can only be reliably queried on the UI thread, otherwise the value
/// is transient.
/// </remarks>
bool IsInitializing
{
get;
}
/// <summary>
/// Appends a input into the editor buffer and history as if it has been executed.
///
/// The input is not executed.
/// </summary>
void AddInput(string input);
IInteractiveWindowOperations Operations
{
get;
}
}
}
// Copyright (c) Microsoft. 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.VisualStudio.InteractiveWindow
{
public interface IInteractiveWindow2 : IInteractiveWindow
{
/// <summary>
/// Adds <paramref name="input"/> to the history as if it has been executed.
/// Method doesn't execute <paramref name="input"/> and doesn't affect current user input.
/// </summary>
/// <exception cref="InvalidOperationException">The interactive window has not been initialized or is resettings.</exception>
void AddToHistory(string input);
}
}
\ No newline at end of file
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Editor;
using Microsoft.VisualStudio.Text.Projection;
using Microsoft.VisualStudio.Utilities;
namespace Microsoft.VisualStudio.InteractiveWindow
{
/// <summary>
/// Implements the service that creates text views and buffers for the interactive window.
///
/// There is a single implementation of this service for each MEF composition catalog. The
/// service understands how the editors and buffers need to be created and sets them up
/// so that commands are properly routed to the editor window.
///
/// This service is imported by <see cref="Microsoft.VisualStudio.InteractiveWindow.IInteractiveWindowFactoryService"/>
/// to use in the creation of <see cref="Microsoft.VisualStudio.InteractiveWindow.IInteractiveWindow"/>s.
/// </summary>
public interface IInteractiveWindowEditorFactoryService
{
/// <summary>
/// Creates a new text view for an interactive window.
/// </summary>
/// <param name="window">The interactive window the text view is being created for.</param>
/// <param name="buffer">The projection buffer used for displaying the interactive window</param>
/// <param name="roles">The requested text view roles.</param>
IWpfTextView CreateTextView(IInteractiveWindow window, ITextBuffer buffer, ITextViewRoleSet roles);
/// <summary>
/// Creates a new input buffer for the interactive window.
/// </summary>
ITextBuffer CreateAndActivateBuffer(IInteractiveWindow window);
}
}
// Copyright (c) Microsoft. 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.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Microsoft.VisualStudio.InteractiveWindow
{
/// <summary>
/// Creates instances of the IInteractiveWindow.
/// </summary>
public interface IInteractiveWindowFactoryService
{
/// <summary>
/// Creates a new interactive window which runs against the provided interactive evaluator.
/// </summary>
IInteractiveWindow CreateWindow(IInteractiveEvaluator evaluator);
}
}
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Threading.Tasks;
namespace Microsoft.VisualStudio.InteractiveWindow
{
/// <summary>
/// Provides access to low level editor operations on the REPL window.
/// </summary>
public interface IInteractiveWindowOperations
{
/// <summary>
/// Deletes the current selection or the character before the caret.
/// </summary>
/// <returns></returns>
bool Backspace();
/// <summary>
/// Attempts to insert a line break. Returns true if a line break is inserted, false if not.
///
/// Will not submit the input.
/// </summary>
bool BreakLine();
/// <summary>
/// Clears the input history.
/// </summary>
void ClearHistory();
/// <summary>
/// Clears the REPL window screen.
/// </summary>
void ClearView();
/// <summary>
/// Advances to the next item in history.
/// </summary>
void HistoryNext(string search = null);
/// <summary>
/// Advanced to the previous item in history.
/// </summary>
void HistoryPrevious(string search = null);
/// <summary>
/// If no search has been performed captures the current input as
/// the search string. Then searches through history for the next
/// match against the current search string.
/// </summary>
void HistorySearchNext();
/// <summary>
/// If no search has been performed captures the current input as
/// the search string. Then searches through history for the previous
/// match against the current search string.
/// </summary>
void HistorySearchPrevious();
/// <summary>
/// Moves to the beginning of the line.
///
/// When in a language buffer the caret is moved to the beginning of the
/// input region not into the prompt region.
///
/// The caret is moved to the first non-whitespace character.
/// </summary>
/// <param name="extendSelection">True to extend the selection from the current caret position.</param>
void Home(bool extendSelection);
/// <summary>
/// Moves to the end of the line.
/// </summary>
/// <param name="extendSelection">True to extend the selection from the current caret position.</param>
void End(bool extendSelection);
/// <summary>
/// Selects all of the text in the buffer
/// </summary>
void SelectAll();
/// <summary>
/// Pastes the current clipboard contents into the interactive window.
/// </summary>
/// <returns></returns>
bool Paste();
/// <summary>
/// Cuts the current selection to the clipboard.
/// </summary>
void Cut();
/// <summary>
/// Deletes the current selection.
///
/// Returns true if the selection was deleted
/// </summary>
bool Delete();
/// <summary>
/// Handles the user pressing return/enter.
///
/// If the caret is at the end of an input submits the current input. Otherwise if the caret is
/// in a language buffer it inserts a newline.
///
/// If not inside of a buffer the caret well be moved to the current language buffer if possible.
///
/// Returns true if the return was successfully processed.
/// </summary>
bool Return();
/// <summary>
/// If the current input is a standard input this will submit the input.
///
/// Returns true if the input was submitted, false otherwise.
/// </summary>
bool TrySubmitStandardInput();
/// <summary>
/// Resets the execution context clearing all variables.
/// </summary>
Task<ExecutionResult> ResetAsync(bool initialize = true);
/// <summary>
/// Executes the current input regardless of the caret position within the input.
///
/// If the caret is in a previously executed input then the input is pasted to the
/// end of the current input and not executed.
/// </summary>
void ExecuteInput();
/// <summary>
/// Clears the current input.
/// </summary>
void Cancel();
}
}
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Microsoft.VisualStudio.InteractiveWindow
{
public interface IInteractiveWindowOperations2 : IInteractiveWindowOperations
{
/// <summary>
/// Copies the current selection to the clipboard.
/// </summary>
void Copy();
/// <summary>
/// Copies code from user inputs to clipboard.
/// If selection is empty, then copy from current line, otherwise copy from selected lines.
/// </summary>
void CopyCode();
/// <summary>
/// Delete Line; Delete all selected lines, or the current line if no selection.
/// </summary>
void DeleteLine();
/// <summary>
/// Line Cut; Cut all selected lines, or the current line if no selection, to the clipboard.
/// </summary>
void CutLine();
/// <summary>
/// Handles character typed in by user.
/// </summary>
void TypeChar(char typedChar);
}
}
// Copyright (c) Microsoft. 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.IO;
using System.Text;
namespace Microsoft.VisualStudio.InteractiveWindow
{
/// <summary>
/// Implements deserialization for clipboard objects created by Interactive Window Copy operations.
/// </summary>
public static class InteractiveClipboardFormat
{
/// <summary>
/// Unique identifier for the clipboard format.
/// </summary>
public const string Tag = "89344A36-9821-495A-8255-99A63969F87D";
/// <summary>
/// Deserializes clipboard object.
/// </summary>
/// <param name="value">Object retrieved fromt the clipboard </param>
/// <exception cref="InvalidDataException">The value is not of the expected format.</exception>
public static string Deserialize(object value)
{
if (value == null)
{
throw new ArgumentNullException(nameof(value));
}
var text = value as string;
if (text == null)
{
throw new InvalidDataException();
}
var blocks = BufferBlock.Deserialize(text);
var result = new StringBuilder();
foreach (var block in blocks)
{
switch (block.Kind)
{
// the actual linebreak was converted to regular Input when copied
// This LineBreak block was created by coping box selection and is used as line separator when pasted
case ReplSpanKind.LineBreak:
result.Append(block.Content);
break;
case ReplSpanKind.Input:
case ReplSpanKind.Output:
case ReplSpanKind.StandardInput:
result.Append(block.Content);
break;
}
}
return result.ToString();
}
}
}
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.ComponentModel.Composition;
using Microsoft.VisualStudio.Utilities;
#pragma warning disable CS0649 // field is not assigned to
namespace Microsoft.VisualStudio.InteractiveWindow
{
internal static class InteractiveContentTypeDefinitions
{
[Export, Name(PredefinedInteractiveContentTypes.InteractiveContentTypeName), BaseDefinition("text"), BaseDefinition("projection")]
internal static readonly ContentTypeDefinition InteractiveContentTypeDefinition;
[Export, Name(PredefinedInteractiveContentTypes.InteractiveOutputContentTypeName), BaseDefinition("text")]
internal static readonly ContentTypeDefinition InteractiveOutputContentTypeDefinition;
}
}
\ No newline at end of file
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Projection;
namespace Microsoft.VisualStudio.InteractiveWindow
{
internal partial class InteractiveWindow
{
private sealed class EditResolver : IProjectionEditResolver
{
private readonly InteractiveWindow _window;
public EditResolver(InteractiveWindow window)
{
_window = window;
}
// We always favor the last buffer of our language type. This handles cases where we're on a boundary between a prompt and a language
// buffer - we favor the language buffer because the prompts cannot be edited. In the case of two language buffers this also works because
// our spans are laid out like:
// <lang span 1 including newline>
// <prompt span><lang span 2>
//
// In the case where the prompts are in the margin we have an insertion conflict between the two language spans. But because
// lang span 1 includes the new line in order to be on the boundary we need to be on lang span 2's line.
//
// This works the same way w/ our input buffer where the input buffer present instead of <lang span 2>.
void IProjectionEditResolver.FillInInsertionSizes(SnapshotPoint projectionInsertionPoint, ReadOnlyCollection<SnapshotPoint> sourceInsertionPoints, string insertionText, IList<int> insertionSizes)
{
int index = _window.UIThread(uiOnly => IndexOfEditableBuffer(sourceInsertionPoints, uiOnly));
if (index != -1)
{
insertionSizes[index] = insertionText.Length;
}
}
int IProjectionEditResolver.GetTypicalInsertionPosition(SnapshotPoint projectionInsertionPoint, ReadOnlyCollection<SnapshotPoint> sourceInsertionPoints)
{
int index = _window.UIThread(uiOnly => IndexOfEditableBuffer(sourceInsertionPoints, uiOnly));
return index != -1 ? index : 0;
}
void IProjectionEditResolver.FillInReplacementSizes(SnapshotSpan projectionReplacementSpan, ReadOnlyCollection<SnapshotSpan> sourceReplacementSpans, string insertionText, IList<int> insertionSizes)
{
int index = _window.UIThread(uiOnly => IndexOfEditableBuffer(sourceReplacementSpans, uiOnly));
if (index != -1)
{
insertionSizes[index] = insertionText.Length;
}
}
private int IndexOfEditableBuffer(ReadOnlyCollection<SnapshotPoint> points, UIThreadOnly uiOnly)
{
Debug.Assert(_window.OnUIThread());
for (int i = points.Count - 1; i >= 0; i--)
{
if (IsEditableBuffer(points[i].Snapshot.TextBuffer, uiOnly))
{
return i;
}
}
return -1;
}
private int IndexOfEditableBuffer(ReadOnlyCollection<SnapshotSpan> spans, UIThreadOnly uiOnly)
{
Debug.Assert(_window.OnUIThread());
for (int i = spans.Count - 1; i >= 0; i--)
{
if (IsEditableBuffer(spans[i].Snapshot.TextBuffer, uiOnly))
{
return i;
}
}
return -1;
}
private bool IsEditableBuffer(ITextBuffer buffer, UIThreadOnly uiOnly)
{
return buffer == uiOnly.CurrentLanguageBuffer || buffer == uiOnly.StandardInputBuffer;
}
}
}
}
\ No newline at end of file
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Threading.Tasks;
namespace Microsoft.VisualStudio.InteractiveWindow
{
internal partial class InteractiveWindow
{
private class PendingSubmission
{
public readonly string Input;
/// <remarks>
/// Set only on the last submission in each batch (to notify the caller).
/// </remarks>
public readonly TaskCompletionSource<object> Completion;
public Task Task;
public PendingSubmission(string input, TaskCompletionSource<object> completion)
{
Input = input;
Completion = completion;
}
}
}
}
\ No newline at end of file
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Runtime.Serialization;
namespace Microsoft.VisualStudio.InteractiveWindow
{
[DataContract]
internal enum ReplSpanKind
{
/// <summary>
/// Primary, secondary, or standard input prompt.
/// </summary>
[EnumMember]
Prompt = 0,
/// <summary>
/// The span represents output from the program (standard output).
/// </summary>
[EnumMember]
Output = 1,
/// <summary>
/// The span represents code inputted after a prompt or secondary prompt.
/// </summary>
[EnumMember]
Input = 2,
/// <summary>
/// The span represents the input for a standard input (non code input).
/// </summary>
[EnumMember]
StandardInput = 3,
/// <summary>
/// Line break inserted at end of output.
/// </summary>
[EnumMember]
LineBreak = 4,
}
}
\ No newline at end of file
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Microsoft.VisualStudio.InteractiveWindow
{
internal partial class InteractiveWindow
{
private struct SpanRangeEdit
{
public readonly int Start;
public readonly int End;
public readonly object[] Replacement;
public SpanRangeEdit(int start, int count, object[] replacement)
{
Start = start;
End = start + count;
Replacement = replacement;
}
}
}
}
\ No newline at end of file
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Microsoft.VisualStudio.InteractiveWindow
{
internal partial class InteractiveWindow
{
internal enum State
{
/// <summary>
/// Initial state. <see cref="IInteractiveWindow.InitializeAsync"/> hasn't been called.
/// Transition to <see cref="Initializing"/> when <see cref="IInteractiveWindow.InitializeAsync"/> is called.
/// Transition to <see cref="Resetting"/> when <see cref="IInteractiveWindowOperations.ResetAsync"/> is called.
/// </summary>
Starting,
/// <summary>
/// In the process of calling <see cref="IInteractiveWindow.InitializeAsync"/>.
/// Transition to <see cref="WaitingForInput"/> when finished (in <see cref="UIThreadOnly.ProcessPendingSubmissions"/>).
/// Transition to <see cref="Resetting"/> when <see cref="IInteractiveWindowOperations.ResetAsync"/> is called.
/// </summary>
Initializing,
/// <summary>
/// In the process of calling <see cref="IInteractiveWindowOperations.ResetAsync"/>.
/// Transition to <see cref="WaitingForInput"/> when finished (in <see cref="UIThreadOnly.ProcessPendingSubmissions"/>).
/// Transition to <see cref="ResettingAndReadingStandardInput"/> when <see cref="IInteractiveWindow.ReadStandardInput"/> is called
/// </summary>
Resetting,
/// <summary>
/// Prompt has been displayed - waiting for the user to make the next submission.
/// Transition to <see cref="ExecutingInput"/> when <see cref="IInteractiveWindowOperations.ExecuteInput"/> is called.
/// Transition to <see cref="Resetting"/> when <see cref="IInteractiveWindowOperations.ResetAsync"/> is called.
/// Transition to <see cref="WaitingForInputAndReadingStandardInput"/> when <see cref="IInteractiveWindow.ReadStandardInput"/> is called
/// </summary>
WaitingForInput,
/// <summary>
/// Executing the user's submission.
/// Transition to <see cref="WaitingForInput"/> when finished (in <see cref="UIThreadOnly.ProcessPendingSubmissions"/>).
/// Transition to <see cref="Resetting"/> when <see cref="IInteractiveWindowOperations.ResetAsync"/> is called.
/// Transition to <see cref="ExecutingInputAndReadingStandardInput"/> when <see cref="IInteractiveWindow.ReadStandardInput"/> is called
/// </summary>
ExecutingInput,
/// <summary>
/// In the process of calling <see cref="IInteractiveWindow.ReadStandardInput"/> (within <see cref="IInteractiveWindowOperations.ResetAsync"/>).
/// Transition to <see cref="Resetting"/> when <see cref="IInteractiveWindowOperations.ClearView"/>,
/// <see cref="IInteractiveWindowOperations.TrySubmitStandardInput"/>, or
/// <see cref="IInteractiveWindowOperations.ResetAsync"/> is called.
/// </summary>
ResettingAndReadingStandardInput,
/// <summary>
/// In the process of calling <see cref="IInteractiveWindow.ReadStandardInput"/> (while prompt has been displayed).
/// Transition to <see cref="WaitingForInput"/> when <see cref="IInteractiveWindowOperations.ClearView"/> or <see cref="IInteractiveWindowOperations.TrySubmitStandardInput"/> is called.
/// Transition to <see cref="Resetting"/> when <see cref="IInteractiveWindowOperations.ResetAsync"/> is called.
/// </summary>
WaitingForInputAndReadingStandardInput,
/// <summary>
/// In the process of calling <see cref="IInteractiveWindow.ReadStandardInput"/> (while executing the user's submission).
/// Transition to <see cref="ExecutingInput"/> when <see cref="IInteractiveWindowOperations.ClearView"/> or <see cref="IInteractiveWindowOperations.TrySubmitStandardInput"/> is called.
/// Transition to <see cref="Resetting"/> when <see cref="IInteractiveWindowOperations.ResetAsync"/> is called.
/// </summary>
ExecutingInputAndReadingStandardInput,
}
}
}
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Windows;
namespace Microsoft.VisualStudio.InteractiveWindow
{
internal partial class InteractiveWindow
{
private sealed class SystemClipboard : InteractiveWindowClipboard
{
internal override bool ContainsData(string format) => Clipboard.ContainsData(format);
internal override object GetData(string format) => Clipboard.GetData(format);
internal override bool ContainsText() => Clipboard.ContainsText();
internal override string GetText() => Clipboard.GetText();
internal override void SetDataObject(object data, bool copy) => Clipboard.SetDataObject(data, copy);
internal override IDataObject GetDataObject() => Clipboard.GetDataObject();
}
}
}
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
// Dumps commands in QueryStatus and Exec.
// #define DUMP_COMMANDS
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Threading;
using Microsoft.VisualStudio.Language.Intellisense;
using Microsoft.VisualStudio.Language.Intellisense.Utilities;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Editor;
using Microsoft.VisualStudio.Text.Formatting;
using Microsoft.VisualStudio.Text.Operations;
using Microsoft.VisualStudio.Text.Projection;
using Microsoft.VisualStudio.Utilities;
namespace Microsoft.VisualStudio.InteractiveWindow
{
// TODO: We should condense committed language buffers into a single language buffer and save the
// classifications from the previous language buffer if the perf of having individual buffers
// starts having problems w/ a large number of inputs.
/// <summary>
/// Provides implementation of a Repl Window built on top of the VS editor using projection buffers.
/// </summary>
internal partial class InteractiveWindow : IInteractiveWindow2, IInteractiveWindowOperations2
{
// The following two field definitions have to stay in sync with VS editor implementation
/// <summary>
/// A data format used to tag the contents of the clipboard so that it's clear
/// the data has been put in the clipboard by our editor
/// </summary>
internal const string ClipboardLineBasedCutCopyTag = "VisualStudioEditorOperationsLineCutCopyClipboardTag";
/// <summary>
/// A data format used to tag the contents of the clipboard as a box selection.
/// This is the same string that was used in VS9 and previous versions.
/// </summary>
internal const string BoxSelectionCutCopyTag = "MSDEVColumnSelect";
public event EventHandler<SubmissionBufferAddedEventArgs> SubmissionBufferAdded;
PropertyCollection IPropertyOwner.Properties { get; } = new PropertyCollection();
private readonly SemaphoreSlim _inputReaderSemaphore = new SemaphoreSlim(initialCount: 1, maxCount: 1);
/// <remarks>
/// WARNING: Members of this object should only be accessed from the UI thread.
/// </remarks>
private readonly UIThreadOnly _uiOnly;
// Setter for InteractiveWindowClipboard is a test hook.
internal InteractiveWindowClipboard InteractiveWindowClipboard { get; set; } = new SystemClipboard();
#region Initialization
public InteractiveWindow(
IInteractiveWindowEditorFactoryService host,
IContentTypeRegistryService contentTypeRegistry,
ITextBufferFactoryService bufferFactory,
IProjectionBufferFactoryService projectionBufferFactory,
IEditorOperationsFactoryService editorOperationsFactory,
ITextBufferUndoManagerProvider textBufferUndoManagerProvider,
ITextEditorFactoryService editorFactory,
IRtfBuilderService rtfBuilderService,
IIntellisenseSessionStackMapService intellisenseSessionStackMap,
ISmartIndentationService smartIndenterService,
IInteractiveEvaluator evaluator,
IWaitIndicator waitIndicator)
{
if (evaluator == null)
{
throw new ArgumentNullException(nameof(evaluator));
}
_uiOnly = new UIThreadOnly(
this,
host,
contentTypeRegistry,
bufferFactory,
projectionBufferFactory,
editorOperationsFactory,
textBufferUndoManagerProvider,
editorFactory,
rtfBuilderService,
intellisenseSessionStackMap,
smartIndenterService,
evaluator,
waitIndicator);
evaluator.CurrentWindow = this;
RequiresUIThread();
}
async Task<ExecutionResult> IInteractiveWindow.InitializeAsync()
{
try
{
RequiresUIThread();
var uiOnly = _uiOnly; // Verified above.
if (uiOnly.State != State.Starting)
{
throw new InvalidOperationException(InteractiveWindowResources.AlreadyInitialized);
}
uiOnly.State = State.Initializing;
// Anything that reads options should wait until after this call so the evaluator can set the options first
ExecutionResult result = await uiOnly.Evaluator.InitializeAsync().ConfigureAwait(continueOnCapturedContext: true);
Debug.Assert(OnUIThread()); // ConfigureAwait should bring us back to the UI thread.
if (result.IsSuccessful)
{
uiOnly.PrepareForInput();
}
return result;
}
catch (Exception e) when (ReportAndPropagateException(e))
{
throw ExceptionUtilities.Unreachable;
}
}
private bool ReportAndPropagateException(Exception e)
{
FatalError.ReportWithoutCrashUnlessCanceled(e); // Drop return value.
((IInteractiveWindow)this).WriteErrorLine(InteractiveWindowResources.InternalError);
return false; // Never consider the exception handled.
}
#endregion
void IInteractiveWindow.Close()
{
UIThread(uiOnly => uiOnly.Close());
}
#region Misc Helpers
/// <remarks>
/// The caller is responsible for using the buffer in a thread-safe manner.
/// </remarks>
public ITextBuffer CurrentLanguageBuffer => _uiOnly.CurrentLanguageBuffer;
void IDisposable.Dispose()
{
UIThread(uiOnly => ((IDisposable)uiOnly).Dispose());
}
public static InteractiveWindow FromBuffer(ITextBuffer buffer)
{
object result;
buffer.Properties.TryGetProperty(typeof(InteractiveWindow), out result);
return result as InteractiveWindow;
}
#endregion
#region IInteractiveWindow
public event Action ReadyForInput;
/// <remarks>
/// The caller is responsible for using the text view in a thread-safe manner.
/// </remarks>
IWpfTextView IInteractiveWindow.TextView => _uiOnly.TextView;
/// <remarks>
/// The caller is responsible for using the buffer in a thread-safe manner.
/// </remarks>
ITextBuffer IInteractiveWindow.OutputBuffer => _uiOnly.OutputBuffer;
/// <remarks>
/// The caller is responsible for using the writer in a thread-safe manner.
/// </remarks>
TextWriter IInteractiveWindow.OutputWriter => _uiOnly.OutputWriter;
/// <remarks>
/// The caller is responsible for using the writer in a thread-safe manner.
/// </remarks>
TextWriter IInteractiveWindow.ErrorOutputWriter => _uiOnly.ErrorOutputWriter;
/// <remarks>
/// The caller is responsible for using the evaluator in a thread-safe manner.
/// </remarks>
IInteractiveEvaluator IInteractiveWindow.Evaluator => _uiOnly.Evaluator;
/// <remarks>
/// Normally, an async method would have an NFW exception filter. This
/// one doesn't because it just calls other async methods that already
/// have filters.
/// </remarks>
async Task IInteractiveWindow.SubmitAsync(IEnumerable<string> inputs)
{
var completion = new TaskCompletionSource<object>();
var submissions = inputs.ToArray();
var numSubmissions = submissions.Length;
PendingSubmission[] pendingSubmissions = new PendingSubmission[numSubmissions];
if (numSubmissions == 0)
{
completion.SetResult(null);
}
else
{
for (int i = 0; i < numSubmissions; i++)
{
pendingSubmissions[i] = new PendingSubmission(submissions[i], i == numSubmissions - 1 ? completion : null);
}
}
UIThread(uiOnly => uiOnly.Submit(pendingSubmissions));
// This indicates that the last submission has completed.
await completion.Task.ConfigureAwait(false);
// These should all have finished already, but we'll await them so that their
// statuses are folded into the task we return.
await Task.WhenAll(pendingSubmissions.Select(p => p.Task)).ConfigureAwait(false);
}
void IInteractiveWindow.AddInput(string command)
{
UIThread(uiOnly => uiOnly.AddInput(command));
}
void IInteractiveWindow2.AddToHistory(string input)
{
UIThread(uiOnly => uiOnly.AddToHistory(input));
}
void IInteractiveWindow.FlushOutput()
{
UIThread(uiOnly => uiOnly.FlushOutput());
}
void IInteractiveWindow.InsertCode(string text)
{
UIThread(uiOnly => uiOnly.InsertCode(text));
}
#endregion
#region Commands
Task<ExecutionResult> IInteractiveWindowOperations.ResetAsync(bool initialize)
{
return UIThread(uiOnly => uiOnly.ResetAsync(initialize));
}
void IInteractiveWindowOperations.ClearHistory()
{
UIThread(uiOnly => uiOnly.ClearHistory());
}
void IInteractiveWindowOperations.ClearView()
{
UIThread(uiOnly => uiOnly.ClearView());
}
/// <summary>
/// Pastes from the clipboard into the text view
/// </summary>
bool IInteractiveWindowOperations.Paste()
{
return UIThread(uiOnly => uiOnly.Paste());
}
void IInteractiveWindowOperations.ExecuteInput()
{
UIThread(uiOnly => uiOnly.ExecuteInputAsync());
}
/// <remarks>
/// Test hook.
/// </remarks>
internal Task ExecuteInputAsync()
{
return UIThread(uiOnly => uiOnly.ExecuteInputAsync());
}
/// <summary>
/// Appends text to the output buffer and updates projection buffer to include it.
/// WARNING: this has to be the only method that writes to the output buffer so that
/// the output buffering counters are kept in sync.
/// </summary>
internal void AppendOutput(IEnumerable<string> output)
{
RequiresUIThread();
_uiOnly.AppendOutput(output); // Verified above.
}
/// <summary>
/// Clears the current input
/// </summary>
void IInteractiveWindowOperations.Cancel()
{
UIThread(uiOnly => uiOnly.Cancel());
}
void IInteractiveWindowOperations.HistoryPrevious(string search)
{
UIThread(uiOnly => uiOnly.HistoryPrevious(search));
}
void IInteractiveWindowOperations.HistoryNext(string search)
{
UIThread(uiOnly => uiOnly.HistoryNext(search));
}
void IInteractiveWindowOperations.HistorySearchNext()
{
UIThread(uiOnly => uiOnly.HistorySearchNext());
}
void IInteractiveWindowOperations.HistorySearchPrevious()
{
UIThread(uiOnly => uiOnly.HistorySearchPrevious());
}
/// <summary>
/// Moves to the beginning of the line.
/// </summary>
void IInteractiveWindowOperations.Home(bool extendSelection)
{
UIThread(uiOnly => uiOnly.Home(extendSelection));
}
/// <summary>
/// Moves to the end of the line.
/// </summary>
void IInteractiveWindowOperations.End(bool extendSelection)
{
UIThread(uiOnly => uiOnly.End(extendSelection));
}
void IInteractiveWindowOperations.SelectAll()
{
UIThread(uiOnly => uiOnly.SelectAll());
}
#endregion
#region Keyboard Commands
/// <remarks>Only consistent on the UI thread.</remarks>
bool IInteractiveWindow.IsRunning => _uiOnly.State != State.WaitingForInput;
/// <remarks>Only consistent on the UI thread.</remarks>
bool IInteractiveWindow.IsResetting => _uiOnly.State == State.Resetting || _uiOnly.State == State.ResettingAndReadingStandardInput;
/// <remarks>Only consistent on the UI thread.</remarks>
bool IInteractiveWindow.IsInitializing => _uiOnly.State == State.Starting || _uiOnly.State == State.Initializing;
IInteractiveWindowOperations IInteractiveWindow.Operations => this;
bool IInteractiveWindowOperations.Delete()
{
return UIThread(uiOnly => uiOnly.Delete());
}
void IInteractiveWindowOperations.Cut()
{
UIThread(uiOnly => uiOnly.Cut());
}
void IInteractiveWindowOperations2.Copy()
{
UIThread(uiOnly => uiOnly.Copy());
}
void IInteractiveWindowOperations2.CopyCode()
{
UIThread(uiOnly => uiOnly.CopyCode());
}
bool IInteractiveWindowOperations.Backspace()
{
return UIThread(uiOnly => uiOnly.Backspace());
}
bool IInteractiveWindowOperations.TrySubmitStandardInput()
{
return UIThread(uiOnly => uiOnly.TrySubmitStandardInput());
}
bool IInteractiveWindowOperations.BreakLine()
{
return UIThread(uiOnly => uiOnly.BreakLine());
}
bool IInteractiveWindowOperations.Return()
{
return UIThread(uiOnly => uiOnly.Return());
}
void IInteractiveWindowOperations2.DeleteLine()
{
UIThread(uiOnly => uiOnly.DeleteLine());
}
void IInteractiveWindowOperations2.CutLine()
{
UIThread(uiOnly => uiOnly.CutLine());
}
void IInteractiveWindowOperations2.TypeChar(char typedChar)
{
UIThread(uiOnly => uiOnly.TypeChar(typedChar));
}
#endregion
#region Command Debugging
#if DUMP_COMMANDS
private static void DumpCmd(string prefix, int result, ref Guid pguidCmdGroup, uint cmd, uint cmdf)
{
string cmdName;
if (pguidCmdGroup == VSConstants.GUID_VSStandardCommandSet97)
{
cmdName = ((VSConstants.VSStd97CmdID)cmd).ToString();
}
else if (pguidCmdGroup == VSConstants.VSStd2K)
{
cmdName = ((VSConstants.VSStd2KCmdID)cmd).ToString();
}
else if (pguidCmdGroup == VSConstants.VsStd2010)
{
cmdName = ((VSConstants.VSStd2010CmdID)cmd).ToString();
}
else if (pguidCmdGroup == GuidList.guidReplWindowCmdSet)
{
cmdName = ((ReplCommandId)cmd).ToString();
}
else
{
return;
}
Debug.WriteLine("{3}({0}) -> {1} {2}", cmdName, Enum.Format(typeof(OLECMDF), (OLECMDF)cmdf, "F"), result, prefix);
}
#endif
#endregion
#region Active Code and Standard Input
TextReader IInteractiveWindow.ReadStandardInput()
{
// shouldn't be called on the UI thread because we'll hang
RequiresNonUIThread();
return ReadStandardInputAsync().GetAwaiter().GetResult();
}
private async Task<TextReader> ReadStandardInputAsync()
{
try
{
// True because this is a public API and we want to use the same
// thread as the caller (esp for blocking).
await _inputReaderSemaphore.WaitAsync().ConfigureAwait(true); // Only one thread can read from standard input at a time.
try
{
return await UIThread(uiOnly => uiOnly.ReadStandardInputAsync()).ConfigureAwait(true);
}
finally
{
_inputReaderSemaphore.Release();
}
}
catch (Exception e) when (ReportAndPropagateException(e))
{
throw ExceptionUtilities.Unreachable;
}
}
#endregion
#region Output
Span IInteractiveWindow.Write(string text)
{
return UIThread(uiOnly => uiOnly.Write(text));
}
Span IInteractiveWindow.WriteLine(string text)
{
return UIThread(uiOnly => uiOnly.WriteLine(text));
}
Span IInteractiveWindow.WriteError(string text)
{
return UIThread(uiOnly => uiOnly.WriteError(text));
}
Span IInteractiveWindow.WriteErrorLine(string text)
{
return UIThread(uiOnly => uiOnly.WriteErrorLine(text));
}
void IInteractiveWindow.Write(UIElement element)
{
UIThread(uiOnly => uiOnly.Write(element));
}
#endregion
#region UI Dispatcher Helpers
private Dispatcher Dispatcher => ((FrameworkElement)_uiOnly.TextView).Dispatcher; // Always safe to access the dispatcher.
internal bool OnUIThread()
{
return Dispatcher.CheckAccess();
}
private T UIThread<T>(Func<UIThreadOnly, T> func)
{
if (!OnUIThread())
{
return (T)Dispatcher.Invoke(func, _uiOnly); // Safe because of dispatch.
}
return func(_uiOnly); // Safe because of check.
}
private void UIThread(Action<UIThreadOnly> action)
{
if (!OnUIThread())
{
Dispatcher.Invoke(action, _uiOnly); // Safe because of dispatch.
return;
}
action(_uiOnly); // Safe because of check.
}
private void RequiresUIThread()
{
if (!OnUIThread())
{
throw new InvalidOperationException(InteractiveWindowResources.RequireUIThread);
}
}
private void RequiresNonUIThread()
{
if (OnUIThread())
{
throw new InvalidOperationException(InteractiveWindowResources.RequireNonUIThread);
}
}
private static void DoEvents()
{
var frame = new DispatcherFrame();
Dispatcher.CurrentDispatcher.BeginInvoke(
DispatcherPriority.Background,
new Action<DispatcherFrame>(f => f.Continue = false),
frame);
Dispatcher.PushFrame(frame);
}
#endregion
#region Testing
internal event Action<State> StateChanged;
internal void Undo_TestOnly(int count)
{
UIThread(uiOnly => uiOnly.UndoHistory?.Undo(count));
}
internal void Redo_TestOnly(int count)
{
UIThread(uiOnly => uiOnly.UndoHistory?.Redo(count));
}
#endregion
}
}
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\..\..\build\Targets\VSL.Settings.targets" />
<PropertyGroup>
<ProjectGuid>{01E9BD68-0339-4A13-B42F-A3CA84D164F3}</ProjectGuid>
<OutputType>Library</OutputType>
<RootNamespace>Microsoft.VisualStudio.InteractiveWindow</RootNamespace>
<AssemblyName>Microsoft.VisualStudio.InteractiveWindow</AssemblyName>
<CopyNuGetImplementations>false</CopyNuGetImplementations>
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
</PropertyGroup>
<ItemGroup>
<InternalsVisibleToTest Include="Microsoft.VisualStudio.InteractiveWindow.UnitTests" />
</ItemGroup>
<ItemGroup>
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="System" />
<Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.Core" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Xaml" />
<Reference Include="System.XML" />
<Reference Include="WindowsBase" />
</ItemGroup>
<ItemGroup>
<Content Include="Resources\ReplToolBarImages.bmp" />
</ItemGroup>
<ItemGroup>
<Compile Include="BufferBlock.cs" />
<Compile Include="InteractiveClipboardFormat.cs" />
<Compile Include="Commands\CancelExecutionCommand.cs" />
<Compile Include="Commands\ClearScreenCommand.cs" />
<Compile Include="Commands\CommandClassifier.cs" />
<Compile Include="Commands\CommandClassifierProvider.cs" />
<Compile Include="Commands\PredefinedInteractiveCommandsContentTypes.cs" />
<Compile Include="Commands\InteractiveCommandsFactory.cs" />
<Compile Include="Commands\InteractiveWindowCommandExtensions.cs" />
<Compile Include="Commands\InteractiveWindowCommands.cs" />
<Compile Include="Commands\HelpCommand.cs" />
<Compile Include="Commands\IInteractiveWindowCommand.cs" />
<Compile Include="Commands\InteractiveWindowCommand.cs" />
<Compile Include="Commands\ResetCommand.cs" />
<Compile Include="CustomTrackingSpan.cs" />
<Compile Include="ExecutionResult.cs" />
<Compile Include="History.cs" />
<Compile Include="ContentTypeMetadata.cs" />
<Compile Include="Commands\IInteractiveWindowCommands.cs" />
<Compile Include="Commands\IInteractiveWindowCommandsFactory.cs" />
<Compile Include="IInteractiveEvaluator.cs" />
<Compile Include="IInteractiveWindow.cs" />
<Compile Include="IInteractiveWindow2.cs" />
<Compile Include="IInteractiveWindowEditorFactoryService.cs" />
<Compile Include="IInteractiveWindowFactoryService.cs" />
<Compile Include="IInteractiveWindowOperations.cs" />
<Compile Include="IInteractiveWindowOperations2.cs" />
<Compile Include="InteractiveContentTypeDefinitions.cs" />
<Compile Include="InteractiveWindowClipboard.cs" />
<Compile Include="InteractiveWindow.SpanRangeEdit.cs" />
<Compile Include="InteractiveWindow.SystemClipboard.cs" />
<Compile Include="InteractiveWindow.PendingSubmission.cs" />
<Compile Include="InteractiveWindow.ReplSpanKind.cs" />
<Compile Include="InteractiveWindow.EditResolver.cs" />
<Compile Include="InteractiveWindow.State.cs" />
<Compile Include="InteractiveWindow.UIThreadOnly.cs" />
<Compile Include="InteractiveWindow.cs" />
<Compile Include="InteractiveWindowExtensions.cs" />
<Compile Include="InteractiveWindowOptions.cs" />
<Compile Include="InteractiveWindowProvider.cs" />
<Compile Include="InteractiveWindowResources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>InteractiveWindowResources.resx</DependentUpon>
</Compile>
<Compile Include="InternalUtilities\ExceptionUtilities.cs" />
<Compile Include="InternalUtilities\FatalError.cs" />
<Compile Include="Output\InlineAdornmentProvider.cs" />
<Compile Include="Output\OutputBuffer.cs" />
<Compile Include="Output\OutputClassifierProvider.cs" />
<Compile Include="Output\OutputWriter.cs" />
<Compile Include="Output\ResizingAdorner.cs" />
<Compile Include="Output\SortedSpans.cs" />
<Compile Include="Output\ZoomableInlineAdornment.cs" />
<Compile Include="PredefinedInteractiveContentTypes.cs" />
<Compile Include="PredefinedInteractiveTextViewRoles.cs" />
<Compile Include="ProjectionBufferExtensions.cs" />
<Compile Include="SmartIndent\InteractiveSmartIndenter.cs" />
<Compile Include="SmartIndent\InteractiveSmartIndenterProvider.cs" />
<Compile Include="SmartUpDownOption.cs" />
<Compile Include="SubmissionBufferAddedEventArgs.cs" />
<Compile Include="TextTransactionMergePolicy.cs" />
<Compile Include="Utils\Contract.cs" />
<Compile Include="Utils\EditorExtensions.cs" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="InteractiveWindowResources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>InteractiveWindowResources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<None Include="project.json" />
<PublicAPI Include="PublicAPI.Unshipped.txt" />
<PublicAPI Include="PublicAPI.Shipped.txt" />
</ItemGroup>
<Import Project="..\..\..\build\Targets\VSL.Imports.targets" />
</Project>
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Windows;
namespace Microsoft.VisualStudio.InteractiveWindow
{
internal abstract class InteractiveWindowClipboard
{
internal abstract bool ContainsData(string format);
internal abstract object GetData(string format);
internal abstract bool ContainsText();
internal abstract string GetText();
internal abstract void SetDataObject(object data, bool copy);
internal abstract IDataObject GetDataObject();
}
}
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.VisualStudio.Text;
namespace Microsoft.VisualStudio.InteractiveWindow
{
public static class InteractiveWindowExtensions
{
/// <summary>
/// Gets the interactive window associated with the text buffer if the text
/// buffer is being hosted in the interactive window.
///
/// Returns null if the text buffer is not hosted in the interactive window.
/// </summary>
public static IInteractiveWindow GetInteractiveWindow(this ITextBuffer buffer)
{
return InteractiveWindow.FromBuffer(buffer);
}
}
}
// Copyright (c) Microsoft. 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.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.VisualStudio.Text.Editor;
namespace Microsoft.VisualStudio.InteractiveWindow
{
public static class InteractiveWindowOptions
{
private static readonly EditorOptionKey<bool> s_smartUpDown = new EditorOptionKey<bool>(SmartUpDownOption.OptionName);
/// <summary>
/// Indicates that the window should be using smart up/down behavior. When enabled pressing
/// the up or down arrow key will navigate history if the caret is at the end of the current
/// input. When disabled the up/down arrow keys will always navigate the buffer.
/// </summary>
public static EditorOptionKey<bool> SmartUpDown
{
get
{
return s_smartUpDown;
}
}
}
}
// Copyright (c) Microsoft. 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.ComponentModel.Composition;
using Microsoft.VisualStudio.Language.Intellisense;
using Microsoft.VisualStudio.Language.Intellisense.Utilities;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Editor;
using Microsoft.VisualStudio.Text.Formatting;
using Microsoft.VisualStudio.Text.Operations;
using Microsoft.VisualStudio.Text.Projection;
using Microsoft.VisualStudio.Utilities;
namespace Microsoft.VisualStudio.InteractiveWindow
{
[Export(typeof(IInteractiveWindowFactoryService))]
internal class InteractiveWindowProvider : IInteractiveWindowFactoryService
{
private readonly IContentTypeRegistryService _contentTypeRegistry;
private readonly ITextBufferFactoryService _bufferFactory;
private readonly IProjectionBufferFactoryService _projectionBufferFactory;
private readonly IEditorOperationsFactoryService _editorOperationsFactory;
private readonly ITextBufferUndoManagerProvider _textBufferUndoManagerProvider;
private readonly ITextEditorFactoryService _editorFactory;
private readonly IRtfBuilderService _rtfBuilderService;
private readonly IIntellisenseSessionStackMapService _intellisenseSessionStackMap;
private readonly ISmartIndentationService _smartIndenterService;
private readonly IInteractiveWindowEditorFactoryService _windowFactoryService;
private readonly IWaitIndicator _waitIndicator;
[ImportingConstructor]
public InteractiveWindowProvider(
IContentTypeRegistryService contentTypeRegistry,
ITextBufferFactoryService bufferFactory,
IProjectionBufferFactoryService projectionBufferFactory,
IEditorOperationsFactoryService editorOperationsFactory,
ITextBufferUndoManagerProvider textBufferUndoManagerProvider,
ITextEditorFactoryService editorFactory,
IRtfBuilderService rtfBuilderService,
IIntellisenseSessionStackMapService intellisenseSessionStackMap,
ISmartIndentationService smartIndenterService,
IInteractiveWindowEditorFactoryService windowFactoryService,
IWaitIndicator waitIndicator)
{
_contentTypeRegistry = contentTypeRegistry;
_bufferFactory = bufferFactory;
_projectionBufferFactory = projectionBufferFactory;
_editorOperationsFactory = editorOperationsFactory;
_textBufferUndoManagerProvider = textBufferUndoManagerProvider;
_editorFactory = editorFactory;
_rtfBuilderService = rtfBuilderService;
_intellisenseSessionStackMap = intellisenseSessionStackMap;
_smartIndenterService = smartIndenterService;
_windowFactoryService = windowFactoryService;
_waitIndicator = waitIndicator;
}
public IInteractiveWindow CreateWindow(IInteractiveEvaluator evaluator)
{
if (evaluator == null)
{
throw new ArgumentNullException(nameof(evaluator));
}
return new InteractiveWindow(
_windowFactoryService,
_contentTypeRegistry,
_bufferFactory,
_projectionBufferFactory,
_editorOperationsFactory,
_textBufferUndoManagerProvider,
_editorFactory,
_rtfBuilderService,
_intellisenseSessionStackMap,
_smartIndenterService,
evaluator,
_waitIndicator);
}
}
}
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Microsoft.VisualStudio.InteractiveWindow {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class InteractiveWindowResources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal InteractiveWindowResources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.VisualStudio.InteractiveWindow.InteractiveWindowResources", typeof(InteractiveWindowResources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Looks up a localized string similar to The interactive window has already been initialized..
/// </summary>
internal static string AlreadyInitialized {
get {
return ResourceManager.GetString("AlreadyInitialized", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Replace the current submission with a subsequent submission (after having previously navigated backwards)..
/// </summary>
internal static string AltDownArrowHelp {
get {
return ResourceManager.GetString("AltDownArrowHelp", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Replace the current submission with a previous submission..
/// </summary>
internal static string AltUpArrowHelp {
get {
return ResourceManager.GetString("AltUpArrowHelp", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Delete Character To Left.
/// </summary>
internal static string Backspace {
get {
return ResourceManager.GetString("Backspace", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Insert New Line.
/// </summary>
internal static string BreakLine {
get {
return ResourceManager.GetString("BreakLine", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Clears the contents of the editor window, leaving history and execution context intact..
/// </summary>
internal static string ClearScreenCommandDescription {
get {
return ResourceManager.GetString("ClearScreenCommandDescription", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Command &apos;{0}&apos; failed: {1}.
/// </summary>
internal static string CommandFailed {
get {
return ResourceManager.GetString("CommandFailed", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to [command-name].
/// </summary>
internal static string CommandNamePlaceholder {
get {
return ResourceManager.GetString("CommandNamePlaceholder", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Script directives:.
/// </summary>
internal static string CSVBScriptDirectives {
get {
return ResourceManager.GetString("CSVBScriptDirectives", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to First press, select the submission containing the cursor. Second press, select all text in the window..
/// </summary>
internal static string CtrlAHelp {
get {
return ResourceManager.GetString("CtrlAHelp", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Replace the current submission with a subsequent submission beginning with the same text (after having previously navigated backwards)..
/// </summary>
internal static string CtrlAltDownArrowHelp {
get {
return ResourceManager.GetString("CtrlAltDownArrowHelp", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Replace the current submission with a previous submission beginning with the same text..
/// </summary>
internal static string CtrlAltUpArrowHelp {
get {
return ResourceManager.GetString("CtrlAltUpArrowHelp", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Paste and execute the selection before any pending input in the interactive buffer..
/// </summary>
internal static string CtrlECtrlEnterHelp {
get {
return ResourceManager.GetString("CtrlECtrlEnterHelp", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Within the current submission, evaluate the current submission..
/// </summary>
internal static string CtrlEnterHelp1 {
get {
return ResourceManager.GetString("CtrlEnterHelp1", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Within a previous submission, append the previous submission to the current submission..
/// </summary>
internal static string CtrlEnterHelp2 {
get {
return ResourceManager.GetString("CtrlEnterHelp2", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Paste the selection at the end of interactive buffer, leave caret at the end of input..
/// </summary>
internal static string CtrlKCtrlEnterHelp {
get {
return ResourceManager.GetString("CtrlKCtrlEnterHelp", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Cut Selection.
/// </summary>
internal static string Cut {
get {
return ResourceManager.GetString("Cut", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Cut Line.
/// </summary>
internal static string CutLine {
get {
return ResourceManager.GetString("CutLine", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Delete Text.
/// </summary>
internal static string Delete {
get {
return ResourceManager.GetString("Delete", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Delete Line.
/// </summary>
internal static string DeleteLine {
get {
return ResourceManager.GetString("DeleteLine", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to At the end of the current submission, replace the current submission with a subsequent submission (after having previously navigated backwards)..
/// </summary>
internal static string DownArrowHelp1 {
get {
return ResourceManager.GetString("DownArrowHelp1", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Elsewhere, move the cursor down one line..
/// </summary>
internal static string DownArrowHelp2 {
get {
return ResourceManager.GetString("DownArrowHelp2", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to A command with the name &apos;{0}&apos; has already been registered..
/// </summary>
internal static string DuplicateCommand {
get {
return ResourceManager.GetString("DuplicateCommand", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to If the current submission appears to be complete, evaluate it. Otherwise, insert a new line..
/// </summary>
internal static string EnterHelp {
get {
return ResourceManager.GetString("EnterHelp", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Clear the current submission..
/// </summary>
internal static string EscapeHelp {
get {
return ResourceManager.GetString("EscapeHelp", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Display help on specified command, or all available commands and key bindings if none specified..
/// </summary>
internal static string HelpCommandDescription {
get {
return ResourceManager.GetString("HelpCommandDescription", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to An internal error has occurred in the Interactive window. Please restart Visual Studio..
/// </summary>
internal static string InternalError {
get {
return ResourceManager.GetString("InternalError", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to The interactive window is resettings..
/// </summary>
internal static string IsResettings {
get {
return ResourceManager.GetString("IsResettings", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Keyboard shortcuts:.
/// </summary>
internal static string KeyboardShortcuts {
get {
return ResourceManager.GetString("KeyboardShortcuts", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Load specified script file and execute it, e.g. #load &quot;myScript.csx&quot;..
/// </summary>
internal static string LoadHelp {
get {
return ResourceManager.GetString("LoadHelp", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to The command of type &apos;{0}&apos; has no command names..
/// </summary>
internal static string MissingCommandName {
get {
return ResourceManager.GetString("MissingCommandName", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to The interactive window has not yet been initialized..
/// </summary>
internal static string NotInitialized {
get {
return ResourceManager.GetString("NotInitialized", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Parameters:.
/// </summary>
internal static string Parameters {
get {
return ResourceManager.GetString("Parameters", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Paste.
/// </summary>
internal static string Paste {
get {
return ResourceManager.GetString("Paste", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Add a metadata reference to specified assembly and all its dependencies, e.g. #r &quot;myLib.dll&quot;..
/// </summary>
internal static string RefHelp {
get {
return ResourceManager.GetString("RefHelp", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to REPL commands:.
/// </summary>
internal static string ReplCommands {
get {
return ResourceManager.GetString("ReplCommands", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to This method may not be called on the UI thread (to avoid hangs)..
/// </summary>
internal static string RequireNonUIThread {
get {
return ResourceManager.GetString("RequireNonUIThread", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to This method may only be called on the UI thread..
/// </summary>
internal static string RequireUIThread {
get {
return ResourceManager.GetString("RequireUIThread", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Reset the execution environment to the initial state, keep history..
/// </summary>
internal static string ResetCommandDescription {
get {
return ResourceManager.GetString("ResetCommandDescription", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Reset to a clean environment (only mscorlib referenced), do not run initialization script..
/// </summary>
internal static string ResetCommandParametersDescription {
get {
return ResourceManager.GetString("ResetCommandParametersDescription", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Insert a new line..
/// </summary>
internal static string ShiftEnterHelp {
get {
return ResourceManager.GetString("ShiftEnterHelp", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Insert Text.
/// </summary>
internal static string TypeChar {
get {
return ResourceManager.GetString("TypeChar", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Unknown command &apos;{0}&apos;.
/// </summary>
internal static string UnknownCommand {
get {
return ResourceManager.GetString("UnknownCommand", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to At the end of the current submission, replace the current submission with a previous submission..
/// </summary>
internal static string UpArrowHelp1 {
get {
return ResourceManager.GetString("UpArrowHelp1", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Elsewhere, move the cursor up one line..
/// </summary>
internal static string UpArrowHelp2 {
get {
return ResourceManager.GetString("UpArrowHelp2", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Usage:.
/// </summary>
internal static string Usage {
get {
return ResourceManager.GetString("Usage", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Generating Rich Text Format representation from selection..
/// </summary>
internal static string WaitMessage {
get {
return ResourceManager.GetString("WaitMessage", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Copy.
/// </summary>
internal static string WaitTitle {
get {
return ResourceManager.GetString("WaitTitle", resourceCulture);
}
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="AlreadyInitialized" xml:space="preserve">
<value>The interactive window has already been initialized.</value>
</data>
<data name="AltDownArrowHelp" xml:space="preserve">
<value>Replace the current submission with a subsequent submission (after having previously navigated backwards).</value>
</data>
<data name="AltUpArrowHelp" xml:space="preserve">
<value>Replace the current submission with a previous submission.</value>
</data>
<data name="ClearScreenCommandDescription" xml:space="preserve">
<value>Clears the contents of the editor window, leaving history and execution context intact.</value>
</data>
<data name="CommandFailed" xml:space="preserve">
<value>Command '{0}' failed: {1}</value>
</data>
<data name="CommandNamePlaceholder" xml:space="preserve">
<value>[command-name]</value>
</data>
<data name="CtrlAHelp" xml:space="preserve">
<value>First press, select the submission containing the cursor. Second press, select all text in the window.</value>
</data>
<data name="CtrlAltDownArrowHelp" xml:space="preserve">
<value>Replace the current submission with a subsequent submission beginning with the same text (after having previously navigated backwards).</value>
</data>
<data name="CtrlAltUpArrowHelp" xml:space="preserve">
<value>Replace the current submission with a previous submission beginning with the same text.</value>
</data>
<data name="CtrlECtrlEnterHelp" xml:space="preserve">
<value>Paste and execute the selection before any pending input in the interactive buffer.</value>
</data>
<data name="CtrlEnterHelp1" xml:space="preserve">
<value>Within the current submission, evaluate the current submission.</value>
</data>
<data name="CtrlEnterHelp2" xml:space="preserve">
<value>Within a previous submission, append the previous submission to the current submission.</value>
</data>
<data name="CtrlKCtrlEnterHelp" xml:space="preserve">
<value>Paste the selection at the end of interactive buffer, leave caret at the end of input.</value>
</data>
<data name="DownArrowHelp1" xml:space="preserve">
<value>At the end of the current submission, replace the current submission with a subsequent submission (after having previously navigated backwards).</value>
</data>
<data name="DownArrowHelp2" xml:space="preserve">
<value>Elsewhere, move the cursor down one line.</value>
</data>
<data name="DuplicateCommand" xml:space="preserve">
<value>A command with the name '{0}' has already been registered.</value>
</data>
<data name="EnterHelp" xml:space="preserve">
<value>If the current submission appears to be complete, evaluate it. Otherwise, insert a new line.</value>
</data>
<data name="EscapeHelp" xml:space="preserve">
<value>Clear the current submission.</value>
</data>
<data name="HelpCommandDescription" xml:space="preserve">
<value>Display help on specified command, or all available commands and key bindings if none specified.</value>
</data>
<data name="InternalError" xml:space="preserve">
<value>An internal error has occurred in the Interactive window. Please restart Visual Studio.</value>
</data>
<data name="KeyboardShortcuts" xml:space="preserve">
<value>Keyboard shortcuts:</value>
</data>
<data name="MissingCommandName" xml:space="preserve">
<value>The command of type '{0}' has no command names.</value>
</data>
<data name="NotInitialized" xml:space="preserve">
<value>The interactive window has not yet been initialized.</value>
</data>
<data name="IsResettings" xml:space="preserve">
<value>The interactive window is resettings.</value>
</data>
<data name="Parameters" xml:space="preserve">
<value>Parameters:</value>
</data>
<data name="ReplCommands" xml:space="preserve">
<value>REPL commands:</value>
</data>
<data name="RequireNonUIThread" xml:space="preserve">
<value>This method may not be called on the UI thread (to avoid hangs).</value>
</data>
<data name="RequireUIThread" xml:space="preserve">
<value>This method may only be called on the UI thread.</value>
</data>
<data name="ResetCommandDescription" xml:space="preserve">
<value>Reset the execution environment to the initial state, keep history.</value>
</data>
<data name="ResetCommandParametersDescription" xml:space="preserve">
<value>Reset to a clean environment (only mscorlib referenced), do not run initialization script.</value>
</data>
<data name="ShiftEnterHelp" xml:space="preserve">
<value>Insert a new line.</value>
</data>
<data name="UnknownCommand" xml:space="preserve">
<value>Unknown command '{0}'</value>
</data>
<data name="UpArrowHelp1" xml:space="preserve">
<value>At the end of the current submission, replace the current submission with a previous submission.</value>
</data>
<data name="UpArrowHelp2" xml:space="preserve">
<value>Elsewhere, move the cursor up one line.</value>
</data>
<data name="Usage" xml:space="preserve">
<value>Usage:</value>
</data>
<data name="WaitTitle" xml:space="preserve">
<value>Copy</value>
</data>
<data name="WaitMessage" xml:space="preserve">
<value>Generating Rich Text Format representation from selection.</value>
</data>
<data name="Backspace" xml:space="preserve">
<value>Delete Character To Left</value>
</data>
<data name="BreakLine" xml:space="preserve">
<value>Insert New Line</value>
</data>
<data name="Paste" xml:space="preserve">
<value>Paste</value>
</data>
<data name="Cut" xml:space="preserve">
<value>Cut Selection</value>
</data>
<data name="Delete" xml:space="preserve">
<value>Delete Text</value>
</data>
<data name="CutLine" xml:space="preserve">
<value>Cut Line</value>
</data>
<data name="DeleteLine" xml:space="preserve">
<value>Delete Line</value>
</data>
<data name="TypeChar" xml:space="preserve">
<value>Insert Text</value>
</data>
<data name="CSVBScriptDirectives" xml:space="preserve">
<value>Script directives:</value>
</data>
<data name="RefHelp" xml:space="preserve">
<value>Add a metadata reference to specified assembly and all its dependencies, e.g. #r "myLib.dll".</value>
</data>
<data name="LoadHelp" xml:space="preserve">
<value>Load specified script file and execute it, e.g. #load "myScript.csx".</value>
</data>
</root>
\ No newline at end of file
// Copyright (c) Microsoft. 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.Diagnostics;
namespace Microsoft.VisualStudio.InteractiveWindow
{
internal static class ExceptionUtilities
{
internal static Exception UnexpectedValue(object o)
{
string output = string.Format("Unexpected value '{0}' of type '{1}'", o, (o != null) ? o.GetType().FullName : "<unknown>");
Debug.Assert(false, output);
// We do not throw from here because we don't want all Watson reports to be bucketed to this call.
return new InvalidOperationException(output);
}
internal static Exception Unreachable
{
get { return new InvalidOperationException("This program location is thought to be unreachable."); }
}
}
}
// Copyright (c) Microsoft. 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.ComponentModel;
using System.Diagnostics;
namespace Microsoft.VisualStudio.InteractiveWindow
{
internal static class FatalError
{
private static Action<Exception> s_fatalHandler;
private static Action<Exception> s_nonFatalHandler;
private static Exception s_reportedException;
private static string s_reportedExceptionMessage;
/// <summary>
/// Set by the host to a fail fast trigger,
/// if the host desires to crash the process on a fatal exception.
/// </summary>
public static Action<Exception> Handler
{
get
{
return s_fatalHandler;
}
set
{
if (s_fatalHandler != value)
{
Debug.Assert(s_fatalHandler == null, "Handler already set");
s_fatalHandler = value;
}
}
}
/// <summary>
/// Set by the host to a fail fast trigger,
/// if the host desires to NOT crash the process on a non fatal exception.
/// </summary>
public static Action<Exception> NonFatalHandler
{
get
{
return s_nonFatalHandler;
}
set
{
if (s_nonFatalHandler != value)
{
Debug.Assert(s_nonFatalHandler == null, "Handler already set");
s_nonFatalHandler = value;
}
}
}
// Same as setting the Handler property except that it avoids the assert. This is useful in
// test code which needs to verify the handler is called in specific cases and will continually
// overwrite this value.
public static void OverwriteHandler(Action<Exception> value)
{
s_fatalHandler = value;
}
/// <summary>
/// Use in an exception filter to report a fatal error.
/// Unless the exception is <see cref="OperationCanceledException"/>
/// it calls <see cref="Handler"/>. The exception is passed through (the method returns false).
/// </summary>
/// <returns>False to avoid catching the exception.</returns>
[DebuggerHidden]
public static bool ReportUnlessCanceled(Exception exception)
{
if (exception is OperationCanceledException)
{
return false;
}
return Report(exception);
}
/// <summary>
/// Use in an exception filter to report a non fatal error.
/// Unless the exception is <see cref="OperationCanceledException"/>
/// it calls <see cref="NonFatalHandler"/>. The exception isn't passed through (the method returns true).
/// </summary>
/// <returns>True to catch the exception.</returns>
[DebuggerHidden]
public static bool ReportWithoutCrashUnlessCanceled(Exception exception)
{
if (exception is OperationCanceledException)
{
return false;
}
return ReportWithoutCrash(exception);
}
/// <summary>
/// Use in an exception filter to report a fatal error.
/// Unless the exception is <see cref="NotImplementedException"/>
/// it calls <see cref="Handler"/>. The exception is passed through (the method returns false).
/// </summary>
/// <returns>False to avoid catching the exception.</returns>
[DebuggerHidden]
public static bool ReportUnlessNotImplemented(Exception exception)
{
if (exception is NotImplementedException)
{
return false;
}
return Report(exception);
}
/// <summary>
/// Use in an exception filter to report a fatal error.
/// Calls <see cref="Handler"/> and passes the exception through (the method returns false).
/// </summary>
/// <returns>False to avoid catching the exception.</returns>
[DebuggerHidden]
public static bool Report(Exception exception)
{
Report(exception, s_fatalHandler);
return false;
}
/// <summary>
/// Use in an exception filter to report a non fatal error.
/// Calls <see cref="NonFatalHandler"/> and doesn't pass the exception through (the method returns true).
/// </summary>
/// <returns>True to catch the exception.</returns>
[DebuggerHidden]
public static bool ReportWithoutCrash(Exception exception)
{
Report(exception, s_nonFatalHandler);
return true;
}
private static void Report(Exception exception, Action<Exception> handler)
{
// hold onto last exception to make investigation easier
s_reportedException = exception;
s_reportedExceptionMessage = exception.ToString();
handler?.Invoke(exception);
}
}
}
// Copyright (c) Microsoft. 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.Collections.Generic;
using System.ComponentModel.Composition;
using System.Windows;
using System.Windows.Threading;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Editor;
using Microsoft.VisualStudio.Text.Tagging;
using Microsoft.VisualStudio.Utilities;
namespace Microsoft.VisualStudio.InteractiveWindow
{
[Export(typeof(IViewTaggerProvider))]
[TagType(typeof(IntraTextAdornmentTag))]
[ContentType(PredefinedInteractiveContentTypes.InteractiveContentTypeName)]
internal sealed class InlineAdornmentProvider : IViewTaggerProvider
{
public ITagger<T> CreateTagger<T>(ITextView textView, ITextBuffer buffer) where T : ITag
{
if (buffer == null || textView == null || typeof(T) != typeof(IntraTextAdornmentTag))
{
return null;
}
return (ITagger<T>)textView.Properties.GetOrCreateSingletonProperty<InlineReplAdornmentManager>(
typeof(InlineReplAdornmentManager),
() => new InlineReplAdornmentManager(textView));
}
private class InlineReplAdornmentManager : ITagger<IntraTextAdornmentTag>
{
private readonly ITextView _textView;
private readonly List<Tuple<int, ZoomableInlineAdornment>> _tags;
private readonly Dispatcher _dispatcher;
internal InlineReplAdornmentManager(ITextView textView)
{
_textView = textView;
_tags = new List<Tuple<int, ZoomableInlineAdornment>>();
_dispatcher = Dispatcher.CurrentDispatcher;
}
public IEnumerable<ITagSpan<IntraTextAdornmentTag>> GetTags(NormalizedSnapshotSpanCollection spans)
{
var result = new List<TagSpan<IntraTextAdornmentTag>>();
foreach (var t in _tags)
{
var span = new SnapshotSpan(_textView.TextSnapshot, t.Item1, 0);
t.Item2.UpdateSize();
var tag = new IntraTextAdornmentTag(t.Item2, null);
result.Add(new TagSpan<IntraTextAdornmentTag>(span, tag));
}
return result;
}
public void AddAdornment(ZoomableInlineAdornment uiElement)
{
if (Dispatcher.CurrentDispatcher != _dispatcher)
{
_dispatcher.BeginInvoke(new Action(() => AddAdornment(uiElement)));
return;
}
var caretPos = _textView.Caret.Position.BufferPosition;
var caretLine = caretPos.GetContainingLine();
_tags.Add(new Tuple<int, ZoomableInlineAdornment>(caretPos.Position, uiElement));
var handler = TagsChanged;
if (handler != null)
{
var span = new SnapshotSpan(_textView.TextSnapshot, caretLine.Start, caretLine.Length);
var args = new SnapshotSpanEventArgs(span);
handler(this, args);
}
}
public IList<Tuple<int, ZoomableInlineAdornment>> Adornments
{
get { return _tags; }
}
public void RemoveAll()
{
_tags.Clear();
}
public event EventHandler<SnapshotSpanEventArgs> TagsChanged;
}
private static InlineReplAdornmentManager GetManager(ITextView view)
{
InlineReplAdornmentManager result;
if (!view.Properties.TryGetProperty<InlineReplAdornmentManager>(typeof(InlineReplAdornmentManager), out result))
{
return null;
}
return result;
}
public static void AddInlineAdornment(ITextView view, UIElement uiElement, RoutedEventHandler onLoaded)
{
var manager = GetManager(view);
if (manager != null)
{
var adornment = new ZoomableInlineAdornment(uiElement, view);
// Original Python code unhooked this event after load was complete
// I don't think this should be needed... we'll see.
adornment.Loaded += onLoaded;
manager.AddAdornment(adornment);
}
}
public static void ZoomInlineAdornments(ITextView view, double zoomFactor)
{
var manager = GetManager(view);
if (manager != null)
{
foreach (var t in manager.Adornments)
{
t.Item2.Zoom(zoomFactor);
}
}
}
public static void MinimizeLastInlineAdornment(ITextView view)
{
var manager = GetManager(view);
if (manager != null && manager.Adornments.Count > 0)
{
var adornment = manager.Adornments[manager.Adornments.Count - 1].Item2;
adornment.Zoom(adornment.MinimizedZoom);
}
}
public static void RemoveAllAdornments(ITextView view)
{
var manager = GetManager(view);
if (manager != null)
{
manager.RemoveAll();
}
}
}
}
// Copyright (c) Microsoft. 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.Collections.Generic;
using System.Diagnostics;
using System.Windows.Threading;
namespace Microsoft.VisualStudio.InteractiveWindow
{
/// <summary>
/// Serializes and buffers output so that we avoid frequent switching to UI thread to write to the editor buffer.
/// </summary>
internal sealed class OutputBuffer : IDisposable
{
private sealed class Entry
{
public readonly string Text;
public Entry Next;
public Entry(string text)
{
Debug.Assert(!string.IsNullOrEmpty(text));
Text = text;
}
}
private static readonly Stopwatch s_stopwatch;
private readonly InteractiveWindow _window;
private readonly DispatcherTimer _timer;
private readonly object _mutex;
private Entry _firstEntry;
private Entry _lastEntry;
private long _lastFlushTimeMilliseconds;
// the number of characters written to the buffer that trigger an auto-flush
private int _flushThreshold;
// the number of characters written to the buffer that haven't been flushed yet
private int _unflushedLength;
// the number of characters written to the output (doesn't reset on flush)
private int _totalLength;
private const int InitialFlushThreshold = 1024;
private const int AutoFlushMilliseconds = 100;
static OutputBuffer()
{
s_stopwatch = new Stopwatch();
s_stopwatch.Start();
}
public OutputBuffer(InteractiveWindow window)
{
Reset();
_mutex = new object();
_window = window;
_timer = new DispatcherTimer();
_timer.Tick += (sender, args) => Flush();
_timer.Interval = TimeSpan.FromMilliseconds(AutoFlushMilliseconds);
}
internal void Reset()
{
_firstEntry = _lastEntry = null;
_totalLength = _unflushedLength = 0;
_flushThreshold = InitialFlushThreshold;
}
/// <summary>
/// Appends text to the end of the buffer.
/// </summary>
/// <param name="text">Text to append.</param>
/// <returns>Returns the position where this text is inserted relative to the buffer start.</returns>
public int Write(string text)
{
int result = _totalLength;
if (string.IsNullOrEmpty(text))
{
return result;
}
bool needsFlush = false;
lock (_mutex)
{
AddEntry(text);
needsFlush = _unflushedLength > _flushThreshold;
if (!needsFlush && !_timer.IsEnabled)
{
_timer.IsEnabled = true;
}
}
if (needsFlush)
{
Flush();
}
return result;
}
/// <summary>
/// Flushes the buffer, should always be called from the UI thread.
/// </summary>
public void Flush()
{
Entry firstEntryToFlush = null;
lock (_mutex)
{
// if we're rapidly outputting grow the threshold
long curTime = s_stopwatch.ElapsedMilliseconds;
if (curTime - _lastFlushTimeMilliseconds < 1000)
{
if (_flushThreshold < 1024 * 1024)
{
_flushThreshold *= 2;
}
}
_lastFlushTimeMilliseconds = s_stopwatch.ElapsedMilliseconds;
if (_unflushedLength > 0)
{
// normalize line breaks - the editor isn't happy about projections that cut "\r\n" line break in half:
if (_lastEntry.Text[_lastEntry.Text.Length - 1] == '\r')
{
AddEntry("\n");
}
firstEntryToFlush = _firstEntry;
_firstEntry = _lastEntry = null;
_unflushedLength = 0;
}
_timer.IsEnabled = false;
}
if (firstEntryToFlush != null)
{
_window.AppendOutput(GetEntries(firstEntryToFlush));
}
}
private void AddEntry(string text)
{
var entry = new Entry(text);
if (_firstEntry == null)
{
_firstEntry = _lastEntry = entry;
}
else
{
_lastEntry.Next = entry;
_lastEntry = entry;
}
_totalLength += text.Length;
_unflushedLength += text.Length;
}
private IEnumerable<string> GetEntries(Entry entry)
{
while (entry != null)
{
yield return entry.Text;
entry = entry.Next;
}
}
public void Dispose()
{
_timer.IsEnabled = false;
}
}
}
// Copyright (c) Microsoft. 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.Diagnostics;
using System.Globalization;
using System.IO;
using System.Text;
using Microsoft.VisualStudio.Text;
namespace Microsoft.VisualStudio.InteractiveWindow
{
internal sealed class InteractiveWindowWriter : TextWriter
{
private readonly IInteractiveWindow _window;
private readonly SortedSpans _spans;
internal InteractiveWindowWriter(IInteractiveWindow window, SortedSpans spans)
{
Debug.Assert(window != null);
_window = window;
_spans = spans;
}
public IInteractiveWindow Window
{
get { return _window; }
}
public SortedSpans Spans
{
get
{
return _spans;
}
}
public override object InitializeLifetimeService()
{
return null;
}
public override IFormatProvider FormatProvider
{
get { return CultureInfo.CurrentCulture; }
}
public override Encoding Encoding
{
get { return Encoding.UTF8; }
}
public override void Write(string value)
{
if (string.IsNullOrEmpty(value))
{
return;
}
int offset = _window.Write(value).Start;
if (_spans != null)
{
_spans.Add(new Span(offset, value.Length));
}
}
public override void Write(char[] value, int start, int count)
{
Write(new string(value, start, count));
}
public override void WriteLine()
{
Span span = _window.WriteLine(text: null);
if (_spans != null)
{
_spans.Add(span);
}
}
public override void WriteLine(string str)
{
Span span = _window.WriteLine(str);
if (_spans != null)
{
_spans.Add(span);
}
}
}
}
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.ComponentModel.Composition;
using Microsoft.VisualStudio.Utilities;
namespace Microsoft.VisualStudio.InteractiveWindow
{
public static class PredefinedInteractiveContentTypes
{
public const string InteractiveContentTypeName = "Interactive Content";
public const string InteractiveOutputContentTypeName = "Interactive Output";
}
}
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册