Skip to content

Commit 8ee5be0

Browse files
committed
Support wrapping single line comment and multi-line comments based on
width.
1 parent 676c8bc commit 8ee5be0

File tree

2 files changed

+114
-22
lines changed

2 files changed

+114
-22
lines changed

Src/CSharpier.Tests/CodeFormatterTests.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,24 @@ public void Format_Should_Use_Width()
6464
result.Code.Should().Be("var someVariable =\n someValue;\n");
6565
}
6666

67+
[Test]
68+
public void Format_Should_Use_Width_For_Single_Line_Comment()
69+
{
70+
var code = "// Test very long line comment. \n // Second line of long comment. \n var someVariable = someValue;";
71+
var result = CodeFormatter.Format(code, new CodeFormatterOptions { Width = 10 });
72+
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");
73+
}
74+
75+
[Test]
76+
public void Format_Should_Use_Width_For_Multi_Line_Comments()
77+
{
78+
var code =
79+
"/* Test very long line comment.\n Second line of long comment.\n Third line of long comment. */\n var someVariable = someValue;";
80+
var result = CodeFormatter.Format(code, new CodeFormatterOptions { Width = 10 });
81+
82+
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");
83+
}
84+
6785
[Test]
6886
public void Format_Should_Measure_Regular_Characters()
6987
{

Src/CSharpier/DocPrinter/DocPrinter.cs

Lines changed: 96 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1+
using CSharpier.DocTypes;
2+
using System;
3+
using System.Collections;
4+
using System.Runtime.CompilerServices;
15
using System.Text;
6+
using System.Xml.Linq;
27

38
namespace CSharpier.DocPrinter;
49

@@ -67,6 +72,8 @@ private void EnsureOutputEndsWithSingleNewLine()
6772
this.Output.Append(this.EndOfLine);
6873
}
6974

75+
76+
7077
private void ProcessNextCommand()
7178
{
7279
var (indent, mode, doc) = this.RemainingCommands.Pop();
@@ -186,6 +193,47 @@ private void ProcessNextCommand()
186193
}
187194
}
188195

196+
private List<string> BreakCommentLine(string comment)
197+
{
198+
List<string> result = new List<string>();
199+
if (comment.Length > this.PrinterOptions.Width)
200+
{
201+
string[] comments = comment.Split(' ');
202+
StringBuilder singleLine = new StringBuilder();
203+
bool firstLine = true;
204+
foreach (var word in comments)
205+
{
206+
if (singleLine.Length + word.Length >= this.PrinterOptions.Width)
207+
{
208+
result.Add(singleLine.ToString());
209+
singleLine.Clear();
210+
if (firstLine)
211+
{
212+
firstLine = false;
213+
}
214+
}
215+
216+
if (singleLine.Length > 0)
217+
{
218+
singleLine.Append(' ');
219+
}
220+
221+
singleLine.Append(word);
222+
}
223+
224+
if (singleLine.Length > 0)
225+
{
226+
result.Add(singleLine.ToString());
227+
}
228+
}
229+
else
230+
{
231+
result.Add(comment);
232+
}
233+
234+
return result;
235+
}
236+
189237
private void AppendComment(LeadingComment leadingComment, Indent indent)
190238
{
191239
int CalculateIndentLength(string line) =>
@@ -206,42 +254,68 @@ int CalculateIndentLength(string line) =>
206254

207255
while (line != null)
208256
{
209-
if (leadingComment.Type == CommentType.SingleLine)
210-
{
211-
this.Output.Append(indent.Value);
212-
}
213-
else
257+
string entireLine = line;
258+
List<string> lines = BreakCommentLine(line.Trim());
259+
260+
var nextLine = stringReader.ReadLine();
261+
262+
int total = lines.Count;
263+
int lineNumber = 0;
264+
foreach (var singleLine in lines)
214265
{
215-
var spacesToAppend = CalculateIndentLength(line) + numberOfSpacesToAddOrRemove;
216-
if (this.PrinterOptions.UseTabs)
266+
if (leadingComment.Type == CommentType.SingleLine)
217267
{
218-
var indentLength = CalculateIndentLength(indent.Value);
219-
if (spacesToAppend >= indentLength)
268+
this.Output.Append(indent.Value);
269+
}
270+
else
271+
{
272+
var spacesToAppend = CalculateIndentLength(singleLine) + numberOfSpacesToAddOrRemove;
273+
if (this.PrinterOptions.UseTabs)
220274
{
221-
this.Output.Append(indent.Value);
222-
spacesToAppend -= indentLength;
223-
}
275+
var indentLength = CalculateIndentLength(indent.Value);
276+
if (spacesToAppend >= indentLength)
277+
{
278+
this.Output.Append(indent.Value);
279+
spacesToAppend -= indentLength;
280+
}
224281

225-
while (spacesToAppend > 0 && spacesToAppend >= this.PrinterOptions.IndentSize)
282+
while (spacesToAppend > 0 && spacesToAppend >= this.PrinterOptions.IndentSize)
283+
{
284+
this.Output.Append('\t');
285+
spacesToAppend -= this.PrinterOptions.IndentSize;
286+
}
287+
}
288+
if (spacesToAppend > 0)
226289
{
227-
this.Output.Append('\t');
228-
spacesToAppend -= this.PrinterOptions.IndentSize;
290+
this.Output.Append(' ', spacesToAppend);
229291
}
230292
}
231-
if (spacesToAppend > 0)
293+
294+
if (leadingComment.Type == CommentType.SingleLine && lineNumber > 0)
295+
{
296+
this.Output.Append("// ");
297+
}
298+
299+
this.Output.Append(singleLine.Trim());
300+
301+
// Printer will generate a new line for the next line after the comment.
302+
if (nextLine != null || lineNumber < total - 1)
232303
{
233-
this.Output.Append(' ', spacesToAppend);
304+
this.Output.Append(this.EndOfLine);
234305
}
306+
307+
++lineNumber;
235308
}
236309

237-
this.Output.Append(line.Trim());
238-
line = stringReader.ReadLine();
239-
if (line == null)
310+
311+
if (nextLine == null)
240312
{
241313
return;
242314
}
243-
244-
this.Output.Append(this.EndOfLine);
315+
else
316+
{
317+
line = nextLine;
318+
}
245319
}
246320
}
247321

0 commit comments

Comments
 (0)