向IElisonBuffer添加语法突出显示

时间:2014-02-28 02:42:29

标签: c# visual-studio syntax-highlighting vspackage languageservice

我正在开发一个项目,我们将C#代码分解为函数并将这些函数存储在IElisonBuffers中。我已经将Intellisense连接起来了,缓冲区与其他扩展交互得很好,如下所示:

enter image description here

但是,我无法在这些编辑器中使用语法突出显示。

我通过以下步骤嵌入这些编辑器:

  1. 为文件创建IVsInvisibleEditor
  2. 获取此IVsTextLines
  3. IVsInvisibleEditor
  4. 创建IVsCodeWindow并将此IVsCodeWindow的缓冲区设置为IVsTextLines
  5. 中的IVsInvisibleEditor
  6. 从此代码窗口获取IWpfTextViewHost。这让我回到了“WPF Land”,在那里我能够与传统的跨度互动。
  7. 创建IWpfTextViewHost文本视图的SnapshotSpan。此SnapshotSpan包含单个函数。
  8. 创建包含SnapshotSpan的IElisionBuffer
  9. 通过IVsTextBuffer传递IVsEditorAdaptersFactoryService.CreateVsTextBufferAdapterForSecondaryBuffer()来创建IElisionBuffer
  10. 现在我将IVsTextBuffer转换为IVsTextLines并通过C#GUID传递SetLanguageServiceID():694DD9B6-B865-4C5B-AD85-86356E9C88DC。
  11. 我仔细检查它是否通过GetLanguageServiceID()正确设置,一切看起来都没问题。
  12. 我创建了一个IVsTextView并使用新的IVsTextBuffer初始化它。
  13. 然后,我为此IWpfTextViewHost获取IVsTextView
  14. 在为IElisionBuffer设置语言服务ID时是否需要注意哪些特殊步骤?

    为了完整起见,这是我正在使用的代码:

    public CustomEditorViewModel CreateEditor(string filePath, int start, int end) {
    
    IVsInvisibleEditor invisibleEditor;
    ErrorHandler.ThrowOnFailure(this._InvisibleEditorManager.RegisterInvisibleEditor(
        filePath
        , pProject: null
        , dwFlags: (uint)_EDITORREGFLAGS.RIEF_ENABLECACHING
        , pFactory: null
        , ppEditor: out invisibleEditor));
    
    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);
    
    //Createa a code window adapter
    var codeWindow = _EditorAdapterFactory.CreateVsCodeWindowAdapter(VisualStudioServices.OLEServiceProvider);
    
    //Associate our IVsTextLines with our new code window
    ErrorHandler.ThrowOnFailure(codeWindow.SetBuffer(docData));
    
    //Get our text view for our editor which we will use to get the WPF control that hosts that editor.
    IVsTextView textView;
    ErrorHandler.ThrowOnFailure(codeWindow.GetPrimaryView(out textView));
    
    //This is our TextViewHost
    //It transports us back into the land of WPF 
    IWpfTextViewHost textViewHost = _EditorAdapterFactory.GetWpfTextViewHost(textView);
    
      //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      //Now we need to subset TextBuffer somehow... 
      //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    int length = end - start;
    SnapshotSpan subsetSnapshot = new SnapshotSpan(textViewHost.TextView.TextSnapshot, start, length);
    
    var CSharpType = _contentTypeRegistry.GetContentType("CSharp");
    
    var projBuffer = _ProjectionBufferFactory.CreateElisionBuffer(
      null
      , new NormalizedSnapshotSpanCollection(subsetSnapshot)
      , ElisionBufferOptions.None
      ,CSharpType);
    
    IVsTextBuffer bufferAdapter = _EditorAdapterFactory.CreateVsTextBufferAdapterForSecondaryBuffer(VisualStudioServices.OLEServiceProvider, projBuffer);
    
    //My attempt at getting syntax coloring to work:
    Guid CSharpLanguageServiceId = new Guid("694DD9B6-B865-4C5B-AD85-86356E9C88DC");
    IVsTextLines buffer = (IVsTextLines)bufferAdapter;
    buffer.SetLanguageServiceID(ref CSharpLanguageServiceId);
    
    
    IVsTextView projTextView = _EditorAdapterFactory.CreateVsTextViewAdapter(VisualStudioServices.OLEServiceProvider);
    
    projTextView.Initialize(
                (IVsTextLines)bufferAdapter
                , IntPtr.Zero
                , (uint)TextViewInitFlags.VIF_HSCROLL | (uint)TextViewInitFlags.VIF_VSCROLL | (uint)TextViewInitFlags3.VIF_NO_HWND_SUPPORT,
                        new[] { new INITVIEW { fSelectionMargin = 0, fWidgetMargin = 0, fVirtualSpace = 0, fDragDropMove = 0 } }
                    );
    
    
     return _EditorAdapterFactory.GetWpfTextViewHost(projTextView);
    }
    

1 个答案:

答案 0 :(得分:3)

使elision缓冲区的内容类型为内容类型“projection”,或者从内容类型“projection”派生。这是标记者应该通过它进行投射的暗示。