public IWpfTextViewHost CreateEditor(string filePath) { SplayCodeToolWindow.ApplicationObject.ItemOperations.OpenFile(filePath); SplayCodeToolWindow.Instance.Activate(); //IVsInvisibleEditors are in-memory represenations of typical Visual Studio editors. //Language services, highlighting and error squiggles are hooked up to these editors //for us once we convert them to WpfTextViews. var invisibleEditor = GetInvisibleEditor(filePath); var docDataPointer = IntPtr.Zero; Guid guidIVsTextLines = typeof(IVsTextLines).GUID; ErrorHandler.ThrowOnFailure(invisibleEditor.GetDocData( fEnsureWritable: 1 , riid: ref guidIVsTextLines , ppDocData: out docDataPointer)); IVsTextLines docData = (IVsTextLines)Marshal.GetObjectForIUnknown(docDataPointer); //Create a code window adapter var codeWindow = editorAdapter.CreateVsCodeWindowAdapter(OLEServiceProvider); ErrorHandler.ThrowOnFailure(codeWindow.SetBuffer(docData)); //Get a text view for our editor which we will then use to get the WPF control for that editor. IVsTextView textView; ErrorHandler.ThrowOnFailure(codeWindow.GetPrimaryView(out textView)); currentlyFocusedTextView = textView; var textViewHost = editorAdapter.GetWpfTextViewHost(textView); return(textViewHost); }
public IWpfTextViewHost CreateEditor(string filePath, int start = 0, int end = 0, bool createProjectedEditor = false) { //IVsInvisibleEditors are in-memory represenations of typical Visual Studio editors. //Language services, highlighting and error squiggles are hooked up to these editors //for us once we convert them to WpfTextViews. var invisibleEditor = GetInvisibleEditor(filePath); var docDataPointer = IntPtr.Zero; Guid guidIVsTextLines = typeof(IVsTextLines).GUID; ErrorHandler.ThrowOnFailure(invisibleEditor.GetDocData( fEnsureWritable: 1 , riid: ref guidIVsTextLines , ppDocData: out docDataPointer)); IVsTextLines docData = (IVsTextLines)Marshal.GetObjectForIUnknown(docDataPointer); // This will actually be defined as _codewindowbehaviorflags2.CWB_DISABLEDIFF once the latest version of // Microsoft.VisualStudio.TextManager.Interop.16.0.DesignTime is published. Setting the flag will have no effect // on releases prior to d16.0. const _codewindowbehaviorflags CWB_DISABLEDIFF = (_codewindowbehaviorflags)0x04; //Create a code window adapter var codeWindow = _editorAdapter.CreateVsCodeWindowAdapter(VisualStudioServices.OLEServiceProvider); // You need to disable the dropdown, splitter and -- for d16.0 -- diff since you are extracting the code window's TextViewHost and using it. ((IVsCodeWindowEx)codeWindow).Initialize((uint)_codewindowbehaviorflags.CWB_DISABLESPLITTER | (uint)_codewindowbehaviorflags.CWB_DISABLEDROPDOWNBAR | (uint)CWB_DISABLEDIFF, VSUSERCONTEXTATTRIBUTEUSAGE.VSUC_Usage_Filter, string.Empty, string.Empty, 0, new INITVIEW[1]); ErrorHandler.ThrowOnFailure(codeWindow.SetBuffer(docData)); //Get a text view for our editor which we will then use to get the WPF control for that editor. IVsTextView textView; ErrorHandler.ThrowOnFailure(codeWindow.GetPrimaryView(out textView)); if (createProjectedEditor) { //We add our own role to this text view. Later this will allow us to selectively modify //this editor without getting in the way of Visual Studio's normal editors. var roles = _editorFactoryService.DefaultRoles.Concat(new string[] { "CustomProjectionRole" }); var vsTextBuffer = docData as IVsTextBuffer; var textBuffer = _editorAdapter.GetDataBuffer(vsTextBuffer); textBuffer.Properties.AddProperty("StartPosition", start); textBuffer.Properties.AddProperty("EndPosition", end); var guid = VSConstants.VsTextBufferUserDataGuid.VsTextViewRoles_guid; ((IVsUserData)codeWindow).SetData(ref guid, _editorFactoryService.CreateTextViewRoleSet(roles).ToString()); } _currentlyFocusedTextView = textView; var textViewHost = _editorAdapter.GetWpfTextViewHost(textView); return(textViewHost); }
public int CreateEditorInstance(uint grfCreateDoc, string pszMkDocument, string pszPhysicalView, IVsHierarchy pvHier, uint itemid, IntPtr punkDocDataExisting, out IntPtr ppunkDocView, out IntPtr ppunkDocData, out string pbstrEditorCaption, out Guid pguidCmdUI, out int pgrfCDW) { ppunkDocView = IntPtr.Zero; ppunkDocData = IntPtr.Zero; pbstrEditorCaption = String.Empty; //pguidCmdUI is the highest priority Guid that Visual Studio Shell looks at when translating key strokes into editor commands. //Here we intentionally set it to Guid.Empty so it will not play a part in translating keystrokes at all. The next highest priority //will be commands tied to this FSharpEditorFactory (such as Alt-Enter). //However, because we are setting pguidCmdUI, we are not going to get typical text editor commands bound to this editor unless we inherit //those keybindings on the IVsWindowFrame in which our editor lives. pguidCmdUI = Guid.Empty; pgrfCDW = 0; IVsTextBuffer textBuffer = null; // Is this document already open? If so, let's see if it's a IVsTextBuffer we should re-use. This allows us // to properly handle multiple windows open for the same document. if (punkDocDataExisting != IntPtr.Zero) { object docDataExisting = Marshal.GetObjectForIUnknown(punkDocDataExisting); textBuffer = docDataExisting as IVsTextBuffer; if (textBuffer == null) { // We are incompatible with the existing doc data return(VSConstants.VS_E_INCOMPATIBLEDOCDATA); } } // Do we need to create a text buffer? if (textBuffer == null) { var contentType = _contentTypeRegistryService.GetContentType(Constants.FSharpContentType); textBuffer = _editorAdaptersFactoryService.CreateVsTextBufferAdapter(_oleServiceProvider, contentType); } // If the text buffer is marked as read-only, ensure that the padlock icon is displayed // next the new window's title and that [Read Only] is appended to title. READONLYSTATUS readOnlyStatus = READONLYSTATUS.ROSTATUS_NotReadOnly; uint textBufferFlags; if (ErrorHandler.Succeeded(textBuffer.GetStateFlags(out textBufferFlags)) && 0 != (textBufferFlags & ((uint)BUFFERSTATEFLAGS.BSF_FILESYS_READONLY | (uint)BUFFERSTATEFLAGS.BSF_USER_READONLY))) { readOnlyStatus = READONLYSTATUS.ROSTATUS_ReadOnly; } var codeWindow = _editorAdaptersFactoryService.CreateVsCodeWindowAdapter(_oleServiceProvider); codeWindow.SetBuffer((IVsTextLines)textBuffer); codeWindow.GetEditorCaption(readOnlyStatus, out pbstrEditorCaption); ppunkDocView = Marshal.GetIUnknownForObject(codeWindow); ppunkDocData = Marshal.GetIUnknownForObject(textBuffer); return(VSConstants.S_OK); }
private IntPtr CreateTextView( IVsTextLines textLines, IntPtr docDataExisting, Guid languageServiceId, out string editorCaption) { IVsCodeWindow window = _adaptersFactory.CreateVsCodeWindowAdapter(VsServiceProvider); ErrorHandler.ThrowOnFailure(window.SetBuffer(textLines)); ErrorHandler.ThrowOnFailure(window.SetBaseEditorCaption(null)); ErrorHandler.ThrowOnFailure(window.GetEditorCaption(READONLYSTATUS.ROSTATUS_Unknown, out editorCaption)); CreateTextBufferInitializationTracker(textLines, docDataExisting, languageServiceId); return(Marshal.GetIUnknownForObject(window)); }
public IWpfTextViewHost CreateEditor(string filePath, int start = 0, int end = 0, bool createProjectedEditor = false) { //IVsInvisibleEditors are in-memory represenations of typical Visual Studio editors. //Language services, highlighting and error squiggles are hooked up to these editors //for us once we convert them to WpfTextViews. var invisibleEditor = GetInvisibleEditor(filePath); var docDataPointer = IntPtr.Zero; Guid guidIVsTextLines = typeof(IVsTextLines).GUID; ErrorHandler.ThrowOnFailure(invisibleEditor.GetDocData( fEnsureWritable: 1 , riid: ref guidIVsTextLines , ppDocData: out docDataPointer)); IVsTextLines docData = (IVsTextLines)Marshal.GetObjectForIUnknown(docDataPointer); //Create a code window adapter var codeWindow = _editorAdapter.CreateVsCodeWindowAdapter(VisualStudioServices.OLEServiceProvider); ErrorHandler.ThrowOnFailure(codeWindow.SetBuffer(docData)); //Get a text view for our editor which we will then use to get the WPF control for that editor. IVsTextView textView; ErrorHandler.ThrowOnFailure(codeWindow.GetPrimaryView(out textView)); if (createProjectedEditor) { //We add our own role to this text view. Later this will allow us to selectively modify //this editor without getting in the way of Visual Studio's normal editors. var roles = _editorFactoryService.DefaultRoles.Concat(new string[] { "CustomProjectionRole" }); var vsTextBuffer = docData as IVsTextBuffer; var textBuffer = _editorAdapter.GetDataBuffer(vsTextBuffer); textBuffer.Properties.AddProperty("StartPosition", start); textBuffer.Properties.AddProperty("EndPosition", end); var guid = VSConstants.VsTextBufferUserDataGuid.VsTextViewRoles_guid; ((IVsUserData)codeWindow).SetData(ref guid, _editorFactoryService.CreateTextViewRoleSet(roles).ToString()); } _currentlyFocusedTextView = textView; var textViewHost = _editorAdapter.GetWpfTextViewHost(textView); return(textViewHost); }
private IntPtr CreateTextView( IVsTextLines textLines, string documentName, IVsHierarchy hierarchy, VSConstants.VSITEMID itemid, IntPtr docDataExisting, Guid languageServiceId, ref string editorCaption, ref Guid cmdUI) { IVsCodeWindow window = _adaptersFactory.CreateVsCodeWindowAdapter(VsServiceProvider); ErrorHandler.ThrowOnFailure(window.SetBuffer(textLines)); ErrorHandler.ThrowOnFailure(window.SetBaseEditorCaption(null)); ErrorHandler.ThrowOnFailure(window.GetEditorCaption(READONLYSTATUS.ROSTATUS_Unknown, out editorCaption)); cmdUI = VSConstants.GUID_TextEditorFactory; CreateTextBufferInitializationTracker(textLines, documentName, hierarchy, itemid, docDataExisting, languageServiceId); return(Marshal.GetIUnknownForObject(window)); }
/// <summary> /// Creates the code view. /// </summary> protected virtual IVsCodeWindow CreateCodeView(string documentMoniker, IVsTextLines?textLines, bool createdDocData, ref string editorCaption, ref Guid cmdUI) { ThreadHelper.ThrowIfNotOnUIThread(); if (_serviceProvider == null) { throw new Exception("ServiceProvider can't be null"); } IVsEditorAdaptersFactoryService adapterService = VS.GetMefService <IVsEditorAdaptersFactoryService>(); IVsCodeWindow window = adapterService.CreateVsCodeWindowAdapter((IOleServiceProvider)_serviceProvider.GetService(typeof(IOleServiceProvider))); ErrorHandler.ThrowOnFailure(window.SetBuffer(textLines)); ErrorHandler.ThrowOnFailure(window.SetBaseEditorCaption(null)); ErrorHandler.ThrowOnFailure(window.GetEditorCaption(READONLYSTATUS.ROSTATUS_Unknown, out editorCaption)); if (textLines is IVsUserData userData) { if (PromptEncodingOnLoad) { Guid guid = VSConstants.VsTextBufferUserDataGuid.VsBufferEncodingPromptOnLoad_guid; userData.SetData(ref guid, (uint)1); } } cmdUI = VSConstants.GUID_TextEditorFactory; if (!createdDocData && textLines != null) { // we have a pre-created buffer, go ahead and initialize now as the buffer already // exists and is initialized TextBufferEventListener?bufferEventListener = new(textLines, _languageServiceId); bufferEventListener.OnLoadCompleted(0); } return(window); }
private void CreateHostedEditor() { //Get the component model so we can request the editor adapter factory which we can use to spin up an editor instance. IComponentModel componentModel = (IComponentModel)ServiceProvider.GlobalProvider.GetService(typeof(SComponentModel)); IContentTypeRegistryService contentTypeRegistry = componentModel.GetService <IContentTypeRegistryService>(); IContentType contentType = contentTypeRegistry.GetContentType("CSharp"); IVsEditorAdaptersFactoryService editorAdapterFactory = componentModel.GetService <IVsEditorAdaptersFactoryService>(); this.textBuffer = editorAdapterFactory.CreateVsTextBufferAdapter(OleServiceProvider); Guid CSharpLanguageService = new Guid("{694DD9B6-B865-4C5B-AD85-86356E9C88DC}"); ErrorHandler.ThrowOnFailure(textBuffer.SetLanguageServiceID(ref CSharpLanguageService)); string initialContents = String.Format("using System;{0}{0}namespace Lazers{0}{{{0}{1}public class Awesome{0}{1}{{{0}{1}}}{0}}}", Environment.NewLine, " "); ErrorHandler.ThrowOnFailure(textBuffer.InitializeContent(initialContents, initialContents.Length)); //Disable the splitter due to a crashing bug if we don't :( this.codeWindow = editorAdapterFactory.CreateVsCodeWindowAdapter(OleServiceProvider); ((IVsCodeWindowEx)this.codeWindow).Initialize((uint)_codewindowbehaviorflags.CWB_DISABLESPLITTER, VSUSERCONTEXTATTRIBUTEUSAGE.VSUC_Usage_Filter, "", "", 0, new INITVIEW[1]); this.codeWindow.SetBuffer((IVsTextLines)this.textBuffer); ErrorHandler.ThrowOnFailure(this.codeWindow.GetPrimaryView(out this.textView)); this.textViewHost = editorAdapterFactory.GetWpfTextViewHost(this.textView); this.Content = textViewHost.HostControl; this.editorCommandTarget = (IOleCommandTarget)this.textView; }
public int CreateEditorInstance( uint grfCreateDoc, string pszMkDocument, string pszPhysicalView, IVsHierarchy vsHierarchy, uint itemid, IntPtr punkDocDataExisting, out IntPtr ppunkDocView, out IntPtr ppunkDocData, out string pbstrEditorCaption, out Guid pguidCmdUI, out int pgrfCDW) { ppunkDocView = IntPtr.Zero; ppunkDocData = IntPtr.Zero; pbstrEditorCaption = string.Empty; pguidCmdUI = Guid.Empty; pgrfCDW = 0; var physicalView = pszPhysicalView == null ? "Code" : pszPhysicalView; IVsTextBuffer textBuffer = null; // Is this document already open? If so, let's see if it's a IVsTextBuffer we should re-use. This allows us // to properly handle multiple windows open for the same document. if (punkDocDataExisting != IntPtr.Zero) { object docDataExisting = Marshal.GetObjectForIUnknown(punkDocDataExisting); textBuffer = docDataExisting as IVsTextBuffer; if (textBuffer == null) { // We are incompatible with the existing doc data return(VSConstants.VS_E_INCOMPATIBLEDOCDATA); } } // Do we need to create a text buffer? if (textBuffer == null) { var contentType = _contentTypeRegistryService.GetContentType(ContentTypeName); textBuffer = _editorAdaptersFactoryService.CreateVsTextBufferAdapter(_oleServiceProvider, contentType); if (_encoding) { var userData = textBuffer as IVsUserData; if (userData != null) { // The editor shims require that the boxed value when setting the PromptOnLoad flag is a uint int hresult = userData.SetData( VSConstants.VsTextBufferUserDataGuid.VsBufferEncodingPromptOnLoad_guid, (uint)__PROMPTONLOADFLAGS.codepagePrompt); if (ErrorHandler.Failed(hresult)) { return(hresult); } } } } // If the text buffer is marked as read-only, ensure that the padlock icon is displayed // next the new window's title and that [Read Only] is appended to title. READONLYSTATUS readOnlyStatus = READONLYSTATUS.ROSTATUS_NotReadOnly; uint textBufferFlags; if (ErrorHandler.Succeeded(textBuffer.GetStateFlags(out textBufferFlags)) && 0 != (textBufferFlags & ((uint)BUFFERSTATEFLAGS.BSF_FILESYS_READONLY | (uint)BUFFERSTATEFLAGS.BSF_USER_READONLY))) { readOnlyStatus = READONLYSTATUS.ROSTATUS_ReadOnly; } switch (physicalView) { case "Form": // We must create the WinForms designer here const string LoaderName = "Microsoft.VisualStudio.Design.Serialization.CodeDom.VSCodeDomDesignerLoader"; var designerService = (IVSMDDesignerService)ServiceProvider.GetService(typeof(SVSMDDesignerService)); var designerLoader = (IVSMDDesignerLoader)designerService.CreateDesignerLoader(LoaderName); try { designerLoader.Initialize(_oleServiceProvider, vsHierarchy, (int)itemid, (IVsTextLines)textBuffer); pbstrEditorCaption = designerLoader.GetEditorCaption((int)readOnlyStatus); var designer = designerService.CreateDesigner(_oleServiceProvider, designerLoader); ppunkDocView = Marshal.GetIUnknownForObject(designer.View); pguidCmdUI = designer.CommandGuid; } catch { designerLoader.Dispose(); throw; } break; case "Code": var codeWindow = _editorAdaptersFactoryService.CreateVsCodeWindowAdapter(_oleServiceProvider); codeWindow.SetBuffer((IVsTextLines)textBuffer); codeWindow.GetEditorCaption(readOnlyStatus, out pbstrEditorCaption); ppunkDocView = Marshal.GetIUnknownForObject(codeWindow); pguidCmdUI = VSConstants.GUID_TextEditorFactory; break; default: return(VSConstants.E_INVALIDARG); } ppunkDocData = Marshal.GetIUnknownForObject(textBuffer); return(VSConstants.S_OK); }
/// <summary> /// Method to call to cause us to place the file at the given path into our hosted editor. /// </summary> public void SetDisplayedFile(string filePath) { ClearOldEditor(); //Get an invisible editor over the file, this makes it much easier than having to manually figure out the right content type, //language service, and it will automatically associate the document with its owning project, meaning we will get intellisense //in our editor with no extra work. IVsInvisibleEditorManager invisibleEditorManager = (IVsInvisibleEditorManager)GetService(typeof(SVsInvisibleEditorManager)); ErrorHandler.ThrowOnFailure(invisibleEditorManager.RegisterInvisibleEditor(filePath, pProject: null, dwFlags: (uint)_EDITORREGFLAGS.RIEF_ENABLECACHING, pFactory: null, ppEditor: out this.invisibleEditor)); //The doc data is the IVsTextLines that represents the in-memory version of the file we opened in our invisibe editor, we need //to extract that so that we can create our real (visible) editor. IntPtr docDataPointer = IntPtr.Zero; Guid guidIVSTextLines = typeof(IVsTextLines).GUID; ErrorHandler.ThrowOnFailure(this.invisibleEditor.GetDocData(fEnsureWritable: 1, riid: ref guidIVSTextLines, ppDocData: out docDataPointer)); try { IVsTextLines docData = (IVsTextLines)Marshal.GetObjectForIUnknown(docDataPointer); //Get the component model so we can request the editor adapter factory which we can use to spin up an editor instance. IComponentModel componentModel = (IComponentModel)GetService(typeof(SComponentModel)); IVsEditorAdaptersFactoryService editorAdapterFactoryService = componentModel.GetService <IVsEditorAdaptersFactoryService>(); //Create a code window adapter. this.codeWindow = editorAdapterFactoryService.CreateVsCodeWindowAdapter(OleServiceProvider); //Disable the splitter control on the editor as leaving it enabled causes a crash if the user //tries to use it here :( IVsCodeWindowEx codeWindowEx = (IVsCodeWindowEx)this.codeWindow; INITVIEW[] initView = new INITVIEW[1]; codeWindowEx.Initialize((uint)_codewindowbehaviorflags.CWB_DISABLESPLITTER, VSUSERCONTEXTATTRIBUTEUSAGE.VSUC_Usage_Filter, szNameAuxUserContext: "", szValueAuxUserContext: "", InitViewFlags: 0, pInitView: initView); //Associate our IVsTextLines with our new code window. ErrorHandler.ThrowOnFailure(this.codeWindow.SetBuffer((IVsTextLines)docData)); //Get our text view for our editor which we will use to get the WPF control that hosts said editor. ErrorHandler.ThrowOnFailure(this.codeWindow.GetPrimaryView(out this.textView)); //Get our WPF host from our text view (from our code window). IWpfTextViewHost textViewHost = editorAdapterFactoryService.GetWpfTextViewHost(this.textView); Debug.Assert(this.control != null); //We already have an open window, so just insert this editor in place of the old one. this.control.InsertNewEditor(textViewHost.HostControl); } finally { if (docDataPointer != IntPtr.Zero) { //Release the doc data from the invisible editor since it gave us a ref-counted copy. Marshal.Release(docDataPointer); } } }
private void CreateEditor(string filePath) { //IVsInvisibleEditors are in-memory represenations of typical Visual Studio editors. //Language services, highlighting and error squiggles are hooked up to these editors //for us once we convert them to WpfTextViews. IVsInvisibleEditor invisibleEditor; ErrorHandler.ThrowOnFailure(_invisibleEditorManager.RegisterInvisibleEditor( filePath , pProject: null , dwFlags: (uint)_EDITORREGFLAGS.RIEF_ENABLECACHING , pFactory: null , ppEditor: out invisibleEditor)); //Then when creating the IVsInvisibleEditor, find and lock the document IntPtr docData; IVsHierarchy hierarchy; var runningDocTable = (IVsRunningDocumentTable)Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(SVsRunningDocumentTable)); uint docCookie; ErrorHandler.ThrowOnFailure(runningDocTable.FindAndLockDocument( dwRDTLockType: (uint)_VSRDTFLAGS.RDT_ReadLock, pszMkDocument: filePath, ppHier: out hierarchy, pitemid: out uint itemId, ppunkDocData: out docData, pdwCookie: out docCookie)); IntPtr docDataPointer; var guidIVsTextLines = typeof(IVsTextLines).GUID; ErrorHandler.ThrowOnFailure(invisibleEditor.GetDocData( fEnsureWritable: 1 , riid: ref guidIVsTextLines , ppDocData: out docDataPointer)); _docData = (IVsTextLines)Marshal.GetObjectForIUnknown(docDataPointer); //Make Buffer Readonly _docData.GetStateFlags(out uint oldFlags); _docData.SetStateFlags(oldFlags | (uint)BUFFERSTATEFLAGS.BSF_USER_READONLY); //Create a code window adapter _codeWindow = _editorAdapter.CreateVsCodeWindowAdapter(ProfilerPlugin.Instance.OLEServiceProvider); //Disable the splitter control on the editor as leaving it enabled causes a crash if the user //tries to use it here :( IVsCodeWindowEx codeWindowEx = (IVsCodeWindowEx)_codeWindow; INITVIEW[] initView = new INITVIEW[1]; codeWindowEx.Initialize((uint)_codewindowbehaviorflags.CWB_DISABLESPLITTER,// | ((uint)TextViewInitFlags2.VIF_READONLY), VSUSERCONTEXTATTRIBUTEUSAGE.VSUC_Usage_Filter, szNameAuxUserContext: "", szValueAuxUserContext: "", InitViewFlags: 0, pInitView: initView); ErrorHandler.ThrowOnFailure(_codeWindow.SetBuffer(_docData)); //Get a text view for our editor which we will then use to get the WPF control for that editor. ErrorHandler.ThrowOnFailure(_codeWindow.GetPrimaryView(out _textView)); _textViewHost = _editorAdapter.GetWpfTextViewHost(_textView); }