berenm updated this revision to Diff 42718.
berenm added a comment.

- Patch rebased on trunk
- Small cleanups in the RunningDocumentTable usage
- Tested and appears work on VS >= 2012


http://reviews.llvm.org/D12407

Files:
  tools/clang-format-vs/ClangFormat/ClangFormat.csproj
  tools/clang-format-vs/ClangFormat/ClangFormatPackage.cs

Index: tools/clang-format-vs/ClangFormat/ClangFormatPackage.cs
===================================================================
--- tools/clang-format-vs/ClangFormat/ClangFormatPackage.cs
+++ tools/clang-format-vs/ClangFormat/ClangFormatPackage.cs
@@ -12,12 +12,14 @@
 //
 //===----------------------------------------------------------------------===//
 
+using Microsoft.VisualStudio;
 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 Microsoft.VisualStudio.ComponentModelHost;
 using System;
 using System.Collections;
 using System.ComponentModel;
@@ -163,28 +165,51 @@
             get { return sortIncludes; }
             set { sortIncludes = value; }
         }
+
+        [Category("LLVM/Clang")]
+        [DisplayName("Reformat On Save")]
+        [Description("Reformat code when the source file is saved on disk")]
+        public bool ReformatOnSave
+        {
+            get;
+            set;
+        }
     }
 
     [PackageRegistration(UseManagedResourcesOnly = true)]
     [InstalledProductRegistration("#110", "#112", "1.0", IconResourceID = 400)]
     [ProvideMenuResource("Menus.ctmenu", 1)]
     [Guid(GuidList.guidClangFormatPkgString)]
     [ProvideOptionPage(typeof(OptionPageGrid), "LLVM/Clang", "ClangFormat", 0, 0, true)]
