diff --git a/vsintegration/src/FSharp.Editor/FSharp.Editor.fsproj b/vsintegration/src/FSharp.Editor/FSharp.Editor.fsproj
index b4b3cb163aa..b88fedf9d7d 100644
--- a/vsintegration/src/FSharp.Editor/FSharp.Editor.fsproj
+++ b/vsintegration/src/FSharp.Editor/FSharp.Editor.fsproj
@@ -70,6 +70,7 @@
QuickInfo\QuickInfoProvider.fs
+
@@ -91,6 +92,11 @@
FSharp.LanguageService.Compiler
True
+
+ FSharp.VS.FSI
+ {991dcf75-c2eb-42b6-9a0d-aa1d2409d519}
+ True
+
diff --git a/vsintegration/src/FSharp.Editor/FsiCommandService.fs b/vsintegration/src/FSharp.Editor/FsiCommandService.fs
new file mode 100644
index 00000000000..95c50ba7a82
--- /dev/null
+++ b/vsintegration/src/FSharp.Editor/FsiCommandService.fs
@@ -0,0 +1,87 @@
+namespace Microsoft.VisualStudio.FSharp.Editor
+
+open System
+open Microsoft.VisualStudio.Text.Editor
+open Microsoft.VisualStudio.OLE.Interop
+open System.ComponentModel.Composition
+open Microsoft.VisualStudio
+open Microsoft.VisualStudio.Editor
+open Microsoft.VisualStudio.TextManager.Interop
+open Microsoft.VisualStudio.Utilities
+open Microsoft.VisualStudio.Shell
+open Microsoft.VisualStudio.Shell.Interop
+open Microsoft.VisualStudio.FSharp.Interactive
+open EnvDTE
+
+type FsiCommandFilter(serviceProvider: System.IServiceProvider) =
+ let projectSystemPackage =
+ lazy(
+ let shell = serviceProvider.GetService(typeof) :?> IVsShell
+ let packageToBeLoadedGuid = ref (Guid "{91a04a73-4f2c-4e7c-ad38-c1a68e7da05c}") // FSharp ProjectSystem guid
+ match shell.LoadPackage packageToBeLoadedGuid with
+ | VSConstants.S_OK, pkg ->
+ pkg :?> Package
+ | _ -> null)
+
+ let mutable nextTarget = null
+
+ member x.AttachToViewAdapter (viewAdapter: IVsTextView) =
+ match viewAdapter.AddCommandFilter x with
+ | VSConstants.S_OK, next ->
+ nextTarget <- next
+ | errorCode, _ ->
+ ErrorHandler.ThrowOnFailure errorCode |> ignore
+
+ interface IOleCommandTarget with
+ member x.Exec (pguidCmdGroup, nCmdId, nCmdexecopt, pvaIn, pvaOut) =
+ if pguidCmdGroup = VSConstants.VsStd11 then
+ if nCmdId = uint32 VSConstants.VSStd11CmdID.ExecuteSelectionInInteractive then
+ Hooks.OnMLSend projectSystemPackage.Value FsiEditorSendAction.ExecuteSelection null null
+ elif nCmdId = uint32 VSConstants.VSStd11CmdID.ExecuteLineInInteractive then
+ Hooks.OnMLSend projectSystemPackage.Value FsiEditorSendAction.ExecuteLine null null
+ VSConstants.S_OK
+ elif pguidCmdGroup = Guids.guidInteractive then
+ if nCmdId = uint32 Guids.cmdIDDebugSelection then
+ Hooks.OnMLSend projectSystemPackage.Value FsiEditorSendAction.DebugSelection null null
+ VSConstants.S_OK
+ elif isNotNull nextTarget then
+ nextTarget.Exec(&pguidCmdGroup, nCmdId, nCmdexecopt, pvaIn, pvaOut)
+ else
+ VSConstants.E_FAIL
+
+ member x.QueryStatus (pguidCmdGroup, cCmds, prgCmds, pCmdText) =
+ if pguidCmdGroup = VSConstants.VsStd11 then
+ for i = 0 to int cCmds-1 do
+ if prgCmds.[i].cmdID = uint32 VSConstants.VSStd11CmdID.ExecuteSelectionInInteractive then
+ prgCmds.[i].cmdf <- uint32 (OLECMDF.OLECMDF_SUPPORTED ||| OLECMDF.OLECMDF_ENABLED)
+ elif prgCmds.[i].cmdID = uint32 VSConstants.VSStd11CmdID.ExecuteLineInInteractive then
+ prgCmds.[i].cmdf <- uint32 (OLECMDF.OLECMDF_SUPPORTED ||| OLECMDF.OLECMDF_ENABLED ||| OLECMDF.OLECMDF_DEFHIDEONCTXTMENU)
+ VSConstants.S_OK
+ elif pguidCmdGroup = Guids.guidInteractive then
+ for i = 0 to int cCmds-1 do
+ if prgCmds.[i].cmdID = uint32 Guids.cmdIDDebugSelection then
+ let dbgState = Hooks.GetDebuggerState projectSystemPackage.Value
+ if dbgState = FsiDebuggerState.AttachedNotToFSI then
+ prgCmds.[i].cmdf <- uint32 OLECMDF.OLECMDF_INVISIBLE
+ else
+ prgCmds.[i].cmdf <- uint32 (OLECMDF.OLECMDF_SUPPORTED ||| OLECMDF.OLECMDF_ENABLED)
+ VSConstants.S_OK
+ elif isNotNull nextTarget then
+ nextTarget.QueryStatus(&pguidCmdGroup, cCmds, prgCmds, pCmdText)
+ else
+ VSConstants.E_FAIL
+
+[)>]
+[]
+[]
+type FsiCommandFilterProvider []
+ ([)>] serviceProvider: System.IServiceProvider,
+ editorFactory: IVsEditorAdaptersFactoryService) =
+ interface IWpfTextViewCreationListener with
+ member __.TextViewCreated(textView) =
+ match editorFactory.GetViewAdapter(textView) with
+ | null -> ()
+ | textViewAdapter ->
+ let commandFilter = FsiCommandFilter serviceProvider
+ commandFilter.AttachToViewAdapter textViewAdapter
+
\ No newline at end of file
diff --git a/vsintegration/src/FSharp.VS.FSI/AssemblyInfo.fs b/vsintegration/src/FSharp.VS.FSI/AssemblyInfo.fs
index 6fa80ea3d1c..5a8ab326cc3 100644
--- a/vsintegration/src/FSharp.VS.FSI/AssemblyInfo.fs
+++ b/vsintegration/src/FSharp.VS.FSI/AssemblyInfo.fs
@@ -9,6 +9,7 @@ open Microsoft.VisualStudio.Shell
[]
+[]
[]
[]
[]