Clang Project

clang_source_code/tools/clang-format-vs/ClangFormat/Vsix.cs
1using EnvDTE;
2using Microsoft.VisualStudio.Editor;
3using Microsoft.VisualStudio.Shell;
4using Microsoft.VisualStudio.Shell.Interop;
5using Microsoft.VisualStudio.Text;
6using Microsoft.VisualStudio.Text.Editor;
7using Microsoft.VisualStudio.TextManager.Interop;
8using System;
9using System.IO;
10
11namespace 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