-    public sealed class ClangFormatPackage : Package
+    [ProvideAutoLoad(UIContextGuids80.NoSolution)]
+    public sealed class ClangFormatPackage : Package, IVsRunningDocTableEvents3
     {
+        private RunningDocumentTable runningDocumentTable;
+        private uint adviseCookie;
+
         #region Package Members
         protected override void Initialize()
         {
             base.Initialize();
 
+            runningDocumentTable = new RunningDocumentTable(this);
+            adviseCookie = runningDocumentTable.Advise(this);
+
             var commandService = GetService(typeof(IMenuCommandService)) as OleMenuCommandService;
             if (commandService != null)
             {
                 var menuCommandID = new CommandID(GuidList.guidClangFormatCmdSet, (int)PkgCmdIDList.cmdidClangFormat);
                 var menuItem = new MenuCommand(MenuItemCallback, menuCommandID);
                 commandService.AddCommand(menuItem);
             }
         }
+
+        protected override void Dispose(bool disposing)
+        {
+            runningDocumentTable.Unadvise(adviseCookie);
+
+            base.Dispose(disposing);
+        }
         #endregion
 
         private void MenuItemCallback(object sender, EventArgs args)
@@ -202,10 +227,16 @@
             if (start >= text.Length && text.Length > 0)
                 start = text.Length - 1;
             string path = GetDocumentParent(view);
+            FormatTextBuffer(view.TextBuffer, start, length, path);
+        }
+
+        private void FormatTextBuffer(ITextBuffer textBuffer, int offset, int length, string path)
+        {
             try
             {
-                var root = XElement.Parse(RunClangFormat(text, start, length, path));
-                var edit = view.TextBuffer.CreateEdit();
+                string text = textBuffer.CurrentSnapshot.GetText();
+                var root = XElement.Parse(RunClangFormat(text, offset, length, path));
+                var edit = textBuffer.CreateEdit();
                 foreach (XElement replacement in root.Descendants("replacement"))
                 {
                     var span = new Span(
@@ -316,7 +347,7 @@
             var userData = (IVsUserData)textView;
             if (userData == null)
                 return null;
-            Guid guidWpfViewHost = DefGuidList.guidIWpfTextViewHost;
+            Guid guidWpfViewHost = Microsoft.VisualStudio.Editor.DefGuidList.guidIWpfTextViewHost;
             object host;
             userData.GetData(ref guidWpfViewHost, out host);
             return ((IWpfTextViewHost)host).TextView;
@@ -346,6 +377,12 @@
             return page.SortIncludes;
         }
 
+        private bool ShouldReformatOnSave()
+        {
+            var page = (OptionPageGrid)GetDialogPage(typeof(OptionPageGrid));
+            return page.ReformatOnSave;
+        }
+
         private string GetDocumentParent(IWpfTextView view)
         {
             ITextDocument document;
@@ -355,5 +392,78 @@
             }
             return null;
         }
+
+        public int OnAfterFirstDocumentLock(uint docCookie, uint dwRDTLockType,
+            uint dwReadLocksRemaining, uint dwEditLocksRemaining)
+        {
+            return VSConstants.S_OK;
+        }
+
+        public int OnBeforeLastDocumentUnlock(uint docCookie, uint dwRDTLockType,
+            uint dwReadLocksRemaining, uint dwEditLocksRemaining)
+        {
+            return VSConstants.S_OK;
+        }
+
+        public int OnAfterSave(uint docCookie)
+        {
+            return VSConstants.S_OK;
+        }
+
+        public int OnAfterAttributeChange(uint docCookie, uint grfAttribs)
+        {
+            return VSConstants.S_OK;
+        }
+
+        public int OnBeforeDocumentWindowShow(uint docCookie, int fFirstShow, IVsWindowFrame pFrame)
+        {
+            return VSConstants.S_OK;
+        }
+
+        public int OnAfterDocumentWindowHide(uint docCookie, IVsWindowFrame pFrame)
+        {
+            return VSConstants.S_OK;
+        }
+
+        public int OnAfterAttributeChangeEx(uint docCookie, uint grfAttribs,
+            IVsHierarchy pHierOld, uint itemidOld, string pszMkDocumentOld,
+            IVsHierarchy pHierNew, uint itemidNew, string pszMkDocumentNew)
+        {
+            return VSConstants.S_OK;
+        }
+
+        public int OnBeforeSave(uint docCookie)
+        {
+            if (!ShouldReformatOnSave())
+                return VSConstants.S_OK;
+
+            var documentInfo = runningDocumentTable.GetDocumentInfo(docCookie);
+            if (documentInfo.DocData == null)
+                return VSConstants.S_OK;
+
+            var buffer = documentInfo.DocData as IVsTextBuffer;
+            if (buffer == null)
+                return VSConstants.S_OK;
+
+            var componentModel = GetService(typeof(SComponentModel)) as IComponentModel;
+            if (componentModel == null)
+                return VSConstants.S_OK;
+
+            var editorAdaptersFactoryService = componentModel.GetService<IVsEditorAdaptersFactoryService>();
+            if (editorAdaptersFactoryService == null)
+                return VSConstants.S_OK;
+            
+            var textBuffer = editorAdaptersFactoryService.GetDocumentBuffer(buffer);
+            if (textBuffer == null)
+                return VSConstants.S_OK;
+
+            if (!textBuffer.ContentType.IsOfType("C/C++"))
+                return VSConstants.S_OK;
+
+            string text = textBuffer.CurrentSnapshot.GetText();
+            FormatTextBuffer(textBuffer, 0, text.Length, Directory.GetParent(documentInfo.Moniker).ToString());
+
+            return VSConstants.S_OK;
+        }
     }
 }
Index: tools/clang-format-vs/ClangFormat/ClangFormat.csproj
===================================================================
--- tools/clang-format-vs/ClangFormat/ClangFormat.csproj
+++ tools/clang-format-vs/ClangFormat/ClangFormat.csproj
@@ -57,6 +57,7 @@
   <ItemGroup>
     <Reference Include="Microsoft.CSharp" />
     <Reference Include="Microsoft.VisualStudio.CoreUtility, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
+    <Reference Include="Microsoft.VisualStudio.ComponentModelHost" />
     <Reference Include="Microsoft.VisualStudio.Editor, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
     <Reference Include="Microsoft.VisualStudio.OLE.Interop" />
     <Reference Include="Microsoft.VisualStudio.Shell.Interop" />
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to