mirror of
https://github.com/chylex/IntelliJ-IdeaVim.git
synced 2025-03-07 21:32:52 +01:00
Refactor put group
This commit is contained in:
parent
cbc5e8aea1
commit
1bb6345fcb
src/com/maddyhome/idea/vim
action/copy
PutTextAfterCursorAction.javaPutTextAfterCursorActionMoveCursor.javaPutTextAfterCursorNoIndentAction.javaPutTextBeforeCursorAction.javaPutTextBeforeCursorActionMoveCursor.javaPutTextBeforeCursorNoIndentAction.javaPutVisualTextAction.ktPutVisualTextMoveCursorAction.ktPutVisualTextNoIndentAction.kt
ex
group
test/org/jetbrains/plugins/ideavim/action/copy
@ -23,19 +23,27 @@ import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.actionSystem.EditorAction;
|
||||
import com.maddyhome.idea.vim.VimPlugin;
|
||||
import com.maddyhome.idea.vim.command.Argument;
|
||||
import com.maddyhome.idea.vim.common.Register;
|
||||
import com.maddyhome.idea.vim.group.copy.PutData;
|
||||
import com.maddyhome.idea.vim.handler.ChangeEditorActionHandler;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class PutTextAfterCursorAction extends EditorAction {
|
||||
public PutTextAfterCursorAction() {
|
||||
super(new ChangeEditorActionHandler() {
|
||||
@Override
|
||||
public boolean execute(@NotNull Editor editor, @NotNull DataContext context, int count, int rawCount,
|
||||
public boolean execute(@NotNull Editor editor,
|
||||
@NotNull DataContext context,
|
||||
int count,
|
||||
int rawCount,
|
||||
@Nullable Argument argument) {
|
||||
return VimPlugin.getPut().putText(editor, context, count, true, false, false);
|
||||
final Register lastRegister = VimPlugin.getRegister().getLastRegister();
|
||||
|
||||
final PutData.TextData textData =
|
||||
lastRegister != null ? new PutData.TextData(lastRegister.getText(), lastRegister.getType()) : null;
|
||||
final PutData putData = new PutData(textData, null, count, false, true, false, -1);
|
||||
return VimPlugin.getPut().putText(editor, context, putData);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -23,11 +23,14 @@ import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.actionSystem.EditorAction;
|
||||
import com.maddyhome.idea.vim.VimPlugin;
|
||||
import com.maddyhome.idea.vim.command.Argument;
|
||||
import com.maddyhome.idea.vim.common.Register;
|
||||
import com.maddyhome.idea.vim.group.copy.PutData;
|
||||
import com.maddyhome.idea.vim.handler.ChangeEditorActionHandler;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class PutTextAfterCursorActionMoveCursor extends EditorAction {
|
||||
public PutTextAfterCursorActionMoveCursor() {
|
||||
@ -38,7 +41,12 @@ public class PutTextAfterCursorActionMoveCursor extends EditorAction {
|
||||
int count,
|
||||
int rawCount,
|
||||
@Nullable Argument argument) {
|
||||
return VimPlugin.getPut().putText(editor, context, count, true, true, false);
|
||||
final Register lastRegister = VimPlugin.getRegister().getLastRegister();
|
||||
|
||||
final PutData.TextData textData =
|
||||
lastRegister != null ? new PutData.TextData(lastRegister.getText(), lastRegister.getType()) : null;
|
||||
final PutData putData = new PutData(textData, null, count, false, true, true, -1);
|
||||
return VimPlugin.getPut().putText(editor, context, putData);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -23,11 +23,14 @@ import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.actionSystem.EditorAction;
|
||||
import com.maddyhome.idea.vim.VimPlugin;
|
||||
import com.maddyhome.idea.vim.command.Argument;
|
||||
import com.maddyhome.idea.vim.common.Register;
|
||||
import com.maddyhome.idea.vim.group.copy.PutData;
|
||||
import com.maddyhome.idea.vim.handler.ChangeEditorActionHandler;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class PutTextAfterCursorNoIndentAction extends EditorAction {
|
||||
public PutTextAfterCursorNoIndentAction() {
|
||||
@ -38,7 +41,12 @@ public class PutTextAfterCursorNoIndentAction extends EditorAction {
|
||||
int count,
|
||||
int rawCount,
|
||||
@Nullable Argument argument) {
|
||||
return VimPlugin.getPut().putText(editor, context, count, false, false, false);
|
||||
final Register lastRegister = VimPlugin.getRegister().getLastRegister();
|
||||
|
||||
final PutData.TextData textData =
|
||||
lastRegister != null ? new PutData.TextData(lastRegister.getText(), lastRegister.getType()) : null;
|
||||
final PutData putData = new PutData(textData, null, count, false, false, false, -1);
|
||||
return VimPlugin.getPut().putText(editor, context, putData);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -23,11 +23,14 @@ import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.actionSystem.EditorAction;
|
||||
import com.maddyhome.idea.vim.VimPlugin;
|
||||
import com.maddyhome.idea.vim.command.Argument;
|
||||
import com.maddyhome.idea.vim.common.Register;
|
||||
import com.maddyhome.idea.vim.group.copy.PutData;
|
||||
import com.maddyhome.idea.vim.handler.ChangeEditorActionHandler;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class PutTextBeforeCursorAction extends EditorAction {
|
||||
public PutTextBeforeCursorAction() {
|
||||
@ -38,7 +41,12 @@ public class PutTextBeforeCursorAction extends EditorAction {
|
||||
int count,
|
||||
int rawCount,
|
||||
@Nullable Argument argument) {
|
||||
return VimPlugin.getPut().putText(editor, context, count, true, false, true);
|
||||
final Register lastRegister = VimPlugin.getRegister().getLastRegister();
|
||||
|
||||
final PutData.TextData textData =
|
||||
lastRegister != null ? new PutData.TextData(lastRegister.getText(), lastRegister.getType()) : null;
|
||||
final PutData putData = new PutData(textData, null, count, true, true, false, -1);
|
||||
return VimPlugin.getPut().putText(editor, context, putData);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -23,11 +23,14 @@ import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.actionSystem.EditorAction;
|
||||
import com.maddyhome.idea.vim.VimPlugin;
|
||||
import com.maddyhome.idea.vim.command.Argument;
|
||||
import com.maddyhome.idea.vim.common.Register;
|
||||
import com.maddyhome.idea.vim.group.copy.PutData;
|
||||
import com.maddyhome.idea.vim.handler.ChangeEditorActionHandler;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class PutTextBeforeCursorActionMoveCursor extends EditorAction {
|
||||
public PutTextBeforeCursorActionMoveCursor() {
|
||||
@ -38,7 +41,12 @@ public class PutTextBeforeCursorActionMoveCursor extends EditorAction {
|
||||
int count,
|
||||
int rawCount,
|
||||
@Nullable Argument argument) {
|
||||
return VimPlugin.getPut().putText(editor, context, count, true, true, true);
|
||||
final Register lastRegister = VimPlugin.getRegister().getLastRegister();
|
||||
|
||||
final PutData.TextData textData =
|
||||
lastRegister != null ? new PutData.TextData(lastRegister.getText(), lastRegister.getType()) : null;
|
||||
final PutData putData = new PutData(textData, null, count, true, true, true, -1);
|
||||
return VimPlugin.getPut().putText(editor, context, putData);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -23,11 +23,14 @@ import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.actionSystem.EditorAction;
|
||||
import com.maddyhome.idea.vim.VimPlugin;
|
||||
import com.maddyhome.idea.vim.command.Argument;
|
||||
import com.maddyhome.idea.vim.common.Register;
|
||||
import com.maddyhome.idea.vim.group.copy.PutData;
|
||||
import com.maddyhome.idea.vim.handler.ChangeEditorActionHandler;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class PutTextBeforeCursorNoIndentAction extends EditorAction {
|
||||
public PutTextBeforeCursorNoIndentAction() {
|
||||
@ -38,7 +41,12 @@ public class PutTextBeforeCursorNoIndentAction extends EditorAction {
|
||||
int count,
|
||||
int rawCount,
|
||||
@Nullable Argument argument) {
|
||||
return VimPlugin.getPut().putText(editor, context, count, false, false, true);
|
||||
final Register lastRegister = VimPlugin.getRegister().getLastRegister();
|
||||
|
||||
final PutData.TextData textData =
|
||||
lastRegister != null ? new PutData.TextData(lastRegister.getText(), lastRegister.getType()) : null;
|
||||
final PutData putData = new PutData(textData, null, count, true, false, false, -1);
|
||||
return VimPlugin.getPut().putText(editor, context, putData);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -26,10 +26,9 @@ import com.maddyhome.idea.vim.action.VimCommandAction
|
||||
import com.maddyhome.idea.vim.command.Command
|
||||
import com.maddyhome.idea.vim.command.CommandFlags
|
||||
import com.maddyhome.idea.vim.command.MappingMode
|
||||
import com.maddyhome.idea.vim.command.SelectionType
|
||||
import com.maddyhome.idea.vim.group.copy.PutData
|
||||
import com.maddyhome.idea.vim.group.visual.VimSelection
|
||||
import com.maddyhome.idea.vim.handler.VisualOperatorActionHandler
|
||||
import com.maddyhome.idea.vim.helper.StringHelper.parseKeys
|
||||
import java.util.*
|
||||
import javax.swing.KeyStroke
|
||||
|
||||
@ -39,22 +38,15 @@ private object PutVisualTextActionHandler : VisualOperatorActionHandler.SingleEx
|
||||
context: DataContext,
|
||||
cmd: Command,
|
||||
caretsAndSelections: Map<Caret, VimSelection>): Boolean {
|
||||
val register = VimPlugin.getRegister().lastRegister
|
||||
VimPlugin.getRegister().resetRegister()
|
||||
if (register != null && register.type == SelectionType.LINE_WISE && editor.isOneLineMode) return false
|
||||
if (caretsAndSelections.isEmpty()) return false
|
||||
val textData = VimPlugin.getRegister().lastRegister?.let { PutData.TextData(it.text, it.type) }
|
||||
VimPlugin.getRegister().resetRegister()
|
||||
|
||||
val range = caretsAndSelections.values.first()
|
||||
val insertTextBeforeCaret = cmd.keys[0].keyChar == 'P'
|
||||
val selection = PutData.VisualSelection(caretsAndSelections, caretsAndSelections.values.first().type)
|
||||
val putData = PutData(textData, selection, cmd.count, insertTextBeforeCaret, _indent = true, caretAfterInsertedText = false)
|
||||
|
||||
return if (range.type == SelectionType.BLOCK_WISE) {
|
||||
val isBigP = cmd.keys[0] == parseKeys("P")[0]
|
||||
|
||||
VimPlugin.getPut()
|
||||
.putVisualRangeBlockwise(editor, context, range, cmd.count, true, false, register, isBigP)
|
||||
} else {
|
||||
VimPlugin.getPut()
|
||||
.putVisualRangeCaL(editor, context, caretsAndSelections, cmd.count, true, false, register)
|
||||
}
|
||||
return VimPlugin.getPut().putText(editor, context, putData)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -26,31 +26,23 @@ import com.maddyhome.idea.vim.action.VimCommandAction
|
||||
import com.maddyhome.idea.vim.command.Command
|
||||
import com.maddyhome.idea.vim.command.CommandFlags
|
||||
import com.maddyhome.idea.vim.command.MappingMode
|
||||
import com.maddyhome.idea.vim.command.SelectionType
|
||||
import com.maddyhome.idea.vim.group.copy.PutData
|
||||
import com.maddyhome.idea.vim.group.visual.VimSelection
|
||||
import com.maddyhome.idea.vim.handler.VisualOperatorActionHandler
|
||||
import com.maddyhome.idea.vim.helper.StringHelper.parseKeys
|
||||
import java.util.*
|
||||
import javax.swing.KeyStroke
|
||||
|
||||
private object PutVisualTextMoveCursorActionHandler : VisualOperatorActionHandler.SingleExecution() {
|
||||
override fun executeForAllCarets(editor: Editor, context: DataContext, cmd: Command, caretsAndSelections: Map<Caret, VimSelection>): Boolean {
|
||||
val register = VimPlugin.getRegister().lastRegister
|
||||
if (caretsAndSelections.isEmpty()) return false
|
||||
val textData = VimPlugin.getRegister().lastRegister?.let { PutData.TextData(it.text, it.type) }
|
||||
VimPlugin.getRegister().resetRegister()
|
||||
if (register == null) return false
|
||||
if (register.type == SelectionType.LINE_WISE && editor.isOneLineMode) return false
|
||||
if (register.text == null) return false
|
||||
|
||||
val range = caretsAndSelections.values.first()
|
||||
return if (range.type == SelectionType.BLOCK_WISE) {
|
||||
val isBigP = cmd.keys[1] == parseKeys("P")[0]
|
||||
val insertTextBeforeCaret = cmd.keys[1].keyChar == 'P'
|
||||
val selection = PutData.VisualSelection(caretsAndSelections, caretsAndSelections.values.first().type)
|
||||
val putData = PutData(textData, selection, cmd.count, insertTextBeforeCaret, _indent = true, caretAfterInsertedText = true)
|
||||
|
||||
VimPlugin.getPut()
|
||||
.putVisualRangeBlockwise(editor, context, range, cmd.count, true, true, register, isBigP)
|
||||
} else {
|
||||
VimPlugin.getPut()
|
||||
.putVisualRangeCaL(editor, context, caretsAndSelections, cmd.count, true, true, register)
|
||||
}
|
||||
return VimPlugin.getPut().putText(editor, context, putData)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -26,31 +26,23 @@ import com.maddyhome.idea.vim.action.VimCommandAction
|
||||
import com.maddyhome.idea.vim.command.Command
|
||||
import com.maddyhome.idea.vim.command.CommandFlags
|
||||
import com.maddyhome.idea.vim.command.MappingMode
|
||||
import com.maddyhome.idea.vim.command.SelectionType
|
||||
import com.maddyhome.idea.vim.group.copy.PutData
|
||||
import com.maddyhome.idea.vim.group.visual.VimSelection
|
||||
import com.maddyhome.idea.vim.handler.VisualOperatorActionHandler
|
||||
import com.maddyhome.idea.vim.helper.StringHelper.parseKeys
|
||||
import java.util.*
|
||||
import javax.swing.KeyStroke
|
||||
|
||||
private object PutVisualTextNoIndentActionHandler : VisualOperatorActionHandler.SingleExecution() {
|
||||
override fun executeForAllCarets(editor: Editor, context: DataContext, cmd: Command, caretsAndSelections: Map<Caret, VimSelection>): Boolean {
|
||||
val register = VimPlugin.getRegister().lastRegister
|
||||
if (caretsAndSelections.isEmpty()) return false
|
||||
val textData = VimPlugin.getRegister().lastRegister?.let { PutData.TextData(it.text, it.type) }
|
||||
VimPlugin.getRegister().resetRegister()
|
||||
if (register == null) return false
|
||||
if (register.type == SelectionType.LINE_WISE && editor.isOneLineMode) return false
|
||||
if (register.text == null) return false
|
||||
|
||||
val range = caretsAndSelections.values.first()
|
||||
return if (range.type == SelectionType.BLOCK_WISE) {
|
||||
val isBigP = cmd.keys[1] == parseKeys("P")[0]
|
||||
val insertBeforeCaret = cmd.keys[1].keyChar == 'P'
|
||||
val selection = PutData.VisualSelection(caretsAndSelections, caretsAndSelections.values.first().type)
|
||||
val putData = PutData(textData, selection, cmd.count, insertBeforeCaret, _indent = false, caretAfterInsertedText = false)
|
||||
|
||||
VimPlugin.getPut()
|
||||
.putVisualRangeBlockwise(editor, context, range, cmd.count, false, false, register, isBigP)
|
||||
} else {
|
||||
VimPlugin.getPut()
|
||||
.putVisualRangeCaL(editor, context, caretsAndSelections, cmd.count, false, false, register)
|
||||
}
|
||||
return VimPlugin.getPut().putText(editor, context, putData)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,13 +22,8 @@ import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.editor.Caret;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.maddyhome.idea.vim.common.TextRange;
|
||||
import com.maddyhome.idea.vim.handler.CaretOrder;
|
||||
import com.maddyhome.idea.vim.helper.EditorHelper;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@ -47,16 +42,6 @@ public class ExCommand {
|
||||
return ranges.getLine(editor, caret, context);
|
||||
}
|
||||
|
||||
public List<Integer> getOrderedLines(@NotNull Editor editor, @NotNull DataContext context,
|
||||
@NotNull CaretOrder caretOrder) {
|
||||
final ArrayList<Integer> lines = new ArrayList<>(editor.getCaretModel().getCaretCount());
|
||||
for (Caret caret : EditorHelper.getOrderedCaretsList(editor, caretOrder)) {
|
||||
final int line = getLine(editor, caret, context);
|
||||
lines.add(line);
|
||||
}
|
||||
return lines;
|
||||
}
|
||||
|
||||
public int getCount(@NotNull Editor editor, DataContext context, int defaultCount, boolean checkCount) {
|
||||
int count = -1;
|
||||
if (checkCount) {
|
||||
|
@ -21,14 +21,10 @@ package com.maddyhome.idea.vim.ex.handler
|
||||
import com.intellij.openapi.actionSystem.DataContext
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.maddyhome.idea.vim.VimPlugin
|
||||
import com.maddyhome.idea.vim.command.CommandState
|
||||
import com.maddyhome.idea.vim.command.SelectionType
|
||||
import com.maddyhome.idea.vim.ex.*
|
||||
import com.maddyhome.idea.vim.ex.CommandHandler.Flag.WRITABLE
|
||||
import com.maddyhome.idea.vim.ex.CommandParser
|
||||
import com.maddyhome.idea.vim.ex.ExCommand
|
||||
import com.maddyhome.idea.vim.ex.commands
|
||||
import com.maddyhome.idea.vim.ex.flags
|
||||
import com.maddyhome.idea.vim.group.copy.PutData
|
||||
import com.maddyhome.idea.vim.handler.CaretOrder
|
||||
import com.maddyhome.idea.vim.helper.EditorHelper
|
||||
|
||||
@ -44,10 +40,10 @@ class CopyTextHandler : CommandHandler(
|
||||
|
||||
val arg = CommandParser.getInstance().parse(cmd.argument)
|
||||
val line = arg.ranges.getFirstLine(editor, caret, context)
|
||||
val offset = VimPlugin.getMotion().moveCaretToLineStart(editor, line + 1)
|
||||
|
||||
VimPlugin.getPut().putText(editor, caret, context, text, SelectionType.LINE_WISE, CommandState.SubMode.NONE,
|
||||
offset, 1, true, false)
|
||||
val textData = PutData.TextData(text, SelectionType.LINE_WISE)
|
||||
val putData = PutData(textData, null, 1, insertTextBeforeCaret = false, _indent = true, caretAfterInsertedText = false, putToLine = line)
|
||||
VimPlugin.getPut().putTextForCaret(editor, caret, context, putData)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
@ -22,11 +22,11 @@ import com.intellij.openapi.actionSystem.DataContext
|
||||
import com.intellij.openapi.editor.Caret
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.maddyhome.idea.vim.VimPlugin
|
||||
import com.maddyhome.idea.vim.command.CommandState
|
||||
import com.maddyhome.idea.vim.command.SelectionType
|
||||
import com.maddyhome.idea.vim.common.TextRange
|
||||
import com.maddyhome.idea.vim.ex.*
|
||||
import com.maddyhome.idea.vim.ex.CommandHandler.Flag.WRITABLE
|
||||
import com.maddyhome.idea.vim.group.copy.PutData
|
||||
import com.maddyhome.idea.vim.handler.CaretOrder
|
||||
import com.maddyhome.idea.vim.helper.EditorHelper
|
||||
import com.maddyhome.idea.vim.helper.MessageHelper
|
||||
@ -62,17 +62,15 @@ class MoveTextHandler : CommandHandler(
|
||||
}
|
||||
}
|
||||
|
||||
for (range in ranges) {
|
||||
editor.document.deleteString(range.startOffset, range.endOffset)
|
||||
}
|
||||
ranges.forEach { editor.document.deleteString(it.startOffset, it.endOffset) }
|
||||
|
||||
for (i in 0 until caretCount) {
|
||||
val caret = carets[i]
|
||||
val text = texts[i]
|
||||
|
||||
val offset = VimPlugin.getMotion().moveCaretToLineStart(editor, line + 1)
|
||||
VimPlugin.getPut().putText(editor, caret, context, text, SelectionType.LINE_WISE, CommandState.SubMode.NONE,
|
||||
offset, 1, true, false)
|
||||
val textData = PutData.TextData(text, SelectionType.LINE_WISE)
|
||||
val putData = PutData(textData, null, 1, insertTextBeforeCaret = false, _indent = true, caretAfterInsertedText = false, putToLine = line)
|
||||
VimPlugin.getPut().putTextForCaret(editor, caret, context, putData)
|
||||
}
|
||||
|
||||
return true
|
||||
|
@ -21,21 +21,19 @@ package com.maddyhome.idea.vim.ex.handler
|
||||
import com.intellij.openapi.actionSystem.DataContext
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.maddyhome.idea.vim.VimPlugin
|
||||
import com.maddyhome.idea.vim.command.CommandState
|
||||
import com.maddyhome.idea.vim.command.SelectionType
|
||||
import com.maddyhome.idea.vim.common.TextRange
|
||||
import com.maddyhome.idea.vim.ex.*
|
||||
import com.maddyhome.idea.vim.ex.CommandHandler
|
||||
import com.maddyhome.idea.vim.ex.CommandHandler.Flag.WRITABLE
|
||||
import com.maddyhome.idea.vim.group.MarkGroup
|
||||
import com.maddyhome.idea.vim.handler.CaretOrder
|
||||
import com.maddyhome.idea.vim.helper.EditorHelper
|
||||
import com.maddyhome.idea.vim.ex.ExCommand
|
||||
import com.maddyhome.idea.vim.ex.commands
|
||||
import com.maddyhome.idea.vim.ex.flags
|
||||
import com.maddyhome.idea.vim.group.copy.PutData
|
||||
|
||||
class PutLinesHandler : CommandHandler(
|
||||
commands("pu[t]"),
|
||||
flags(RangeFlag.RANGE_OPTIONAL, ArgumentFlag.ARGUMENT_OPTIONAL, WRITABLE)
|
||||
) {
|
||||
|
||||
@Throws(ExException::class)
|
||||
override fun execute(editor: Editor, context: DataContext, cmd: ExCommand): Boolean {
|
||||
if (editor.isOneLineMode) return false
|
||||
|
||||
@ -47,33 +45,9 @@ class PutLinesHandler : CommandHandler(
|
||||
registerGroup.selectRegister(registerGroup.defaultRegister)
|
||||
}
|
||||
|
||||
val register = registerGroup.lastRegister ?: return false
|
||||
val text = register.text
|
||||
|
||||
val lines = cmd.getOrderedLines(editor, context, CaretOrder.DECREASING_OFFSET)
|
||||
val carets = EditorHelper.getOrderedCaretsList(editor, CaretOrder.DECREASING_OFFSET)
|
||||
for (i in carets.indices) {
|
||||
val caret = carets[i]
|
||||
val line = lines[i]
|
||||
|
||||
var startOffset = minOf(editor.document.textLength,
|
||||
VimPlugin.getMotion().moveCaretToLineEnd(editor, line, true) + 1)
|
||||
if (startOffset > 0 && startOffset == editor.document.textLength &&
|
||||
editor.document.charsSequence[startOffset - 1] != '\n') {
|
||||
editor.document.insertString(startOffset, "\n")
|
||||
startOffset++
|
||||
}
|
||||
|
||||
if (text == null) {
|
||||
VimPlugin.getMark().setMark(editor, MarkGroup.MARK_CHANGE_POS, startOffset)
|
||||
VimPlugin.getMark().setChangeMarks(editor, TextRange(startOffset, startOffset))
|
||||
continue
|
||||
}
|
||||
|
||||
VimPlugin.getPut().putText(editor, caret, context, text, SelectionType.LINE_WISE, CommandState.SubMode.NONE,
|
||||
startOffset, 1, false, false)
|
||||
}
|
||||
|
||||
return true
|
||||
val line = if (cmd.ranges.size() == 0) -1 else cmd.getLine(editor, context)
|
||||
val textData = registerGroup.lastRegister?.let { PutData.TextData(it.text, SelectionType.LINE_WISE) }
|
||||
val putData = PutData(textData, null, 1, false, false, false, line)
|
||||
return VimPlugin.getPut().putText(editor, context, putData)
|
||||
}
|
||||
}
|
||||
|
@ -22,223 +22,187 @@ import com.intellij.openapi.actionSystem.DataContext
|
||||
import com.intellij.openapi.editor.Caret
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.editor.LogicalPosition
|
||||
import com.intellij.openapi.util.Ref
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
import com.maddyhome.idea.vim.VimPlugin
|
||||
import com.maddyhome.idea.vim.command.CommandState
|
||||
import com.maddyhome.idea.vim.command.SelectionType
|
||||
import com.maddyhome.idea.vim.common.Register
|
||||
import com.maddyhome.idea.vim.common.TextRange
|
||||
import com.maddyhome.idea.vim.group.MarkGroup
|
||||
import com.maddyhome.idea.vim.group.MotionGroup
|
||||
import com.maddyhome.idea.vim.group.visual.VimSelection
|
||||
import com.maddyhome.idea.vim.handler.CaretOrder.DECREASING_OFFSET
|
||||
import com.maddyhome.idea.vim.handler.CaretOrder.INCREASING_OFFSET
|
||||
import com.maddyhome.idea.vim.helper.EditorHelper
|
||||
import java.util.*
|
||||
import kotlin.math.abs
|
||||
import kotlin.math.min
|
||||
|
||||
/**
|
||||
* [putToLine] has affect only of [insertTextBeforeCaret] is false and [visualSelection] is null
|
||||
*/
|
||||
data class PutData(
|
||||
val textData: TextData?,
|
||||
val visualSelection: VisualSelection?,
|
||||
val count: Int,
|
||||
val insertTextBeforeCaret: Boolean,
|
||||
private val _indent: Boolean,
|
||||
val caretAfterInsertedText: Boolean,
|
||||
val putToLine: Int = -1
|
||||
) {
|
||||
val indent: Boolean =
|
||||
if (_indent && textData?.typeInRegister != SelectionType.LINE_WISE && visualSelection?.typeInEditor != SelectionType.LINE_WISE) false else _indent
|
||||
|
||||
data class VisualSelection(
|
||||
val caretsAndSelections: Map<Caret, VimSelection>,
|
||||
val typeInEditor: SelectionType
|
||||
)
|
||||
|
||||
data class TextData(
|
||||
val rawText: String?,
|
||||
val typeInRegister: SelectionType
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
class PutGroup {
|
||||
fun putVisualRangeCaL(
|
||||
editor: Editor,
|
||||
context: DataContext,
|
||||
caretsAndSelections: Map<Caret, VimSelection>,
|
||||
count: Int,
|
||||
indent: Boolean,
|
||||
cursorAfter: Boolean,
|
||||
register: Register?
|
||||
): Boolean {
|
||||
caretsAndSelections.entries.sortedByDescending { it.key.logicalPosition }.forEach { (caret, selection) ->
|
||||
putVisualRangeCaLEx(editor, context, caret, selection, count, indent, cursorAfter, register)
|
||||
}
|
||||
fun putText(editor: Editor, context: DataContext, data: PutData): Boolean {
|
||||
val additionalData = collectPreModificationData(editor, data)
|
||||
deleteSelectedText(editor, data)
|
||||
val (text, typeInRegister) = getText(editor, data) ?: return false
|
||||
putTextAndSetCaretPosition(editor, context, text, typeInRegister, data, additionalData)
|
||||
return true
|
||||
}
|
||||
|
||||
private fun putVisualRangeCaLEx(
|
||||
editor: Editor,
|
||||
context: DataContext,
|
||||
caret: Caret,
|
||||
selection: VimSelection,
|
||||
count: Int,
|
||||
indent: Boolean,
|
||||
cursorAfter: Boolean,
|
||||
register: Register?
|
||||
): Boolean {
|
||||
val range = selection.toVimTextRange(false).normalize()
|
||||
|
||||
VimPlugin.getChange().deleteRange(editor, caret, range, selection.type, false)
|
||||
var startOffset = range.startOffset
|
||||
|
||||
caret.moveToOffset(startOffset)
|
||||
|
||||
if (register == null) return false
|
||||
var text = register.text ?: run {
|
||||
VimPlugin.getMark().setMark(editor, MarkGroup.MARK_CHANGE_POS, startOffset)
|
||||
VimPlugin.getMark().setChangeMarks(editor, TextRange(startOffset, startOffset))
|
||||
return false
|
||||
}
|
||||
|
||||
val type = register.type
|
||||
if (type == SelectionType.LINE_WISE) {
|
||||
if (selection.type != SelectionType.LINE_WISE) {
|
||||
editor.document.insertString(startOffset, "\n")
|
||||
startOffset += 1
|
||||
}
|
||||
} else if (type == SelectionType.CHARACTER_WISE) {
|
||||
if (selection.type == SelectionType.LINE_WISE) {
|
||||
text += "\n"
|
||||
}
|
||||
}
|
||||
|
||||
putText(editor, caret, context, text, type, selection.type.toSubMode(), startOffset,
|
||||
count, indent && type == SelectionType.LINE_WISE, cursorAfter)
|
||||
|
||||
fun putTextForCaret(editor: Editor, caret: Caret, context: DataContext, data: PutData): Boolean {
|
||||
val additionalData = collectPreModificationData(editor, data)
|
||||
val (text, typeInRegister) = getText(editor, data) ?: return false
|
||||
putForCaret(editor, caret, typeInRegister, data, additionalData, context, text)
|
||||
return true
|
||||
}
|
||||
|
||||
fun putVisualRangeBlockwise(
|
||||
editor: Editor,
|
||||
context: DataContext,
|
||||
selection: VimSelection,
|
||||
count: Int,
|
||||
indent: Boolean,
|
||||
cursorAfter: Boolean,
|
||||
register: Register?,
|
||||
insertBefore: Boolean
|
||||
): Boolean {
|
||||
val res = Ref.create(true)
|
||||
val caret = editor.caretModel.primaryCaret
|
||||
val range = selection.toVimTextRange(false).normalize()
|
||||
val line = if (insertBefore) {
|
||||
editor.offsetToLogicalPosition(range.startOffset).line
|
||||
private fun collectPreModificationData(editor: Editor, data: PutData): Map<String, Any> {
|
||||
return if (data.visualSelection != null && data.visualSelection.typeInEditor == SelectionType.BLOCK_WISE) {
|
||||
val vimSelection = data.visualSelection.caretsAndSelections.getValue(editor.caretModel.primaryCaret)
|
||||
val selStart = editor.offsetToLogicalPosition(vimSelection.vimStart)
|
||||
val selEnd = editor.offsetToLogicalPosition(vimSelection.vimEnd)
|
||||
mapOf(
|
||||
"startColumnOfSelection" to min(selStart.column, selEnd.column),
|
||||
"selectedLines" to abs(selStart.line - selEnd.line),
|
||||
"firstSelectedLine" to min(selStart.line, selEnd.line)
|
||||
)
|
||||
} else mutableMapOf()
|
||||
}
|
||||
|
||||
private fun deleteSelectedText(editor: Editor, data: PutData) {
|
||||
if (data.visualSelection == null) return
|
||||
|
||||
data.visualSelection.caretsAndSelections.entries.sortedByDescending { it.key.logicalPosition }.forEach { (caret, selection) ->
|
||||
if (!caret.isValid) return@forEach
|
||||
val range = selection.toVimTextRange(false).normalize()
|
||||
|
||||
VimPlugin.getChange().deleteRange(editor, caret, range, selection.type, false)
|
||||
caret.moveToOffset(range.startOffset)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getText(editor: Editor, data: PutData): Pair<String, SelectionType>? {
|
||||
var text = data.textData?.rawText ?: run {
|
||||
if (data.visualSelection != null) {
|
||||
val offset = editor.caretModel.primaryCaret.offset
|
||||
VimPlugin.getMark().setMark(editor, MarkGroup.MARK_CHANGE_POS, offset)
|
||||
VimPlugin.getMark().setChangeMarks(editor, TextRange(offset, offset))
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
if (data.visualSelection?.typeInEditor == SelectionType.LINE_WISE && data.textData.typeInRegister == SelectionType.CHARACTER_WISE) text += "\n"
|
||||
|
||||
if (data.textData.typeInRegister == SelectionType.LINE_WISE && text.isNotEmpty() && text.last() != '\n') text += '\n'
|
||||
|
||||
return text to data.textData.typeInRegister
|
||||
}
|
||||
|
||||
private fun putTextAndSetCaretPosition(editor: Editor, context: DataContext, text: String, typeInRegister: SelectionType, data: PutData, additionalData: Map<String, Any>) {
|
||||
val myCarets = if (data.visualSelection != null) {
|
||||
data.visualSelection.caretsAndSelections.keys.sortedByDescending { it.logicalPosition }
|
||||
} else {
|
||||
editor.offsetToLogicalPosition(range.endOffset).line
|
||||
EditorHelper.getOrderedCaretsList(editor, DECREASING_OFFSET)
|
||||
}
|
||||
myCarets.forEach { caret -> putForCaret(editor, caret, typeInRegister, data, additionalData, context, text) }
|
||||
}
|
||||
|
||||
private fun putForCaret(editor: Editor, caret: Caret, typeInRegister: SelectionType, data: PutData, additionalData: Map<String, Any>, context: DataContext, text: String) {
|
||||
if (data.visualSelection?.typeInEditor == SelectionType.LINE_WISE && editor.isOneLineMode) return
|
||||
val startOffsets = prepareDocumentAndGetStartOffsets(editor, caret, typeInRegister, data, additionalData)
|
||||
|
||||
VimPlugin.getChange().deleteRange(editor, caret, range, SelectionType.BLOCK_WISE, false)
|
||||
startOffsets.forEach { startOffset ->
|
||||
val subMode = data.visualSelection?.typeInEditor?.toSubMode() ?: CommandState.SubMode.NONE
|
||||
val endOffset = putTextInternal(editor, caret, context, text, typeInRegister, subMode,
|
||||
startOffset, data.count, data.indent, data.caretAfterInsertedText)
|
||||
VimPlugin.getMark().setChangeMarks(editor, TextRange(startOffset, endOffset))
|
||||
moveCaretToEndPosition(editor, caret, startOffset, endOffset, typeInRegister, subMode, data.caretAfterInsertedText)
|
||||
}
|
||||
}
|
||||
|
||||
val type = register?.type ?: return false
|
||||
val lineWiseInsert = type == SelectionType.LINE_WISE
|
||||
|
||||
when (type) {
|
||||
SelectionType.CHARACTER_WISE -> {
|
||||
selection.forEachLine { startOffset, _ ->
|
||||
caret.moveToOffset(startOffset)
|
||||
|
||||
if (!lineWiseInsert) {
|
||||
val text = register.text ?: run {
|
||||
VimPlugin.getMark().setMark(editor, MarkGroup.MARK_CHANGE_POS, startOffset)
|
||||
VimPlugin.getMark().setChangeMarks(editor, TextRange(startOffset, startOffset))
|
||||
res.set(false)
|
||||
return@forEachLine
|
||||
private fun prepareDocumentAndGetStartOffsets(editor: Editor, caret: Caret, typeInRegister: SelectionType, data: PutData, additionalData: Map<String, Any>): List<Int> {
|
||||
if (data.visualSelection != null) {
|
||||
return when {
|
||||
data.visualSelection.typeInEditor == SelectionType.CHARACTER_WISE && typeInRegister == SelectionType.LINE_WISE -> {
|
||||
editor.document.insertString(caret.offset, "\n")
|
||||
listOf(caret.offset + 1)
|
||||
}
|
||||
data.visualSelection.typeInEditor == SelectionType.BLOCK_WISE -> {
|
||||
val firstSelectedLine = additionalData["firstSelectedLine"] as Int
|
||||
val selectedLines = additionalData["selectedLines"] as Int
|
||||
val startColumnOfSelection = additionalData["startColumnOfSelection"] as Int
|
||||
val line = if (data.insertTextBeforeCaret) firstSelectedLine else firstSelectedLine + selectedLines
|
||||
when (typeInRegister) {
|
||||
SelectionType.LINE_WISE -> when {
|
||||
data.insertTextBeforeCaret -> listOf(EditorHelper.getLineStartOffset(editor, line))
|
||||
else -> {
|
||||
val pos = EditorHelper.getLineEndOffset(editor, line, true)
|
||||
editor.document.insertString(pos, "\n")
|
||||
listOf(pos + 1)
|
||||
}
|
||||
}
|
||||
SelectionType.CHARACTER_WISE -> (firstSelectedLine + selectedLines downTo firstSelectedLine)
|
||||
.map { editor.logicalPositionToOffset(LogicalPosition(it, startColumnOfSelection)) }
|
||||
SelectionType.BLOCK_WISE -> listOf(editor.logicalPositionToOffset(LogicalPosition(firstSelectedLine, startColumnOfSelection)))
|
||||
}
|
||||
}
|
||||
else -> listOf(caret.offset)
|
||||
}
|
||||
} else {
|
||||
if (data.insertTextBeforeCaret) {
|
||||
return when (typeInRegister) {
|
||||
SelectionType.LINE_WISE -> listOf(VimPlugin.getMotion().moveCaretToLineStart(editor, caret))
|
||||
else -> listOf(caret.offset)
|
||||
}
|
||||
}
|
||||
|
||||
putText(editor, caret, context, text, type, CommandState.SubMode.VISUAL_BLOCK, startOffset,
|
||||
count, indent && type == SelectionType.LINE_WISE, cursorAfter)
|
||||
var startOffset: Int
|
||||
val line = if (data.putToLine < 0) caret.visualPosition.line else data.putToLine
|
||||
when (typeInRegister) {
|
||||
SelectionType.LINE_WISE -> {
|
||||
startOffset = min(editor.document.textLength, VimPlugin.getMotion().moveCaretToLineEnd(editor, line, true) + 1)
|
||||
if (startOffset > 0 && startOffset == editor.document.textLength &&
|
||||
editor.document.charsSequence[startOffset - 1] != '\n') {
|
||||
editor.document.insertString(startOffset, "\n")
|
||||
startOffset++
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
startOffset = caret.offset
|
||||
if (!EditorHelper.isLineEmpty(editor, line, false)) {
|
||||
startOffset++
|
||||
}
|
||||
}
|
||||
}
|
||||
SelectionType.LINE_WISE -> {
|
||||
val startOffset = if (insertBefore) {
|
||||
EditorHelper.getLineStartOffset(editor, line)
|
||||
} else {
|
||||
EditorHelper.getLineEndOffset(editor, line, true)
|
||||
}
|
||||
|
||||
var text = register.text ?: run {
|
||||
VimPlugin.getMark().setMark(editor, MarkGroup.MARK_CHANGE_POS, startOffset)
|
||||
VimPlugin.getMark().setChangeMarks(editor, TextRange(startOffset, startOffset))
|
||||
return false
|
||||
}
|
||||
|
||||
if (!insertBefore) text = "\n" + text
|
||||
|
||||
putText(editor, editor.caretModel.primaryCaret, context, text, type, CommandState.SubMode.VISUAL_BLOCK, startOffset,
|
||||
count, indent && type == SelectionType.LINE_WISE, cursorAfter)
|
||||
}
|
||||
SelectionType.BLOCK_WISE -> {
|
||||
val startOffset = range.startOffset
|
||||
caret.moveToOffset(startOffset)
|
||||
|
||||
if (!lineWiseInsert) {
|
||||
val text = register.text ?: run {
|
||||
VimPlugin.getMark().setMark(editor, MarkGroup.MARK_CHANGE_POS, startOffset)
|
||||
VimPlugin.getMark().setChangeMarks(editor, TextRange(startOffset, startOffset))
|
||||
res.set(false)
|
||||
return false
|
||||
}
|
||||
|
||||
putText(editor, caret, context, text, type, CommandState.SubMode.VISUAL_BLOCK, startOffset,
|
||||
count, indent && type == SelectionType.LINE_WISE, cursorAfter)
|
||||
}
|
||||
}
|
||||
return if (startOffset > editor.document.textLength) listOf(editor.document.textLength) else listOf(startOffset)
|
||||
}
|
||||
|
||||
return res.get()
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Pastes text from the last register into the editor.
|
||||
*
|
||||
* @param editor The editor to paste into
|
||||
* @param context The data context
|
||||
* @param count The number of times to perform the paste
|
||||
* @return true if able to paste, false if not
|
||||
*/
|
||||
fun putText(editor: Editor, context: DataContext, count: Int, indent: Boolean,
|
||||
cursorAfter: Boolean, beforeCursor: Boolean): Boolean {
|
||||
val register = VimPlugin.getRegister().lastRegister ?: return false
|
||||
val selectionType = register.type
|
||||
if (selectionType == SelectionType.LINE_WISE && editor.isOneLineMode) return false
|
||||
|
||||
val text = register.text
|
||||
val carets = EditorHelper.getOrderedCaretsList(editor, if (beforeCursor) INCREASING_OFFSET else DECREASING_OFFSET)
|
||||
for (caret in carets) {
|
||||
val startOffset = getStartOffset(editor, caret, selectionType, beforeCursor)
|
||||
|
||||
if (text == null) {
|
||||
VimPlugin.getMark().setMark(editor, MarkGroup.MARK_CHANGE_POS, startOffset)
|
||||
VimPlugin.getMark().setChangeMarks(editor, TextRange(startOffset, startOffset))
|
||||
continue
|
||||
}
|
||||
|
||||
putText(editor, caret, context, text, selectionType, CommandState.SubMode.NONE, startOffset, count, indent,
|
||||
cursorAfter)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* This performs the actual insert of the paste
|
||||
*
|
||||
* @param editor The editor to paste into
|
||||
* @param context The data context
|
||||
* @param startOffset The location within the file to paste the text
|
||||
* @param text The text to paste
|
||||
* @param type The type of paste
|
||||
* @param count The number of times to paste the text
|
||||
* @param indent True if pasted lines should be autoindented, false if not
|
||||
* @param cursorAfter If true move cursor to just after pasted text
|
||||
* @param mode The type of highlight prior to the put.
|
||||
* @param caret The caret to insert to
|
||||
*/
|
||||
fun putText(editor: Editor, caret: Caret, context: DataContext, text: String,
|
||||
type: SelectionType, mode: CommandState.SubMode, startOffset: Int, count: Int,
|
||||
indent: Boolean, cursorAfter: Boolean) {
|
||||
var actualText = text
|
||||
var actualIndent = indent
|
||||
if (mode == CommandState.SubMode.VISUAL_LINE && editor.isOneLineMode) return
|
||||
if (actualIndent && type != SelectionType.LINE_WISE && mode != CommandState.SubMode.VISUAL_LINE) actualIndent = false
|
||||
if (type == SelectionType.LINE_WISE && actualText.isNotEmpty() && actualText[actualText.length - 1] != '\n') {
|
||||
actualText += '\n'
|
||||
}
|
||||
|
||||
val endOffset = putTextInternal(editor, caret, context, actualText, type, mode, startOffset, count, actualIndent, cursorAfter)
|
||||
VimPlugin.getMark().setChangeMarks(editor, TextRange(startOffset, endOffset))
|
||||
}
|
||||
|
||||
private fun putTextInternal(editor: Editor, caret: Caret, context: DataContext,
|
||||
text: String, type: SelectionType, mode: CommandState.SubMode,
|
||||
startOffset: Int, count: Int, indent: Boolean, cursorAfter: Boolean): Int =
|
||||
@ -327,7 +291,7 @@ class PutGroup {
|
||||
}
|
||||
|
||||
if (indent) endOffset = doIndent(editor, caret, context, startOffset, endOffset)
|
||||
moveCaret(editor, caret, type, mode, startOffset, endOffset, cursorAfter)
|
||||
moveCaretToEndPosition(editor, caret, startOffset, endOffset, type, mode, cursorAfter)
|
||||
|
||||
return endOffset
|
||||
}
|
||||
@ -344,64 +308,41 @@ class PutGroup {
|
||||
doIndent(editor, caret, context, startOffset, startOffset + insertedText.length)
|
||||
else
|
||||
startOffset + insertedText.length
|
||||
moveCaret(editor, caret, type, mode, startOffset, endOffset, cursorAfter)
|
||||
moveCaretToEndPosition(editor, caret, startOffset, endOffset, type, mode, cursorAfter)
|
||||
|
||||
return endOffset
|
||||
}
|
||||
|
||||
private fun getStartOffset(editor: Editor, caret: Caret, type: SelectionType, beforeCursor: Boolean): Int {
|
||||
if (beforeCursor) {
|
||||
return if (type == SelectionType.LINE_WISE)
|
||||
VimPlugin.getMotion().moveCaretToLineStart(editor, caret)
|
||||
else
|
||||
caret.offset
|
||||
}
|
||||
|
||||
var startOffset: Int
|
||||
if (type == SelectionType.LINE_WISE) {
|
||||
startOffset = Math.min(editor.document.textLength,
|
||||
VimPlugin.getMotion().moveCaretToLineEnd(editor, caret) + 1)
|
||||
if (startOffset > 0 && startOffset == editor.document.textLength &&
|
||||
editor.document.charsSequence[startOffset - 1] != '\n') {
|
||||
editor.document.insertString(startOffset, "\n")
|
||||
startOffset++
|
||||
private fun moveCaretToEndPosition(
|
||||
editor: Editor,
|
||||
caret: Caret,
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
typeInRegister: SelectionType,
|
||||
modeInEditor: CommandState.SubMode,
|
||||
caretAfterInsertedText: Boolean
|
||||
) {
|
||||
val cursorMode = when (typeInRegister) {
|
||||
SelectionType.BLOCK_WISE -> when (modeInEditor) {
|
||||
CommandState.SubMode.VISUAL_LINE -> if (caretAfterInsertedText) "postEndOffset" else "startOffset"
|
||||
else -> if (caretAfterInsertedText) "preLineEndOfEndOffset" else "startOffset"
|
||||
}
|
||||
} else {
|
||||
startOffset = caret.offset
|
||||
if (!EditorHelper.isLineEmpty(editor, caret.logicalPosition.line, false)) {
|
||||
startOffset++
|
||||
}
|
||||
}
|
||||
|
||||
return if (startOffset > 0 && startOffset > editor.document.textLength) startOffset - 1 else startOffset
|
||||
|
||||
}
|
||||
|
||||
private fun moveCaret(editor: Editor, caret: Caret, type: SelectionType,
|
||||
mode: CommandState.SubMode, startOffset: Int, endOffset: Int, cursorAfter: Boolean) {
|
||||
val cursorMode = when (type) {
|
||||
SelectionType.BLOCK_WISE -> if (mode == CommandState.SubMode.VISUAL_LINE) {
|
||||
if (cursorAfter) 4 else 1
|
||||
} else {
|
||||
if (cursorAfter) 5 else 1
|
||||
}
|
||||
SelectionType.LINE_WISE -> if (cursorAfter) 4 else 3
|
||||
else -> if (mode == CommandState.SubMode.VISUAL_LINE) {
|
||||
if (cursorAfter) 4 else 1
|
||||
} else {
|
||||
if (cursorAfter) 5 else 2
|
||||
SelectionType.LINE_WISE -> if (caretAfterInsertedText) "postEndOffset" else "startOffsetSkipLeading"
|
||||
SelectionType.CHARACTER_WISE -> when (modeInEditor) {
|
||||
CommandState.SubMode.VISUAL_LINE -> if (caretAfterInsertedText) "postEndOffset" else "startOffset"
|
||||
else -> if (caretAfterInsertedText) "preLineEndOfEndOffset" else "preEndOffset"
|
||||
}
|
||||
}
|
||||
|
||||
when (cursorMode) {
|
||||
1 -> MotionGroup.moveCaret(editor, caret, startOffset)
|
||||
2 -> MotionGroup.moveCaret(editor, caret, endOffset - 1)
|
||||
3 -> {
|
||||
"startOffset" -> MotionGroup.moveCaret(editor, caret, startOffset)
|
||||
"preEndOffset" -> MotionGroup.moveCaret(editor, caret, endOffset - 1)
|
||||
"startOffsetSkipLeading" -> {
|
||||
MotionGroup.moveCaret(editor, caret, startOffset)
|
||||
MotionGroup.moveCaret(editor, caret, VimPlugin.getMotion().moveCaretToLineStartSkipLeading(editor, caret))
|
||||
}
|
||||
4 -> MotionGroup.moveCaret(editor, caret, endOffset + 1)
|
||||
5 -> {
|
||||
"postEndOffset" -> MotionGroup.moveCaret(editor, caret, endOffset + 1)
|
||||
"preLineEndOfEndOffset" -> {
|
||||
val pos = Math.min(endOffset, EditorHelper.getLineEndForOffset(editor, endOffset - 1) - 1)
|
||||
MotionGroup.moveCaret(editor, caret, pos)
|
||||
}
|
||||
|
@ -50,14 +50,6 @@ sealed class VimSelection {
|
||||
|
||||
abstract fun toVimTextRange(skipNewLineForLineMode: Boolean = false): TextRange
|
||||
|
||||
/**
|
||||
* Execute [action] for each line of selection.
|
||||
* Action will be executed in bottom-up direction if [vimStart] > [vimEnd]
|
||||
*
|
||||
* [action#start] and [action#end] are offsets in current line
|
||||
*/
|
||||
abstract fun forEachLine(action: (start: Int, end: Int) -> Unit)
|
||||
|
||||
abstract fun getNativeStartAndEnd(): Pair<Int, Int>
|
||||
|
||||
companion object {
|
||||
@ -106,17 +98,6 @@ sealed class VimSimpleSelection : VimSelection() {
|
||||
abstract val normNativeStart: Int
|
||||
abstract val normNativeEnd: Int
|
||||
|
||||
override fun forEachLine(action: (start: Int, end: Int) -> Unit) {
|
||||
val logicalStart = editor.offsetToLogicalPosition(nativeStart)
|
||||
val logicalEnd = editor.offsetToLogicalPosition(nativeEnd)
|
||||
val lineRange = if (logicalStart.line > logicalEnd.line) logicalStart.line downTo logicalEnd.line else logicalStart.line..logicalEnd.line
|
||||
lineRange.map { line ->
|
||||
val start = editor.logicalPositionToOffset(LogicalPosition(line, logicalStart.column))
|
||||
val end = editor.logicalPositionToOffset(LogicalPosition(line, logicalEnd.column))
|
||||
action(start, end)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getNativeStartAndEnd() = normNativeStart to normNativeEnd
|
||||
|
||||
companion object {
|
||||
@ -185,7 +166,7 @@ class VimBlockSelection(
|
||||
return TextRange(starts.toIntArray(), ends.toIntArray()).also { it.normalize(editor.document.textLength) }
|
||||
}
|
||||
|
||||
override fun forEachLine(action: (start: Int, end: Int) -> Unit) {
|
||||
private fun forEachLine(action: (start: Int, end: Int) -> Unit) {
|
||||
val offsets = toNativeSelection(editor, vimStart, vimEnd, CommandState.Mode.VISUAL, type.toSubMode())
|
||||
val logicalStart = editor.offsetToLogicalPosition(min(offsets.first, offsets.second))
|
||||
val logicalEnd = editor.offsetToLogicalPosition(max(offsets.first, offsets.second))
|
||||
|
@ -991,15 +991,6 @@ class PutVisualTextActionTest : VimTestCase() {
|
||||
myFixture.checkResult(after)
|
||||
}
|
||||
|
||||
|
||||
@VimBehaviourDiffers(originalVimAfter = """
|
||||
A Discovery
|
||||
|
||||
I Discover${c}y it in a legendary land
|
||||
alDiscoveryks and lavender and tufted grass,
|
||||
whDiscoveryt was settled on some sodden sand
|
||||
hard by the torrent of a mountain pass.
|
||||
""", description = "Different cursor position")
|
||||
@Test
|
||||
fun `test put visual text character to block`() {
|
||||
val before = """
|
||||
@ -1016,22 +1007,38 @@ class PutVisualTextActionTest : VimTestCase() {
|
||||
val after = """
|
||||
A Discovery
|
||||
|
||||
I Discovery it in a legendary land
|
||||
I Discover${c}y it in a legendary land
|
||||
alDiscoveryks and lavender and tufted grass,
|
||||
whDiscover${c}yt was settled on some sodden sand
|
||||
whDiscoveryt was settled on some sodden sand
|
||||
hard by the torrent of a mountain pass.
|
||||
""".trimIndent()
|
||||
myFixture.checkResult(after)
|
||||
}
|
||||
|
||||
@VimBehaviourDiffers(originalVimAfter = """
|
||||
@Test
|
||||
fun `test put visual text character to block motion up`() {
|
||||
val before = """
|
||||
A Discovery
|
||||
|
||||
I DiscoveryDiscover${c}y it in a legendary land
|
||||
alDiscoveryDiscoveryks and lavender and tufted grass,
|
||||
whDiscoveryDiscoveryt was settled on some sodden sand
|
||||
I |found| it in a legendary land
|
||||
al|l roc|ks and lavender and tufted grass,
|
||||
wh$c|ere i|t was settled on some sodden sand
|
||||
hard by the torrent of a mountain pass.
|
||||
""", description = "Different cursor position")
|
||||
""".trimIndent()
|
||||
val editor = configureByText(before)
|
||||
VimPlugin.getRegister().storeText(editor, before rangeOf "Discovery", SelectionType.CHARACTER_WISE, false)
|
||||
typeText(parseKeys("<C-V>3e2k", "p"))
|
||||
val after = """
|
||||
A Discovery
|
||||
|
||||
I Discover${c}y it in a legendary land
|
||||
alDiscoveryks and lavender and tufted grass,
|
||||
whDiscoveryt was settled on some sodden sand
|
||||
hard by the torrent of a mountain pass.
|
||||
""".trimIndent()
|
||||
myFixture.checkResult(after)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test put visual text character to block twice`() {
|
||||
val before = """
|
||||
@ -1048,22 +1055,14 @@ class PutVisualTextActionTest : VimTestCase() {
|
||||
val after = """
|
||||
A Discovery
|
||||
|
||||
I DiscoveryDiscovery it in a legendary land
|
||||
I DiscoveryDiscover${c}y it in a legendary land
|
||||
alDiscoveryDiscoveryks and lavender and tufted grass,
|
||||
whDiscoveryDiscover${c}yt was settled on some sodden sand
|
||||
whDiscoveryDiscoveryt was settled on some sodden sand
|
||||
hard by the torrent of a mountain pass.
|
||||
""".trimIndent()
|
||||
myFixture.checkResult(after)
|
||||
}
|
||||
|
||||
@VimBehaviourDiffers(originalVimAfter = """
|
||||
A Discovery
|
||||
|
||||
I Discover${c}y
|
||||
alDiscovery
|
||||
whDiscovery
|
||||
haDiscovery
|
||||
""", description = "Different cursor position")
|
||||
@Test
|
||||
fun `test put visual text character to block with dollar motion`() {
|
||||
val before = """
|
||||
@ -1080,10 +1079,10 @@ class PutVisualTextActionTest : VimTestCase() {
|
||||
val after = """
|
||||
A Discovery
|
||||
|
||||
I Discovery
|
||||
I Discover${c}y
|
||||
alDiscovery
|
||||
whDiscovery
|
||||
haDiscover${c}y
|
||||
haDiscovery
|
||||
""".trimIndent()
|
||||
myFixture.checkResult(after)
|
||||
}
|
||||
@ -1117,9 +1116,34 @@ class PutVisualTextActionTest : VimTestCase() {
|
||||
|
||||
I it in a legendary land
|
||||
alks and lavender and tufted grass,
|
||||
${c}wht was settled on some sodden sand
|
||||
wht was settled on some sodden sand
|
||||
${c}A Discovery
|
||||
|
||||
hard by the torrent of a mountain pass.
|
||||
""".trimIndent()
|
||||
myFixture.checkResult(after)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test put visual text line to block before caret`() {
|
||||
val before = """
|
||||
A Discovery
|
||||
|
||||
I $c|found| it in a legendary land
|
||||
al|l roc|ks and lavender and tufted grass,
|
||||
wh|ere i|t was settled on some sodden sand
|
||||
hard by the torrent of a mountain pass.
|
||||
""".trimIndent()
|
||||
val editor = configureByText(before)
|
||||
VimPlugin.getRegister().storeText(editor, before rangeOf "A Discovery\n", SelectionType.LINE_WISE, false)
|
||||
typeText(parseKeys("<C-V>2e2j", "P"))
|
||||
val after = """
|
||||
A Discovery
|
||||
|
||||
${c}A Discovery
|
||||
I it in a legendary land
|
||||
alks and lavender and tufted grass,
|
||||
wht was settled on some sodden sand
|
||||
hard by the torrent of a mountain pass.
|
||||
""".trimIndent()
|
||||
myFixture.checkResult(after)
|
||||
@ -1153,9 +1177,8 @@ class PutVisualTextActionTest : VimTestCase() {
|
||||
|
||||
I it in a legendary land
|
||||
alks and lavender and tufted grass,
|
||||
${c}wht was settled on some sodden sand
|
||||
A Discovery
|
||||
|
||||
wht was settled on some sodden sand
|
||||
${c}A Discovery
|
||||
A Discovery
|
||||
|
||||
hard by the torrent of a mountain pass.
|
||||
@ -1163,7 +1186,6 @@ class PutVisualTextActionTest : VimTestCase() {
|
||||
myFixture.checkResult(after)
|
||||
}
|
||||
|
||||
|
||||
@VimBehaviourDiffers(originalVimAfter = """
|
||||
A Discovery
|
||||
|
||||
@ -1192,8 +1214,8 @@ class PutVisualTextActionTest : VimTestCase() {
|
||||
I it in a legendary land
|
||||
alks and lavender and tufted grass,
|
||||
wht was settled on some sodden sand
|
||||
${c}ha the torrent of a mountain pass.
|
||||
A Discovery
|
||||
ha the torrent of a mountain pass.
|
||||
${c}A Discovery
|
||||
|
||||
""".trimIndent()
|
||||
myFixture.checkResult(after)
|
||||
@ -1226,8 +1248,8 @@ class PutVisualTextActionTest : VimTestCase() {
|
||||
|
||||
I
|
||||
a
|
||||
${c}w
|
||||
A Discovery
|
||||
w
|
||||
${c}A Discovery
|
||||
|
||||
hard by the torrent of a mountain pass.
|
||||
""".trimIndent()
|
||||
|
Loading…
Reference in New Issue
Block a user