24
24
using System . Runtime . InteropServices ;
25
25
using System . Xml . Linq ;
26
26
using System . Linq ;
27
+ using System . Text ;
27
28
28
29
namespace LLVM . ClangFormat
29
30
{
@@ -292,16 +293,15 @@ private void FormatSelection(OptionPageGrid options)
292
293
string text = view . TextBuffer . CurrentSnapshot . GetText ( ) ;
293
294
int start = view . Selection . Start . Position . GetContainingLine ( ) . Start . Position ;
294
295
int end = view . Selection . End . Position . GetContainingLine ( ) . End . Position ;
295
- int length = end - start ;
296
-
296
+
297
297
// clang-format doesn't support formatting a range that starts at the end
298
298
// of the file.
299
299
if ( start >= text . Length && text . Length > 0 )
300
300
start = text . Length - 1 ;
301
301
string path = Vsix . GetDocumentParent ( view ) ;
302
302
string filePath = Vsix . GetDocumentPath ( view ) ;
303
303
304
- RunClangFormatAndApplyReplacements ( text , start , length , path , filePath , options , view ) ;
304
+ RunClangFormatAndApplyReplacements ( text , start , end , path , filePath , options , view ) ;
305
305
}
306
306
307
307
/// <summary>
@@ -336,11 +336,11 @@ private void FormatView(IWpfTextView view, OptionPageGrid options)
336
336
RunClangFormatAndApplyReplacements ( text , 0 , text . Length , path , filePath , options , view ) ;
337
337
}
338
338
339
- private void RunClangFormatAndApplyReplacements ( string text , int offset , int length , string path , string filePath , OptionPageGrid options , IWpfTextView view )
339
+ private void RunClangFormatAndApplyReplacements ( string text , int start , int end , string path , string filePath , OptionPageGrid options , IWpfTextView view )
340
340
{
341
341
try
342
342
{
343
- string replacements = RunClangFormat ( text , offset , length , path , filePath , options ) ;
343
+ string replacements = RunClangFormat ( text , start , end , path , filePath , options ) ;
344
344
ApplyClangFormatReplacements ( replacements , view ) ;
345
345
}
346
346
catch ( Exception e )
@@ -363,16 +363,19 @@ private void RunClangFormatAndApplyReplacements(string text, int offset, int len
363
363
/// <summary>
364
364
/// Runs the given text through clang-format and returns the replacements as XML.
365
365
///
366
- /// Formats the text range starting at offset of the given length .
366
+ /// Formats the text in range start and end .
367
367
/// </summary>
368
- private static string RunClangFormat ( string text , int offset , int length , string path , string filePath , OptionPageGrid options )
368
+ private static string RunClangFormat ( string text , int start , int end , string path , string filePath , OptionPageGrid options )
369
369
{
370
370
string vsixPath = Path . GetDirectoryName (
371
371
typeof ( ClangFormatPackage ) . Assembly . Location ) ;
372
372
373
373
System . Diagnostics . Process process = new System . Diagnostics . Process ( ) ;
374
374
process . StartInfo . UseShellExecute = false ;
375
375
process . StartInfo . FileName = vsixPath + "\\ clang-format.exe" ;
376
+ char [ ] chars = text . ToCharArray ( ) ;
377
+ int offset = Encoding . UTF8 . GetByteCount ( chars , 0 , start ) ;
378
+ int length = Encoding . UTF8 . GetByteCount ( chars , 0 , end ) - offset ;
376
379
// Poor man's escaping - this will not work when quotes are already escaped
377
380
// in the input (but we don't need more).
378
381
string style = options . Style . Replace ( "\" " , "\\ \" " ) ;
@@ -413,10 +416,11 @@ private static string RunClangFormat(string text, int offset, int length, string
413
416
// 2. We write everything to the standard output - this cannot block, as clang-format
414
417
// reads the full standard input before analyzing it without writing anything to the
415
418
// standard output.
416
- process . StandardInput . Write ( text ) ;
419
+ StreamWriter utf8Writer = new StreamWriter ( process . StandardInput . BaseStream , new UTF8Encoding ( false ) ) ;
420
+ utf8Writer . Write ( text ) ;
417
421
// 3. We notify clang-format that the input is done - after this point clang-format
418
422
// will start analyzing the input and eventually write the output.
419
- process . StandardInput . Close ( ) ;
423
+ utf8Writer . Close ( ) ;
420
424
// 4. We must read clang-format's output before waiting for it to exit; clang-format
421
425
// will close the channel by exiting.
422
426
string output = process . StandardOutput . ReadToEnd ( ) ;
@@ -440,13 +444,18 @@ private static void ApplyClangFormatReplacements(string replacements, IWpfTextVi
440
444
if ( replacements . Length == 0 )
441
445
return ;
442
446
447
+ string text = view . TextBuffer . CurrentSnapshot . GetText ( ) ;
448
+ byte [ ] bytes = Encoding . UTF8 . GetBytes ( text ) ;
449
+
443
450
var root = XElement . Parse ( replacements ) ;
444
451
var edit = view . TextBuffer . CreateEdit ( ) ;
445
452
foreach ( XElement replacement in root . Descendants ( "replacement" ) )
446
453
{
454
+ int offset = int . Parse ( replacement . Attribute ( "offset" ) . Value ) ;
455
+ int length = int . Parse ( replacement . Attribute ( "length" ) . Value ) ;
447
456
var span = new Span (
448
- int . Parse ( replacement . Attribute ( " offset" ) . Value ) ,
449
- int . Parse ( replacement . Attribute ( " length" ) . Value ) ) ;
457
+ Encoding . UTF8 . GetCharCount ( bytes , 0 , offset ) ,
458
+ Encoding . UTF8 . GetCharCount ( bytes , offset , length ) ) ;
450
459
edit . Replace ( span , replacement . Value ) ;
451
460
}
452
461
edit . Apply ( ) ;
0 commit comments