1
0
mirror of https://github.com/chylex/IntelliJ-IdeaVim.git synced 2025-08-17 16:31:45 +02:00

Compare commits

...

8 Commits

Author SHA1 Message Date
9f469d0eb2 Set plugin version to chylex-13 2022-10-24 02:18:35 +02:00
f59d2f769c Stop IdeaVIM blocking editor scrolling 2022-10-24 02:18:35 +02:00
dc00b59733 Change matchit plugin to use HTML patterns in unrecognized files 2022-10-24 02:11:31 +02:00
bc20e6af9c Fix vim-surround not working with multiple cursors
Fixes multiple cursors with vim-surround commands `cs, ds, S` (but not `ys`).

 Conflicts:
	src/main/java/com/maddyhome/idea/vim/extension/surround/VimSurroundExtension.kt
2022-10-24 02:09:43 +02:00
c40f07714a Add VimScript 'renaming()' function 2022-10-24 02:04:59 +02:00
fa68842c2d Add support for repeatable actions with ':raction' 2022-10-24 02:04:59 +02:00
eca9258607 Disable taking over arrow keys and Home/End 2022-10-24 02:04:26 +02:00
46fb030977 Set custom plugin version 2022-10-24 02:04:25 +02:00
10 changed files with 145 additions and 24 deletions

View File

@@ -1,14 +1,13 @@
# suppress inspection "UnusedProperty" for whole file
ideaVersion=LATEST-EAP-SNAPSHOT
ideaVersion=2022.2.2
downloadIdeaSources=true
instrumentPluginCode=true
version=SNAPSHOT
version=chylex-13
javaVersion=17
remoteRobotVersion=0.11.15
antlrVersion=4.10.1
# Please don't forget to update kotlin version in buildscript section
kotlinVersion=1.6.21
publishToken=token

View File

