c# - How do you use a projection buffer to support embedded languages in the Visual Studio editor -


at end of first paragraph in link states:

the visual studio text outlining feature implemented using projection buffer hide collapsed text, , the visual studio editor asp.net pages uses projection support embedded languages such visual basic , c#.

i have searched , searched have not found examples or documentation @ accomplish this, have idea how done? have gotten classification working , created projection buffer of spans want classified c# code. set buffers context type "csharp" spans never classified. have tried base content type "projection" work either.

i've managed embed projection buffers in tool window , hook them c#'s language services. 1 caveat: approach works visual studio using roslyn. i've published github project can use accompanying blog post.

the answer question long , involves many moving pieces doesn't lend stackoverflow style of q&a well. being said, i'll summarize necessary steps , include relevant code.

the following sample creates projection buffer of file comprised of first 100 characters of file.

we first create ivsinvisibleeditor given filepath , create code window it. set contents of code window ivstextlines of ivsinvisibleeditor.

we set custom role "customprojectionrole" on text buffer of code window. role allows customize text buffer via mef exported itextviewmodelprovider.

public iwpftextviewhost createeditor(string filepath, int start = 0, int end = 100) {     //ivsinvisibleeditors in-memory represenations of typical visual studio editors.     //language services, highlighting , error squiggles hooked these editors     //for once convert them 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 code window adapter     var codewindow = _editoradapter.createvscodewindowadapter(visualstudioservices.oleserviceprovider);     errorhandler.throwonfailure(codewindow.setbuffer(docdata));      //get text view our editor use wpf control editor.     ivstextview textview;     errorhandler.throwonfailure(codewindow.getprimaryview(out textview));      //we add our own role text view. later allow selectively modify     //this editor without getting in way of visual studio's normal editors.     var roles = _editorfactoryservice.defaultroles.concat(new string[] { "customprojectionrole" });      var vstextbuffer = docdata 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; } 

we create ivstextviewmodelprovider creates , returns projectiontextviewmodel. projectiontextviewmodel saves projection buffer within visual buffer. means when buffer displayed, projection buffer shown. however, language services of backing data buffer operate correctly.

[export(typeof(itextviewmodelprovider)), contenttype("csharp"), textviewrole("customprojectionrole")] internal class projectiontextviewmodelprovider : itextviewmodelprovider {     public itextviewmodel createtextviewmodel(itextdatamodel datamodel, itextviewroleset roles)     {         //create projection buffer based on specified start , end position.         var projectionbuffer = createprojectionbuffer(datamodel);         //display projection buffer in visual buffer, while still maintaining         //the full file buffer underlying data buffer.         var textviewmodel = new projectiontextviewmodel(datamodel, projectionbuffer);         return textviewmodel;      }      public iprojectionbuffer createprojectionbuffer(itextdatamodel datamodel)     {         //retrieve start , end position saved in mytoolwindow.createeditor()         var startposition = (int)datamodel.databuffer.properties.getproperty("startposition");         var endposition = (int)datamodel.databuffer.properties.getproperty("endposition");         var length = endposition - startposition;          //take snapshot of text within these indices.         var textsnapshot = datamodel.databuffer.currentsnapshot;         var trackingspan = textsnapshot.createtrackingspan(startposition, length, spantrackingmode.edgeexclusive);          //create actual projection buffer         var projectionbuffer = projectionbufferfactory.createprojectionbuffer(             null             , new list<object>() { trackingspan }             , projectionbufferoptions.none             );         return projectionbuffer;     }       [import]     public iprojectionbufferfactoryservice projectionbufferfactory { get; set; } } 

hopefully gets future visitors off start.


Comments

Popular posts from this blog

apache - Remove .php and add trailing slash in url using htaccess not loading css -

javascript - jQuery show full size image on click -