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; } } } |