JoinLinesHandler: comments are joined by separate delegate

GitOrigin-RevId: 7413c26002f399d72ec86feca1778016b1c52f85
This commit is contained in:
Tagir Valeev
2019-08-24 15:00:58 +03:00
committed by intellij-monorepo-bot
parent 976feaa4b7
commit e991fc19ef
3 changed files with 57 additions and 46 deletions
@@ -0,0 +1,45 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.codeInsight.editorActions;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiComment;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiWhiteSpace;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;
public class CommentJoinLinesHandler implements JoinRawLinesHandlerDelegate {
@Override
public int tryJoinLines(@NotNull Document document, @NotNull PsiFile file, int start, int end) {
return CANNOT_JOIN;
}
@Override
public int tryJoinRawLines(@NotNull Document document, @NotNull PsiFile file, int start, int end) {
PsiElement prevElement = file.findElementAt(start);
if (prevElement instanceof PsiWhiteSpace) {
prevElement = file.findElementAt(start - 1);
}
PsiComment prevComment = PsiTreeUtil.getNonStrictParentOfType(prevElement, PsiComment.class);
PsiComment nextComment = PsiTreeUtil.getNonStrictParentOfType(file.findElementAt(end), PsiComment.class);
if (prevComment == null || nextComment == null) return CANNOT_JOIN;
boolean sameComment = prevComment == nextComment;
boolean adjacentLineComments = false;
CharSequence text = document.getText();
if (text.charAt(end) == '*' && end < text.length() && text.charAt(end + 1) != '/') {
end = StringUtil.skipWhitespaceForward(text, end + 1);
}
else if (!sameComment &&
!(start >= 2 && text.charAt(start - 2) == '*' && text.charAt(start - 1) == '/') &&
text.charAt(end) == '/' && end + 1 < text.length() && text.charAt(end + 1) == '/') {
adjacentLineComments = true;
end = StringUtil.skipWhitespaceForward(text, end + 2);
}
document.replaceString(start, end, adjacentLineComments || sameComment ? " " : "");
return start;
}
}
@@ -142,7 +142,7 @@ public class JoinLinesHandler extends EditorActionHandler {
docManager.doPostponedOperationsAndUnblockDocument(doc);
docManager.commitDocument(doc);
CharSequence text = doc.getCharsSequence();
JoinLinesOffsets offsets = calcJoinLinesOffsets(psiFile, doc, startLine);
JoinLinesOffsets offsets = new JoinLinesOffsets(doc, startLine);
TextRange limits = findStartAndEnd(text, offsets.lastNonSpaceOffsetInStartLine, offsets.firstNonSpaceOffsetInNextLine);
int start = limits.getStartOffset();
@@ -200,12 +200,7 @@ public class JoinLinesHandler extends EditorActionHandler {
int replaceStart = start == offsets.lineEndOffset ? start : start + 1;
if (caretRestoreOffset.get() == CANNOT_JOIN) caretRestoreOffset.set(replaceStart);
if (offsets.isStartLineEndsWithComment() && offsets.isNextLineStartsWithComment()) {
postProcessAdjacentComments(doc, text, offsets, end, replaceStart);
} else {
postProcessWhitespace(doc, project, docManager, psiFile, text, limits, replaceStart, doc.getLineStartOffset(startLine));
}
postProcessWhitespace(doc, project, docManager, psiFile, text, limits, replaceStart, doc.getLineStartOffset(startLine));
docManager.commitDocument(doc);
}
@@ -229,23 +224,6 @@ public class JoinLinesHandler extends EditorActionHandler {
}
}
private static void postProcessAdjacentComments(@NotNull DocumentEx doc,
CharSequence text,
JoinLinesOffsets offsets, int end, int replaceStart) {
boolean adjacentLineComments = false;
if (text.charAt(end) == '*' && end < text.length() && text.charAt(end + 1) != '/') {
end = StringUtil.skipWhitespaceForward(text, end + 1);
}
else if (!offsets.isJoiningSameComment() &&
!(replaceStart >= 2 && text.charAt(replaceStart - 2) == '*' && text.charAt(replaceStart - 1) == '/') &&
text.charAt(end) == '/' && end + 1 < text.length() && text.charAt(end + 1) == '/') {
adjacentLineComments = true;
end = StringUtil.skipWhitespaceForward(text, end + 2);
}
doc.replaceString(replaceStart, end, adjacentLineComments || offsets.isJoiningSameComment() ? " " : "");
}
private static int checkOffset(int offset, JoinLinesHandlerDelegate delegate, DocumentEx doc) {
if (offset == CANNOT_JOIN) return offset;
if (offset < 0) {
@@ -260,29 +238,16 @@ public class JoinLinesHandler extends EditorActionHandler {
}
private static class JoinLinesOffsets {
int lineEndOffset;
int lastNonSpaceOffsetInStartLine;
int firstNonSpaceOffsetInNextLine;
PsiComment commentAtLineEnd;
PsiComment commentAtLineStart;
boolean isStartLineEndsWithComment() { return commentAtLineEnd != null; }
boolean isNextLineStartsWithComment() { return commentAtLineStart != null; }
boolean isJoiningSameComment() { return commentAtLineStart == commentAtLineEnd; }
}
private static JoinLinesOffsets calcJoinLinesOffsets(PsiFile psiFile, Document doc, int startLine) {
JoinLinesOffsets offsets = new JoinLinesOffsets();
CharSequence text = doc.getCharsSequence();
offsets.lineEndOffset = doc.getLineEndOffset(startLine);
offsets.firstNonSpaceOffsetInNextLine = StringUtil.skipWhitespaceForward(text, doc.getLineStartOffset(startLine + 1));
PsiElement elementAtNextLineStart = psiFile.findElementAt(offsets.firstNonSpaceOffsetInNextLine);
offsets.commentAtLineStart = getCommentElement(elementAtNextLineStart);
offsets.lastNonSpaceOffsetInStartLine = StringUtil.skipWhitespaceBackward(text, offsets.lineEndOffset);
int elemOffset = offsets.lastNonSpaceOffsetInStartLine > doc.getLineStartOffset(startLine) ? offsets.lastNonSpaceOffsetInStartLine - 1 : -1;
offsets.commentAtLineEnd = getCommentElement(elemOffset == -1 ? null : psiFile.findElementAt(elemOffset));
return offsets;
final int lineEndOffset;
final int lastNonSpaceOffsetInStartLine;
final int firstNonSpaceOffsetInNextLine;
JoinLinesOffsets(Document doc, int startLine) {
CharSequence text = doc.getCharsSequence();
this.lineEndOffset = doc.getLineEndOffset(startLine);
this.firstNonSpaceOffsetInNextLine = StringUtil.skipWhitespaceForward(text, doc.getLineStartOffset(startLine + 1));
this.lastNonSpaceOffsetInStartLine = StringUtil.skipWhitespaceBackward(text, this.lineEndOffset);
}
}
private static void convertEndComments(PsiFile psiFile, Document doc, int startLine, int lineCount) {
@@ -1227,6 +1227,7 @@
<applicationInitializedListener implementation="com.intellij.ide.script.IdeStartupScripts"/>
<projectService serviceInterface="com.intellij.codeInsight.daemon.impl.IntentionsUI"
serviceImplementation="com.intellij.codeInsight.daemon.impl.IntentionsUIImpl"/>
<joinLinesHandler implementation="com.intellij.codeInsight.editorActions.CommentJoinLinesHandler"/>
</extensions>
</idea-plugin>