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