diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/template/LiveTemplateTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/template/LiveTemplateTest.groovy index e2ccb58f981a..09a8154c42bd 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/template/LiveTemplateTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/template/LiveTemplateTest.groovy @@ -485,7 +485,7 @@ class Foo { writeCommand(runnable) } - private writeCommand(Runnable runnable) { + private static writeCommand(Runnable runnable) { WriteCommandAction.runWriteCommandAction(null, runnable) } @@ -894,7 +894,7 @@ class Foo { class Foo { { System.out.println(); - sout + System.out.println(); System.out.println(); } } @@ -924,8 +924,7 @@ class Foo { class Foo { { System.out.println(); - sout - + System.out.println(); System.out.println(); } } @@ -956,7 +955,7 @@ class Foo { class Foo { { System.out.println(); - sout + System.out.println(); System.out.println(); } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/actions/MultiCaretCodeInsightAction.java b/platform/lang-impl/src/com/intellij/codeInsight/actions/MultiCaretCodeInsightAction.java index 568e17b58bd6..b91087dae459 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/actions/MultiCaretCodeInsightAction.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/actions/MultiCaretCodeInsightAction.java @@ -37,16 +37,16 @@ import org.jetbrains.annotations.NotNull; /** * Base class for PSI-aware editor actions that need to support multiple carets. * Recognizes multi-root PSI and injected fragments, so different carets might be processed in context of different - * {@link com.intellij.openapi.editor.Editor} and {@link com.intellij.psi.PsiFile} instances. + * {@link Editor} and {@link PsiFile} instances. *

* Implementations should implement {@link #getHandler()} method, and might override {@link - * #isValidFor(com.intellij.openapi.project.Project, com.intellij.openapi.editor.Editor, com.intellij.openapi.editor.Caret, com.intellij.psi.PsiFile)} method. + * #isValidFor(Project, Editor, Caret, PsiFile)} method. * - * @see com.intellij.codeInsight.actions.MultiCaretCodeInsightActionHandler + * @see MultiCaretCodeInsightActionHandler */ public abstract class MultiCaretCodeInsightAction extends AnAction { @Override - public void actionPerformed(AnActionEvent e) { + public void actionPerformed(@NotNull AnActionEvent e) { final Project project = e.getProject(); if (project == null) { return; @@ -82,7 +82,7 @@ public abstract class MultiCaretCodeInsightAction extends AnAction { } @Override - public void update(AnActionEvent e) { + public void update(@NotNull AnActionEvent e) { final Presentation presentation = e.getPresentation(); Project project = e.getProject(); @@ -132,7 +132,7 @@ public abstract class MultiCaretCodeInsightAction extends AnAction { handler.invoke(project, editor, caret, file); } } - }, true); + }); } /** diff --git a/platform/lang-impl/src/com/intellij/codeInsight/actions/MultiCaretCodeInsightActionHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/actions/MultiCaretCodeInsightActionHandler.java index bfe7e325b8eb..f67801198988 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/actions/MultiCaretCodeInsightActionHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/actions/MultiCaretCodeInsightActionHandler.java @@ -22,11 +22,11 @@ import com.intellij.psi.PsiFile; import org.jetbrains.annotations.NotNull; /** - * Delegate class that performs actual work for {@link com.intellij.codeInsight.actions.MultiCaretCodeInsightAction} + * Delegate class that performs actual work for {@link MultiCaretCodeInsightAction} */ public abstract class MultiCaretCodeInsightActionHandler { /** - * Invoked for each caret in editor (in bottom-to-top order). project value is the same for all carets, editor + * Invoked for each caret in editor (in top-to-bottom order). project value is the same for all carets, editor * and file values can be different in presence of multi-root PSI and injected fragments. For injected fragments * caret instance will belong to corresponding injected editor. */ diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java index 03fd6cfd335a..7c7bdd9507a5 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java @@ -621,7 +621,7 @@ public class CodeCompletionHandlerBase { injectedMap); contexts.add(currentContext); } - }, true); + }); context = contexts.get(contexts.size() - 1); if (context.shouldAddCompletionChar() && context.getCompletionChar() != Lookup.COMPLETE_STATEMENT_SELECT_CHAR) { ApplicationManager.getApplication().runWriteAction(new Runnable() { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/TypedHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/TypedHandler.java index 14ab0b69ca72..c4a3d2187d6f 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/TypedHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/TypedHandler.java @@ -54,6 +54,7 @@ import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.TokenSet; import com.intellij.psi.util.PsiUtilBase; import com.intellij.util.IncorrectOperationException; +import com.intellij.util.containers.ContainerUtil; import com.intellij.util.text.CharArrayUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -198,7 +199,7 @@ public class TypedHandler extends TypedActionHandlerBase { } } else if ('"' == charTyped || '\'' == charTyped || '`' == charTyped/* || '/' == charTyped*/) { - if (handleQuote(editor, charTyped, dataContext, file)) return; + if (handleQuote(editor, charTyped, file)) return; } long modificationStampBeforeTyping = editor.getDocument().getModificationStamp(); @@ -233,7 +234,7 @@ public class TypedHandler extends TypedActionHandlerBase { indentOpenedParenth(project, editor); } } - }, true); + }); } private static void type(Editor editor, char charTyped) { @@ -252,6 +253,12 @@ public class TypedHandler extends TypedActionHandlerBase { AutoPopupController.getInstance(project).autoPopupMemberLookup(editor, null); } } + + public static void commitDocumentIfCurrentCaretIsNotTheFirstOne(@NotNull Editor editor, @NotNull Project project) { + if (ContainerUtil.getFirstItem(editor.getCaretModel().getAllCarets()) != editor.getCaretModel().getCurrentCaret()) { + PsiDocumentManager.getInstance(project).commitDocument(editor.getDocument()); + } + } private static boolean isAutoPopup(@NotNull Editor editor, @NotNull PsiFile file, char charTyped) { final int offset = editor.getCaretModel().getOffset() - 1; @@ -425,7 +432,7 @@ public class TypedHandler extends TypedActionHandlerBase { return true; } - private boolean handleQuote(@NotNull Editor editor, char quote, @NotNull DataContext dataContext, @NotNull PsiFile file) { + private static boolean handleQuote(@NotNull Editor editor, char quote, @NotNull PsiFile file) { if (!CodeInsightSettings.getInstance().AUTOINSERT_PAIR_QUOTE) return false; final QuoteHandler quoteHandler = getQuoteHandler(file, editor); if (quoteHandler == null) return false; diff --git a/platform/lang-impl/src/com/intellij/codeInsight/generation/CommentByLineCommentHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/generation/CommentByLineCommentHandler.java index 313f49bfc962..c545a64ff160 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/generation/CommentByLineCommentHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/generation/CommentByLineCommentHandler.java @@ -122,18 +122,18 @@ public class CommentByLineCommentHandler extends MultiCaretCodeInsightActionHand Block lastBlock = myBlocks.isEmpty() ? null : myBlocks.get(myBlocks.size() - 1); Block currentBlock; - if (lastBlock == null || lastBlock.editor != editor || lastBlock.psiFile != file || endLine < (lastBlock.startLine - 1)) { + if (lastBlock == null || lastBlock.editor != editor || lastBlock.psiFile != file || startLine > (lastBlock.endLine + 1)) { currentBlock = new Block(); currentBlock.editor = editor; currentBlock.psiFile = file; - currentBlock.endLine = endLine; + currentBlock.startLine = startLine; myBlocks.add(currentBlock); } else { currentBlock = lastBlock; } currentBlock.carets.add(caret); - currentBlock.startLine = startLine; + currentBlock.endLine = endLine; boolean wholeLinesSelected = !hasSelection || startOffset == document.getLineStartOffset(document.getLineNumber(startOffset)) && diff --git a/platform/platform-api/src/com/intellij/openapi/editor/actionSystem/EditorActionHandler.java b/platform/platform-api/src/com/intellij/openapi/editor/actionSystem/EditorActionHandler.java index 294622ce1916..6b0ebd64dc6c 100644 --- a/platform/platform-api/src/com/intellij/openapi/editor/actionSystem/EditorActionHandler.java +++ b/platform/platform-api/src/com/intellij/openapi/editor/actionSystem/EditorActionHandler.java @@ -15,7 +15,9 @@ */ package com.intellij.openapi.editor.actionSystem; -import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; +import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.editor.Caret; import com.intellij.openapi.editor.CaretAction; import com.intellij.openapi.editor.Editor; @@ -25,11 +27,11 @@ import org.jetbrains.annotations.Nullable; /** * Interface for actions activated by keystrokes in the editor. * Implementations should override - * {@link #execute(com.intellij.openapi.editor.Editor, com.intellij.openapi.editor.Caret, com.intellij.openapi.actionSystem.DataContext)} + * {@link #execute(Editor, Caret, DataContext)} * . *

* Two types of handlers are supported: the ones which are executed once, and the ones which are executed for each caret. The latter can be - * created using {@link com.intellij.openapi.editor.actionSystem.EditorActionHandler#EditorActionHandler(boolean)} constructor. + * created using {@link EditorActionHandler#EditorActionHandler(boolean)} constructor. * * @see EditorActionManager#setActionHandler(String, EditorActionHandler) */ @@ -49,10 +51,10 @@ public abstract class EditorActionHandler { /** * @deprecated Implementations should override - * {@link #isEnabledForCaret(com.intellij.openapi.editor.Editor, com.intellij.openapi.editor.Caret, com.intellij.openapi.actionSystem.DataContext)} + * {@link #isEnabledForCaret(Editor, Caret, DataContext)} * instead, * client code should invoke - * {@link #isEnabled(com.intellij.openapi.editor.Editor, com.intellij.openapi.editor.Caret, com.intellij.openapi.actionSystem.DataContext)} + * {@link #isEnabled(Editor, Caret, DataContext)} * instead. */ public boolean isEnabled(Editor editor, final DataContext dataContext) { @@ -135,9 +137,9 @@ public abstract class EditorActionHandler { } /** * @deprecated To implement action logic, override - * {@link #doExecute(com.intellij.openapi.editor.Editor, com.intellij.openapi.editor.Caret, com.intellij.openapi.actionSystem.DataContext)}, + * {@link #doExecute(Editor, Caret, DataContext)}, * to invoke the handler, call - * {@link #execute(com.intellij.openapi.editor.Editor, com.intellij.openapi.editor.Caret, com.intellij.openapi.actionSystem.DataContext)}. + * {@link #execute(Editor, Caret, DataContext)}. */ public void execute(Editor editor, DataContext dataContext) { if (inExecution) { @@ -205,7 +207,7 @@ public abstract class EditorActionHandler { } }); } - }, true); + }); } else { if (contextCaret == null) { diff --git a/platform/platform-tests/testData/editor/multiCaret/EditorDeleteToWordEnd-after.txt b/platform/platform-tests/testData/editor/multiCaret/EditorDeleteToWordEnd-after.txt index a9d628d0c856..0e8f561530eb 100644 --- a/platform/platform-tests/testData/editor/multiCaret/EditorDeleteToWordEnd-after.txt +++ b/platform/platform-tests/testData/editor/multiCaret/EditorDeleteToWordEnd-after.txt @@ -1,3 +1,2 @@ -s textor text -aner l -yet aher line \ No newline at end of file +stextor text +aner lyet aher line \ No newline at end of file diff --git a/platform/platform-tests/testData/editor/multiCaret/EditorDeleteToWordEndInDifferentHumpsMode-after.txt b/platform/platform-tests/testData/editor/multiCaret/EditorDeleteToWordEndInDifferentHumpsMode-after.txt index c48a5ad7f48a..1b3f82a9edf6 100644 --- a/platform/platform-tests/testData/editor/multiCaret/EditorDeleteToWordEndInDifferentHumpsMode-after.txt +++ b/platform/platform-tests/testData/editor/multiCaret/EditorDeleteToWordEndInDifferentHumpsMode-after.txt @@ -1,2 +1,2 @@ -AbCaDabraHumump Hump +AbDabraHumump Hump \ No newline at end of file diff --git a/platform/platform-tests/testData/editor/multiCaret/EditorDeleteToWordStart-after.txt b/platform/platform-tests/testData/editor/multiCaret/EditorDeleteToWordStart-after.txt index 37984912c5bc..b66dd51f46f7 100644 --- a/platform/platform-tests/testData/editor/multiCaret/EditorDeleteToWordStart-after.txt +++ b/platform/platform-tests/testData/editor/multiCaret/EditorDeleteToWordStart-after.txt @@ -1,3 +1,3 @@ -t +some t oer tt lineyet another line \ No newline at end of file diff --git a/platform/platform-tests/testData/editor/multiCaret/EditorEnter-after.txt b/platform/platform-tests/testData/editor/multiCaret/EditorEnter-after.txt index 6168f195986e..fb348125e7a7 100644 --- a/platform/platform-tests/testData/editor/multiCaret/EditorEnter-after.txt +++ b/platform/platform-tests/testData/editor/multiCaret/EditorEnter-after.txt @@ -1,6 +1,6 @@ some te -xt + xt other diff --git a/platform/platform-tests/testData/editor/multiCaret/EditorTab-after.txt b/platform/platform-tests/testData/editor/multiCaret/EditorTab-after.txt index 4a2968934c3c..309b65c1e7d3 100644 --- a/platform/platform-tests/testData/editor/multiCaret/EditorTab-after.txt +++ b/platform/platform-tests/testData/editor/multiCaret/EditorTab-after.txt @@ -1,2 +1,2 @@ -so me t t +so me t t text \ No newline at end of file diff --git a/xml/impl/src/com/intellij/codeInsight/editorActions/XmlEqTypedHandler.java b/xml/impl/src/com/intellij/codeInsight/editorActions/XmlEqTypedHandler.java index bd0d76c42d38..2896a274823b 100644 --- a/xml/impl/src/com/intellij/codeInsight/editorActions/XmlEqTypedHandler.java +++ b/xml/impl/src/com/intellij/codeInsight/editorActions/XmlEqTypedHandler.java @@ -31,10 +31,11 @@ public class XmlEqTypedHandler extends TypedHandlerDelegate { @Override public Result beforeCharTyped(char c, Project project, Editor editor, PsiFile file, FileType fileType) { - if (WebEditorOptions.getInstance().isInsertQuotesForAttributeValue()) { boolean inXml = file.getLanguage() instanceof XMLLanguage || file.getViewProvider().getBaseLanguage() instanceof XMLLanguage; if (c == '=' && inXml) { + TypedHandler.commitDocumentIfCurrentCaretIsNotTheFirstOne(editor, project); + PsiElement at = file.findElementAt(editor.getCaretModel().getOffset() - 1); PsiElement atParent = at != null ? at.getParent() : null; if(atParent instanceof XmlAttribute && ((XmlAttribute)atParent).getValueElement() == null) { diff --git a/xml/tests/src/com/intellij/codeInsight/completion/XmlTypedHandlersTest.java b/xml/tests/src/com/intellij/codeInsight/completion/XmlTypedHandlersTest.java index 89b6333a7e8a..eeeed9e9707a 100644 --- a/xml/tests/src/com/intellij/codeInsight/completion/XmlTypedHandlersTest.java +++ b/xml/tests/src/com/intellij/codeInsight/completion/XmlTypedHandlersTest.java @@ -60,7 +60,7 @@ public class XmlTypedHandlersTest extends LightPlatformCodeInsightFixtureTestCas ""); } - public void _testCloseTagOnSlashWithMultiCaretsInDifferentContexts() { + public void testCloseTagOnSlashWithMultiCaretsInDifferentContexts() { doTest("\n" + "<\n" + "<\n" + @@ -70,7 +70,7 @@ public class XmlTypedHandlersTest extends LightPlatformCodeInsightFixtureTestCas ""); } - public void _testCloseTagOnGtWithMultiCaretsInDifferentContexts() { + public void testCloseTagOnGtWithMultiCaretsInDifferentContexts() { doTest("\n" + "\n" + "\n" +