mirror of
				https://github.com/chylex/IntelliJ-IdeaVim.git
				synced 2025-11-04 01:40:12 +01:00 
			
		
		
		
	Compare commits
	
		
			8 Commits
		
	
	
		
			8bcb0d116d
			...
			customized
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						
						
							
						
						9f469d0eb2
	
				 | 
					
					
						|||
| 
						
						
							
						
						f59d2f769c
	
				 | 
					
					
						|||
| 
						
						
							
						
						dc00b59733
	
				 | 
					
					
						|||
| 
						
						
							
						
						bc20e6af9c
	
				 | 
					
					
						|||
| 
						
						
							
						
						c40f07714a
	
				 | 
					
					
						|||
| 
						
						
							
						
						fa68842c2d
	
				 | 
					
					
						|||
| 
						
						
							
						
						eca9258607
	
				 | 
					
					
						|||
| 
						
						
							
						
						46fb030977
	
				 | 
					
					
						
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -233,7 +233,7 @@ private object FileTypePatterns {
 | 
			
		||||
    } else if (fileTypeName == "CMakeLists.txt" || fileName == "CMakeLists") {
 | 
			
		||||
      this.cMakePatterns
 | 
			
		||||
    } else {
 | 
			
		||||
      return null
 | 
			
		||||
      this.htmlPatterns
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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)
 | 
			
		||||
        // 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) }
 | 
			
		||||
 
 | 
			
		||||
@@ -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) {
 | 
			
		||||
 
 | 
			
		||||
@@ -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,7 +134,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());
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
  } 
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -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>
 | 
			
		||||
@@ -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 -->
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user