@@ -154,6 +154,10 @@ class VimShortcutKeyAction : AnAction(), DumbAware/*, LightEditCompatible*/ {
if ((keyCode == KeyEvent.VK_TAB || keyCode == KeyEvent.VK_ENTER) && editor.appCodeTemplateCaptured()) return false
if (keyCode == KeyEvent.VK_LEFT || keyCode == KeyEvent.VK_RIGHT) return false
if (keyCode == KeyEvent.VK_UP || keyCode == KeyEvent.VK_DOWN) return false
if (keyCode == KeyEvent.VK_HOME || keyCode == KeyEvent.VK_END) return false
if (editor.inInsertMode) {
if (keyCode == KeyEvent.VK_TAB) {
// TODO: This stops VimEditorTab seeing <Tab> in insert mode and correctly scrolling the view

View File

@@ -233,7 +233,7 @@ private object FileTypePatterns {
} else if (fileTypeName == "CMakeLists.txt" || fileName == "CMakeLists") {
this.cMakePatterns
} else {
return null
this.htmlPatterns
}
}

View File

@@ -22,6 +22,7 @@ import com.intellij.openapi.editor.Editor
import com.maddyhome.idea.vim.VimPlugin
import com.maddyhome.idea.vim.api.ExecutionContext
import com.maddyhome.idea.vim.api.VimCaret
import com.maddyhome.idea.vim.api.VimChangeGroup
import com.maddyhome.idea.vim.api.VimEditor
import com.maddyhome.idea.vim.api.injector
import com.maddyhome.idea.vim.command.MappingMode
@@ -39,6 +40,7 @@ import com.maddyhome.idea.vim.extension.VimExtensionFacade.putKeyMappingIfMissin
import com.maddyhome.idea.vim.extension.VimExtensionFacade.setOperatorFunction
import com.maddyhome.idea.vim.extension.VimExtensionFacade.setRegisterForCaret
import com.maddyhome.idea.vim.helper.editorMode
import com.maddyhome.idea.vim.helper.runWithEveryCaretAndRestore
import com.maddyhome.idea.vim.key.OperatorFunction
import com.maddyhome.idea.vim.newapi.IjVimCaret
import com.maddyhome.idea.vim.newapi.IjVimEditor
@@ -84,22 +86,20 @@ class VimSurroundExtension : VimExtension {
override val isRepeatable = true
override fun execute(editor: VimEditor, context: ExecutionContext) {
setOperatorFunction(Operator())
setOperatorFunction(Operator(supportsMultipleCursors = false)) // TODO
executeNormalWithoutMapping(injector.parser.parseKeys("g@"), editor.ij)
}
}
private class VSurroundHandler : ExtensionHandler {
override fun execute(editor: VimEditor, context: ExecutionContext) {
val selectionStart = editor.ij.caretModel.primaryCaret.selectionStart
// NB: Operator ignores SelectionType anyway
if (!Operator().apply(editor, context, SelectionType.CHARACTER_WISE)) {
if (!Operator(supportsMultipleCursors = true).apply(editor, context, SelectionType.CHARACTER_WISE)) {
return
}
runWriteAction {
// Leave visual mode
executeNormalWithoutMapping(injector.parser.parseKeys("<Esc>"), editor.ij)
editor.ij.caretModel.moveToOffset(selectionStart)
}
}
}
@@ -120,6 +120,10 @@ class VimSurroundExtension : VimExtension {
companion object {
fun change(editor: VimEditor, context: ExecutionContext, charFrom: Char, newSurround: Pair<String, String>?) {
editor.ij.runWithEveryCaretAndRestore { changeAtCaret(editor, context, charFrom, newSurround) }
}
fun changeAtCaret(editor: VimEditor, context: ExecutionContext, charFrom: Char, newSurround: Pair<String, String>?) {
// Save old register values for carets
val surroundings = editor.sortedCarets()
.map {
@@ -218,27 +222,45 @@ class VimSurroundExtension : VimExtension {
}
}
private class Operator : OperatorFunction {
private class Operator(private val supportsMultipleCursors: Boolean) : OperatorFunction {
override fun apply(vimEditor: VimEditor, context: ExecutionContext, selectionType: SelectionType): Boolean {
val editor = vimEditor.ij
val c = getChar(editor)
if (c.code == 0) return true
val pair = getOrInputPair(c, editor) ?: return false
// XXX: Will it work with line-wise or block-wise selections?
val range = getSurroundRange(editor) ?: return false
runWriteAction {
val change = VimPlugin.getChange()
val leftSurround = pair.first
val primaryCaret = editor.caretModel.primaryCaret
change.insertText(IjVimEditor(editor), IjVimCaret(primaryCaret), range.startOffset, leftSurround)
change.insertText(IjVimEditor(editor), IjVimCaret(primaryCaret), range.endOffset + leftSurround.length, pair.second)
if (supportsMultipleCursors) {
editor.runWithEveryCaretAndRestore {
applyOnce(editor, change, pair)
}
}
else {
applyOnce(editor, change, pair)
// Jump back to start
executeNormalWithoutMapping(injector.parser.parseKeys("`["), editor)
}
}
return true
}
private fun applyOnce(editor: Editor, change: VimChangeGroup, pair: Pair<String, String>) {
// XXX: Will it work with line-wise or block-wise selections?
val range = getSurroundRange(editor)
if (range != null) {
val primaryCaret = editor.caretModel.primaryCaret
change.insertText(IjVimEditor(editor), IjVimCaret(primaryCaret), range.startOffset, pair.first)
change.insertText(
IjVimEditor(editor),
IjVimCaret(primaryCaret),
range.endOffset + pair.first.length,
pair.second
)
}
}
private fun getSurroundRange(editor: Editor): TextRange? = when (editor.editorMode) {
VimStateMachine.Mode.COMMAND -> VimPlugin.getMark().getChangeMarks(editor.vim)
VimStateMachine.Mode.VISUAL -> editor.caretModel.primaryCaret.run { TextRange(selectionStart, selectionEnd) }

View File

@@ -232,7 +232,7 @@ public class EditorGroup implements PersistentStateComponent<Element>, VimEditor
KeyHandler.getInstance().reset(new IjVimEditor(editor));
}
updateCaretsVisualAttributes(editor);
editor.getSettings().setRefrainFromScrolling(REFRAIN_FROM_SCROLLING_VIM_VALUE);
//editor.getSettings().setRefrainFromScrolling(REFRAIN_FROM_SCROLLING_VIM_VALUE);
}
public void editorDeinit(@NotNull Editor editor, boolean isReleased) {

View File

@@ -92,7 +92,7 @@ public class ProcessGroup extends VimProcessGroupBase {
String initText = getRange(((IjVimEditor) editor).getEditor(), cmd);
VimStateMachine.getInstance(editor).pushModes(VimStateMachine.Mode.CMD_LINE, VimStateMachine.SubMode.NONE);
ExEntryPanel panel = ExEntryPanel.getInstance();
panel.activate(((IjVimEditor) editor).getEditor(), ((IjExecutionContext) context).getContext(), ":", initText, 1);
panel.activate(((IjVimEditor) editor).getEditor(), ((IjExecutionContext) context).getContext(), ":", initText, cmd.getCount());
}
@Override
@@ -123,7 +123,7 @@ public class ProcessGroup extends VimProcessGroupBase {
logger.debug("processing command");
final String text = panel.getText();
String text = panel.getText();
if (!panel.getLabel().equals(":")) {
// Search is handled via Argument.Type.EX_STRING. Although ProcessExEntryAction is registered as the handler for
@@ -134,8 +134,16 @@ public class ProcessGroup extends VimProcessGroupBase {
if (logger.isDebugEnabled()) logger.debug("swing=" + SwingUtilities.isEventDispatchThread());
int repeat = 1;
if (text.contains("raction ")) {
text = text.replace("raction ", "action ");
repeat = panel.getCount();
}
for (int i = 0; i < repeat; i++) {
VimInjectorKt.getInjector().getVimscriptExecutor().execute(text, editor, context, skipHistory(editor), true, CommandLineVimLContext.INSTANCE);
}
}
catch (ExException e) {
VimPlugin.showMessage(e.getMessage());
VimPlugin.indicateError();

View File

@@ -22,6 +22,7 @@ package com.maddyhome.idea.vim.helper
import com.intellij.codeWithMe.ClientId
import com.intellij.openapi.editor.Caret
import com.intellij.openapi.editor.CaretState
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.editor.ex.util.EditorUtil
import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx
@@ -106,3 +107,41 @@ val Caret.vimLine: Int
*/
val Editor.vimLine: Int
get() = this.caretModel.currentCaret.vimLine
inline fun Editor.runWithEveryCaretAndRestore(action: () -> Unit) {
val caretModel = this.caretModel
val carets = if (this.inBlockSubMode) null else caretModel.allCarets
if (carets == null || carets.size == 1) {
action()
}
else {
var initialDocumentSize = this.document.textLength
var documentSizeDifference = 0
val caretOffsets = carets.map { it.selectionStart to it.selectionEnd }
val restoredCarets = mutableListOf<CaretState>()
caretModel.removeSecondaryCarets()
for ((selectionStart, selectionEnd) in caretOffsets) {
if (selectionStart == selectionEnd) {
caretModel.primaryCaret.moveToOffset(selectionStart + documentSizeDifference)
}
else {
caretModel.primaryCaret.setSelection(
selectionStart + documentSizeDifference,
selectionEnd + documentSizeDifference
)
}
action()
restoredCarets.add(caretModel.caretsAndSelections.single())
val documentLength = this.document.textLength
documentSizeDifference += documentLength - initialDocumentSize
initialDocumentSize = documentLength
}
caretModel.caretsAndSelections = restoredCarets
}
}

View File

@@ -0,0 +1,48 @@
/*
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
* Copyright (C) 2003-2021 The IdeaVim authors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.maddyhome.idea.vim.vimscript.model.functions.handlers
import com.intellij.refactoring.rename.inplace.InplaceRefactoring
import com.maddyhome.idea.vim.api.ExecutionContext
import com.maddyhome.idea.vim.api.VimEditor
import com.maddyhome.idea.vim.newapi.ij
import com.maddyhome.idea.vim.vimscript.model.VimLContext
import com.maddyhome.idea.vim.vimscript.model.datatypes.VimDataType
import com.maddyhome.idea.vim.vimscript.model.datatypes.VimInt
import com.maddyhome.idea.vim.vimscript.model.expressions.Expression
import com.maddyhome.idea.vim.vimscript.model.functions.FunctionHandler
object RenamingFunctionHandler : FunctionHandler() {
override val name = "renaming"
override val minimumNumberOfArguments = 0
override val maximumNumberOfArguments = 0
override fun doFunction(
argumentValues: List<Expression>,
editor: VimEditor,
context: ExecutionContext,
vimContext: VimLContext,
): VimDataType {
return if (InplaceRefactoring.getActiveInplaceRenamer(editor.ij) == null)
VimInt.ZERO
else
VimInt.ONE
}
}

View File

@@ -14,5 +14,6 @@
<vimLibraryFunction implementation="com.maddyhome.idea.vim.vimscript.model.functions.handlers.TolowerFunctionHandler" name="tolower"/>
<vimLibraryFunction implementation="com.maddyhome.idea.vim.vimscript.model.functions.handlers.ToupperFunctionHandler" name="toupper"/>
<vimLibraryFunction implementation="com.maddyhome.idea.vim.vimscript.model.functions.handlers.JoinFunctionHandler" name="join"/>
<vimLibraryFunction implementation="com.maddyhome.idea.vim.vimscript.model.functions.handlers.RenamingFunctionHandler" name="renaming"/>
</extensions>
</idea-plugin>

View File

@@ -1,4 +1,4 @@
<idea-plugin url="https://plugins.jetbrains.com/plugin/164" xmlns:xi="http://www.w3.org/2001/XInclude">
<idea-plugin xmlns:xi="http://www.w3.org/2001/XInclude">
<name>IdeaVim</name>
<id>IdeaVIM</id>
<change-notes><![CDATA[
@@ -120,7 +120,7 @@
<li><a href="https://youtrack.jetbrains.com/issues/VIM">Issue tracker</a>: feature requests and bug reports</li>
</ul>
]]></description>
<version>SNAPSHOT</version>
<version>chylex</version>
<vendor>JetBrains</vendor>
<!-- Please search for "[VERSION UPDATE]" in project in case you update the since-build version -->