-
Notifications
You must be signed in to change notification settings - Fork 789
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Re-add Execute/Debug in Interactive context menu (#1913)
* Hook F# Interactive menu commands into language service Rudimentary implementation * Refactor * Refactor again for better robustness
- Loading branch information
Showing
3 changed files
with
94 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<SVsShell>) :?> 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 | ||
|
||
[<Export(typeof<IWpfTextViewCreationListener>)>] | ||
[<ContentType("F#")>] | ||
[<TextViewRole(PredefinedTextViewRoles.PrimaryDocument)>] | ||
type FsiCommandFilterProvider [<ImportingConstructor>] | ||
([<Import(typeof<SVsServiceProvider>)>] 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 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters