mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
duplicate lines action (IDEA-56385)
This commit is contained in:
+25
-20
@@ -62,29 +62,34 @@ public class DuplicateAction extends EditorAction {
|
||||
editor.getSelectionModel().setSelection(end, end+s.length());
|
||||
}
|
||||
else {
|
||||
Pair<LogicalPosition, LogicalPosition> lines = EditorUtil.calcCaretLinesRange(editor);
|
||||
int offset = caretModel.getOffset();
|
||||
|
||||
LogicalPosition lineStart = lines.first;
|
||||
LogicalPosition nextLineStart = lines.second;
|
||||
int start = editor.logicalPositionToOffset(lineStart);
|
||||
int end = editor.logicalPositionToOffset(nextLineStart);
|
||||
String s = document.getCharsSequence().subSequence(start, end).toString();
|
||||
final int lineToCheck = nextLineStart.line - 1;
|
||||
|
||||
int newOffset = end + offset - start;
|
||||
if(lineToCheck == document.getLineCount () /*empty document*/ ||
|
||||
document.getLineSeparatorLength(lineToCheck) == 0) {
|
||||
s = "\n"+s;
|
||||
newOffset++;
|
||||
}
|
||||
document.insertString(end, s);
|
||||
|
||||
caretModel.moveToOffset(newOffset);
|
||||
scrollingModel.scrollToCaret(ScrollType.RELATIVE);
|
||||
duplicateLinesRange(editor, document, caretModel.getVisualPosition(), caretModel.getVisualPosition());
|
||||
}
|
||||
}
|
||||
|
||||
static Pair<Integer, Integer> duplicateLinesRange(Editor editor, Document document, VisualPosition rangeStart, VisualPosition rangeEnd) {
|
||||
Pair<LogicalPosition, LogicalPosition> lines = EditorUtil.calcCaretLinesRange(editor, rangeStart, rangeEnd);
|
||||
int offset = editor.getCaretModel().getOffset();
|
||||
|
||||
LogicalPosition lineStart = lines.first;
|
||||
LogicalPosition nextLineStart = lines.second;
|
||||
int start = editor.logicalPositionToOffset(lineStart);
|
||||
int end = editor.logicalPositionToOffset(nextLineStart);
|
||||
String s = document.getCharsSequence().subSequence(start, end).toString();
|
||||
final int lineToCheck = nextLineStart.line - 1;
|
||||
|
||||
int newOffset = end + offset - start;
|
||||
if(lineToCheck == document.getLineCount () /*empty document*/ ||
|
||||
document.getLineSeparatorLength(lineToCheck) == 0) {
|
||||
s = "\n"+s;
|
||||
newOffset++;
|
||||
}
|
||||
document.insertString(end, s);
|
||||
|
||||
editor.getCaretModel().moveToOffset(newOffset);
|
||||
editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
|
||||
return new Pair<Integer, Integer>(end, end+s.length());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(final Editor editor, final Presentation presentation, final DataContext dataContext) {
|
||||
super.update(editor, presentation, dataContext);
|
||||
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2000-2010 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.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.VisualPosition;
|
||||
import com.intellij.openapi.editor.actionSystem.EditorAction;
|
||||
import com.intellij.openapi.editor.actionSystem.EditorWriteActionHandler;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
public class DuplicateLinesAction extends EditorAction {
|
||||
public DuplicateLinesAction() {
|
||||
super(new Handler());
|
||||
}
|
||||
|
||||
private static class Handler extends EditorWriteActionHandler {
|
||||
@Override
|
||||
public void executeWriteAction(Editor editor, DataContext dataContext) {
|
||||
if (editor.getSelectionModel().hasSelection()) {
|
||||
int selStart = editor.getSelectionModel().getSelectionStart();
|
||||
int selEnd = editor.getSelectionModel().getSelectionEnd();
|
||||
VisualPosition rangeStart = editor.offsetToVisualPosition(Math.min(selStart, selEnd));
|
||||
VisualPosition rangeEnd = editor.offsetToVisualPosition(Math.max(selStart, selEnd));
|
||||
final Pair<Integer,Integer> copiedRange =
|
||||
DuplicateAction.duplicateLinesRange(editor, editor.getDocument(), rangeStart, rangeEnd);
|
||||
editor.getSelectionModel().setSelection(copiedRange.first, copiedRange.second);
|
||||
}
|
||||
else {
|
||||
VisualPosition caretPos = editor.getCaretModel().getVisualPosition();
|
||||
DuplicateAction.duplicateLinesRange(editor, editor.getDocument(), caretPos, caretPos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -544,23 +544,26 @@ public class EditorUtil {
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Pair<LogicalPosition, LogicalPosition> calcCaretLinesRange(Editor editor) {
|
||||
return calcCaretLinesRange(editor, editor.getCaretModel().getVisualPosition(), editor.getCaretModel().getVisualPosition());
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the closest non-soft-wrapped logical positions for current caret position.
|
||||
*
|
||||
* @param editor target editor to use
|
||||
* @return pair of non-soft-wrapped logical positions closest to the caret position of the given editor
|
||||
*/
|
||||
public static Pair<LogicalPosition, LogicalPosition> calcCaretLinesRange(Editor editor) {
|
||||
VisualPosition caret = editor.getCaretModel().getVisualPosition();
|
||||
int visualLine = caret.line;
|
||||
public static Pair<LogicalPosition, LogicalPosition> calcCaretLinesRange(Editor editor, VisualPosition start, VisualPosition end) {
|
||||
int visualLine = start.line;
|
||||
|
||||
LogicalPosition lineStart = editor.visualToLogicalPosition(new VisualPosition(visualLine, 0));
|
||||
while (lineStart.softWrapLinesOnCurrentLogicalLine > 0) {
|
||||
lineStart = editor.visualToLogicalPosition(new VisualPosition(--visualLine, 0));
|
||||
}
|
||||
|
||||
visualLine = caret.line + 1;
|
||||
LogicalPosition nextLineStart = editor.visualToLogicalPosition(new VisualPosition(caret.line + 1, 0));
|
||||
visualLine = end.line + 1;
|
||||
LogicalPosition nextLineStart = editor.visualToLogicalPosition(new VisualPosition(end.line + 1, 0));
|
||||
while (nextLineStart.line == lineStart.line) {
|
||||
nextLineStart = editor.visualToLogicalPosition(new VisualPosition(++visualLine, 0));
|
||||
}
|
||||
|
||||
@@ -65,8 +65,7 @@
|
||||
<action id="EditorDeleteLine">
|
||||
<keyboard-shortcut first-keystroke="control D" />
|
||||
</action>
|
||||
<action id="EditorDuplicate">
|
||||
<keyboard-shortcut first-keystroke="control alt UP" />
|
||||
<action id="EditorDuplicateLines">
|
||||
<keyboard-shortcut first-keystroke="control alt DOWN" />
|
||||
</action>
|
||||
<action id="EditorIndentSelection">
|
||||
|
||||
@@ -71,6 +71,7 @@
|
||||
<action id="EditorDeleteToWordEnd" class="com.intellij.openapi.editor.actions.DeleteToWordEndAction"/>
|
||||
<action id="EditorDeleteLine" class="com.intellij.openapi.editor.actions.DeleteLineAction"/>
|
||||
<action id="EditorDuplicate" class="com.intellij.openapi.editor.actions.DuplicateAction"/>
|
||||
<action id="EditorDuplicateLines" class="com.intellij.openapi.editor.actions.DuplicateLinesAction"/>
|
||||
<action id="EditorToggleInsertState" class="com.intellij.openapi.editor.actions.ToggleInsertStateAction"/>
|
||||
<action id="EditorToggleColumnMode" class="com.intellij.openapi.editor.actions.ToggleColumnModeAction"/>
|
||||
<action id="EditorToggleShowWhitespaces" class="com.intellij.openapi.editor.actions.ToggleShowWhitespacesAction"/>
|
||||
|
||||
Reference in New Issue
Block a user