This revision was automatically updated to reflect the committed changes. Closed by commit rL289910: clang-format-vsix: add command to format document (authored by amaiorano).
Changed prior to commit: https://reviews.llvm.org/D27501?vs=80533&id=81701#toc Repository: rL LLVM https://reviews.llvm.org/D27501 Files: 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
Index: cfe/trunk/tools/clang-format-vs/README.txt =================================================================== --- cfe/trunk/tools/clang-format-vs/README.txt +++ cfe/trunk/tools/clang-format-vs/README.txt @@ -25,3 +25,27 @@ 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. Index: cfe/trunk/tools/clang-format-vs/.gitignore =================================================================== --- cfe/trunk/tools/clang-format-vs/.gitignore +++ cfe/trunk/tools/clang-format-vs/.gitignore @@ -1,5 +1,6 @@ # Visual Studio files .vs/ +*.user /packages/ /ClangFormat/obj/ /ClangFormat/bin/ Index: cfe/trunk/tools/clang-format-vs/ClangFormat/ClangFormatPackage.cs =================================================================== --- cfe/trunk/tools/clang-format-vs/ClangFormat/ClangFormatPackage.cs +++ cfe/trunk/tools/clang-format-vs/ClangFormat/ClangFormatPackage.cs @@ -180,41 +180,86 @@ 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. return; string text = view.TextBuffer.CurrentSnapshot.GetText(); 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 @@ } /// <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() Index: cfe/trunk/tools/clang-format-vs/ClangFormat/ClangFormat.vsct =================================================================== --- cfe/trunk/tools/clang-format-vs/ClangFormat/ClangFormat.vsct +++ cfe/trunk/tools/clang-format-vs/ClangFormat/ClangFormat.vsct @@ -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}" /> Index: cfe/trunk/tools/clang-format-vs/ClangFormat/PkgCmdID.cs =================================================================== --- cfe/trunk/tools/clang-format-vs/ClangFormat/PkgCmdID.cs +++ cfe/trunk/tools/clang-format-vs/ClangFormat/PkgCmdID.cs @@ -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
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits