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> |
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 | |
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 | |
37 | public static IWpfTextView GetDocumentView(Document document) |
38 | { |
39 | var textView = GetVsTextViewFrompPath(document.FullName); |
40 | return VsToWpfTextView(textView); |
41 | } |
42 | |
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 | |
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 | |
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 | |
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 | |
91 | public static string GetDocumentPath(IWpfTextView view) |
92 | { |
93 | return GetTextDocument(view)?.FilePath; |
94 | } |
95 | } |
96 | } |
97 | |