diff --git a/Src/CSharpier.Tests/CodeFormatterTests.cs b/Src/CSharpier.Tests/CodeFormatterTests.cs index da686609c..eabb06dfa 100644 --- a/Src/CSharpier.Tests/CodeFormatterTests.cs +++ b/Src/CSharpier.Tests/CodeFormatterTests.cs @@ -64,6 +64,24 @@ public void Format_Should_Use_Width() result.Code.Should().Be("var someVariable =\n someValue;\n"); } + [Test] + public void Format_Should_Use_Width_For_Single_Line_Comment() + { + var code = "// Test very long line comment. \n // Second line of long comment. \n var someVariable = someValue;"; + var result = CodeFormatter.Format(code, new CodeFormatterOptions { Width = 10 }); + result.Code.Should().Be("// Test\n// very long\n// line\n// comment.\n// Second\n// line of\n// long\n// comment.\nvar someVariable =\n someValue;\n"); + } + + [Test] + public void Format_Should_Use_Width_For_Multi_Line_Comments() + { + var code = + "/* Test very long line comment.\n Second line of long comment.\n Third line of long comment. */\n var someVariable = someValue;"; + var result = CodeFormatter.Format(code, new CodeFormatterOptions { Width = 10 }); + + result.Code.Should().Be("/* Test\nvery long\nline\ncomment.\nSecond\nline of\nlong\ncomment.\nThird line\nof long\ncomment.\n*/\nvar someVariable =\n someValue;\n"); + } + [Test] public void Format_Should_Measure_Regular_Characters() { diff --git a/Src/CSharpier/DocPrinter/DocPrinter.cs b/Src/CSharpier/DocPrinter/DocPrinter.cs index 8354fd47d..2696616c1 100644 --- a/Src/CSharpier/DocPrinter/DocPrinter.cs +++ b/Src/CSharpier/DocPrinter/DocPrinter.cs @@ -1,4 +1,9 @@ +using CSharpier.DocTypes; +using System; +using System.Collections; +using System.Runtime.CompilerServices; using System.Text; +using System.Xml.Linq; namespace CSharpier.DocPrinter; @@ -67,6 +72,8 @@ private void EnsureOutputEndsWithSingleNewLine() this.Output.Append(this.EndOfLine); } + + private void ProcessNextCommand() { var (indent, mode, doc) = this.RemainingCommands.Pop(); @@ -186,6 +193,47 @@ private void ProcessNextCommand() } } + private List BreakCommentLine(string comment) + { + List result = new List(); + if (comment.Length > this.PrinterOptions.Width) + { + string[] comments = comment.Split(' '); + StringBuilder singleLine = new StringBuilder(); + bool firstLine = true; + foreach (var word in comments) + { + if (singleLine.Length + word.Length >= this.PrinterOptions.Width) + { + result.Add(singleLine.ToString()); + singleLine.Clear(); + if (firstLine) + { + firstLine = false; + } + } + + if (singleLine.Length > 0) + { + singleLine.Append(' '); + } + + singleLine.Append(word); + } + + if (singleLine.Length > 0) + { + result.Add(singleLine.ToString()); + } + } + else + { + result.Add(comment); + } + + return result; + } + private void AppendComment(LeadingComment leadingComment, Indent indent) { int CalculateIndentLength(string line) => @@ -206,42 +254,68 @@ int CalculateIndentLength(string line) => while (line != null) { - if (leadingComment.Type == CommentType.SingleLine) - { - this.Output.Append(indent.Value); - } - else + string entireLine = line; + List lines = BreakCommentLine(line.Trim()); + + var nextLine = stringReader.ReadLine(); + + int total = lines.Count; + int lineNumber = 0; + foreach (var singleLine in lines) { - var spacesToAppend = CalculateIndentLength(line) + numberOfSpacesToAddOrRemove; - if (this.PrinterOptions.UseTabs) + if (leadingComment.Type == CommentType.SingleLine) { - var indentLength = CalculateIndentLength(indent.Value); - if (spacesToAppend >= indentLength) + this.Output.Append(indent.Value); + } + else + { + var spacesToAppend = CalculateIndentLength(singleLine) + numberOfSpacesToAddOrRemove; + if (this.PrinterOptions.UseTabs) { - this.Output.Append(indent.Value); - spacesToAppend -= indentLength; - } + var indentLength = CalculateIndentLength(indent.Value); + if (spacesToAppend >= indentLength) + { + this.Output.Append(indent.Value); + spacesToAppend -= indentLength; + } - while (spacesToAppend > 0 && spacesToAppend >= this.PrinterOptions.IndentSize) + while (spacesToAppend > 0 && spacesToAppend >= this.PrinterOptions.IndentSize) + { + this.Output.Append('\t'); + spacesToAppend -= this.PrinterOptions.IndentSize; + } + } + if (spacesToAppend > 0) { - this.Output.Append('\t'); - spacesToAppend -= this.PrinterOptions.IndentSize; + this.Output.Append(' ', spacesToAppend); } } - if (spacesToAppend > 0) + + if (leadingComment.Type == CommentType.SingleLine && lineNumber > 0) + { + this.Output.Append("// "); + } + + this.Output.Append(singleLine.Trim()); + + // Printer will generate a new line for the next line after the comment. + if (nextLine != null || lineNumber < total - 1) { - this.Output.Append(' ', spacesToAppend); + this.Output.Append(this.EndOfLine); } + + ++lineNumber; } - this.Output.Append(line.Trim()); - line = stringReader.ReadLine(); - if (line == null) + + if (nextLine == null) { return; } - - this.Output.Append(this.EndOfLine); + else + { + line = nextLine; + } } }