1
0
mirror of https://github.com/chylex/IntelliJ-IdeaVim.git synced 2025-06-05 13:34:04 +02:00

[New Typing Handler]: Support d

This commit is contained in:
Alex Plate 2022-09-06 13:13:31 +03:00
parent 43a79dbad4
commit c32c62eacc
No known key found for this signature in database
GPG Key ID: 0B97153C8FFEC09F
10 changed files with 64 additions and 26 deletions

View File

@ -25,10 +25,12 @@ import com.intellij.openapi.fileTypes.FileType
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.psi.PsiFile import com.intellij.psi.PsiFile
import com.maddyhome.idea.vim.api.VimEditor import com.maddyhome.idea.vim.api.VimEditor
import com.maddyhome.idea.vim.command.VimStateMachine
import com.maddyhome.idea.vim.helper.EditorDataContext import com.maddyhome.idea.vim.helper.EditorDataContext
import com.maddyhome.idea.vim.helper.inInsertMode import com.maddyhome.idea.vim.helper.inInsertMode
import com.maddyhome.idea.vim.helper.inNormalMode import com.maddyhome.idea.vim.helper.inNormalMode
import com.maddyhome.idea.vim.helper.isIdeaVimDisabledHere import com.maddyhome.idea.vim.helper.isIdeaVimDisabledHere
import com.maddyhome.idea.vim.helper.mode
import com.maddyhome.idea.vim.newapi.vim import com.maddyhome.idea.vim.newapi.vim
import javax.swing.KeyStroke import javax.swing.KeyStroke
@ -92,8 +94,8 @@ class VimTypedDelegateHandler : TypedHandlerDelegate() {
} }
} }
internal val charsByDelegate = setOf('j') internal val charsByDelegate = setOf('j', 'd')
internal fun useNewHandler(editor: VimEditor, c: Char): Boolean { internal fun useNewHandler(editor: VimEditor, c: Char): Boolean {
return c in charsByDelegate && editor.inNormalMode return c in charsByDelegate && (editor.inNormalMode || editor.mode == VimStateMachine.Mode.OP_PENDING)
} }

View File

@ -27,10 +27,7 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.command.UndoConfirmationPolicy; import com.intellij.openapi.command.UndoConfirmationPolicy;
import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Caret; import com.intellij.openapi.editor.*;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.LogicalPosition;
import com.intellij.openapi.editor.event.EditorMouseEvent; import com.intellij.openapi.editor.event.EditorMouseEvent;
import com.intellij.openapi.editor.event.EditorMouseListener; import com.intellij.openapi.editor.event.EditorMouseListener;
import com.intellij.openapi.editor.impl.TextRangeInterval; import com.intellij.openapi.editor.impl.TextRangeInterval;
@ -176,6 +173,15 @@ public class ChangeGroup extends VimChangeGroupBase {
MotionGroup.scrollCaretIntoView(editor); MotionGroup.scrollCaretIntoView(editor);
} }
@Override
public void typeDirectly(@NotNull VimEditor vimEditor, @NotNull ExecutionContext context, char key) {
Editor editor = ((IjVimEditor)vimEditor).getEditor();
final Document doc = ((IjVimEditor)vimEditor).getEditor().getDocument();
CommandProcessor.getInstance().executeCommand(editor.getProject(), () -> ApplicationManager.getApplication()
.runWriteAction(() -> EditorModificationUtilEx.insertStringAtCaret(editor, Character.toString(key))), "", doc,
UndoConfirmationPolicy.DEFAULT, doc);
MotionGroup.scrollCaretIntoView(editor);
}
@Override @Override

View File

