mirror of
https://github.com/chylex/IntelliJ-IdeaVim.git
synced 2025-08-18 10:31:44 +02:00
Compare commits
15 Commits
customized
...
customized
Author | SHA1 | Date | |
---|---|---|---|
4ca05ba6df
|
|||
114ac40990
|
|||
2829109eb7
|
|||
f1323139b4
|
|||
df4aa59310
|
|||
7a3bb5b2d7
|
|||
c4b05957fc
|
|||
db83b89931
|
|||
ce27c3e5ba
|
|||
31358bc983
|
|||
f7e1c9c837
|
|||
c46109caa3
|
|||
9f7ca83306
|
|||
b5761f20d2
|
|||
305c6d2bf9
|
@@ -11,7 +11,7 @@
|
||||
ideaVersion=2023.2
|
||||
downloadIdeaSources=true
|
||||
instrumentPluginCode=true
|
||||
version=chylex-18
|
||||
version=chylex-19
|
||||
javaVersion=17
|
||||
remoteRobotVersion=0.11.17
|
||||
antlrVersion=4.10.1
|
||||
|
@@ -163,10 +163,6 @@ internal class VimShortcutKeyAction : AnAction(), DumbAware/*, LightEditCompatib
|
||||
if ((keyCode == KeyEvent.VK_TAB || keyCode == KeyEvent.VK_ENTER) && editor.appCodeTemplateCaptured()) {
|
||||
return ActionEnableStatus.no("App code template is active", LogLevel.INFO)
|
||||
}
|
||||
|
||||
if (keyCode == KeyEvent.VK_LEFT || keyCode == KeyEvent.VK_RIGHT || keyCode == KeyEvent.VK_UP || keyCode == KeyEvent.VK_DOWN || keyCode == KeyEvent.VK_HOME || keyCode == KeyEvent.VK_END) {
|
||||
return ActionEnableStatus.no("Special keys", LogLevel.INFO)
|
||||
}
|
||||
|
||||
val nextTemplateVariableShortcuts = KeymapManager.getInstance().activeKeymap.getShortcuts(IdeActions.ACTION_EDITOR_NEXT_TEMPLATE_VARIABLE)
|
||||
if (nextTemplateVariableShortcuts.any { it is KeyboardShortcut && it.firstKeyStroke == keyStroke }) {
|
||||
@@ -394,4 +390,4 @@ private class ActionEnableStatus(
|
||||
|
||||
private enum class LogLevel {
|
||||
DEBUG, INFO,
|
||||
}
|
||||
}
|
@@ -0,0 +1,30 @@
|
||||
package com.maddyhome.idea.vim.extension.surround
|
||||
|
||||
import com.intellij.util.text.CharSequenceSubSequence
|
||||
|
||||
internal data class RepeatedCharSequence(val text: CharSequence, val count: Int) : CharSequence {
|
||||
override val length = text.length * count
|
||||
|
||||
override fun get(index: Int): Char {
|
||||
if (index < 0 || index >= length) throw IndexOutOfBoundsException()
|
||||
return text[index % text.length]
|
||||
}
|
||||
|
||||
override fun subSequence(startIndex: Int, endIndex: Int): CharSequence {
|
||||
return CharSequenceSubSequence(this, startIndex, endIndex)
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return text.repeat(count)
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun of(text: CharSequence, count: Int): CharSequence {
|
||||
return when (count) {
|
||||
0 -> ""
|
||||
1 -> text
|
||||
else -> RepeatedCharSequence(text, count)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -19,10 +19,7 @@ import com.maddyhome.idea.vim.api.getLeadingCharacterOffset
|
||||
import com.maddyhome.idea.vim.api.injector
|
||||
import com.maddyhome.idea.vim.api.setChangeMarks
|
||||
import com.maddyhome.idea.vim.command.MappingMode
|
||||
import com.maddyhome.idea.vim.state.mode.Mode
|
||||
import com.maddyhome.idea.vim.command.OperatorArguments
|
||||
import com.maddyhome.idea.vim.state.mode.SelectionType
|
||||
import com.maddyhome.idea.vim.state.mode.selectionType
|
||||
import com.maddyhome.idea.vim.common.TextRange
|
||||
import com.maddyhome.idea.vim.extension.ExtensionHandler
|
||||
import com.maddyhome.idea.vim.extension.VimExtension
|
||||
@@ -34,7 +31,6 @@ import com.maddyhome.idea.vim.extension.VimExtensionFacade.putExtensionHandlerMa
|
||||
import com.maddyhome.idea.vim.extension.VimExtensionFacade.putKeyMappingIfMissing
|
||||
import com.maddyhome.idea.vim.extension.VimExtensionFacade.setOperatorFunction
|
||||
import com.maddyhome.idea.vim.extension.VimExtensionFacade.setRegisterForCaret
|
||||
import com.maddyhome.idea.vim.state.mode.mode
|
||||
import com.maddyhome.idea.vim.helper.runWithEveryCaretAndRestore
|
||||
import com.maddyhome.idea.vim.key.OperatorFunction
|
||||
import com.maddyhome.idea.vim.newapi.IjVimCaret
|
||||
@@ -43,6 +39,10 @@ import com.maddyhome.idea.vim.newapi.ij
|
||||
import com.maddyhome.idea.vim.newapi.vim
|
||||
import com.maddyhome.idea.vim.options.helpers.ClipboardOptionHelper
|
||||
import com.maddyhome.idea.vim.put.PutData
|
||||
import com.maddyhome.idea.vim.state.mode.Mode
|
||||
import com.maddyhome.idea.vim.state.mode.SelectionType
|
||||
import com.maddyhome.idea.vim.state.mode.mode
|
||||
import com.maddyhome.idea.vim.state.mode.selectionType
|
||||
import org.jetbrains.annotations.NonNls
|
||||
import java.awt.event.KeyEvent
|
||||
import javax.swing.KeyStroke
|
||||
@@ -83,7 +83,7 @@ internal class VimSurroundExtension : VimExtension {
|
||||
override val isRepeatable = true
|
||||
|
||||
override fun execute(editor: VimEditor, context: ExecutionContext, operatorArguments: OperatorArguments) {
|
||||
setOperatorFunction(Operator(supportsMultipleCursors = false)) // TODO
|
||||
setOperatorFunction(Operator(supportsMultipleCursors = false, count = 1)) // TODO
|
||||
executeNormalWithoutMapping(injector.parser.parseKeys("g@"), editor.ij)
|
||||
}
|
||||
}
|
||||
@@ -104,7 +104,7 @@ internal class VimSurroundExtension : VimExtension {
|
||||
val lastNonWhiteSpaceOffset = getLastNonWhitespaceCharacterOffset(editor.text(), lineStartOffset, lineEndOffset)
|
||||
if (lastNonWhiteSpaceOffset != null) {
|
||||
val range = TextRange(lineStartOffset, lastNonWhiteSpaceOffset + 1)
|
||||
performSurround(pair, range, it)
|
||||
performSurround(pair, range, it, count = operatorArguments.count1)
|
||||
}
|
||||
// it.moveToOffset(lineStartOffset)
|
||||
}
|
||||
@@ -125,7 +125,7 @@ internal class VimSurroundExtension : VimExtension {
|
||||
private class VSurroundHandler : ExtensionHandler {
|
||||
override fun execute(editor: VimEditor, context: ExecutionContext, operatorArguments: OperatorArguments) {
|
||||
// NB: Operator ignores SelectionType anyway
|
||||
if (!Operator(supportsMultipleCursors = true).apply(editor, context, editor.mode.selectionType)) {
|
||||
if (!Operator(supportsMultipleCursors = true, count = operatorArguments.count1).apply(editor, context, editor.mode.selectionType)) {
|
||||
return
|
||||
}
|
||||
runWriteAction {
|
||||
@@ -261,7 +261,7 @@ internal class VimSurroundExtension : VimExtension {
|
||||
}
|
||||
}
|
||||
|
||||
private class Operator(private val supportsMultipleCursors: Boolean) : OperatorFunction {
|
||||
private class Operator(private val supportsMultipleCursors: Boolean, private val count: Int) : OperatorFunction {
|
||||
override fun apply(vimEditor: VimEditor, context: ExecutionContext, selectionType: SelectionType?): Boolean {
|
||||
val editor = vimEditor.ij
|
||||
val c = getChar(editor)
|
||||
@@ -273,11 +273,11 @@ internal class VimSurroundExtension : VimExtension {
|
||||
val change = VimPlugin.getChange()
|
||||
if (supportsMultipleCursors) {
|
||||
editor.runWithEveryCaretAndRestore {
|
||||
applyOnce(editor, change, pair)
|
||||
applyOnce(editor, change, pair, count)
|
||||
}
|
||||
}
|
||||
else {
|
||||
applyOnce(editor, change, pair)
|
||||
applyOnce(editor, change, pair, count)
|
||||
// Jump back to start
|
||||
executeNormalWithoutMapping(injector.parser.parseKeys("`["), editor)
|
||||
}
|
||||
@@ -285,18 +285,15 @@ internal class VimSurroundExtension : VimExtension {
|
||||
return true
|
||||
}
|
||||
|
||||
private fun applyOnce(editor: Editor, change: VimChangeGroup, pair: Pair<String, String>) {
|
||||
private fun applyOnce(editor: Editor, change: VimChangeGroup, pair: Pair<String, String>, count: Int) {
|
||||
// XXX: Will it work with line-wise or block-wise selections?
|
||||
val primaryCaret = editor.caretModel.primaryCaret
|
||||
val range = getSurroundRange(primaryCaret.vim)
|
||||
if (range != null) {
|
||||
change.insertText(IjVimEditor(editor), IjVimCaret(primaryCaret), range.startOffset, pair.first)
|
||||
change.insertText(
|
||||
IjVimEditor(editor),
|
||||
IjVimCaret(primaryCaret),
|
||||
range.endOffset + pair.first.length,
|
||||
pair.second
|
||||
)
|
||||
val start = RepeatedCharSequence.of(pair.first, count)
|
||||
val end = RepeatedCharSequence.of(pair.second, count)
|
||||
change.insertText(IjVimEditor(editor), IjVimCaret(primaryCaret), range.startOffset, start)
|
||||
change.insertText(IjVimEditor(editor), IjVimCaret(primaryCaret), range.endOffset + start.length, end)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -378,15 +375,15 @@ internal class VimSurroundExtension : VimExtension {
|
||||
}
|
||||
}
|
||||
|
||||
private fun performSurround(pair: Pair<String, String>, range: TextRange, caret: VimCaret, tagsOnNewLines: Boolean = false) {
|
||||
private fun performSurround(pair: Pair<String, String>, range: TextRange, caret: VimCaret, count: Int, tagsOnNewLines: Boolean = false) {
|
||||
runWriteAction {
|
||||
val editor = caret.editor
|
||||
val change = VimPlugin.getChange()
|
||||
val leftSurround = pair.first + if (tagsOnNewLines) "\n" else ""
|
||||
val leftSurround = RepeatedCharSequence.of(pair.first + if (tagsOnNewLines) "\n" else "", count)
|
||||
|
||||
val isEOF = range.endOffset == editor.text().length
|
||||
val hasNewLine = editor.endsWithNewLine()
|
||||
val rightSurround = if (tagsOnNewLines) {
|
||||
val rightSurround = (if (tagsOnNewLines) {
|
||||
if (isEOF && !hasNewLine) {
|
||||
"\n" + pair.second
|
||||
} else {
|
||||
@@ -394,7 +391,7 @@ internal class VimSurroundExtension : VimExtension {
|
||||
}
|
||||
} else {
|
||||
pair.second
|
||||
}
|
||||
}).let { RepeatedCharSequence.of(it, count) }
|
||||
|
||||
change.insertText(editor, caret, range.startOffset, leftSurround)
|
||||
change.insertText(editor, caret, range.endOffset + leftSurround.length, rightSurround)
|
||||
|
@@ -335,7 +335,7 @@ public class EditorHelper {
|
||||
|
||||
final int offset = y - ((screenHeight - lineHeight) / lineHeight / 2 * lineHeight);
|
||||
@NotNull final VimEditor editor1 = new IjVimEditor(editor);
|
||||
final int lastVisualLine = EngineEditorHelperKt.getVisualLineCount(editor1) - 1;
|
||||
final int lastVisualLine = EngineEditorHelperKt.getVisualLineCount(editor1) + editor.getSettings().getAdditionalLinesCount();
|
||||
final int offsetForLastLineAtBottom = getOffsetToScrollVisualLineToBottomOfScreen(editor, lastVisualLine);
|
||||
|
||||
// For `zz`, we want to use virtual space and move any line, including the last one, to the middle of the screen.
|
||||
|
@@ -14,7 +14,6 @@ import com.maddyhome.idea.vim.api.injector
|
||||
import com.maddyhome.idea.vim.api.normalizeVisualColumn
|
||||
import com.maddyhome.idea.vim.api.options
|
||||
import com.maddyhome.idea.vim.command.CommandFlags
|
||||
import com.maddyhome.idea.vim.state.VimStateMachine
|
||||
import com.maddyhome.idea.vim.helper.EditorHelper.getApproximateScreenHeight
|
||||
import com.maddyhome.idea.vim.helper.EditorHelper.getApproximateScreenWidth
|
||||
import com.maddyhome.idea.vim.helper.EditorHelper.getNonNormalizedVisualLineAtBottomOfScreen
|
||||
@@ -29,6 +28,7 @@ import com.maddyhome.idea.vim.helper.EditorHelper.scrollVisualLineToBottomOfScre
|
||||
import com.maddyhome.idea.vim.helper.EditorHelper.scrollVisualLineToMiddleOfScreen
|
||||
import com.maddyhome.idea.vim.helper.EditorHelper.scrollVisualLineToTopOfScreen
|
||||
import com.maddyhome.idea.vim.newapi.vim
|
||||
import com.maddyhome.idea.vim.state.VimStateMachine
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
import kotlin.math.roundToInt
|
||||
@@ -56,7 +56,7 @@ internal object ScrollViewHelper {
|
||||
// that this needs to be replaced as a more or less dumb line for line rewrite.
|
||||
val topLine = getVisualLineAtTopOfScreen(editor)
|
||||
val bottomLine = getVisualLineAtBottomOfScreen(editor)
|
||||
val lastLine = vimEditor.getVisualLineCount() - 1
|
||||
val lastLine = vimEditor.getVisualLineCount() + editor.settings.additionalLinesCount
|
||||
|
||||
// We need the non-normalised value here, so we can handle cases such as so=999 to keep the current line centred
|
||||
val scrollOffset = injector.options(vimEditor).scrolloff
|
||||
|
@@ -18,12 +18,12 @@ import com.intellij.openapi.diagnostic.logger
|
||||
import com.intellij.openapi.editor.Document
|
||||
import com.intellij.openapi.editor.toolbar.floating.AbstractFloatingToolbarProvider
|
||||
import com.intellij.openapi.editor.toolbar.floating.FloatingToolbarComponent
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager
|
||||
import com.intellij.openapi.project.DumbAwareAction
|
||||
import com.intellij.openapi.util.Disposer
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import com.maddyhome.idea.vim.api.VimrcFileState
|
||||
import com.maddyhome.idea.vim.api.injector
|
||||
import com.maddyhome.idea.vim.extension.VimExtensionRegistrar
|
||||
import com.maddyhome.idea.vim.helper.MessageHelper
|
||||
import com.maddyhome.idea.vim.icons.VimIcons
|
||||
import com.maddyhome.idea.vim.key.MappingOwner
|
||||
@@ -149,12 +149,14 @@ internal class ReloadVimRc : DumbAwareAction() {
|
||||
|
||||
override fun actionPerformed(e: AnActionEvent) {
|
||||
val editor = e.getData(PlatformDataKeys.EDITOR) ?: return
|
||||
FileDocumentManager.getInstance().saveDocumentAsIs(editor.document)
|
||||
injector.keyGroup.removeKeyMapping(MappingOwner.IdeaVim.InitScript)
|
||||
Troubleshooter.instance.removeByType("old-action-notation-in-mappings")
|
||||
|
||||
// Reload the ideavimrc in the context of the current window, as though we had called `:source ~/.ideavimrc`
|
||||
executeIdeaVimRc(editor.vim)
|
||||
|
||||
// Ensure newly added extensions are initialized
|
||||
VimExtensionRegistrar.enableDelayedExtensions()
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -11,6 +11,8 @@ package com.maddyhome.idea.vim.vimscript
|
||||
import com.intellij.openapi.actionSystem.DataContext
|
||||
import com.intellij.openapi.components.Service
|
||||
import com.intellij.openapi.diagnostic.logger
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager
|
||||
import com.intellij.openapi.vfs.VirtualFileManager
|
||||
import com.maddyhome.idea.vim.VimPlugin
|
||||
import com.maddyhome.idea.vim.api.ExecutionContext
|
||||
import com.maddyhome.idea.vim.api.VimEditor
|
||||
@@ -88,12 +90,22 @@ internal class Executor : VimScriptExecutorBase() {
|
||||
override fun executeFile(file: File, editor: VimEditor, indicateErrors: Boolean) {
|
||||
val context = DataContext.EMPTY_CONTEXT.vim
|
||||
try {
|
||||
ensureFileIsSaved(file)
|
||||
execute(file.readText(), editor, context, skipHistory = true, indicateErrors)
|
||||
} catch (ignored: IOException) {
|
||||
LOG.error(ignored)
|
||||
}
|
||||
}
|
||||
|
||||
private fun ensureFileIsSaved(file: File) {
|
||||
val documentManager = FileDocumentManager.getInstance()
|
||||
|
||||
VirtualFileManager.getInstance().findFileByNioPath(file.toPath())
|
||||
?.let(documentManager::getCachedDocument)
|
||||
?.takeIf(documentManager::isDocumentUnsaved)
|
||||
?.let(documentManager::saveDocumentAsIs)
|
||||
}
|
||||
|
||||
@Throws(ExException::class)
|
||||
override fun executeLastCommand(editor: VimEditor, context: ExecutionContext): Boolean {
|
||||
val reg = VimPlugin.getRegister().getRegister(':') ?: return false
|
||||
|
@@ -134,5 +134,6 @@
|
||||
</group>
|
||||
|
||||
<action id="VimFindActionIdAction" class="com.maddyhome.idea.vim.listener.FindActionIdAction"/>
|
||||
<action id="VimJumpToSource" class="com.intellij.diff.actions.impl.OpenInEditorAction" />
|
||||
</actions>
|
||||
</idea-plugin>
|
||||
|
@@ -27,6 +27,7 @@ public class FilterVisualLinesAction : VimActionHandler.SingleExecution() {
|
||||
override val flags: EnumSet<CommandFlags> = enumSetOf(CommandFlags.FLAG_MOT_LINEWISE)
|
||||
|
||||
override fun execute(editor: VimEditor, context: ExecutionContext, cmd: Command, operatorArguments: OperatorArguments): Boolean {
|
||||
injector.markService.setVisualSelectionMarks(editor)
|
||||
injector.processGroup.startFilterCommand(editor, context, cmd)
|
||||
editor.exitVisualMode()
|
||||
return true
|
||||
|
@@ -144,7 +144,7 @@ public interface VimChangeGroup {
|
||||
operatorArguments: OperatorArguments,
|
||||
)
|
||||
|
||||
public fun insertText(editor: VimEditor, caret: VimCaret, offset: Int, str: String): VimCaret
|
||||
public fun insertText(editor: VimEditor, caret: VimCaret, offset: Int, str: CharSequence): VimCaret
|
||||
|
||||
public fun insertText(editor: VimEditor, caret: VimCaret, str: String): VimCaret
|
||||
|
||||
|
@@ -202,7 +202,7 @@ public abstract class VimChangeGroupBase : VimChangeGroup {
|
||||
* @param caret The caret to start insertion in
|
||||
* @param str The text to insert
|
||||
*/
|
||||
override fun insertText(editor: VimEditor, caret: VimCaret, offset: Int, str: String): VimCaret {
|
||||
override fun insertText(editor: VimEditor, caret: VimCaret, offset: Int, str: CharSequence): VimCaret {
|
||||
(editor as MutableVimEditor).insertText(Offset(offset), str)
|
||||
val newCaret = caret.moveToInlayAwareOffset(offset + str.length)
|
||||
|
||||
|
Reference in New Issue
Block a user