Search code examples
visual-studio-2017vsix

VSIX how to get current snapshot document name?


I have been trying to to create an extension that highlights specific line numbers for me in Visual Studio in the margins.

I manged to get my marking in the margins using predefined line number but for it to work properly I need to know what the current document FullName is (Path and filename)

After much googling I figured out how to do it with the sample code (which is not ideal)

DTE2 dte = (DTE2)System.Runtime.InteropServices.Marshal.GetActiveObject("VisualStudio.DTE.15.0");

var activeDocument = dte.ActiveDocument;

var docName = activeDocument.Name;
var docFullName = activeDocument.FullName;

Now I know the problems here

  • is that is for specific version bases on the text
  • there is no way to select which instance (when running more than one VS)
  • It seems to be very slow

I have a feeling I should be doing this with MEF Attributes but the MS docs examples are so simple that they do not work for me. I scanned a few SO questions too and I just cannot get them to work. They mostly talk about Services.. which I do not have and have no idea how to get.

The rest of my code uses SnapshotSpans as in the example Extension of Todo_Classification examples which is great if you do NOT need to know the file name.

I have never done any extensions development. Please can somebody help me do this correctly.


Solution

  • You can use following code to get a file from a snapshot without any dependencies.

        public string GetDocumentPath(Microsoft.VisualStudio.Text.ITextSnapshot ts)
        {
            Microsoft.VisualStudio.Text.ITextDocument textDoc;
            bool rc = ts.TextBuffer.Properties.TryGetProperty(
                typeof(Microsoft.VisualStudio.Text.ITextDocument), out textDoc);
            if (rc && textDoc != null)
                return textDoc.FilePath;
            return null;
        }
    

    If you don't mind adding Microsoft.CodeAnalysis.EditorFeatures.Text to your project it will provide you with an extension method Document GetOpenDocumentInCurrentContextWithChanges() on the Microsoft.VisualStudio.Text.Snapshot class. (Plus many other Rosyln based helpers)

    using Microsoft.CodeAnalysis.Text;
    
    Document doc = span.Snapshot.GetOpenDocumentInCurrentContextWithChanges();