mirror of
				https://github.com/chylex/IntelliJ-IdeaVim.git
				synced 2025-10-31 20:17:13 +01:00 
			
		
		
		
	Compare commits
	
		
			8 Commits
		
	
	
		
			943ddeb5ab
			...
			customized
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 8a9d9af1bb | |||
| b52c331adf | |||
| dca254219a | |||
| c50b8cb5cd | |||
| 09a86c204d | |||
| afcbdf3326 | |||
| 663c92e1c5 | |||
| d9674494f5 | 
							
								
								
									
										1
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| * text=auto eol=lf | ||||
| @@ -8,15 +8,14 @@ | ||||
|  | ||||
| # suppress inspection "UnusedProperty" for whole file | ||||
|  | ||||
| ideaVersion=LATEST-EAP-SNAPSHOT | ||||
| ideaVersion=2022.3 | ||||
| downloadIdeaSources=true | ||||
| instrumentPluginCode=true | ||||
| version=SNAPSHOT | ||||
| version=chylex-14 | ||||
| javaVersion=17 | ||||
| remoteRobotVersion=0.11.15 | ||||
| antlrVersion=4.10.1 | ||||
|  | ||||
|  | ||||
| # Please don't forget to update kotlin version in buildscript section | ||||
| kotlinVersion=1.7.20 | ||||
| publishToken=token | ||||
|   | ||||
| @@ -144,6 +144,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 | ||||
|   | ||||
| @@ -228,7 +228,7 @@ private object FileTypePatterns { | ||||
|     } else if (fileTypeName == "CMakeLists.txt" || fileName == "CMakeLists") { | ||||
|       this.cMakePatterns | ||||
|     } else { | ||||
|       return null | ||||
|       this.htmlPatterns | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -12,6 +12,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.getLineEndOffset | ||||
| import com.maddyhome.idea.vim.api.injector | ||||
| @@ -30,6 +31,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 | ||||
| @@ -75,22 +77,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) | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| @@ -111,6 +111,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 { | ||||
| @@ -209,27 +213,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) | ||||
|         // Jump back to start | ||||
|         executeNormalWithoutMapping(injector.parser.parseKeys("`["), editor) | ||||
|         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) } | ||||
|   | ||||
| @@ -82,7 +82,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 | ||||
| @@ -113,7 +113,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 | ||||
| @@ -124,7 +124,15 @@ public class ProcessGroup extends VimProcessGroupBase { | ||||
|  | ||||
|       if (logger.isDebugEnabled()) logger.debug("swing=" + SwingUtilities.isEventDispatchThread()); | ||||
|  | ||||
|       VimInjectorKt.getInjector().getVimscriptExecutor().execute(text, editor, context, skipHistory(editor), true, CommandLineVimLContext.INSTANCE); | ||||
|       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()); | ||||
|   | ||||
| @@ -12,6 +12,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 | ||||
| @@ -96,3 +97,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 | ||||
|   }  | ||||
| } | ||||
|   | ||||
| @@ -15,9 +15,11 @@ import com.intellij.openapi.command.impl.UndoManagerImpl | ||||
| import com.intellij.openapi.command.undo.UndoManager | ||||
| import com.intellij.openapi.components.Service | ||||
| import com.intellij.openapi.fileEditor.impl.text.TextEditorProvider | ||||
| import com.maddyhome.idea.vim.VimPlugin | ||||
| import com.maddyhome.idea.vim.api.ExecutionContext | ||||
| import com.maddyhome.idea.vim.api.VimEditor | ||||
| import com.maddyhome.idea.vim.api.injector | ||||
| import com.maddyhome.idea.vim.command.VimStateMachine | ||||
| import com.maddyhome.idea.vim.common.ChangesListener | ||||
| import com.maddyhome.idea.vim.listener.SelectionVimListenerSuppressor | ||||
| import com.maddyhome.idea.vim.newapi.ij | ||||
| @@ -42,6 +44,7 @@ class UndoRedoHelper : UndoRedoBase() { | ||||
|     if (undoManager.isUndoAvailable(fileEditor)) { | ||||
|       if (injector.optionService.isSet(OptionScope.GLOBAL, IjVimOptionService.oldUndo)) { | ||||
|         SelectionVimListenerSuppressor.lock().use { undoManager.undo(fileEditor) } | ||||
|         restoreVisualMode(editor) | ||||
|       } else { | ||||
|         performUntilFileChanges(editor, { undoManager.isUndoAvailable(fileEditor) }, { undoManager.undo(fileEditor) }) | ||||
|  | ||||
| @@ -71,6 +74,7 @@ class UndoRedoHelper : UndoRedoBase() { | ||||
|     if (undoManager.isRedoAvailable(fileEditor)) { | ||||
|       if (injector.optionService.isSet(OptionScope.GLOBAL, IjVimOptionService.oldUndo)) { | ||||
|         SelectionVimListenerSuppressor.lock().use { undoManager.redo(fileEditor) } | ||||
|         restoreVisualMode(editor) | ||||
|       } else { | ||||
|         performUntilFileChanges(editor, { undoManager.isRedoAvailable(fileEditor) }, { undoManager.redo(fileEditor) }) | ||||
|         CommandProcessor.getInstance().runUndoTransparentAction { | ||||
| @@ -105,4 +109,21 @@ class UndoRedoHelper : UndoRedoBase() { | ||||
|   private fun ifFilePathChanged(editor: VimEditor, oldPath: String?): Boolean { | ||||
|     return editor.getPath() != oldPath | ||||
|   } | ||||
|  | ||||
|   private fun restoreVisualMode(editor: VimEditor) { | ||||
|     if (!editor.mode.inVisualMode && editor.getSelectionModel().hasSelection()) { | ||||
|       val detectedMode = VimPlugin.getVisualMotion().autodetectVisualSubmode(editor) | ||||
|        | ||||
|       // Visual block selection is restored into multiple carets, so multi-carets that form a block are always | ||||
|       // identified as visual block mode, leading to false positives. | ||||
|       // Since I use visual block mode much less often than multi-carets, this is a judgment call to never restore | ||||
|       // visual block mode. | ||||
|       val wantedMode = if (detectedMode == VimStateMachine.SubMode.VISUAL_BLOCK) | ||||
|         VimStateMachine.SubMode.VISUAL_CHARACTER | ||||
|       else | ||||
|         detectedMode | ||||
|        | ||||
|       VimPlugin.getVisualMotion().enterVisualMode(editor, wantedMode) | ||||
|     } | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -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 | ||||
|   } | ||||
| } | ||||
| @@ -226,12 +226,12 @@ | ||||
|  | ||||
|     <!-- Change --> | ||||
|     <vimAction implementation="com.maddyhome.idea.vim.action.change.change.ChangeCaseLowerMotionAction" mappingModes="N" keys="gu"/> | ||||
|     <vimAction implementation="com.maddyhome.idea.vim.action.change.change.ChangeCaseLowerVisualAction" mappingModes="X" keys="u"/> | ||||
| <!--    <vimAction implementation="com.maddyhome.idea.vim.action.change.change.ChangeCaseLowerVisualAction" mappingModes="X" keys="u"/>--> | ||||
|     <vimAction implementation="com.maddyhome.idea.vim.action.change.change.ChangeCaseToggleCharacterAction" mappingModes="N" keys="~"/> | ||||
|     <vimAction implementation="com.maddyhome.idea.vim.action.change.change.ChangeCaseToggleMotionAction" mappingModes="N" keys="g~"/> | ||||
|     <vimAction implementation="com.maddyhome.idea.vim.action.change.change.ChangeCaseToggleVisualAction" mappingModes="X" keys="~"/> | ||||
|     <vimAction implementation="com.maddyhome.idea.vim.action.change.change.ChangeCaseUpperMotionAction" mappingModes="N" keys="gU"/> | ||||
|     <vimAction implementation="com.maddyhome.idea.vim.action.change.change.ChangeCaseUpperVisualAction" mappingModes="X" keys="U"/> | ||||
| <!--    <vimAction implementation="com.maddyhome.idea.vim.action.change.change.ChangeCaseUpperVisualAction" mappingModes="X" keys="U"/>--> | ||||
|     <vimAction implementation="com.maddyhome.idea.vim.action.change.change.ChangeCharacterAction" mappingModes="N" keys="r"/> | ||||
|     <vimAction implementation="com.maddyhome.idea.vim.action.change.change.ChangeCharactersAction" mappingModes="N" keys="s"/> | ||||
|     <vimAction implementation="com.maddyhome.idea.vim.action.change.change.ChangeEndOfLineAction" mappingModes="N" keys="C"/> | ||||
| @@ -329,8 +329,8 @@ | ||||
|     <vimAction implementation="com.maddyhome.idea.vim.action.change.RepeatChangeAction" mappingModes="N" keys="."/> | ||||
|     <vimAction implementation="com.maddyhome.idea.vim.action.ExEntryAction" mappingModes="NXO" keys=":"/> | ||||
|     <vimAction implementation="com.maddyhome.idea.vim.action.ResetModeAction" mappingModes="ALL" keys="«C-\»«C-N»"/> | ||||
|     <vimAction implementation="com.maddyhome.idea.vim.action.change.RedoAction" mappingModes="N" keys="«C-R»"/> | ||||
|     <vimAction implementation="com.maddyhome.idea.vim.action.change.UndoAction" mappingModes="N"/> | ||||
|     <vimAction implementation="com.maddyhome.idea.vim.action.change.RedoAction" mappingModes="NX" keys="U,«C-R»"/> | ||||
|     <vimAction implementation="com.maddyhome.idea.vim.action.change.UndoAction" mappingModes="NX"/> | ||||
|  | ||||
|     <!-- Keys --> | ||||
|     <vimAction implementation="com.maddyhome.idea.vim.action.change.OperatorAction" mappingModes="N" keys="g@"/> | ||||
|   | ||||
| @@ -22,5 +22,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> | ||||
| @@ -1,12 +1,4 @@ | ||||
| <!-- | ||||
|   ~ Copyright 2003-2022 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. | ||||
|   --> | ||||
|  | ||||
| <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[ | ||||
| @@ -50,7 +42,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 --> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user