Skip to content

Commit 34e9581

Browse files
sormurascushon
authored andcommitted
Prevent edit if nothing was formatted (google#120)
Handle trivial cases, where input equals output, to prevent dirty flags in active editors.
1 parent 760a13c commit 34e9581

File tree

1 file changed

+30
-2
lines changed

1 file changed

+30
-2
lines changed

eclipse_plugin/src/com/google/googlejavaformat/java/GoogleJavaFormatter.java

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,16 @@ private TextEdit formatInternal(int kind, String source, IRegion[] regions, int
8282
default:
8383
throw new IllegalArgumentException(String.format("Unknown snippet kind: %d", kind));
8484
}
85-
return editFromReplacements(
85+
List<Replacement> replacements =
8686
new SnippetFormatter()
8787
.format(
88-
snippetKind, source, rangesFromRegions(regions), initialIndent, includeComments));
88+
snippetKind, source, rangesFromRegions(regions), initialIndent, includeComments);
89+
if (idempotent(source, regions, replacements)) {
90+
// Do not create edits if there's no diff.
91+
return null;
92+
}
93+
// Convert replacements to text edits.
94+
return editFromReplacements(replacements);
8995
} catch (IllegalArgumentException | FormatterException exception) {
9096
// Do not format on errors.
9197
return null;
@@ -100,6 +106,28 @@ private List<Range<Integer>> rangesFromRegions(IRegion[] regions) {
100106
return ranges;
101107
}
102108

109+
/** @return {@code true} if input and output texts are equal, else {@code false}. */
110+
private boolean idempotent(String source, IRegion[] regions, List<Replacement> replacements) {
111+
// This implementation only checks for single replacement.
112+
if (replacements.size() == 1) {
113+
Replacement replacement = replacements.get(0);
114+
String output = replacement.getReplacementString();
115+
// Entire source case: input = output, nothing changed.
116+
if (output.equals(source)) {
117+
return true;
118+
}
119+
// Single region and single replacement case: if they are equal, nothing changed.
120+
if (regions.length == 1) {
121+
Range<Integer> range = replacement.getReplaceRange();
122+
String snippet = source.substring(range.lowerEndpoint(), range.upperEndpoint());
123+
if (output.equals(snippet)) {
124+
return true;
125+
}
126+
}
127+
}
128+
return false;
129+
}
130+
103131
private TextEdit editFromReplacements(List<Replacement> replacements) {
104132
// Split the replacements that cross line boundaries.
105133
TextEdit edit = new MultiTextEdit();

0 commit comments

Comments
 (0)