1 using EnvDTE;
2 using Microsoft.VisualStudio.Editor;
3 using Microsoft.VisualStudio.Shell;
4 using Microsoft.VisualStudio.Shell.Interop;
5 using Microsoft.VisualStudio.Text;
6 using Microsoft.VisualStudio.Text.Editor;
7 using Microsoft.VisualStudio.TextManager.Interop;
8 using System;
9 using System.IO;
10 
11 namespace LLVM.ClangFormat
12 {
13     internal sealed class Vsix
14     {
15         /// <summary>
16         /// Returns the currently active view if it is a IWpfTextView.
17         /// </summary>
GetCurrentView()18         public static IWpfTextView GetCurrentView()
19         {
20             // The SVsTextManager is a service through which we can get the active view.
21             var textManager = (IVsTextManager)Package.GetGlobalService(typeof(SVsTextManager));
22             IVsTextView textView;
23             textManager.GetActiveView(1, null, out textView);
24 
25             // Now we have the active view as IVsTextView, but the text interfaces we need
26             // are in the IWpfTextView.
27             return VsToWpfTextView(textView);
28         }
29 
IsDocumentDirty(Document document)30         public static bool IsDocumentDirty(Document document)
31         {
32             var textView = GetDocumentView(document);
33             var textDocument = GetTextDocument(textView);
34             return textDocument?.IsDirty == true;
35         }
36 
GetDocumentView(Document document)37         public static IWpfTextView GetDocumentView(Document document)
38         {
39             var textView = GetVsTextViewFrompPath(document.FullName);
40             return VsToWpfTextView(textView);
41         }
42 
VsToWpfTextView(IVsTextView textView)43         public static IWpfTextView VsToWpfTextView(IVsTextView textView)
44         {
45             var userData = (IVsUserData)textView;
46             if (userData == null)
47                 return null;
48             Guid guidWpfViewHost = DefGuidList.guidIWpfTextViewHost;
49             object host;
50             userData.GetData(ref guidWpfViewHost, out host);
51             return ((IWpfTextViewHost)host).TextView;
52         }
53 
GetVsTextViewFrompPath(string filePath)54         public static IVsTextView GetVsTextViewFrompPath(string filePath)
55         {
56             // From http://stackoverflow.com/a/2427368/4039972
57             var dte2 = (EnvDTE80.DTE2)Package.GetGlobalService(typeof(SDTE));
58             var sp = (Microsoft.VisualStudio.OLE.Interop.IServiceProvider)dte2;
59             var serviceProvider = new Microsoft.VisualStudio.Shell.ServiceProvider(sp);
60 
61             IVsUIHierarchy uiHierarchy;
62             uint itemID;
63             IVsWindowFrame windowFrame;
64             if (VsShellUtilities.IsDocumentOpen(serviceProvider, filePath, Guid.Empty,
65                 out uiHierarchy, out itemID, out windowFrame))
66             {
67                 // Get the IVsTextView from the windowFrame.
68                 return VsShellUtilities.GetTextView(windowFrame);
69             }
70             return null;
71         }
72 
GetTextDocument(IWpfTextView view)73         public static ITextDocument GetTextDocument(IWpfTextView view)
74         {
75             ITextDocument document;
76             if (view != null && view.TextBuffer.Properties.TryGetProperty(typeof(ITextDocument), out document))
77                 return document;
78             return null;
79         }
80 
GetDocumentParent(IWpfTextView view)81         public static string GetDocumentParent(IWpfTextView view)
82         {
83             ITextDocument document = GetTextDocument(view);
84             if (document != null)
85             {
86                 return Directory.GetParent(document.FilePath).ToString();
87             }
88             return null;
89         }
90 
GetDocumentPath(IWpfTextView view)91         public static string GetDocumentPath(IWpfTextView view)
92         {
93             return GetTextDocument(view)?.FilePath;
94         }
95     }
96 }
97