using System.Runtime.InteropServices;
using System.Xml.Linq;
using System.Linq;
+using System.Text;
namespace LLVM.ClangFormat
{
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)
string path = Vsix.GetDocumentParent(view);
string filePath = Vsix.GetDocumentPath(view);
- RunClangFormatAndApplyReplacements(text, start, length, path, filePath, options, view);
+ RunClangFormatAndApplyReplacements(text, start, end, path, filePath, options, view);
}
/// <summary>
RunClangFormatAndApplyReplacements(text, 0, text.Length, path, filePath, options, view);
}
- private void RunClangFormatAndApplyReplacements(string text, int offset, int length, string path, string filePath, OptionPageGrid options, IWpfTextView view)
+ private void RunClangFormatAndApplyReplacements(string text, int start, int end, string path, string filePath, OptionPageGrid options, IWpfTextView view)
{
try
{
- string replacements = RunClangFormat(text, offset, length, path, filePath, options);
+ string replacements = RunClangFormat(text, start, end, path, filePath, options);
ApplyClangFormatReplacements(replacements, view);
}
catch (Exception e)
/// <summary>
/// Runs the given text through clang-format and returns the replacements as XML.
///
- /// Formats the text range starting at offset of the given length.
+ /// Formats the text in range start and end.
/// </summary>
- private static string RunClangFormat(string text, int offset, int length, string path, string filePath, OptionPageGrid options)
+ private static string RunClangFormat(string text, int start, int end, string path, string filePath, OptionPageGrid options)
{
string vsixPath = Path.GetDirectoryName(
typeof(ClangFormatPackage).Assembly.Location);
System.Diagnostics.Process process = new System.Diagnostics.Process();
process.StartInfo.UseShellExecute = false;
process.StartInfo.FileName = vsixPath + "\\clang-format.exe";
+ char[] chars = text.ToCharArray();
+ int offset = Encoding.UTF8.GetByteCount(chars, 0, start);
+ int length = Encoding.UTF8.GetByteCount(chars, 0, end) - offset;
// Poor man's escaping - this will not work when quotes are already escaped
// in the input (but we don't need more).
string style = options.Style.Replace("\"", "\\\"");
// 2. We write everything to the standard output - this cannot block, as clang-format
// reads the full standard input before analyzing it without writing anything to the
// standard output.
- process.StandardInput.Write(text);
+ StreamWriter utf8Writer = new StreamWriter(process.StandardInput.BaseStream, new UTF8Encoding(false));
+ utf8Writer.Write(text);
// 3. We notify clang-format that the input is done - after this point clang-format
// will start analyzing the input and eventually write the output.
- process.StandardInput.Close();
+ utf8Writer.Close();
// 4. We must read clang-format's output before waiting for it to exit; clang-format
// will close the channel by exiting.
string output = process.StandardOutput.ReadToEnd();
if (replacements.Length == 0)
return;
+ string text = view.TextBuffer.CurrentSnapshot.GetText();
+ byte[] bytes = Encoding.UTF8.GetBytes(text);
+
var root = XElement.Parse(replacements);
var edit = view.TextBuffer.CreateEdit();
foreach (XElement replacement in root.Descendants("replacement"))
{
+ int offset = int.Parse(replacement.Attribute("offset").Value);
+ int length = int.Parse(replacement.Attribute("length").Value);
var span = new Span(
- int.Parse(replacement.Attribute("offset").Value),
- int.Parse(replacement.Attribute("length").Value));
+ Encoding.UTF8.GetCharCount(bytes, 0, offset),
+ Encoding.UTF8.GetCharCount(bytes, offset, length));
edit.Replace(span, replacement.Value);
}
edit.Apply();