mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-18764 Emacs-Mode: Ctrl-y only pastes the last line killed and not the entire kill buffer
1. The action removes line feed if [caret offset; line end) interval doesn't contain non-white space symbols; 2. Refactoring: common functionality is moved to utility class; 3, Test are added;
This commit is contained in:
+21
-24
@@ -24,14 +24,13 @@
|
||||
*/
|
||||
package com.intellij.openapi.editor.actions;
|
||||
|
||||
import com.intellij.openapi.ide.KillRingTransferable;
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.actionSystem.EditorAction;
|
||||
import com.intellij.openapi.editor.actionSystem.EditorWriteActionHandler;
|
||||
import com.intellij.openapi.ide.CopyPasteManager;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.text.CharArrayUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class CutLineEndAction extends EditorAction {
|
||||
public CutLineEndAction() {
|
||||
@@ -47,37 +46,35 @@ public class CutLineEndAction extends EditorAction {
|
||||
|
||||
public void executeWriteAction(Editor editor, DataContext dataContext) {
|
||||
final Document doc = editor.getDocument();
|
||||
if (doc.getLineCount() == 0) return;
|
||||
int caretOffset = editor.getCaretModel().getOffset();
|
||||
if (caretOffset >= doc.getTextLength()) {
|
||||
return;
|
||||
}
|
||||
final int lineNumber = doc.getLineNumber(caretOffset);
|
||||
int lineEndOffset = doc.getLineEndOffset(lineNumber);
|
||||
|
||||
int start;
|
||||
int end;
|
||||
if (caretOffset >= lineEndOffset) {
|
||||
if (myCopyToClipboard) {
|
||||
copyToClipboard(doc, lineEndOffset, lineEndOffset + 1);
|
||||
}
|
||||
doc.deleteString(lineEndOffset, lineEndOffset + 1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (myCopyToClipboard) {
|
||||
copyToClipboard(doc, caretOffset, lineEndOffset);
|
||||
}
|
||||
|
||||
final int lineStartOffset = doc.getLineStartOffset(lineNumber);
|
||||
if (StringUtil.isEmptyOrSpaces(doc.getCharsSequence().subSequence(lineStartOffset, lineEndOffset).toString())) {
|
||||
DeleteLineAction.deleteLineAtCaret(editor);
|
||||
start = lineEndOffset;
|
||||
end = lineEndOffset + 1;
|
||||
}
|
||||
else {
|
||||
doc.deleteString(caretOffset, lineEndOffset);
|
||||
start = caretOffset;
|
||||
end = lineEndOffset;
|
||||
if (lineEndOffset < doc.getTextLength() && CharArrayUtil.isEmptyOrSpaces(doc.getCharsSequence(), caretOffset, lineEndOffset)) {
|
||||
end++;
|
||||
}
|
||||
}
|
||||
|
||||
delete(doc, start, end);
|
||||
}
|
||||
|
||||
private static void copyToClipboard(final Document doc, int startOffset, int endOffset) {
|
||||
String s = doc.getCharsSequence().subSequence(startOffset, endOffset).toString();
|
||||
|
||||
s = StringUtil.convertLineSeparators(s);
|
||||
CopyPasteManager.getInstance().setContents(new KillRingTransferable(s, doc, startOffset, startOffset, true));
|
||||
private void delete(@NotNull Document document, int start, int end) {
|
||||
if (myCopyToClipboard) {
|
||||
EditorActionUtil.copyToKillRing(document, start, end, true);
|
||||
}
|
||||
document.deleteString(start, end);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,10 +34,13 @@ import com.intellij.openapi.editor.event.EditorMouseEvent;
|
||||
import com.intellij.openapi.editor.event.EditorMouseEventArea;
|
||||
import com.intellij.openapi.editor.ex.EditorEx;
|
||||
import com.intellij.openapi.editor.ex.util.EditorUtil;
|
||||
import com.intellij.openapi.ide.CopyPasteManager;
|
||||
import com.intellij.openapi.ide.KillRingTransferable;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.EditorPopupHandler;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.MouseEvent;
|
||||
@@ -645,6 +648,21 @@ public class EditorActionUtil {
|
||||
setupSelection(editor, isWithSelection, selectionStart, blockSelectionStart);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies target region from the given offset to the kill ring, i.e. combines it with the previously
|
||||
* copied/cut adjacent text if necessary and puts to the clipboard.
|
||||
*
|
||||
* @param document target document
|
||||
* @param startOffset start offset of the target region within the given document
|
||||
* @param endOffset end offset of the target region within the given document
|
||||
* @param cut flag that identifies if target text region will be cut from the given document
|
||||
*/
|
||||
public static void copyToKillRing(@NotNull final Document document, int startOffset, int endOffset, boolean cut) {
|
||||
String s = document.getCharsSequence().subSequence(startOffset, endOffset).toString();
|
||||
s = StringUtil.convertLineSeparators(s);
|
||||
CopyPasteManager.getInstance().setContents(new KillRingTransferable(s, document, startOffset, endOffset, cut));
|
||||
}
|
||||
|
||||
public static EditorPopupHandler createEditorPopupHandler(final String groupId) {
|
||||
return new EditorPopupHandler() {
|
||||
public void invokePopup(final EditorMouseEvent event) {
|
||||
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright 2000-2011 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.openapi.editor.actions;
|
||||
|
||||
import com.intellij.testFramework.LightPlatformCodeInsightTestCase;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author Denis Zhdanov
|
||||
* @since 4/18/11 2:47 PM
|
||||
*/
|
||||
public class CutLineEndActionsTest extends LightPlatformCodeInsightTestCase {
|
||||
|
||||
public void testNonEmptyLineEnd() throws IOException {
|
||||
doTest(
|
||||
"class Test {\n" +
|
||||
" // This is a <caret>comment string\n" +
|
||||
"}",
|
||||
"class Test {\n" +
|
||||
" // This is a <caret>\n" +
|
||||
"}"
|
||||
);
|
||||
}
|
||||
|
||||
public void testEmptyLineEnd() throws IOException {
|
||||
doTest(
|
||||
"class Test {\n" +
|
||||
" <caret> \n" +
|
||||
" // some comment\n" +
|
||||
"}",
|
||||
"class Test {\n" +
|
||||
" <caret> // some comment\n" +
|
||||
"}"
|
||||
);
|
||||
}
|
||||
|
||||
public void testAtLineEnd() throws IOException {
|
||||
doTest(
|
||||
"class Test {\n" +
|
||||
" // This is a comment string1<caret>\n" +
|
||||
" // This is a comment string2\n" +
|
||||
"}",
|
||||
"class Test {\n" +
|
||||
" // This is a comment string1<caret> // This is a comment string2\n" +
|
||||
"}"
|
||||
);
|
||||
}
|
||||
|
||||
public void testAtDocumentEnd() throws IOException {
|
||||
String text =
|
||||
"class Test{\n" +
|
||||
"}<caret>";
|
||||
doTest(text, text);
|
||||
}
|
||||
|
||||
public void testEmptyLastLineEnd() throws IOException {
|
||||
doTest(
|
||||
"class Test {\n" +
|
||||
"}<caret> ",
|
||||
"class Test {\n" +
|
||||
"}<caret>"
|
||||
);
|
||||
}
|
||||
|
||||
private void doTest(@NotNull String before, @NotNull String after) throws IOException {
|
||||
configureFromFileText(getTestName(false) + ".java", before);
|
||||
cutToLineEnd();
|
||||
checkResultByText(after);
|
||||
}
|
||||
}
|
||||
+4
@@ -500,6 +500,10 @@ public abstract class LightPlatformCodeInsightTestCase extends LightPlatformTest
|
||||
doAction("EditorNextWordWithSelection");
|
||||
}
|
||||
|
||||
protected static void cutToLineEnd() {
|
||||
doAction("EditorCutLineEnd");
|
||||
}
|
||||
|
||||
protected static void lineComment() {
|
||||
new CommentByLineCommentHandler().invoke(getProject(), getEditor(), getFile());
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package com.intellij.util.text;
|
||||
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
@@ -523,4 +524,22 @@ public class CharArrayUtil {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows to answer if target region of the given text contains only white space symbols (tabulations, white spaces and line feeds).
|
||||
*
|
||||
* @param text text to check
|
||||
* @param start start offset within the given text to check (inclusive)
|
||||
* @param end end offset within the given text to check (exclusive)
|
||||
* @return <code>true</code> if target region of the given text contains white space symbols only; <code>false</code> otherwise
|
||||
*/
|
||||
public static boolean isEmptyOrSpaces(@NotNull CharSequence text, int start, int end) {
|
||||
for (int i = start; i < end; i++) {
|
||||
char c = text.charAt(i);
|
||||
if (c != ' ' && c != '\t' && c != '\n') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user