summaryrefslogtreecommitdiffstats
path: root/tools/clang-format-vs/ClangFormat/Vsix.cs
blob: 0d86cb59828a27bc65ef248aafa7538ff794fb2c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
using EnvDTE;
using Microsoft.VisualStudio.Editor;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Editor;
using Microsoft.VisualStudio.TextManager.Interop;
using System;
using System.IO;

namespace LLVM.ClangFormat
{
    internal sealed class Vsix
    {
        /// <summary>
        /// Returns the currently active view if it is a IWpfTextView.
        /// </summary>
        public static IWpfTextView GetCurrentView()
        {
            // The SVsTextManager is a service through which we can get the active view.
            var textManager = (IVsTextManager)Package.GetGlobalService(typeof(SVsTextManager));
            IVsTextView textView;
            textManager.GetActiveView(1, null, out textView);

            // Now we have the active view as IVsTextView, but the text interfaces we need
            // are in the IWpfTextView.
            return VsToWpfTextView(textView);
        }

        public static bool IsDocumentDirty(Document document)
        {
            var textView = GetDocumentView(document);
            var textDocument = GetTextDocument(textView);
            return textDocument?.IsDirty == true;
        }

        public static IWpfTextView GetDocumentView(Document document)
        {
            var textView = GetVsTextViewFrompPath(document.FullName);
            return VsToWpfTextView(textView);
        }

        public static IWpfTextView VsToWpfTextView(IVsTextView textView)
        {
            var userData = (IVsUserData)textView;
            if (userData == null)
                return null;
            Guid guidWpfViewHost = DefGuidList.guidIWpfTextViewHost;
            object host;
            userData.GetData(ref guidWpfViewHost, out host);
            return ((IWpfTextViewHost)host).TextView;
        }

        public static IVsTextView GetVsTextViewFrompPath(string filePath)
        {
            // From http://stackoverflow.com/a/2427368/4039972
            var dte2 = (EnvDTE80.DTE2)Package.GetGlobalService(typeof(SDTE));
            var sp = (Microsoft.VisualStudio.OLE.Interop.IServiceProvider)dte2;
            var serviceProvider = new Microsoft.VisualStudio.Shell.ServiceProvider(sp);

            IVsUIHierarchy uiHierarchy;
            uint itemID;
            IVsWindowFrame windowFrame;
            if (VsShellUtilities.IsDocumentOpen(serviceProvider, filePath, Guid.Empty,
                out uiHierarchy, out itemID, out windowFrame))
            {
                // Get the IVsTextView from the windowFrame.
                return VsShellUtilities.GetTextView(windowFrame);
            }
            return null;
        }

        public static ITextDocument GetTextDocument(IWpfTextView view)
        {
            ITextDocument document;
            if (view != null && view.TextBuffer.Properties.TryGetProperty(typeof(ITextDocument), out document))
                return document;
            return null;
        }

        public static string GetDocumentParent(IWpfTextView view)
        {
            ITextDocument document = GetTextDocument(view);
            if (document != null)
            {
                return Directory.GetParent(document.FilePath).ToString();
            }
            return null;
        }

        public static string GetDocumentPath(IWpfTextView view)
        {
            return GetTextDocument(view)?.FilePath;
        }
    }
}