mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
completion during block selection to handle tab and backspace as expected
This commit is contained in:
+39
-14
@@ -43,7 +43,6 @@ import com.intellij.openapi.extensions.LoadingOrder
|
||||
import com.intellij.openapi.fileEditor.FileEditor
|
||||
import com.intellij.openapi.fileEditor.FileEditorManager
|
||||
import com.intellij.openapi.progress.ProgressManager
|
||||
import com.intellij.openapi.util.Computable
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.PsiJavaFile
|
||||
import com.intellij.util.Consumer
|
||||
@@ -1113,25 +1112,51 @@ public class UTest {
|
||||
}
|
||||
|
||||
public void testBlockSelection() {
|
||||
myFixture.configureByText "a.java", """
|
||||
doTestBlockSelection """
|
||||
class Foo {{
|
||||
<caret>t;
|
||||
t;
|
||||
}}"""
|
||||
def caret = ApplicationManager.getApplication().runReadAction(new Computable<LogicalPosition>() {
|
||||
public LogicalPosition compute() {
|
||||
return myFixture.editor.offsetToLogicalPosition(myFixture.editor.caretModel.offset)
|
||||
}});
|
||||
edt { myFixture.editor.selectionModel.setBlockSelection(caret, new LogicalPosition(caret.line + 1, caret.column + 1)) }
|
||||
type 'toStr'
|
||||
assert lookup
|
||||
type '\n'
|
||||
myFixture.checkResult '''
|
||||
<caret>tx;
|
||||
tx;
|
||||
}}""", '\n', '''
|
||||
class Foo {{
|
||||
toString()x;
|
||||
toString()<caret>x;
|
||||
}}'''
|
||||
}
|
||||
|
||||
public void testBlockSelectionTab() {
|
||||
doTestBlockSelection """
|
||||
class Foo {{
|
||||
<caret>tx;
|
||||
tx;
|
||||
}}""", '\t', '''
|
||||
class Foo {{
|
||||
toString();
|
||||
toString()<caret>;
|
||||
}}'''
|
||||
}
|
||||
|
||||
public void testBlockSelectionBackspace() {
|
||||
doTestBlockSelection """
|
||||
class Foo {{
|
||||
<caret>t;
|
||||
t;
|
||||
}}""", '\b\t', '''
|
||||
class Foo {{
|
||||
toString();
|
||||
toString()<caret>;
|
||||
}}'''
|
||||
}
|
||||
|
||||
private doTestBlockSelection(final String textBefore, final String toType, final String textAfter) {
|
||||
myFixture.configureByText "a.java", textBefore
|
||||
edt {
|
||||
def caret = myFixture.editor.offsetToLogicalPosition(myFixture.editor.caretModel.offset)
|
||||
myFixture.editor.selectionModel.setBlockSelection(caret, new LogicalPosition(caret.line + 1, caret.column + 1))
|
||||
}
|
||||
type 'toStr'
|
||||
assert lookup
|
||||
type toType
|
||||
myFixture.checkResult textAfter
|
||||
def start = myFixture.editor.selectionModel.blockStart
|
||||
def end = myFixture.editor.selectionModel.blockEnd
|
||||
assert start.line == end.line - 1
|
||||
|
||||
+13
-10
@@ -630,6 +630,9 @@ public class CodeCompletionHandlerBase implements CodeInsightActionHandler {
|
||||
|
||||
final Editor editor = indicator.getEditor();
|
||||
|
||||
final int caretOffset = editor.getCaretModel().getOffset();
|
||||
final int idDelta = indicator.getIdentifierEndOffset() - caretOffset;
|
||||
|
||||
WatchingInsertionContext context = null;
|
||||
if (editor.getSelectionModel().hasBlockSelection() && editor.getSelectionModel().getBlockSelectionEnds().length > 0) {
|
||||
List<RangeMarker> insertionPoints = new ArrayList<RangeMarker>();
|
||||
@@ -640,7 +643,7 @@ public class CodeCompletionHandlerBase implements CodeInsightActionHandler {
|
||||
List<RangeMarker> caretsAfter = new ArrayList<RangeMarker>();
|
||||
for (RangeMarker insertionPoint : insertionPoints) {
|
||||
if (insertionPoint.isValid()) {
|
||||
context = insertItem(indicator, item, completionChar, items, update, editor, insertionPoint.getStartOffset());
|
||||
context = insertItem(indicator, item, completionChar, items, update, editor, insertionPoint.getStartOffset(), idDelta);
|
||||
int offset = editor.getCaretModel().getOffset();
|
||||
caretsAfter.add(editor.getDocument().createRangeMarker(offset, offset));
|
||||
}
|
||||
@@ -657,7 +660,7 @@ public class CodeCompletionHandlerBase implements CodeInsightActionHandler {
|
||||
}
|
||||
|
||||
} else {
|
||||
context = insertItem(indicator, item, completionChar, items, update, editor, editor.getCaretModel().getOffset());
|
||||
context = insertItem(indicator, item, completionChar, items, update, editor, caretOffset, idDelta);
|
||||
}
|
||||
|
||||
final Runnable runnable = context.getLaterRunnable();
|
||||
@@ -707,26 +710,26 @@ public class CodeCompletionHandlerBase implements CodeInsightActionHandler {
|
||||
final char completionChar,
|
||||
List<LookupElement> items,
|
||||
final CompletionLookupArranger.StatisticsUpdate update,
|
||||
final Editor editor, final int caretOffset) {
|
||||
final Editor editor, final int caretOffset, final int idDelta) {
|
||||
editor.getCaretModel().moveToOffset(caretOffset);
|
||||
final int initialStartOffset = caretOffset - item.getLookupString().length();
|
||||
assert initialStartOffset >= 0 : "negative startOffset: " + caretOffset + "; " + item.getLookupString();
|
||||
final int idEndOffset = caretOffset + Math.max(idDelta, 0);
|
||||
|
||||
indicator.getOffsetMap().addOffset(CompletionInitializationContext.START_OFFSET, initialStartOffset);
|
||||
indicator.getOffsetMap().addOffset(CompletionInitializationContext.SELECTION_END_OFFSET, caretOffset);
|
||||
indicator.getOffsetMap().addOffset(CompletionInitializationContext.IDENTIFIER_END_OFFSET, idEndOffset);
|
||||
|
||||
final WatchingInsertionContext context = new WatchingInsertionContext(indicator, completionChar, items, editor);
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final int idEndOffset = Math.max(caretOffset, indicator.getIdentifierEndOffset());
|
||||
indicator.getOffsetMap().addOffset(CompletionInitializationContext.IDENTIFIER_END_OFFSET, idEndOffset);
|
||||
int selEnd = indicator.getSelectionEndOffset();
|
||||
if (idEndOffset != selEnd && completionChar == Lookup.REPLACE_SELECT_CHAR) {
|
||||
editor.getDocument().deleteString(selEnd, idEndOffset);
|
||||
if (caretOffset != idEndOffset && completionChar == Lookup.REPLACE_SELECT_CHAR) {
|
||||
editor.getDocument().deleteString(caretOffset, idEndOffset);
|
||||
}
|
||||
|
||||
assert context.getStartOffset() >= 0 : "stale startOffset: was " + initialStartOffset + "; selEnd=" + selEnd + "; idEnd=" + idEndOffset + "; file=" + context.getFile();
|
||||
assert context.getTailOffset() >= 0 : "stale tail: was " + initialStartOffset + "; selEnd=" + selEnd + "; idEnd=" + idEndOffset + "; file=" + context.getFile();
|
||||
assert context.getStartOffset() >= 0 : "stale startOffset: was " + initialStartOffset + "; selEnd=" + caretOffset + "; idEnd=" + idEndOffset + "; file=" + context.getFile();
|
||||
assert context.getTailOffset() >= 0 : "stale tail: was " + initialStartOffset + "; selEnd=" + caretOffset + "; idEnd=" + idEndOffset + "; file=" + context.getFile();
|
||||
|
||||
item.handleInsert(context);
|
||||
Project project = indicator.getProject();
|
||||
|
||||
@@ -45,7 +45,6 @@ public class BackspaceHandler extends EditorActionHandler {
|
||||
lookup.performGuardedChange(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
editor.getSelectionModel().removeSelection();
|
||||
handler.execute(editor, dataContext);
|
||||
}
|
||||
});
|
||||
|
||||
+8
-1
@@ -181,12 +181,19 @@ public abstract class LookupActionHandler extends EditorActionHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void executeInLookup(LookupImpl lookup, DataContext context) {
|
||||
protected void executeInLookup(final LookupImpl lookup, DataContext context) {
|
||||
if (!lookup.isCompletion()) {
|
||||
myOriginalHandler.execute(lookup.getEditor(), context);
|
||||
return;
|
||||
}
|
||||
|
||||
lookup.performGuardedChange(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
lookup.getEditor().getSelectionModel().removeSelection();
|
||||
}
|
||||
});
|
||||
|
||||
BackspaceHandler.truncatePrefix(context, lookup, myOriginalHandler, lookup.getLookupStart() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user