EnterInLineCommentHandler refactoring

This commit is contained in:
Rustam Vishnyakov
2016-05-05 14:30:52 +03:00
parent 3b110194df
commit 9bcf11ec95
3 changed files with 56 additions and 21 deletions
@@ -28,6 +28,7 @@ import com.intellij.lang.documentation.DocumentationProvider;
import com.intellij.lexer.Lexer;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.DataContextWrapper;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.*;
@@ -35,8 +36,10 @@ import com.intellij.openapi.editor.actionSystem.EditorActionHandler;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.UserDataHolder;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
@@ -48,7 +51,6 @@ import com.intellij.psi.impl.source.PostprocessReformattingAspect;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtilBase;
import com.intellij.psi.util.PsiUtilCore;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.text.CharArrayUtil;
import org.jetbrains.annotations.NotNull;
@@ -58,6 +60,7 @@ public class EnterHandler extends BaseEnterHandler {
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.editorActions.EnterHandler");
private final EditorActionHandler myOriginalHandler;
private final static Key<Language> CONTEXT_LANGUAGE = Key.create("EnterHandler.Language");
public EnterHandler(EditorActionHandler originalHandler) {
super(true);
@@ -76,7 +79,7 @@ public class EnterHandler extends BaseEnterHandler {
PostprocessReformattingAspect.getInstance(project).disablePostprocessFormattingInside(new Runnable() {
@Override
public void run() {
executeWriteActionInner(editor, caret, dataContext, project);
executeWriteActionInner(editor, caret, getExtendedContext(dataContext, project, caret), project);
}
});
}
@@ -120,7 +123,6 @@ public class EnterHandler extends BaseEnterHandler {
final PsiDocumentManager documentManager = PsiDocumentManager.getInstance(project);
documentManager.commitDocument(document);
Commenter langCommenter = LanguageCommenters.INSTANCE.forLanguage(PsiUtilCore.getLanguageAtOffset(file, caretOffset));
boolean forceIndent = false;
boolean forceSkipIndent = false;
@@ -168,7 +170,7 @@ public class EnterHandler extends BaseEnterHandler {
}
final DoEnterAction action = new DoEnterAction(
file, editor, document, dataContext, caretOffset, !insertSpace, caretAdvanceRef.get(), project, langCommenter
file, editor, document, dataContext, caretOffset, !insertSpace, caretAdvanceRef.get(), project
);
action.setForceIndent(forceIndent);
action.run();
@@ -178,6 +180,15 @@ public class EnterHandler extends BaseEnterHandler {
}
}
}
@NotNull
private static DataContext getExtendedContext(@NotNull DataContext originalContext,
@NotNull Project project,
@NotNull Caret caret) {
DataContext context = originalContext instanceof UserDataHolder ? originalContext : new DataContextWrapper(originalContext);
((UserDataHolder)context).putUserData(CONTEXT_LANGUAGE, PsiUtilBase.getLanguageInEditor(caret, project));
return context;
}
public static boolean isCommentComplete(PsiComment comment, CodeDocumentationAwareCommenter commenter, Editor editor) {
for (CommentCompleteHandler handler : Extensions.getExtensions(CommentCompleteHandler.EP_NAME)) {
@@ -301,14 +312,13 @@ public class EnterHandler extends BaseEnterHandler {
private final boolean myInsertSpace;
private final Editor myEditor;
private final Project myProject;
private Commenter myCommenter;
private int myCaretAdvance;
private boolean myForceIndent = false;
private static final String LINE_SEPARATOR = "\n";
public DoEnterAction(PsiFile file, Editor view, Document document, DataContext dataContext, int offset, boolean insertSpace,
int caretAdvance, Project project, Commenter commenter)
int caretAdvance, Project project)
{
myEditor = view;
myFile = file;
@@ -318,7 +328,6 @@ public class EnterHandler extends BaseEnterHandler {
myInsertSpace = insertSpace;
myCaretAdvance = caretAdvance;
myProject = project;
myCommenter = commenter;
}
public void setForceIndent(boolean forceIndent) {
@@ -334,8 +343,10 @@ public class EnterHandler extends BaseEnterHandler {
i = CharArrayUtil.shiftBackwardUntil(chars, i, LINE_SEPARATOR) + 1;
if (i < 0) i = 0;
int lineStart = CharArrayUtil.shiftForward(chars, i, " \t");
Language language = myDataContext instanceof UserDataHolder ? CONTEXT_LANGUAGE.get((UserDataHolder)myDataContext):null;
Commenter langCommenter = language != null ? LanguageCommenters.INSTANCE.forLanguage(language) : null;
CodeDocumentationUtil.CommentContext commentContext
= CodeDocumentationUtil.tryParseCommentContext(myCommenter, chars, myOffset, lineStart);
= CodeDocumentationUtil.tryParseCommentContext(langCommenter, chars, myOffset, lineStart);
PsiDocumentManager psiDocumentManager = PsiDocumentManager.getInstance(getProject());
if (commentContext.docStart) {
@@ -722,4 +733,13 @@ public class EnterHandler extends BaseEnterHandler {
return docAsterisk;
}
}
@Nullable
public static Language getLanguage(@NotNull DataContext dataContext) {
if (dataContext instanceof UserDataHolder) {
return CONTEXT_LANGUAGE.get((UserDataHolder)dataContext);
}
return null;
}
}
@@ -16,15 +16,21 @@
package com.intellij.codeInsight.editorActions.enter;
import com.intellij.codeInsight.editorActions.EnterHandler;
import com.intellij.lang.*;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.actionSystem.EditorActionHandler;
import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.editor.highlighter.EditorHighlighter;
import com.intellij.openapi.editor.highlighter.HighlighterIterator;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.tree.IElementType;
import com.intellij.util.text.CharArrayUtil;
import org.jetbrains.annotations.NotNull;
@@ -32,29 +38,31 @@ public class EnterInLineCommentHandler extends EnterHandlerDelegateAdapter {
@Override
public Result preprocessEnter(@NotNull final PsiFile file, @NotNull final Editor editor, @NotNull final Ref<Integer> caretOffsetRef, @NotNull final Ref<Integer> caretAdvance,
@NotNull final DataContext dataContext, final EditorActionHandler originalHandler) {
final Language language = EnterHandler.getLanguage(dataContext);
if (language == null) return Result.Continue;
final Commenter languageCommenter = LanguageCommenters.INSTANCE.forLanguage(language);
final CodeDocumentationAwareCommenter commenter = languageCommenter instanceof CodeDocumentationAwareCommenter
? (CodeDocumentationAwareCommenter)languageCommenter : null;
if (commenter == null) return Result.Continue;
int caretOffset = caretOffsetRef.get().intValue();
PsiElement psiAtOffset = file.findElementAt(caretOffset);
if (psiAtOffset != null && psiAtOffset.getTextOffset() < caretOffset) {
ASTNode token = psiAtOffset.getNode();
if (isInLineComment(editor, caretOffset, commenter.getLineCommentTokenType())) {
Document document = editor.getDocument();
CharSequence text = document.getText();
final Language language = psiAtOffset.getLanguage();
final Commenter languageCommenter = LanguageCommenters.INSTANCE.forLanguage(language);
final CodeDocumentationAwareCommenter commenter = languageCommenter instanceof CodeDocumentationAwareCommenter
? (CodeDocumentationAwareCommenter)languageCommenter:null;
if (commenter != null && token.getElementType() == commenter.getLineCommentTokenType() ) {
PsiDocumentManager.getInstance(file.getProject()).commitDocument(document);
PsiElement psiAtOffset = file.findElementAt(caretOffset);
if (psiAtOffset != null && psiAtOffset.getTextOffset() < caretOffset) {
CharSequence text = document.getText();
final int offset = CharArrayUtil.shiftForward(text, caretOffset, " \t");
if (offset < document.getTextLength() && text.charAt(offset) != '\n') {
String prefix = commenter.getLineCommentPrefix();
assert prefix != null: "Line Comment type is set but Line Comment Prefix is null!";
assert prefix != null : "Line Comment type is set but Line Comment Prefix is null!";
if (!StringUtil.startsWith(text, offset, prefix)) {
if (text.charAt(caretOffset) != ' ' && !prefix.endsWith(" ")) {
prefix += " ";
}
document.insertString(caretOffset, prefix);
return Result.Default;
} else {
}
else {
int afterPrefix = offset + prefix.length();
if (afterPrefix < document.getTextLength() && text.charAt(afterPrefix) != ' ') {
document.insertString(afterPrefix, " ");
@@ -68,4 +76,11 @@ public class EnterInLineCommentHandler extends EnterHandlerDelegateAdapter {
}
return Result.Continue;
}
private static boolean isInLineComment(@NotNull Editor editor, int offset, IElementType lineCommentType) {
if (offset < 1) return false;
EditorHighlighter highlighter = ((EditorEx)editor).getHighlighter();
HighlighterIterator iterator = highlighter.createIterator(offset - 1);
return iterator.getTokenType() == lineCommentType;
}
}
@@ -439,7 +439,7 @@ public class CodeFormatterFacade {
return;
}
editorFactory = EditorFactory.getInstance();
editor = editorFactory.createEditor(document, file.getProject());
editor = editorFactory.createEditor(document, file.getProject(), file.getVirtualFile(), false);
}
try {
final Editor editorToUse = editor;