Add Syntax Highlighting to IElisonBuffer
Asked Answered
U

1

2

I'm working on a project where we've split up C# code into functions and stored these functions within IElisonBuffers. I've got Intellisense hooked up, and the buffers interact with other extensions fine as shown below:

enter image description here

However, I cannot get syntax highlighting to work within these editors.

I embed these editors via the following steps:

  1. Create an IVsInvisibleEditor for the file.
  2. Get the IVsTextLines for this IVsInvisibleEditor
  3. Create an IVsCodeWindow and set the buffer for this IVsCodeWindow to be the IVsTextLines from the IVsInvisibleEditor
  4. Get an IWpfTextViewHost from this code window. This brings me back to "WPF Land" where I'm able to interact with traditional spans.
  5. Create a SnapshotSpan of the IWpfTextViewHost's text view. This SnapshotSpan contains a single function.
  6. Create an IElisionBuffer containing the SnapshotSpan.
  7. Create an IVsTextBuffer via IVsEditorAdaptersFactoryService.CreateVsTextBufferAdapterForSecondaryBuffer() passing in the IElisionBuffer.
  8. Now I cast the IVsTextBuffer to IVsTextLines and call SetLanguageServiceID() passing in the C# GUID: 694DD9B6-B865-4C5B-AD85-86356E9C88DC.
  9. I double check that it was set correctly via GetLanguageServiceID() and everything looks alright.
  10. I create an IVsTextView and initialize it with the new IVsTextBuffer.
  11. I then get the IWpfTextViewHost for this IVsTextView.

Are there any special steps that need to be taken care of when setting up the language service ID for an IElisionBuffer?

For the sake of completeness this is the code I'm using:

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);
}
Unquestioning answered 28/2, 2014 at 2:42 Comment(0)
O
3

Make the content type of your elision buffer be, or derive from, the content type "projection". That's the hint that taggers should project through that.

Oakman answered 28/2, 2014 at 2:45 Comment(3)
If I create the Elision Buffer with the ProjectionContentType, I get syntax highlighting, but lose Intellisense and VsVim within the editor (plugins don't hook up to it like they should). Are there any options for manually setting up the syntax highlighting? I'm worried manually setting up Intellisense will be more difficult.Unquestioning
Thanks for your help. My error was in part due to incorrect content types and part due to creating multiple IVsInvisibleEditors for single files.Unquestioning
I am doing something similar. But I am using a temporary file path that is not part of the solution. It has some parsing errors in it. Those parsing errors appear in the error list, is there someway to tell visual studio to not show parsing errors in the error list window?Worrell

© 2022 - 2024 — McMap. All rights reserved.