mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
don't add a newline when completing with smart enter shortcut (IDEA-126726)
This commit is contained in:
+34
-20
@@ -47,7 +47,21 @@ public class JavaSmartEnterProcessor extends SmartEnterProcessor {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.editorActions.smartEnter.JavaSmartEnterProcessor");
|
||||
|
||||
private static final Fixer[] ourFixers;
|
||||
private static final EnterProcessor[] ourEnterProcessors;
|
||||
private static final EnterProcessor[] ourEnterProcessors = {
|
||||
new CommentBreakerEnterProcessor(),
|
||||
new AfterSemicolonEnterProcessor(),
|
||||
new LeaveCodeBlockEnterProcessor(),
|
||||
new PlainEnterProcessor()
|
||||
};
|
||||
private static final EnterProcessor[] ourAfterCompletionEnterProcessors = {
|
||||
new AfterSemicolonEnterProcessor(),
|
||||
new EnterProcessor() {
|
||||
@Override
|
||||
public boolean doEnter(Editor editor, PsiElement psiElement, boolean isModified) {
|
||||
return PlainEnterProcessor.expandCodeBlock(editor, psiElement);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static {
|
||||
final List<Fixer> fixers = new ArrayList<Fixer>();
|
||||
@@ -78,15 +92,7 @@ public class JavaSmartEnterProcessor extends SmartEnterProcessor {
|
||||
fixers.add(new MissingArrayInitializerBraceFixer());
|
||||
fixers.add(new MissingArrayConstructorBracketFixer());
|
||||
fixers.add(new EnumFieldFixer());
|
||||
//ourFixers.add(new CompletionFixer());
|
||||
ourFixers = fixers.toArray(new Fixer[fixers.size()]);
|
||||
|
||||
List<EnterProcessor> processors = new ArrayList<EnterProcessor>();
|
||||
processors.add(new CommentBreakerEnterProcessor());
|
||||
processors.add(new AfterSemicolonEnterProcessor());
|
||||
processors.add(new LeaveCodeBlockEnterProcessor());
|
||||
processors.add(new PlainEnterProcessor());
|
||||
ourEnterProcessors = processors.toArray(new EnterProcessor[processors.size()]);
|
||||
}
|
||||
|
||||
private int myFirstErrorOffset = Integer.MAX_VALUE;
|
||||
@@ -102,13 +108,22 @@ public class JavaSmartEnterProcessor extends SmartEnterProcessor {
|
||||
public boolean process(@NotNull final Project project, @NotNull final Editor editor, @NotNull final PsiFile psiFile) {
|
||||
FeatureUsageTracker.getInstance().triggerFeatureUsed("codeassists.complete.statement");
|
||||
|
||||
return invokeProcessor(editor, psiFile, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean processAfterCompletion(@NotNull Editor editor, @NotNull PsiFile psiFile) {
|
||||
return invokeProcessor(editor, psiFile, true);
|
||||
}
|
||||
|
||||
private boolean invokeProcessor(Editor editor, PsiFile psiFile, boolean afterCompletion) {
|
||||
final Document document = editor.getDocument();
|
||||
final String textForRollback = document.getText();
|
||||
final CharSequence textForRollback = document.getImmutableCharSequence();
|
||||
try {
|
||||
editor.putUserData(SMART_ENTER_TIMESTAMP, editor.getDocument().getModificationStamp());
|
||||
myFirstErrorOffset = Integer.MAX_VALUE;
|
||||
mySkipEnter = false;
|
||||
process(project, editor, psiFile, 0);
|
||||
process(editor, psiFile, 0, afterCompletion);
|
||||
}
|
||||
catch (TooManyAttemptsException e) {
|
||||
document.replaceString(0, document.getTextLength(), textForRollback);
|
||||
@@ -118,8 +133,7 @@ public class JavaSmartEnterProcessor extends SmartEnterProcessor {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private void process(@NotNull final Project project, @NotNull final Editor editor, @NotNull final PsiFile file, final int attempt) throws TooManyAttemptsException {
|
||||
private void process(@NotNull final Editor editor, @NotNull final PsiFile file, final int attempt, boolean afterCompletion) throws TooManyAttemptsException {
|
||||
if (attempt > MAX_ATTEMPTS) throw new TooManyAttemptsException();
|
||||
|
||||
try {
|
||||
@@ -148,18 +162,18 @@ public class JavaSmartEnterProcessor extends SmartEnterProcessor {
|
||||
for (PsiElement psiElement : queue) {
|
||||
for (Fixer fixer : ourFixers) {
|
||||
fixer.apply(editor, this, psiElement);
|
||||
if (LookupManager.getInstance(project).getActiveLookup() != null) {
|
||||
if (LookupManager.getInstance(file.getProject()).getActiveLookup() != null) {
|
||||
return;
|
||||
}
|
||||
if (isUncommited(project) || !psiElement.isValid()) {
|
||||
if (isUncommited(file.getProject()) || !psiElement.isValid()) {
|
||||
moveCaretInsideBracesIfAny(editor, file);
|
||||
process(project, editor, file, attempt + 1);
|
||||
process(editor, file, attempt + 1, afterCompletion);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
doEnter(atCaret, editor);
|
||||
doEnter(atCaret, editor, afterCompletion);
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
LOG.error(e);
|
||||
@@ -187,7 +201,7 @@ public class JavaSmartEnterProcessor extends SmartEnterProcessor {
|
||||
}
|
||||
|
||||
|
||||
private void doEnter(PsiElement atCaret, Editor editor) throws IncorrectOperationException {
|
||||
private void doEnter(PsiElement atCaret, Editor editor, boolean afterCompletion) throws IncorrectOperationException {
|
||||
final PsiFile psiFile = atCaret.getContainingFile();
|
||||
|
||||
final RangeMarker rangeMarker = createRangeMarker(atCaret);
|
||||
@@ -205,7 +219,7 @@ public class JavaSmartEnterProcessor extends SmartEnterProcessor {
|
||||
}
|
||||
|
||||
atCaret = CodeInsightUtil.findElementInRange(psiFile, rangeMarker.getStartOffset(), rangeMarker.getEndOffset(), atCaret.getClass());
|
||||
for (EnterProcessor processor : ourEnterProcessors) {
|
||||
for (EnterProcessor processor : afterCompletion ? ourAfterCompletionEnterProcessors : ourEnterProcessors) {
|
||||
if(atCaret == null){
|
||||
// Can't restore element at caret after enter processor execution!
|
||||
break;
|
||||
@@ -214,7 +228,7 @@ public class JavaSmartEnterProcessor extends SmartEnterProcessor {
|
||||
if (processor.doEnter(editor, atCaret, isModified(editor))) return;
|
||||
}
|
||||
|
||||
if (!isModified(editor)) {
|
||||
if (!isModified(editor) && !afterCompletion) {
|
||||
plainEnter(editor);
|
||||
} else {
|
||||
if (myFirstErrorOffset == Integer.MAX_VALUE) {
|
||||
|
||||
+25
-17
@@ -42,29 +42,37 @@ import org.jetbrains.annotations.Nullable;
|
||||
public class PlainEnterProcessor implements EnterProcessor {
|
||||
@Override
|
||||
public boolean doEnter(Editor editor, PsiElement psiElement, boolean isModified) {
|
||||
if (expandCodeBlock(editor, psiElement)) return true;
|
||||
|
||||
getEnterHandler(IdeActions.ACTION_EDITOR_START_NEW_LINE).execute(editor, ((EditorEx)editor).getDataContext());
|
||||
return true;
|
||||
}
|
||||
|
||||
static boolean expandCodeBlock(Editor editor, PsiElement psiElement) {
|
||||
PsiCodeBlock block = getControlStatementBlock(editor.getCaretModel().getOffset(), psiElement);
|
||||
if (processExistingBlankLine(editor, block, psiElement)) {
|
||||
return true;
|
||||
}
|
||||
EditorActionHandler enterHandler = getEnterHandler(IdeActions.ACTION_EDITOR_START_NEW_LINE);
|
||||
if (block != null) {
|
||||
PsiElement firstElement = block.getFirstBodyElement();
|
||||
if (firstElement == null) {
|
||||
firstElement = block.getRBrace();
|
||||
// Plain enter processor inserts enter after the end of line, hence, we don't want to use it here because the line ends with
|
||||
// the empty braces block. So, we get the following in case of default handler usage:
|
||||
// Before:
|
||||
// if (condition[caret]) {}
|
||||
// After:
|
||||
// if (condition) {}
|
||||
// [caret]
|
||||
enterHandler = getEnterHandler(IdeActions.ACTION_EDITOR_ENTER);
|
||||
}
|
||||
editor.getCaretModel().moveToOffset(firstElement != null ?
|
||||
firstElement.getTextRange().getStartOffset() :
|
||||
block.getTextRange().getEndOffset());
|
||||
if (block == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
EditorActionHandler enterHandler = getEnterHandler(IdeActions.ACTION_EDITOR_START_NEW_LINE);
|
||||
PsiElement firstElement = block.getFirstBodyElement();
|
||||
if (firstElement == null) {
|
||||
firstElement = block.getRBrace();
|
||||
// Plain enter processor inserts enter after the end of line, hence, we don't want to use it here because the line ends with
|
||||
// the empty braces block. So, we get the following in case of default handler usage:
|
||||
// Before:
|
||||
// if (condition[caret]) {}
|
||||
// After:
|
||||
// if (condition) {}
|
||||
// [caret]
|
||||
enterHandler = getEnterHandler(IdeActions.ACTION_EDITOR_ENTER);
|
||||
}
|
||||
editor.getCaretModel().moveToOffset(firstElement != null ?
|
||||
firstElement.getTextRange().getStartOffset() :
|
||||
block.getTextRange().getEndOffset());
|
||||
enterHandler.execute(editor, ((EditorEx)editor).getDataContext());
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
|
||||
class Tester {
|
||||
private void build(EntityBuilder builder) {
|
||||
}
|
||||
|
||||
public void test1(int abc, int abd) {
|
||||
System.out.println(a<caret>);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
|
||||
class Tester {
|
||||
private void build(EntityBuilder builder) {
|
||||
}
|
||||
|
||||
public void test1(int abc, int abd) {
|
||||
System.out.println(abc);<caret>
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
|
||||
class Tester {
|
||||
private void build(EntityBuilder builder) {
|
||||
}
|
||||
|
||||
public void test1(int abc, int abd) {
|
||||
if(a<caret>)
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
|
||||
class Tester {
|
||||
private void build(EntityBuilder builder) {
|
||||
}
|
||||
|
||||
public void test1(int abc, int abd) {
|
||||
if (abc) {
|
||||
<caret>
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
@@ -920,6 +920,9 @@ public class ListUtils {
|
||||
}
|
||||
|
||||
public void testSmartEnterWrapsConstructorCall() throws Throwable { doTest(Lookup.COMPLETE_STATEMENT_SELECT_CHAR as String) }
|
||||
public void testSmartEnterNoNewLine() { doTest(Lookup.COMPLETE_STATEMENT_SELECT_CHAR as String) }
|
||||
public void testSmartEnterWithNewLine() { doTest(Lookup.COMPLETE_STATEMENT_SELECT_CHAR as String) }
|
||||
|
||||
public void testTabReplacesMethodNameWithLocalVariableName() throws Throwable { doTest('\t'); }
|
||||
public void testMethodParameterAnnotationClass() throws Throwable { doTest(); }
|
||||
public void testPrimitiveCastOverwrite() throws Throwable { doTest '\t' }
|
||||
|
||||
+4
@@ -36,6 +36,10 @@ import org.jetbrains.annotations.Nullable;
|
||||
public abstract class SmartEnterProcessor {
|
||||
public abstract boolean process(@NotNull final Project project, @NotNull final Editor editor, @NotNull final PsiFile psiFile);
|
||||
|
||||
public boolean processAfterCompletion(@NotNull final Editor editor, @NotNull final PsiFile psiFile) {
|
||||
return process(psiFile.getProject(), editor, psiFile);
|
||||
}
|
||||
|
||||
protected void reformat(PsiElement atCaret) throws IncorrectOperationException {
|
||||
final TextRange range = atCaret.getTextRange();
|
||||
final PsiFile file = atCaret.getContainingFile();
|
||||
|
||||
+2
-5
@@ -772,11 +772,8 @@ public class CodeCompletionHandlerBase {
|
||||
if (context.getCompletionChar() == Lookup.COMPLETE_STATEMENT_SELECT_CHAR) {
|
||||
final Language language = PsiUtilBase.getLanguageInEditor(editor, project);
|
||||
if (language != null) {
|
||||
final List<SmartEnterProcessor> processors = SmartEnterProcessors.INSTANCE.forKey(language);
|
||||
if (processors.size() > 0) {
|
||||
for (SmartEnterProcessor processor : processors) {
|
||||
processor.process(project, editor, indicator.getParameters().getOriginalFile());
|
||||
}
|
||||
for (SmartEnterProcessor processor : SmartEnterProcessors.INSTANCE.forKey(language)) {
|
||||
if (processor.processAfterCompletion(editor, indicator.getParameters().getOriginalFile())) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user