1
0
mirror of https://github.com/chylex/IntelliJ-IdeaVim.git synced 2024-10-19 04:42:46 +02:00

Compare commits

...

4 Commits

9 changed files with 169 additions and 38 deletions

View File

@ -11,7 +11,7 @@
ideaVersion=2023.3.2
downloadIdeaSources=true
instrumentPluginCode=true
version=chylex-1
version=chylex-24
javaVersion=17
remoteRobotVersion=0.11.21
antlrVersion=4.10.1

View File

@ -78,7 +78,6 @@ import java.math.BigInteger
import java.util.*
import java.util.function.Consumer
import kotlin.math.max
import kotlin.math.min
/**
* Provides all the insert/replace related functionality
@ -395,6 +394,7 @@ public class ChangeGroup : VimChangeGroupBase() {
context: ExecutionContext,
range: TextRange,
) {
val startPos = editor.offsetToBufferPosition(caret.offset.point)
val startOffset = editor.getLineStartForOffset(range.startOffset)
val endOffset = editor.getLineEndForOffset(range.endOffset)
val ijEditor = (editor as IjVimEditor).editor
@ -419,11 +419,7 @@ public class ChangeGroup : VimChangeGroupBase() {
}
}
val afterAction = {
val firstLine = editor.offsetToBufferPosition(
min(startOffset.toDouble(), endOffset.toDouble()).toInt()
).line
val newOffset = injector.motion.moveCaretToLineStartSkipLeading(editor, firstLine)
caret.moveToOffset(newOffset)
caret.moveToOffset(injector.motion.moveCaretToLineStartSkipLeading(editor, startPos.line))
restoreCursor(editor, caret, (caret as IjVimCaret).caret.logicalPosition.line)
}
if (project != null) {

View File

@ -9,6 +9,7 @@
package com.maddyhome.idea.vim.helper;
import com.google.common.collect.Lists;
import com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerEx;
import com.intellij.lang.CodeDocumentationAwareCommenter;
import com.intellij.lang.Commenter;
import com.intellij.lang.Language;
@ -16,15 +17,15 @@ import com.intellij.lang.LanguageCommenters;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Caret;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiComment;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.spellchecker.SpellCheckerSeveritiesProvider;
import com.maddyhome.idea.vim.VimPlugin;
import com.maddyhome.idea.vim.api.EngineEditorHelperKt;
import com.maddyhome.idea.vim.api.VimEditor;
import com.maddyhome.idea.vim.state.mode.Mode;
import com.maddyhome.idea.vim.state.VimStateMachine;
import com.maddyhome.idea.vim.common.CharacterPosition;
import com.maddyhome.idea.vim.common.Direction;
import com.maddyhome.idea.vim.common.TextRange;
@ -32,6 +33,12 @@ import com.maddyhome.idea.vim.newapi.IjVimCaret;
import com.maddyhome.idea.vim.newapi.IjVimEditor;
import com.maddyhome.idea.vim.regexp.CharPointer;
import com.maddyhome.idea.vim.regexp.RegExp;
import com.maddyhome.idea.vim.state.VimStateMachine;
import com.maddyhome.idea.vim.state.mode.Mode;
import it.unimi.dsi.fastutil.ints.IntComparator;
import it.unimi.dsi.fastutil.ints.IntIterator;
import it.unimi.dsi.fastutil.ints.IntRBTreeSet;
import it.unimi.dsi.fastutil.ints.IntSortedSet;
import kotlin.Pair;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
@ -1523,6 +1530,42 @@ public class SearchHelper {
return PsiHelper.findMethodEnd(editor, caret.getOffset(), count);
}
public static int findMisspelledWords(@NotNull Editor editor,
int startOffset,
int endOffset,
int skipCount,
IntComparator offsetOrdering) {
Project project = editor.getProject();
if (project == null) {
return -1;
}
IntSortedSet offsets = new IntRBTreeSet(offsetOrdering);
DaemonCodeAnalyzerEx.processHighlights(editor.getDocument(), project, SpellCheckerSeveritiesProvider.TYPO,
startOffset, endOffset, highlight -> {
if (highlight.getSeverity() == SpellCheckerSeveritiesProvider.TYPO) {
int offset = highlight.getStartOffset();
if (offset >= startOffset && offset <= endOffset) {
offsets.add(offset);
}
}
return true;
});
if (offsets.isEmpty()) {
return -1;
}
if (skipCount >= offsets.size()) {
return offsets.lastInt();
}
else {
IntIterator offsetIterator = offsets.iterator();
offsetIterator.skip(skipCount);
return offsetIterator.nextInt();
}
}
private static @NotNull String parseMatchPairsOption(final VimEditor vimEditor) {
List<String> pairs = options(injector, vimEditor).getMatchpairs();
StringBuilder res = new StringBuilder();

View File

@ -95,41 +95,43 @@ internal object IdeaSpecifics {
if (VimPlugin.isNotEnabled()) return
val editor = editor
if (editor != null && action is ChooseItemAction && editor.vimStateMachine?.isRecording == true) {
val prevDocumentLength = completionPrevDocumentLength
val prevDocumentOffset = completionPrevDocumentOffset
if (editor != null) {
if (action is ChooseItemAction && editor.vimStateMachine?.isRecording == true) {
val prevDocumentLength = completionPrevDocumentLength
val prevDocumentOffset = completionPrevDocumentOffset
if (prevDocumentLength != null && prevDocumentOffset != null) {
val register = VimPlugin.getRegister()
val addedTextLength = editor.document.textLength - prevDocumentLength
val caretShift = addedTextLength - (editor.caretModel.primaryCaret.offset - prevDocumentOffset)
val leftArrow = KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0)
if (prevDocumentLength != null && prevDocumentOffset != null) {
val register = VimPlugin.getRegister()
val addedTextLength = editor.document.textLength - prevDocumentLength
val caretShift = addedTextLength - (editor.caretModel.primaryCaret.offset - prevDocumentOffset)
val leftArrow = KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0)
register.recordText(editor.document.getText(TextRange(prevDocumentOffset, prevDocumentOffset + addedTextLength)))
repeat(caretShift.coerceAtLeast(0)) {
register.recordKeyStroke(leftArrow)
register.recordText(editor.document.getText(TextRange(prevDocumentOffset, prevDocumentOffset + addedTextLength)))
repeat(caretShift.coerceAtLeast(0)) {
register.recordKeyStroke(leftArrow)
}
}
}
this.completionPrevDocumentLength = null
this.completionPrevDocumentOffset = null
}
//region Enter insert mode after surround with if
if (surrounderAction == action.javaClass.name && surrounderItems.any {
action.templatePresentation.text.endsWith(
it,
)
this.completionPrevDocumentLength = null
this.completionPrevDocumentOffset = null
}
) {
editor?.let {
val commandState = it.vim.vimStateMachine
//region Enter insert mode after surround with if
if (surrounderAction == action.javaClass.name && surrounderItems.any {
action.templatePresentation.text.endsWith(
it,
)
}
) {
val commandState = editor.vim.vimStateMachine
commandState.mode = Mode.NORMAL()
VimPlugin.getChange().insertBeforeCursor(it.vim, event.dataContext.vim)
KeyHandler.getInstance().reset(it.vim)
VimPlugin.getChange().insertBeforeCursor(editor.vim, event.dataContext.vim)
KeyHandler.getInstance().reset(editor.vim)
}
//endregion
injector.scroll.scrollCaretIntoView(editor.vim)
}
//endregion
this.editor = null
}

View File

@ -15,6 +15,8 @@ import com.maddyhome.idea.vim.api.VimSearchHelperBase
import com.maddyhome.idea.vim.common.TextRange
import com.maddyhome.idea.vim.helper.SearchHelper
import com.maddyhome.idea.vim.helper.SearchOptions
import it.unimi.dsi.fastutil.ints.IntComparator
import it.unimi.dsi.fastutil.ints.IntComparators
import java.util.*
@Service
@ -93,4 +95,26 @@ internal class IjVimSearchHelper : VimSearchHelperBase() {
): TextRange? {
return SearchHelper.findBlockRange(editor.ij, caret.ij, type, count, isOuter)
}
override fun findMisspelledWord(editor: VimEditor, caret: ImmutableVimCaret, count: Int): Int {
val startOffset: Int
val endOffset: Int
val skipCount: Int
val offsetOrdering: IntComparator
if (count < 0) {
startOffset = 0
endOffset = caret.offset.point - 1
skipCount = -count - 1
offsetOrdering = IntComparators.OPPOSITE_COMPARATOR
}
else {
startOffset = caret.offset.point + 1
endOffset = editor.ij.document.textLength
skipCount = count - 1
offsetOrdering = IntComparators.NATURAL_COMPARATOR
}
return SearchHelper.findMisspelledWords(editor.ij, startOffset, endOffset, skipCount, offsetOrdering)
}
}

View File

@ -333,7 +333,7 @@
* |[m| {@link com.maddyhome.idea.vim.action.motion.text.MotionMethodPreviousStartAction}
* |[p| {@link com.maddyhome.idea.vim.action.copy.PutVisualTextAfterCursorNoIndentAction}
* |[p| {@link com.maddyhome.idea.vim.action.copy.PutTextAfterCursorNoIndentAction}
* |[s| TO BE IMPLEMENTED
* |[s| {@link com.maddyhome.idea.vim.action.motion.text.MotionMisspelledWordPreviousAction}
* |[z| TO BE IMPLEMENTED
* |[{| {@link com.maddyhome.idea.vim.action.motion.text.MotionUnmatchedBraceOpenAction}
* |]_CTRL-D| TO BE IMPLEMENTED
@ -358,7 +358,7 @@
* |]m| {@link com.maddyhome.idea.vim.action.motion.text.MotionMethodNextStartAction}
* |]p| {@link com.maddyhome.idea.vim.action.copy.PutVisualTextAfterCursorNoIndentAction}
* |]p| {@link com.maddyhome.idea.vim.action.copy.PutTextAfterCursorNoIndentAction}
* |]s| TO BE IMPLEMENTED
* |]s| {@link com.maddyhome.idea.vim.action.motion.text.MotionMisspelledWordNextAction}
* |]z| TO BE IMPLEMENTED
* |]}| {@link com.maddyhome.idea.vim.action.motion.text.MotionUnmatchedBraceCloseAction}
*

View File

@ -94,6 +94,8 @@
<vimAction implementation="com.maddyhome.idea.vim.action.motion.text.MotionMethodPreviousStartAction" mappingModes="NXO" keys="[m"/>
<vimAction implementation="com.maddyhome.idea.vim.action.motion.text.MotionMethodNextEndAction" mappingModes="NXO" keys="]M"/>
<vimAction implementation="com.maddyhome.idea.vim.action.motion.text.MotionMethodNextStartAction" mappingModes="NXO" keys="]m"/>
<vimAction implementation="com.maddyhome.idea.vim.action.motion.text.MotionMisspelledWordPreviousAction" mappingModes="NXO" keys="[s"/>
<vimAction implementation="com.maddyhome.idea.vim.action.motion.text.MotionMisspelledWordNextAction" mappingModes="NXO" keys="]s"/>
<!-- Text Objects -->
<vimAction implementation="com.maddyhome.idea.vim.action.motion.object.MotionOuterWordAction" mappingModes="XO" keys="aw"/>
<vimAction implementation="com.maddyhome.idea.vim.action.motion.object.MotionOuterBigWordAction" mappingModes="XO" keys="aW"/>

View File

@ -0,0 +1,58 @@
/*
* Copyright 2003-2023 The IdeaVim authors
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE.txt file or at
* https://opensource.org/licenses/MIT.
*/
package com.maddyhome.idea.vim.action.motion.text
import com.intellij.vim.annotations.CommandOrMotion
import com.intellij.vim.annotations.Mode
import com.maddyhome.idea.vim.api.ExecutionContext
import com.maddyhome.idea.vim.api.ImmutableVimCaret
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.CommandFlags
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.toMotionOrError
import com.maddyhome.idea.vim.helper.enumSetOf
import java.util.*
@CommandOrMotion(keys = ["]s"], modes = [Mode.NORMAL, Mode.VISUAL, Mode.OP_PENDING])
public class MotionMisspelledWordNextAction : MotionActionHandler.ForEachCaret() {
override val flags: EnumSet<CommandFlags> = enumSetOf(CommandFlags.FLAG_SAVE_JUMP)
override fun getOffset(
editor: VimEditor,
caret: ImmutableVimCaret,
context: ExecutionContext,
argument: Argument?,
operatorArguments: OperatorArguments,
): Motion {
return injector.searchHelper.findMisspelledWord(editor, caret, operatorArguments.count1).toMotionOrError()
}
override val motionType: MotionType = MotionType.EXCLUSIVE
}
@CommandOrMotion(keys = ["[s"], modes = [Mode.NORMAL, Mode.VISUAL, Mode.OP_PENDING])
public class MotionMisspelledWordPreviousAction : MotionActionHandler.ForEachCaret() {
override val flags: EnumSet<CommandFlags> = enumSetOf(CommandFlags.FLAG_SAVE_JUMP)
override fun getOffset(
editor: VimEditor,
caret: ImmutableVimCaret,
context: ExecutionContext,
argument: Argument?,
operatorArguments: OperatorArguments,
): Motion {
return injector.searchHelper.findMisspelledWord(editor, caret, -operatorArguments.count1).toMotionOrError()
}
override val motionType: MotionType = MotionType.EXCLUSIVE
}

View File

@ -197,4 +197,10 @@ public interface VimSearchHelper {
count: Int,
isOuter: Boolean,
): TextRange?
public fun findMisspelledWord(
editor: VimEditor,
caret: ImmutableVimCaret,
count: Int,
): Int
}