r289910 - clang-format-vsix: add command to format document

Antonio Maiorano via cfe-commits cfe-commits at lists.llvm.org
Thu Dec 15 17:51:43 PST 2016


Author: amaiorano
Date: Thu Dec 15 19:51:43 2016
New Revision: 289910

URL: http://llvm.org/viewvc/llvm-project?rev=289910&view=rev
Log:
clang-format-vsix: add command to format document

Bound to Ctrl+R, Ctrl+D by default. Also added section on how to debug the extension to the Readme.

Differential Revision: https://reviews.llvm.org/D27501

Modified:
    cfe/trunk/tools/clang-format-vs/.gitignore
    cfe/trunk/tools/clang-format-vs/ClangFormat/ClangFormat.vsct
    cfe/trunk/tools/clang-format-vs/ClangFormat/ClangFormatPackage.cs
    cfe/trunk/tools/clang-format-vs/ClangFormat/PkgCmdID.cs
    cfe/trunk/tools/clang-format-vs/README.txt

Modified: cfe/trunk/tools/clang-format-vs/.gitignore
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/clang-format-vs/.gitignore?rev=289910&r1=289909&r2=289910&view=diff
==============================================================================
--- cfe/trunk/tools/clang-format-vs/.gitignore (original)
+++ cfe/trunk/tools/clang-format-vs/.gitignore Thu Dec 15 19:51:43 2016
@@ -1,5 +1,6 @@
 # Visual Studio files
 .vs/
+*.user
 /packages/
 /ClangFormat/obj/
 /ClangFormat/bin/

Modified: cfe/trunk/tools/clang-format-vs/ClangFormat/ClangFormat.vsct
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/clang-format-vs/ClangFormat/ClangFormat.vsct?rev=289910&r1=289909&r2=289910&view=diff
==============================================================================
--- cfe/trunk/tools/clang-format-vs/ClangFormat/ClangFormat.vsct (original)
+++ cfe/trunk/tools/clang-format-vs/ClangFormat/ClangFormat.vsct Thu Dec 15 19:51:43 2016
@@ -61,15 +61,21 @@
               <CommandFlag>DynamicVisibility</CommandFlag>
           If you do not want an image next to your command, remove the Icon node /> -->
 
-      <Button guid="guidClangFormatCmdSet" id="cmdidClangFormat" priority="0x0100" type="Button">
+      <Button guid="guidClangFormatCmdSet" id="cmdidClangFormatSelection" priority="0x0100" type="Button">
         <Parent guid="guidClangFormatCmdSet" id="MyMenuGroup" />
         <Icon guid="guidImages" id="bmpPic1" />
         <Strings>
-          <ButtonText>ClangFormat</ButtonText>
+          <ButtonText>Clang Format Selection</ButtonText>
         </Strings>
       </Button>
 
-
+      <Button guid="guidClangFormatCmdSet" id="cmdidClangFormatDocument" priority="0x0101" type="Button">
+        <Parent guid="guidClangFormatCmdSet" id="MyMenuGroup" />
+        <Icon guid="guidImages" id="bmpPic2" />
+        <Strings>
+          <ButtonText>Clang Format Document</ButtonText>
+        </Strings>
+      </Button>
 
     </Buttons>
    
@@ -88,7 +94,8 @@
 
 
   <KeyBindings>
-    <KeyBinding guid="guidClangFormatCmdSet" id="cmdidClangFormat" editor="guidTextEditor" key1="R" mod1="Control" key2="F" mod2="Control"/>
+    <KeyBinding guid="guidClangFormatCmdSet" id="cmdidClangFormatSelection" editor="guidTextEditor" key1="R" mod1="Control" key2="F" mod2="Control"/>
+    <KeyBinding guid="guidClangFormatCmdSet" id="cmdidClangFormatDocument" editor="guidTextEditor" key1="R" mod1="Control" key2="D" mod2="Control"/>
   </KeyBindings>
 
 
