mirror of
https://github.com/chylex/IntelliJ-IdeaVim.git
synced 2025-02-27 17:45:59 +01:00
Remove more postMove overrides
This commit is contained in:
parent
a49631e986
commit
b5aba454ae
src/main/java/com/maddyhome/idea/vim
vim-engine/src/main/kotlin/com/maddyhome/idea/vim
action/motion
leftright
updown
handler
options/helpers
@ -43,6 +43,7 @@ import com.maddyhome.idea.vim.newapi.IjVimEditor;
|
||||
import com.maddyhome.idea.vim.options.LocalOptionChangeListener;
|
||||
import com.maddyhome.idea.vim.options.OptionConstants;
|
||||
import com.maddyhome.idea.vim.options.OptionScope;
|
||||
import com.maddyhome.idea.vim.options.helpers.StrictMode;
|
||||
import com.maddyhome.idea.vim.ui.ex.ExEntryPanel;
|
||||
import com.maddyhome.idea.vim.vimscript.model.datatypes.VimDataType;
|
||||
import com.maddyhome.idea.vim.vimscript.model.datatypes.VimInt;
|
||||
@ -370,7 +371,12 @@ public class MotionGroup extends VimMotionGroupBase {
|
||||
if (offset < 0 || offset > editor.getDocument().getTextLength() || !caret.isValid()) return;
|
||||
|
||||
if (CommandStateHelper.inBlockSubMode(editor)) {
|
||||
StrictMode.INSTANCE.assertTrue(caret == editor.getCaretModel().getPrimaryCaret(),
|
||||
"Block selection can only be moved with primary caret!");
|
||||
|
||||
// Note that this call replaces ALL carets, so any local caret instances will be invalid!
|
||||
VisualGroupKt.vimMoveBlockSelectionToOffset(editor, offset);
|
||||
|
||||
Caret primaryCaret = editor.getCaretModel().getPrimaryCaret();
|
||||
UserDataManager.setVimLastColumn(primaryCaret, primaryCaret.getVisualPosition().column);
|
||||
scrollCaretIntoView(editor);
|
||||
@ -381,6 +387,11 @@ public class MotionGroup extends VimMotionGroupBase {
|
||||
// changes in surrounding text, especially with inline inlays.
|
||||
final int oldOffset = caret.getOffset();
|
||||
InlayHelperKt.moveToInlayAwareOffset(caret, offset);
|
||||
|
||||
// TODO: Remove this. If setting LAST_COLUMN, we have to set it both before and after moveCaret
|
||||
// But not all handlers set vimLastColumn (e.g. ShiftedArrowKeyHandler). It would be better if all handlers reset
|
||||
// vimLastColumn so that it is either calculated on demand (current column) or explicitly set by a handler that needs
|
||||
// special handling
|
||||
if (oldOffset != offset) {
|
||||
UserDataManager.setVimLastColumn(caret, InlayHelperKt.getInlayAwareVisualColumn(caret));
|
||||
}
|
||||
|
@ -58,7 +58,9 @@ fun Caret.vimMoveSelectionToCaret() {
|
||||
|
||||
/**
|
||||
* Move selection end to current primary caret position
|
||||
* This method is created only for block mode
|
||||
*
|
||||
* This method is created only for block mode. Note that this method will invalidate all carets!
|
||||
*
|
||||
* @see vimMoveSelectionToCaret for character and line selection
|
||||
*/
|
||||
fun vimMoveBlockSelectionToOffset(editor: Editor, offset: Int) {
|
||||
@ -163,11 +165,18 @@ private fun setVisualSelection(selectionStart: Int, selectionEnd: Int, caret: Ca
|
||||
caret.vimSetSystemSelectionSilently(nativeStart, nativeEnd)
|
||||
}
|
||||
VimStateMachine.SubMode.VISUAL_BLOCK -> {
|
||||
// This will invalidate any secondary carets, but we shouldn't have any of these cached in local variables, etc.
|
||||
editor.caretModel.removeSecondaryCarets()
|
||||
|
||||
// Set system selection
|
||||
val (blockStart, blockEnd) = blockToNativeSelection(vimEditor, selectionStart, selectionEnd, mode)
|
||||
val lastColumn = editor.caretModel.primaryCaret.vimLastColumn
|
||||
|
||||
// WARNING! This can invalidate the primary caret! I.e. the `caret` parameter will no longer be the primary caret.
|
||||
// Given an existing visual block selection, moving the caret will first remove all secondary carets (above) then
|
||||
// this method will ask IntelliJ to create a new multi-caret block selection. If we're moving up (`k`) a new caret
|
||||
// is added, and becomes the new primary caret. The current `caret` parameter remains valid, but is no longer the
|
||||
// primary caret. Make sure to fetch the new primary caret if necessary.
|
||||
vimEditor.vimSetSystemBlockSelectionSilently(blockStart, blockEnd)
|
||||
|
||||
// We've just added secondary carets again, hide them to better emulate block selection
|
||||
|
@ -31,6 +31,10 @@ import kotlin.reflect.KProperty
|
||||
* @author Alex Plate
|
||||
*/
|
||||
|
||||
// NOTE: Carets, including the primary caret, can be replaced when the caret is moved in visual block mode.
|
||||
// No attempt is made to maintain this user data (apart from vimLastColum which is set during caret movement)
|
||||
// Non-transient data will be lost!
|
||||
|
||||
//region Vim selection start ----------------------------------------------------
|
||||
/**
|
||||
* Caret's offset when entering visual mode
|
||||
@ -55,15 +59,18 @@ fun Caret.vimSelectionStartClear() {
|
||||
private var Caret._vimSelectionStart: Int? by userDataCaretToEditor()
|
||||
//endregion ----------------------------------------------------
|
||||
|
||||
// Last column excluding inlays before the caret
|
||||
// Last column excluding inlays before the caret. Reset during visual block motion
|
||||
var Caret.vimLastColumn: Int by userDataCaretToEditorOr { (this as Caret).inlayAwareVisualColumn }
|
||||
|
||||
// TODO: Is this a per-caret setting? This data is non-transient, so could be lost during visual block motion
|
||||
var Caret.vimLastVisualOperatorRange: VisualChange? by userDataCaretToEditor()
|
||||
|
||||
// Transient data. Does not need to be restored during visual block motion
|
||||
var Caret.vimInsertStart: RangeMarker by userDataOr {
|
||||
(this as Caret).editor.document.createRangeMarker(
|
||||
this.offset,
|
||||
this.offset
|
||||
)
|
||||
(this as Caret).editor.document.createRangeMarker(this.offset, this.offset)
|
||||
}
|
||||
|
||||
// TODO: Data could be lost during visual block motion
|
||||
var Caret.registerStorage: CaretRegisterStorageBase? by userDataCaretToEditor()
|
||||
|
||||
// ------------------ Editor
|
||||
|
@ -12,13 +12,14 @@ import com.maddyhome.idea.vim.api.VimCaret
|
||||
import com.maddyhome.idea.vim.api.VimEditor
|
||||
import com.maddyhome.idea.vim.api.injector
|
||||
import com.maddyhome.idea.vim.command.Argument
|
||||
import com.maddyhome.idea.vim.command.Command
|
||||
import com.maddyhome.idea.vim.command.MotionType
|
||||
import com.maddyhome.idea.vim.command.OperatorArguments
|
||||
import com.maddyhome.idea.vim.handler.Motion
|
||||
import com.maddyhome.idea.vim.handler.MotionActionHandler
|
||||
|
||||
class MotionColumnAction : MotionActionHandler.ForEachCaret() {
|
||||
override val motionType: MotionType = MotionType.EXCLUSIVE
|
||||
|
||||
override fun getOffset(
|
||||
editor: VimEditor,
|
||||
caret: VimCaret,
|
||||
@ -26,17 +27,10 @@ class MotionColumnAction : MotionActionHandler.ForEachCaret() {
|
||||
argument: Argument?,
|
||||
operatorArguments: OperatorArguments,
|
||||
): Motion {
|
||||
return injector.motion.moveCaretToColumn(editor, caret, operatorArguments.count1 - 1, false)
|
||||
val motion = injector.motion.moveCaretToColumn(editor, caret, operatorArguments.count1 - 1, false)
|
||||
return when (motion) {
|
||||
is Motion.AbsoluteOffset -> Motion.AdjustedOffset(motion.offset, operatorArguments.count1 - 1)
|
||||
else -> motion
|
||||
}
|
||||
}
|
||||
|
||||
override fun postMove(
|
||||
editor: VimEditor,
|
||||
caret: VimCaret,
|
||||
context: ExecutionContext,
|
||||
cmd: Command,
|
||||
) {
|
||||
caret.vimLastColumn = cmd.count - 1
|
||||
}
|
||||
|
||||
override val motionType: MotionType = MotionType.EXCLUSIVE
|
||||
}
|
||||
|
@ -20,7 +20,6 @@ import com.maddyhome.idea.vim.command.MotionType
|
||||
import com.maddyhome.idea.vim.command.OperatorArguments
|
||||
import com.maddyhome.idea.vim.handler.Motion
|
||||
import com.maddyhome.idea.vim.handler.MotionActionHandler
|
||||
import com.maddyhome.idea.vim.handler.toMotion
|
||||
import com.maddyhome.idea.vim.helper.enumSetOf
|
||||
import com.maddyhome.idea.vim.helper.inVisualMode
|
||||
import com.maddyhome.idea.vim.helper.isEndAllowed
|
||||
@ -55,11 +54,8 @@ open class MotionLastColumnAction : MotionActionHandler.ForEachCaret() {
|
||||
if (operatorArguments.isOperatorPending) false else editor.isEndAllowed
|
||||
}
|
||||
|
||||
return injector.motion.moveCaretToRelativeLineEnd(editor, caret, operatorArguments.count1 - 1, allow).toMotion()
|
||||
}
|
||||
|
||||
override fun postMove(editor: VimEditor, caret: VimCaret, context: ExecutionContext, cmd: Command) {
|
||||
caret.vimLastColumn = VimMotionGroupBase.LAST_COLUMN
|
||||
val offset = injector.motion.moveCaretToRelativeLineEnd(editor, caret, operatorArguments.count1 - 1, allow)
|
||||
return Motion.AdjustedOffset(offset, VimMotionGroupBase.LAST_COLUMN)
|
||||
}
|
||||
|
||||
override fun preMove(editor: VimEditor, caret: VimCaret, context: ExecutionContext, cmd: Command) {
|
||||
|
@ -13,7 +13,6 @@ import com.maddyhome.idea.vim.api.VimEditor
|
||||
import com.maddyhome.idea.vim.api.VimMotionGroupBase
|
||||
import com.maddyhome.idea.vim.api.injector
|
||||
import com.maddyhome.idea.vim.command.Argument
|
||||
import com.maddyhome.idea.vim.command.Command
|
||||
import com.maddyhome.idea.vim.command.MotionType
|
||||
import com.maddyhome.idea.vim.command.OperatorArguments
|
||||
import com.maddyhome.idea.vim.handler.Motion
|
||||
@ -46,16 +45,11 @@ class MotionLastScreenColumnAction : MotionActionHandler.ForEachCaret() {
|
||||
allow = true
|
||||
}
|
||||
}
|
||||
return injector.motion.moveCaretToCurrentDisplayLineEnd(editor, caret, allow)
|
||||
}
|
||||
|
||||
override fun postMove(
|
||||
editor: VimEditor,
|
||||
caret: VimCaret,
|
||||
context: ExecutionContext,
|
||||
cmd: Command,
|
||||
) {
|
||||
caret.vimLastColumn = VimMotionGroupBase.LAST_COLUMN
|
||||
val motion = injector.motion.moveCaretToCurrentDisplayLineEnd(editor, caret, allow)
|
||||
return when (motion) {
|
||||
is Motion.AbsoluteOffset -> Motion.AdjustedOffset(motion.offset, VimMotionGroupBase.LAST_COLUMN)
|
||||
else -> motion
|
||||
}
|
||||
}
|
||||
|
||||
override val motionType: MotionType = MotionType.INCLUSIVE
|
||||
|
@ -24,6 +24,28 @@ import com.maddyhome.idea.vim.handler.toMotionOrError
|
||||
sealed class MotionDownBase : MotionActionHandler.ForEachCaret() {
|
||||
private var col: Int = 0
|
||||
|
||||
final override fun getOffset(
|
||||
editor: VimEditor,
|
||||
caret: VimCaret,
|
||||
context: ExecutionContext,
|
||||
argument: Argument?,
|
||||
operatorArguments: OperatorArguments
|
||||
): Motion {
|
||||
val motion = getMotion(editor, caret, context, argument, operatorArguments)
|
||||
return when (motion) {
|
||||
is Motion.AbsoluteOffset -> Motion.AdjustedOffset(motion.offset, col)
|
||||
else -> motion
|
||||
}
|
||||
}
|
||||
|
||||
abstract fun getMotion(
|
||||
editor: VimEditor,
|
||||
caret: VimCaret,
|
||||
context: ExecutionContext,
|
||||
argument: Argument?,
|
||||
operatorArguments: OperatorArguments
|
||||
): Motion
|
||||
|
||||
override fun preOffsetComputation(
|
||||
editor: VimEditor,
|
||||
caret: VimCaret,
|
||||
@ -33,17 +55,13 @@ sealed class MotionDownBase : MotionActionHandler.ForEachCaret() {
|
||||
col = injector.engineEditorHelper.prepareLastColumn(caret)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun postMove(editor: VimEditor, caret: VimCaret, context: ExecutionContext, cmd: Command) {
|
||||
injector.engineEditorHelper.updateLastColumn(caret, col)
|
||||
}
|
||||
}
|
||||
|
||||
open class MotionDownAction : MotionDownBase() {
|
||||
|
||||
override val motionType: MotionType = MotionType.LINE_WISE
|
||||
|
||||
override fun getOffset(
|
||||
override fun getMotion(
|
||||
editor: VimEditor,
|
||||
caret: VimCaret,
|
||||
context: ExecutionContext,
|
||||
@ -55,7 +73,7 @@ open class MotionDownAction : MotionDownBase() {
|
||||
}
|
||||
|
||||
class MotionDownCtrlNAction : MotionDownAction() {
|
||||
override fun getOffset(
|
||||
override fun getMotion(
|
||||
editor: VimEditor,
|
||||
caret: VimCaret,
|
||||
context: ExecutionContext,
|
||||
@ -79,7 +97,7 @@ class MotionDownNotLineWiseAction : MotionDownBase() {
|
||||
|
||||
override val motionType: MotionType = MotionType.EXCLUSIVE
|
||||
|
||||
override fun getOffset(
|
||||
override fun getMotion(
|
||||
editor: VimEditor,
|
||||
caret: VimCaret,
|
||||
context: ExecutionContext,
|
||||
|
@ -24,6 +24,28 @@ import com.maddyhome.idea.vim.handler.toMotionOrError
|
||||
sealed class MotionUpBase : MotionActionHandler.ForEachCaret() {
|
||||
private var col: Int = 0
|
||||
|
||||
final override fun getOffset(
|
||||
editor: VimEditor,
|
||||
caret: VimCaret,
|
||||
context: ExecutionContext,
|
||||
argument: Argument?,
|
||||
operatorArguments: OperatorArguments
|
||||
): Motion {
|
||||
val motion = getMotion(editor, caret, context, argument, operatorArguments)
|
||||
return when (motion) {
|
||||
is Motion.AbsoluteOffset -> Motion.AdjustedOffset(motion.offset, col)
|
||||
else -> motion
|
||||
}
|
||||
}
|
||||
|
||||
abstract fun getMotion(
|
||||
editor: VimEditor,
|
||||
caret: VimCaret,
|
||||
context: ExecutionContext,
|
||||
argument: Argument?,
|
||||
operatorArguments: OperatorArguments
|
||||
): Motion
|
||||
|
||||
override fun preOffsetComputation(
|
||||
editor: VimEditor,
|
||||
caret: VimCaret,
|
||||
@ -33,16 +55,12 @@ sealed class MotionUpBase : MotionActionHandler.ForEachCaret() {
|
||||
col = injector.engineEditorHelper.prepareLastColumn(caret)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun postMove(editor: VimEditor, caret: VimCaret, context: ExecutionContext, cmd: Command) {
|
||||
injector.engineEditorHelper.updateLastColumn(caret, col)
|
||||
}
|
||||
}
|
||||
|
||||
open class MotionUpAction : MotionUpBase() {
|
||||
override val motionType: MotionType = MotionType.LINE_WISE
|
||||
|
||||
override fun getOffset(
|
||||
override fun getMotion(
|
||||
editor: VimEditor,
|
||||
caret: VimCaret,
|
||||
context: ExecutionContext,
|
||||
@ -54,7 +72,7 @@ open class MotionUpAction : MotionUpBase() {
|
||||
}
|
||||
|
||||
class MotionUpCtrlPAction : MotionUpAction() {
|
||||
override fun getOffset(
|
||||
override fun getMotion(
|
||||
editor: VimEditor,
|
||||
caret: VimCaret,
|
||||
context: ExecutionContext,
|
||||
@ -77,7 +95,7 @@ class MotionUpCtrlPAction : MotionUpAction() {
|
||||
class MotionUpNotLineWiseAction : MotionUpBase() {
|
||||
override val motionType: MotionType = MotionType.EXCLUSIVE
|
||||
|
||||
override fun getOffset(
|
||||
override fun getMotion(
|
||||
editor: VimEditor,
|
||||
caret: VimCaret,
|
||||
context: ExecutionContext,
|
||||
|
@ -186,10 +186,29 @@ sealed class MotionActionHandler : EditorActionHandlerBase(false) {
|
||||
cmd: Command,
|
||||
offset: Motion.AdjustedOffset,
|
||||
) {
|
||||
// Block selection mode is emulated with multiple carets, but we only ever operate on the primary caret. Changing
|
||||
// the selection (by moving the primary caret) can result in IntelliJ invalidating, replacing or adding a new
|
||||
// primary caret
|
||||
if (editor.inBlockSubMode) {
|
||||
StrictMode.assert(caret.isPrimary, "Block selection mode must only operate on primary caret")
|
||||
}
|
||||
|
||||
val normalisedOffset = prepareMoveToAbsoluteOffset(editor, cmd, offset)
|
||||
StrictMode.assert(normalisedOffset == offset.offset, "Adjusted offset should be normalised by action")
|
||||
caret.moveToOffset(normalisedOffset)
|
||||
|
||||
// Set before moving, so it can be applied during move, especially important for LAST_COLUMN and visual block mode
|
||||
caret.vimLastColumn = offset.intendedColumn
|
||||
|
||||
caret.moveToOffset(normalisedOffset)
|
||||
|
||||
// Visual block movement can replace the primary caret when moving the selection up, so reset the last column
|
||||
if (editor.inBlockSubMode) {
|
||||
editor.primaryCaret().vimLastColumn = offset.intendedColumn
|
||||
}
|
||||
else {
|
||||
// TODO: Remove this - we've already set it before moving the caret, but currently moving the caret sets last col
|
||||
caret.vimLastColumn = offset.intendedColumn
|
||||
}
|
||||
}
|
||||
|
||||
private fun moveToAbsoluteOffset(
|
||||
@ -209,6 +228,8 @@ sealed class MotionActionHandler : EditorActionHandlerBase(false) {
|
||||
val normalisedOffset = prepareMoveToAbsoluteOffset(editor, cmd, offset)
|
||||
preMove(editor, caret, context, cmd)
|
||||
caret.moveToOffset(normalisedOffset)
|
||||
|
||||
// Block selection mode might cause IntelliJ to invalidate/replace/add a new primary caret. Refresh if necessary
|
||||
val postMoveCaret = if (editor.inBlockSubMode) editor.primaryCaret() else caret
|
||||
postMove(editor, postMoveCaret, context, cmd)
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import com.maddyhome.idea.vim.options.OptionConstants
|
||||
import com.maddyhome.idea.vim.options.OptionScope
|
||||
|
||||
object StrictMode {
|
||||
@JvmName("assertTrue")
|
||||
fun assert(condition: Boolean, message: String) {
|
||||
if (!condition) {
|
||||
fail(message)
|
||||
|
Loading…
Reference in New Issue
Block a user