Formatter is discarding empty lines between comments [message #1785977] |
Mon, 23 April 2018 18:09 |
Elie Richa Messages: 72 Registered: February 2016 |
Member |
|
|
Hello again,
I am working on customizing the formatter for my language. I managed to configure most things the way I want, and there is one thing I could not manage to customize.
The formatter removes all empty lines between comments. So for the following example:
package Pkg {
// Comment 1
// Comment 2
/* Multi-line comment 3 */
class C1 {
}
}
The formatter produces:
package Pkg {
// Comment 1
// Comment 2
/* Multi-line comment 3 */
class C1 {
}
}
This is probably due to the fact that my formatter has something like:
def dispatch void format(CClass o, extension IFormattableDocument document) {
o.regionFor.keyword("class").prepend[setNewLines(1, 1, 2)]
...
}
So indeed in the result, if we discard comments, we do have a maximum of 2 line breaks before the 'class' keyword.
So is there something I could do to preserve the empty lines between the comments?
Thanks.
--
Elie
Elie Richa, Ph.D
Software Engineer, AdaCore
https://www.adacore.com
|
|
|
Re: Formatter is discarding empty lines between comments [message #1785979 is a reply to message #1785977] |
Mon, 23 April 2018 18:44 |
|
i think the problem is that the whole bunch of comments and whitespaces are treated as one hidden region.
maybe you can recorrect that behaviour in comment replacers.
e.g.
return new SinglelineCodeCommentReplacer(comment, "//") {
override createReplacements(ITextReplacerContext context) {
var ITextRegionAccess access = comment.getTextRegionAccess();
val region = access.regionForOffset(comment.offset, comment.length)
var prefix = "";
if (comment.previousHiddenPart instanceof NodeWhitespace) {
prefix = comment.previousHiddenPart.text
}
context.addReplacement(region.replaceWith(prefix + comment.text))
context
}
}
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
|
|
|
Re: Formatter is discarding empty lines between comments [message #1786029 is a reply to message #1785979] |
Tue, 24 April 2018 10:57 |
Elie Richa Messages: 72 Registered: February 2016 |
Member |
|
|
Hello Christian,
Thank you for your quick reply!
I tried your solution and the result was that every reformatting was adding extra empty lines before sequences of comments.
However in the mean time I found another solution consisting of this:
class MySLCommentReplacer extends SinglelineDocCommentReplacer {
new(IComment comment, String prefix) {
super(comment, prefix)
}
/**
* We override this to allow up to one empty line around comment blocks
*/
override void configureWhitespace(WhitespaceReplacer leading,
WhitespaceReplacer trailing) {
leading.getFormatting().setNewLinesMax(2)
trailing.getFormatting().setNewLinesMax(2)
}
}
class MyMLCommentReplacer extends MultilineCommentReplacer {
package new(IComment comment, char prefix) {
super(comment, prefix)
}
/**
* We override this to allow up to one empty line around comment blocks
*/
override void configureWhitespace(WhitespaceReplacer leading,
WhitespaceReplacer trailing) {
super.configureWhitespace(leading, trailing)
leading.getFormatting().setNewLinesMax(2)
trailing.getFormatting().setNewLinesMax(2)
}
}
This worked somewhat well: a first formatting was reducing all inter-comment lines to one empty line which was exactly what I want. However, a second formatting step was further removing some of the empty lines which is not great. After some debugging I found that the WhitespaceReplacer was computing the number of lines slightly wrong in some corner cases.
Here is the fix that worked for me. It may be something to include in the original implementation.
public class MyWhitespaceReplacer extends WhitespaceReplacer {
private final IHiddenRegionFormatting formatting;
private final ITextSegment region;
BlocklibraryWhitespaceReplacer(ITextSegment segment,
IHiddenRegionFormatting formatting) {
super(segment, formatting);
this.region = segment;
this.formatting = formatting;
}
/**
* This fixes a bug in the parent implementation. The parent implementation
* computes the new line count without taking into account the trailing line
* breaks of the previous region.
*/
@Override
protected int computeNewLineCount(ITextReplacerContext context) {
Integer newLineDefault = formatting.getNewLineDefault();
Integer newLineMin = formatting.getNewLineMin();
Integer newLineMax = formatting.getNewLineMax();
if (newLineMin != null || newLineDefault != null
|| newLineMax != null) {
if (region instanceof IHiddenRegion
&& ((IHiddenRegion) region).isUndefined()) {
if (newLineDefault != null)
return newLineDefault;
if (newLineMin != null)
return newLineMin;
if (newLineMax != null)
return newLineMax;
} else {
// This line is the different w.r.t. the parent implementation
int lineCount = region.getLineCount() - 1
+ trailingNewLinesOfPreviousRegion();
if (newLineMin != null && newLineMin > lineCount)
lineCount = newLineMin;
if (newLineMax != null && newLineMax < lineCount)
lineCount = newLineMax;
return lineCount;
}
}
return 0;
}
}
Although this may not be the best way to fix the problem since WhitespaceReplacer::createReplacements() also makes use of trailingNewLinesOfPreviousRegion(), so it may be worth reviewing that whole piece of code.
Thanks for the help!
Elie
|
|
|
Powered by
FUDForum. Page generated in 0.03200 seconds