@@ -101,7 +108,8 @@
     <GuidSymbol name="guidClangFormatCmdSet" value="{e39cbab1-0f96-4022-a2bc-da5a9db7eb78}">
 
       <IDSymbol name="MyMenuGroup" value="0x1020" />
-      <IDSymbol name="cmdidClangFormat" value="0x0100" />
+      <IDSymbol name="cmdidClangFormatSelection" value="0x0100" />
+      <IDSymbol name="cmdidClangFormatDocument" value="0x0101" />
     </GuidSymbol>
 
     <GuidSymbol name="guidTextEditor" value="{8B382828-6202-11d1-8870-0000F87579D2}" />

Modified: cfe/trunk/tools/clang-format-vs/ClangFormat/ClangFormatPackage.cs
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/clang-format-vs/ClangFormat/ClangFormatPackage.cs?rev=289910&r1=289909&r2=289910&view=diff
==============================================================================
--- cfe/trunk/tools/clang-format-vs/ClangFormat/ClangFormatPackage.cs (original)
+++ cfe/trunk/tools/clang-format-vs/ClangFormat/ClangFormatPackage.cs Thu Dec 15 19:51:43 2016
@@ -180,15 +180,44 @@ namespace LLVM.ClangFormat
             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);
+                {
+                    var menuCommandID = new CommandID(GuidList.guidClangFormatCmdSet, (int)PkgCmdIDList.cmdidClangFormatSelection);
+                    var menuItem = new MenuCommand(MenuItemCallback, menuCommandID);
+                    commandService.AddCommand(menuItem);
+                }
+
+                {
+                    var menuCommandID = new CommandID(GuidList.guidClangFormatCmdSet, (int)PkgCmdIDList.cmdidClangFormatDocument);
+                    var menuItem = new MenuCommand(MenuItemCallback, menuCommandID);
+                    commandService.AddCommand(menuItem);
+                }
             }
         }
         #endregion
 
         private void MenuItemCallback(object sender, EventArgs args)
         {
+            var mc = sender as System.ComponentModel.Design.MenuCommand;
+            if (mc == null)
+                return;
+
+            switch (mc.CommandID.ID)
+            {
+                case (int)PkgCmdIDList.cmdidClangFormatSelection:
+                    FormatSelection();
+                    break;
+
+                case (int)PkgCmdIDList.cmdidClangFormatDocument:
+                    FormatDocument();
+                    break;
+            }
+        }
+
+        /// <summary>
+        /// Runs clang-format on the current selection
+        /// </summary>
+        private void FormatSelection()
+        {
             IWpfTextView view = GetCurrentView();
             if (view == null)
                 // We're not in a text view.
@@ -197,24 +226,40 @@ namespace LLVM.ClangFormat
             int start = view.Selection.Start.Position.GetContainingLine().Start.Position;
             int end = view.Selection.End.Position.GetContainingLine().End.Position;
             int length = end - start;
+            
             // clang-format doesn't support formatting a range that starts at the end
             // of the file.
             if (start >= text.Length && text.Length > 0)
                 start = text.Length - 1;
             string path = GetDocumentParent(view);
             string filePath = GetDocumentPath(view);
+
+            RunClangFormatAndApplyReplacements(text, start, length, path, filePath, view);
+        }
+
+        /// <summary>
+        /// Runs clang-format on the current document
+        /// </summary>
+        private void FormatDocument()
+        {
+            IWpfTextView view = GetCurrentView();
+            if (view == null)
+                // We're not in a text view.
+                return;
+
+            string filePath = GetDocumentPath(view);
+            var path = Path.GetDirectoryName(filePath);
+            string text = view.TextBuffer.CurrentSnapshot.GetText();
+
+            RunClangFormatAndApplyReplacements(text, 0, text.Length, path, filePath, view);
+        }
+
+        private void RunClangFormatAndApplyReplacements(string text, int offset, int length, string path, string filePath, IWpfTextView view)
+        {
             try
             {
-                var root = XElement.Parse(RunClangFormat(text, start, length, path, filePath));
-                var edit = view.TextBuffer.CreateEdit();
-                foreach (XElement replacement in root.Descendants("replacement"))
-                {
-                    var span = new Span(
-                        int.Parse(replacement.Attribute("offset").Value),
-                        int.Parse(replacement.Attribute("length").Value));
-                    edit.Replace(span, replacement.Value);
-                }
-                edit.Apply();
+                string replacements = RunClangFormat(text, offset, length, path, filePath);
+                ApplyClangFormatReplacements(replacements, view);
             }
             catch (Exception e)
             {
@@ -305,6 +350,27 @@ namespace LLVM.ClangFormat
         }
 
         /// <summary>
+        /// Applies the clang-format replacements (xml) to the current view
+        /// </summary>
+        private void ApplyClangFormatReplacements(string replacements, IWpfTextView view)
+        {
+            // clang-format returns no replacements if input text is empty
+            if (replacements.Length == 0)
+                return;
+
+            var root = XElement.Parse(replacements);
+            var edit = view.TextBuffer.CreateEdit();
+            foreach (XElement replacement in root.Descendants("replacement"))
+            {
+                var span = new Span(
+                    int.Parse(replacement.Attribute("offset").Value),
+                    int.Parse(replacement.Attribute("length").Value));
+                edit.Replace(span, replacement.Value);
+            }
+            edit.Apply();
+        }
+
+        /// <summary>
         /// Returns the currently active view if it is a IWpfTextView.
         /// </summary>
         private IWpfTextView GetCurrentView()

Modified: cfe/trunk/tools/clang-format-vs/ClangFormat/PkgCmdID.cs
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/clang-format-vs/ClangFormat/PkgCmdID.cs?rev=289910&r1=289909&r2=289910&view=diff
==============================================================================
--- cfe/trunk/tools/clang-format-vs/ClangFormat/PkgCmdID.cs (original)
+++ cfe/trunk/tools/clang-format-vs/ClangFormat/PkgCmdID.cs Thu Dec 15 19:51:43 2016
@@ -2,6 +2,7 @@
 {
     static class PkgCmdIDList
     {
-        public const uint cmdidClangFormat = 0x100;
+        public const uint cmdidClangFormatSelection = 0x100;
+        public const uint cmdidClangFormatDocument = 0x101;
     };
 }
\ No newline at end of file

Modified: cfe/trunk/tools/clang-format-vs/README.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/clang-format-vs/README.txt?rev=289910&r1=289909&r2=289910&view=diff
==============================================================================
--- cfe/trunk/tools/clang-format-vs/README.txt (original)
+++ cfe/trunk/tools/clang-format-vs/README.txt Thu Dec 15 19:51:43 2016
@@ -25,3 +25,27 @@ directory so they can be bundled with th
 ClangFormat/source.extension.vsixmanifest. Once the plug-in has been built with
 CMake once, it can be built manually from the ClangFormat.sln solution in Visual
 Studio.
+
+===========
+ Debugging
+===========
+
+Once you've built the clang_format_vsix project from LLVM.sln at least once,
+open ClangFormat.sln in Visual Studio, then:
+
+- Make sure the "Debug" target is selected
+- Open the ClangFormat project properties
+- Select the Debug tab
+- Set "Start external program:" to where your devenv.exe is installed. Typically
+  it's "C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\devenv.exe"
+- Set "Command line arguments" to: /rootsuffix Exp
+- You can now set breakpoints if you like
+- Press F5 to build and run with debugger
+
+If all goes well, a new instance of Visual Studio will be launched in a special
+mode where it uses the experimental hive instead of the normal configuration hive.
+By default, when you build a VSIX project in Visual Studio, it auto-registers the
+extension in the experimental hive, allowing you to test it. In the new Visual Studio
+instance, open or create a C++ solution, and you should now see the Clang Format
+entries in the Tool menu. You can test it out, and any breakpoints you set will be
+hit where you can debug as usual.




More information about the cfe-commits mailing list