@ -73,7 +73,7 @@ public class MacroGroup extends VimMacroBase {
final Runnable run = () -> { final Runnable run = () -> {
// Handle one keystroke then queue up the next key // Handle one keystroke then queue up the next key
if (keyStack.hasStroke()) { if (keyStack.hasStroke()) {
KeyHandler.getInstance().handleKey(editor, keyStack.feedStroke(), context, true, false, true); KeyHandler.getInstance().handleKey(editor, keyStack.feedStroke(), context, true, false, true, false);
} }
if (keyStack.hasStroke()) { if (keyStack.hasStroke()) {
playbackKeys(editor, context, cnt, total); playbackKeys(editor, context, cnt, total);
@ -105,7 +105,7 @@ public class MacroGroup extends VimMacroBase {
return; return;
} }
ProgressManager.getInstance().executeNonCancelableSection(() -> { ProgressManager.getInstance().executeNonCancelableSection(() -> {
KeyHandler.getInstance().handleKey(editor, key, context, true, false, true); KeyHandler.getInstance().handleKey(editor, key, context, true, false, true, false);
}); });
} }
keyStack.resetFirst(); keyStack.resetFirst();

View File

@ -32,6 +32,12 @@ class IjExecutionContext(override val context: DataContext) : ExecutionContext {
override fun isNewDelegate(): Boolean { override fun isNewDelegate(): Boolean {
return context.getData(NEW_DELEGATE) ?: false return context.getData(NEW_DELEGATE) ?: false
} }
override fun withOldDelegate(editor: VimEditor): ExecutionContext {
val context1 = EditorDataContext((editor as IjVimEditor).editor, context)
context1.newTypingDelegate = false
return IjExecutionContext(context1)
}
} }
val DataContext.vim val DataContext.vim

View File

@ -111,6 +111,7 @@ class KeyHandler {
allowKeyMappings: Boolean, allowKeyMappings: Boolean,
mappingCompleted: Boolean, mappingCompleted: Boolean,
execute: Boolean = true, execute: Boolean = true,
directTyping: Boolean = false
): StateUpdateResult { ): StateUpdateResult {
LOG.trace { LOG.trace {
""" """
@ -186,7 +187,7 @@ class KeyHandler {
// If we are in insert/replace mode send this key in for processing // If we are in insert/replace mode send this key in for processing
if (editorState.mode == VimStateMachine.Mode.INSERT || editorState.mode == VimStateMachine.Mode.REPLACE) { if (editorState.mode == VimStateMachine.Mode.INSERT || editorState.mode == VimStateMachine.Mode.REPLACE) {
LOG.trace("Process insert or replace") LOG.trace("Process insert or replace")
shouldRecord = injector.changeGroup.processKey(editor, context, key) && shouldRecord shouldRecord = injector.changeGroup.processKey(editor, context, key, directTyping) && shouldRecord
} else if (editorState.mode == VimStateMachine.Mode.SELECT) { } else if (editorState.mode == VimStateMachine.Mode.SELECT) {
LOG.trace("Process select") LOG.trace("Process select")
shouldRecord = injector.changeGroup.processKeyInSelectMode(editor, context, key) && shouldRecord shouldRecord = injector.changeGroup.processKeyInSelectMode(editor, context, key) && shouldRecord

View File

@ -28,6 +28,7 @@ interface ExecutionContext {
// TODO: 10.02.2022 Not sure about this method // TODO: 10.02.2022 Not sure about this method
fun updateEditor(editor: VimEditor): ExecutionContext fun updateEditor(editor: VimEditor): ExecutionContext
fun isNewDelegate(): Boolean fun isNewDelegate(): Boolean
fun withOldDelegate(editor: VimEditor): ExecutionContext
} }
interface ExecutionContextManager { interface ExecutionContextManager {

View File

@ -79,7 +79,7 @@ interface VimChangeGroup {
operatorArguments: OperatorArguments operatorArguments: OperatorArguments
): Boolean ): Boolean
fun processKey(editor: VimEditor, context: ExecutionContext, key: KeyStroke): Boolean fun processKey(editor: VimEditor, context: ExecutionContext, key: KeyStroke, directTyping: Boolean): Boolean
fun processKeyInSelectMode(editor: VimEditor, context: ExecutionContext, key: KeyStroke): Boolean fun processKeyInSelectMode(editor: VimEditor, context: ExecutionContext, key: KeyStroke): Boolean
@ -199,5 +199,6 @@ interface VimChangeGroup {
) )
fun type(vimEditor: VimEditor, context: ExecutionContext, key: Char) fun type(vimEditor: VimEditor, context: ExecutionContext, key: Char)
fun typeDirectly(vimEditor: VimEditor, context: ExecutionContext, key: Char)
fun replaceText(editor: VimEditor, start: Int, end: Int, str: String) fun replaceText(editor: VimEditor, start: Int, end: Int, str: String)
} }

View File

@ -699,16 +699,25 @@ abstract class VimChangeGroupBase : VimChangeGroup {
editor: VimEditor, editor: VimEditor,
context: ExecutionContext, context: ExecutionContext,
key: KeyStroke, key: KeyStroke,
directTyping: Boolean,
): Boolean { ): Boolean {
logger.debug { "processKey($key)" } logger.debug { "processKey($key)" }
if (key.keyChar != KeyEvent.CHAR_UNDEFINED) { if (key.keyChar != KeyEvent.CHAR_UNDEFINED) {
type(editor, context, key.keyChar) if (directTyping) {
typeDirectly(editor, context, key.keyChar)
} else {
type(editor, context, key.keyChar)
}
return true return true
} }
// Shift-space // Shift-space
if (key.keyCode == 32 && key.modifiers and KeyEvent.SHIFT_DOWN_MASK != 0) { if (key.keyCode == 32 && key.modifiers and KeyEvent.SHIFT_DOWN_MASK != 0) {
type(editor, context, ' ') if (directTyping) {
typeDirectly(editor, context, ' ')
} else {
type(editor, context, ' ')
}
return true return true
} }
return false return false
@ -721,7 +730,7 @@ abstract class VimChangeGroupBase : VimChangeGroup {
): Boolean { ): Boolean {
var res: Boolean var res: Boolean
SelectionVimListenerSuppressor.lock().use { SelectionVimListenerSuppressor.lock().use {
res = processKey(editor, context, key) res = processKey(editor, context, key, false)
editor.exitSelectModeNative(false) editor.exitSelectModeNative(false)
KeyHandler.getInstance().reset(editor) KeyHandler.getInstance().reset(editor)
if (isPrintableChar(key.keyChar) || activeTemplateWithLeftRightMotion(editor, key)) { if (isPrintableChar(key.keyChar) || activeTemplateWithLeftRightMotion(editor, key)) {

View File

@ -87,18 +87,28 @@ sealed class ChangeEditorActionHandler : EditorActionHandlerBase(false) {
try { try {
when (this) { when (this) {
is ForEachCaret -> { is ForEachCaret -> {
editor.forEachNativeCaret( if (!context.isNewDelegate()) {
{ current -> editor.forEachNativeCaret(
if (!current.isValid) return@forEachNativeCaret { current ->
if (!execute(editor, current, context, cmd.argument, operatorArguments)) { if (!current.isValid) return@forEachNativeCaret
worked[0] = false if (!execute(editor, current, context, cmd.argument, operatorArguments)) {
} worked[0] = false
}, }
true },
) true
)
} else {
worked[0] = execute(editor, caret, context, cmd.argument, operatorArguments)
}
} }
is SingleExecution -> { is SingleExecution -> {
worked[0] = execute(editor, context, cmd.argument, operatorArguments) if (!context.isNewDelegate()) {
worked[0] = execute(editor, context, cmd.argument, operatorArguments)
} else {
if (caret == editor.primaryCaret()) {
worked[0] = execute(editor, context, cmd.argument, operatorArguments)
}
}
} }
} }
} catch (e: java.lang.Exception) { } catch (e: java.lang.Exception) {
@ -114,7 +124,9 @@ sealed class ChangeEditorActionHandler : EditorActionHandlerBase(false) {
if (worked[0]) { if (worked[0]) {
VimRepeater.saveLastChange(cmd) VimRepeater.saveLastChange(cmd)
VimRepeater.repeatHandler = false VimRepeater.repeatHandler = false
editor.forEachNativeCaret({ it.vimLastColumn = it.getVisualPosition().column }) editor.carets().forEach {
it.vimLastColumn = it.getVisualPosition().column
}
} }
val toSwitch = editor.vimChangeActionSwitchMode val toSwitch = editor.vimChangeActionSwitchMode

View File

@ -96,7 +96,7 @@ class ToKeysMappingInfo(
override fun execute(editor: VimEditor, context: ExecutionContext) { override fun execute(editor: VimEditor, context: ExecutionContext) {
LOG.debug("Executing 'ToKeys' mapping info...") LOG.debug("Executing 'ToKeys' mapping info...")
val editorDataContext = injector.executionContextManager.onEditor(editor, context) val editorDataContext = injector.executionContextManager.onEditor(editor, context).withOldDelegate(editor)
val fromIsPrefix = KeyHandler.isPrefix(fromKeys, toKeys) val fromIsPrefix = KeyHandler.isPrefix(fromKeys, toKeys)
val keyHandler = KeyHandler.getInstance() val keyHandler = KeyHandler.getInstance()
keyHandler.keyStack.addKeys(toKeys) keyHandler.keyStack.addKeys(toKeys)
@ -104,7 +104,7 @@ class ToKeysMappingInfo(
while (keyHandler.keyStack.hasStroke()) { while (keyHandler.keyStack.hasStroke()) {
val keyStroke = keyHandler.keyStack.feedStroke() val keyStroke = keyHandler.keyStack.feedStroke()
val recursive = isRecursive && !(first && fromIsPrefix) val recursive = isRecursive && !(first && fromIsPrefix)
keyHandler.handleKey(editor, keyStroke, editorDataContext, recursive, false) keyHandler.handleKey(editor, keyStroke, editorDataContext, recursive, false, directTyping = true)
first = false first = false
} }
keyHandler.keyStack.removeFirst() keyHandler.keyStack.removeFirst()