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:
parent
43a79dbad4
commit
c32c62eacc
src/main/java/com/maddyhome/idea/vim
vim-engine/src/main/kotlin/com/maddyhome/idea/vim
@ -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)
|
||||||
}
|
}
|
@ -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
|
||||||
|
@ -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();
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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 {
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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)) {
|
||||||
|
@ -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
|
||||||
|
@ -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()
|
||||||
|
Loading…
Reference in New Issue
Block a user