make smart backspace work when virtual space is enabled in editor

This commit is contained in:
Dmitry Batrak
2014-06-23 16:29:39 +04:00
parent f859f2b39a
commit f0ed98335c
7 changed files with 148 additions and 9 deletions
@@ -23,6 +23,7 @@ import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.LogicalPosition;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.intellij.psi.codeStyle.LanguageCodeStyleSettingsProvider;
@@ -35,13 +36,16 @@ import org.jetbrains.annotations.NotNull;
public class IndentingBackspaceHandler extends BackspaceHandlerDelegate {
private static final Logger LOG = Logger.getInstance(IndentingBackspaceHandler.class);
private boolean caretWasAtLineStart;
@Override
public void beforeCharDeleted(char c, PsiFile file, Editor editor) {
caretWasAtLineStart = editor.getCaretModel().getLogicalPosition().column == 0;
}
@Override
public boolean charDeleted(char c, PsiFile file, Editor editor) {
if (!CodeInsightSettings.getInstance().INDENTING_BACKSPACE || " \n\t".indexOf(c) == -1) {
if (!CodeInsightSettings.getInstance().INDENTING_BACKSPACE || !StringUtil.isWhiteSpace(c)) {
return false;
}
LanguageCodeStyleSettingsProvider codeStyleSettingsProvider = LanguageCodeStyleSettingsProvider.forLanguage(file.getLanguage());
@@ -51,12 +55,13 @@ public class IndentingBackspaceHandler extends BackspaceHandlerDelegate {
Document document = editor.getDocument();
int offset = CharArrayUtil.shiftForward(document.getCharsSequence(), editor.getCaretModel().getOffset(), " \t");
int caretOffset = editor.getCaretModel().getOffset();
int offset = CharArrayUtil.shiftForward(document.getCharsSequence(), caretOffset, " \t");
int beforeWhitespaceOffset = CharArrayUtil.shiftBackward(document.getCharsSequence(), offset - 1, " \t") + 1;
LogicalPosition logicalPosition = editor.offsetToLogicalPosition(offset);
LogicalPosition logicalPosition = caretOffset < offset ? editor.offsetToLogicalPosition(offset) : editor.getCaretModel().getLogicalPosition();
int lineStartOffset = document.getLineStartOffset(logicalPosition.line);
if (lineStartOffset < beforeWhitespaceOffset) {
if (c == '\n' && beforeWhitespaceOffset < offset) {
if (caretWasAtLineStart && beforeWhitespaceOffset < offset) {
document.deleteString(beforeWhitespaceOffset, offset);
return true;
}
@@ -75,11 +80,18 @@ public class IndentingBackspaceHandler extends BackspaceHandlerDelegate {
int targetColumn = getWidth(indent, tabSize);
if (logicalPosition.column == targetColumn) {
return false;
if (caretOffset < offset) {
editor.getCaretModel().moveToLogicalPosition(logicalPosition);
return true;
}
else {
return false;
}
}
if (c == '\n' || logicalPosition.column > targetColumn) {
if (caretWasAtLineStart || logicalPosition.column > targetColumn) {
smartReplace(document, lineStartOffset, offset, indent);
editor.getCaretModel().moveToLogicalPosition(new LogicalPosition(logicalPosition.line, targetColumn));
return true;
}
@@ -93,9 +105,11 @@ public class IndentingBackspaceHandler extends BackspaceHandlerDelegate {
if (prevLineStartOffset < targetOffset) {
document.deleteString(targetOffset, offset);
editor.getCaretModel().moveToOffset(targetOffset);
}
else {
smartReplace(document, prevLineStartOffset, offset, indent);
editor.getCaretModel().moveToLogicalPosition(new LogicalPosition(logicalPosition.line - 1, targetColumn));
}
return true;
}
@@ -1,3 +1,3 @@
class Foo {
<caret> int field;
<caret>int field;
}
@@ -1,3 +1,3 @@
class Foo {
<caret> int field;
<caret>int field;
}
@@ -1,3 +1,3 @@
class Foo {
<caret> int field;
<caret>int field;
}
@@ -0,0 +1,3 @@
class Foo {
<caret>
}
@@ -0,0 +1,4 @@
class Foo {
<caret>
}
@@ -0,0 +1,118 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.codeInsight.editorActions;
import com.intellij.openapi.editor.LogicalPosition;
import com.intellij.testFramework.LightPlatformCodeInsightTestCase;
import java.io.IOException;
public class IndentingBackspaceHandlerVirtualSpaceTest extends LightPlatformCodeInsightTestCase {
public void testAfterLargeIndent() throws IOException {
doTest("class Foo {\n" +
" \n" +
"}",
new LogicalPosition(1, 10),
"class Foo {\n" +
" \n" +
"}",
new LogicalPosition(1, 4));
}
public void testAfterProperIndent() throws IOException {
doTest("class Foo {\n" +
" \n" +
"}",
new LogicalPosition(1, 10),
"class Foo {\n" +
" \n" +
"}",
new LogicalPosition(1, 4));
}
public void testAfterSmallIndent() throws IOException {
doTest("class Foo {\n" +
" \n" +
"}",
new LogicalPosition(1, 10),
"class Foo {\n" +
" \n" +
"}",
new LogicalPosition(1, 4));
}
public void testAfterEmptyIndent() throws IOException {
doTest("class Foo {\n" +
"\n" +
"}",
new LogicalPosition(1, 10),
"class Foo {\n" +
" \n" +
"}",
new LogicalPosition(1, 4));
}
public void testAtIndent() throws IOException {
doTest("class Foo {\n" +
" \n" +
"}",
new LogicalPosition(1, 4),
"class Foo {\n" +
"}",
new LogicalPosition(0, 11));
}
public void testAtIndentOnEmptyLine() throws IOException {
doTest("class Foo {\n" +
"\n" +
"}",
new LogicalPosition(1, 4),
"class Foo {\n" +
"}",
new LogicalPosition(0, 11));
}
public void testBeforeIndent() throws IOException {
doTest("class Foo {\n" +
" \n" +
"}",
new LogicalPosition(1, 3),
"class Foo {\n" +
"}",
new LogicalPosition(0, 11));
}
public void testDeleteLine() throws IOException {
doTest("class Foo {\n" +
"\n" +
"\n" +
"}",
new LogicalPosition(2, 0),
"class Foo {\n" +
" \n" +
"}",
new LogicalPosition(1, 4));
}
private void doTest(String textBefore, LogicalPosition caretBefore, String textAfter, LogicalPosition caretAfter) throws IOException {
configureFromFileText(getTestName(false) + ".java", textBefore);
myEditor.getSettings().setVirtualSpace(true);
myEditor.getCaretModel().moveToLogicalPosition(caretBefore);
backspace();
checkResultByText(textAfter);
assertEquals(caretAfter, myEditor.getCaretModel().getLogicalPosition());
}
}