mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-118389 Forbid completion inside guard blocks
This commit is contained in:
@@ -107,10 +107,16 @@ public class CodeInsightUtilBase extends CodeInsightUtilCore {
|
||||
// returns true on success
|
||||
public static boolean prepareEditorForWrite(@NotNull Editor editor) {
|
||||
if (!editor.isViewer()) return true;
|
||||
showReadOnlyViewWarning(editor);
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void showReadOnlyViewWarning(Editor editor) {
|
||||
if (ApplicationManager.getApplication().isHeadlessEnvironment()) return;
|
||||
|
||||
JComponent component = HintUtil.createInformationLabel("This view is read-only");
|
||||
final LightweightHint hint = new LightweightHint(component);
|
||||
HintManagerImpl.getInstanceImpl().showEditorHint(hint, editor, HintManager.UNDER,
|
||||
HintManager.HIDE_BY_ANY_KEY | HintManager.HIDE_BY_TEXT_CHANGE | HintManager.HIDE_BY_SCROLLING, 0, false);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
+7
-7
@@ -109,6 +109,10 @@ public class CodeCompletionHandlerBase {
|
||||
}
|
||||
|
||||
public final void invokeCompletion(@NotNull final Project project, @NotNull final Editor editor, int time, boolean hasModifiers, boolean restarted) {
|
||||
if (invokedExplicitly) {
|
||||
CompletionLookupArranger.applyLastCompletionStatisticsUpdate();
|
||||
}
|
||||
|
||||
final PsiFile psiFile = PsiUtilBase.getPsiFileInEditor(editor, project);
|
||||
assert psiFile != null : "no PSI file: " + FileDocumentManager.getInstance().getFile(editor.getDocument());
|
||||
|
||||
@@ -116,17 +120,13 @@ public class CodeCompletionHandlerBase {
|
||||
|
||||
CompletionAssertions.checkEditorValid(editor);
|
||||
|
||||
if (editor.isViewer()) {
|
||||
if (editor.isViewer() || editor.getDocument().getOffsetGuard(editor.getCaretModel().getOffset()) != null) {
|
||||
editor.getDocument().fireReadOnlyModificationAttempt();
|
||||
CodeInsightUtilBase.showReadOnlyViewWarning(editor);
|
||||
return;
|
||||
}
|
||||
|
||||
if (invokedExplicitly) {
|
||||
CompletionLookupArranger.applyLastCompletionStatisticsUpdate();
|
||||
}
|
||||
|
||||
if (!CodeInsightUtilBase.prepareEditorForWrite(editor) ||
|
||||
!FileDocumentManager.getInstance().requestWriting(editor.getDocument(), project)) {
|
||||
if (!FileDocumentManager.getInstance().requestWriting(editor.getDocument(), project)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
+7
@@ -17,6 +17,7 @@
|
||||
package com.intellij.codeInsight.completion.actions;
|
||||
|
||||
import com.intellij.codeInsight.CodeInsightActionHandler;
|
||||
import com.intellij.codeInsight.CodeInsightUtilBase;
|
||||
import com.intellij.codeInsight.FileModificationService;
|
||||
import com.intellij.codeInsight.completion.impl.CamelHumpMatcher;
|
||||
import com.intellij.codeInsight.highlighting.HighlightManager;
|
||||
@@ -54,6 +55,12 @@ public class HippieWordCompletionHandler implements CodeInsightActionHandler {
|
||||
public void invoke(@NotNull Project project, @NotNull final Editor editor, @NotNull PsiFile file) {
|
||||
if (!FileModificationService.getInstance().prepareFileForWrite(file)) return;
|
||||
|
||||
if (editor.isViewer() || editor.getDocument().getOffsetGuard(editor.getCaretModel().getOffset()) != null) {
|
||||
editor.getDocument().fireReadOnlyModificationAttempt();
|
||||
CodeInsightUtilBase.showReadOnlyViewWarning(editor);
|
||||
return;
|
||||
}
|
||||
|
||||
LookupManager.getInstance(project).hideActiveLookup();
|
||||
|
||||
final CharSequence charsSequence = editor.getDocument().getCharsSequence();
|
||||
|
||||
@@ -654,7 +654,13 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable
|
||||
myFinishing = true;
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
public void run() {
|
||||
insertLookupString(item, getPrefixLength(item));
|
||||
myEditor.getDocument().startGuardedBlockChecking();
|
||||
try {
|
||||
insertLookupString(item, getPrefixLength(item));
|
||||
}
|
||||
finally {
|
||||
myEditor.getDocument().stopGuardedBlockChecking();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -768,12 +774,14 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable
|
||||
checkValid();
|
||||
assert !myChangeGuard : "already in change";
|
||||
|
||||
myEditor.getDocument().startGuardedBlockChecking();
|
||||
myChangeGuard = true;
|
||||
boolean result;
|
||||
try {
|
||||
result = myOffsets.performGuardedChange(change, debug);
|
||||
}
|
||||
finally {
|
||||
myEditor.getDocument().stopGuardedBlockChecking();
|
||||
myChangeGuard = false;
|
||||
}
|
||||
if (!result || myDisposed) {
|
||||
|
||||
+31
-16
@@ -1,20 +1,22 @@
|
||||
package com.intellij.openapi.editor.impl;
|
||||
|
||||
import com.intellij.codeInsight.lookup.LookupManager;
|
||||
import com.intellij.openapi.actionSystem.IdeActions;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.RangeMarker;
|
||||
import com.intellij.testFramework.LightPlatformCodeInsightTestCase;
|
||||
import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase;
|
||||
|
||||
/**
|
||||
* @author cdr
|
||||
*/
|
||||
public class GuardBlockTest extends LightPlatformCodeInsightTestCase {
|
||||
private static RangeMarker createGuard(final int start, final int end) {
|
||||
final Document document = getEditor().getDocument();
|
||||
public class GuardBlockTest extends LightPlatformCodeInsightFixtureTestCase {
|
||||
private RangeMarker createGuard(final int start, final int end) {
|
||||
final Document document = myFixture.getEditor().getDocument();
|
||||
return document.createGuardedBlock(start, end);
|
||||
}
|
||||
|
||||
public void testZero() throws Exception {
|
||||
configureFromFileText("x.txt", "xxxx");
|
||||
myFixture.configureByText("x.txt", "xxxx");
|
||||
RangeMarker guard = createGuard(0, 0);
|
||||
guard.setGreedyToLeft(true);
|
||||
guard.setGreedyToRight(true);
|
||||
@@ -23,14 +25,14 @@ public class GuardBlockTest extends LightPlatformCodeInsightTestCase {
|
||||
}
|
||||
|
||||
public void testInTheMiddle() throws Exception {
|
||||
configureFromFileText("x.txt", "xxxxxxxx");
|
||||
myFixture.configureByText("x.txt", "xxxxxxxx");
|
||||
createGuard(1, 4);
|
||||
checkUnableToTypeIn(2);
|
||||
checkCanTypeIn(0);
|
||||
}
|
||||
|
||||
public void testGreedy() throws Exception {
|
||||
configureFromFileText("x.txt", "012345678");
|
||||
myFixture.configureByText("x.txt", "012345678");
|
||||
{
|
||||
RangeMarker guard = createGuard(0, 5);
|
||||
guard.setGreedyToLeft(true);
|
||||
@@ -45,7 +47,7 @@ public class GuardBlockTest extends LightPlatformCodeInsightTestCase {
|
||||
checkUnableToTypeIn(0);
|
||||
}
|
||||
public void testGreedyEnd() throws Exception {
|
||||
configureFromFileText("x.txt", "012345678");
|
||||
myFixture.configureByText("x.txt", "012345678");
|
||||
{
|
||||
RangeMarker guard = createGuard(0, 5);
|
||||
guard.setGreedyToLeft(true);
|
||||
@@ -54,22 +56,35 @@ public class GuardBlockTest extends LightPlatformCodeInsightTestCase {
|
||||
checkUnableToTypeIn(5);
|
||||
}
|
||||
|
||||
private static void checkUnableToTypeIn(int offset) {
|
||||
String text = getEditor().getDocument().getText();
|
||||
private void checkUnableToTypeIn(int offset) {
|
||||
String text = myFixture.getEditor().getDocument().getText();
|
||||
try {
|
||||
getEditor().getCaretModel().moveToOffset(offset);
|
||||
type("y");
|
||||
myFixture.getEditor().getCaretModel().moveToOffset(offset);
|
||||
myFixture.type("y");
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
assertEquals("Unable to perform an action since it changes read-only fragments of the current document",e.getMessage());
|
||||
assertEquals(text, getEditor().getDocument().getText());
|
||||
assertEquals(text, myFixture.getEditor().getDocument().getText());
|
||||
return;
|
||||
}
|
||||
fail("must be read only at "+offset);
|
||||
}
|
||||
|
||||
private static void checkCanTypeIn(int offset) {
|
||||
getEditor().getCaretModel().moveToOffset(offset);
|
||||
type("yy");
|
||||
private void checkCanTypeIn(int offset) {
|
||||
myFixture.getEditor().getCaretModel().moveToOffset(offset);
|
||||
myFixture.type("yy");
|
||||
}
|
||||
|
||||
public void testNoCompletion() throws Exception {
|
||||
String text = "abc abd a<caret> abx";
|
||||
myFixture.configureByText("x.txt", text);
|
||||
createGuard(0, myFixture.getFile().getTextLength());
|
||||
|
||||
assertNull(myFixture.completeBasic());
|
||||
myFixture.checkResult(text);
|
||||
|
||||
myFixture.performEditorAction(IdeActions.ACTION_HIPPIE_BACKWARD_COMPLETION);
|
||||
assertNull(LookupManager.getInstance(getProject()).getActiveLookup());
|
||||
myFixture.checkResult(text);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user