mirror of
				https://github.com/chylex/IntelliJ-IdeaVim.git
				synced 2025-11-04 10:40:10 +01:00 
			
		
		
		
	Compare commits
	
		
			8 Commits
		
	
	
		
			customized
			...
			customized
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						
						
							
						
						9f469d0eb2
	
				 | 
					
					
						|||
| 
						
						
							
						
						f59d2f769c
	
				 | 
					
					
						|||
| 
						
						
							
						
						dc00b59733
	
				 | 
					
					
						|||
| 
						
						
							
						
						bc20e6af9c
	
				 | 
					
					
						|||
| 
						
						
							
						
						c40f07714a
	
				 | 
					
					
						|||
| 
						
						
							
						
						fa68842c2d
	
				 | 
					
					
						|||
| 
						
						
							
						
						eca9258607
	
				 | 
					
					
						|||
| 
						
						
							
						
						46fb030977
	
				 | 
					
					
						
							
								
								
									
										1
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
								
							@@ -1 +0,0 @@
 | 
			
		||||
* text=auto eol=lf
 | 
			
		||||
							
								
								
									
										39
									
								
								.github/workflows/closeYoutrackOnCommit.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										39
									
								
								.github/workflows/closeYoutrackOnCommit.yml
									
									
									
									
										vendored
									
									
								
							@@ -1,39 +0,0 @@
 | 
			
		||||
# This workflow will build a package using Gradle and then publish it to GitHub packages when a release is created
 | 
			
		||||
# For more information see: https://github.com/actions/setup-java/blob/main/docs/advanced-usage.md#Publishing-using-gradle
 | 
			
		||||
 | 
			
		||||
name: Close YouTrack on commit
 | 
			
		||||
 | 
			
		||||
on:
 | 
			
		||||
  workflow_dispatch:
 | 
			
		||||
  push:
 | 
			
		||||
    branches: [ master ]
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  build:
 | 
			
		||||
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/checkout@v2
 | 
			
		||||
        with:
 | 
			
		||||
          fetch-depth: 300
 | 
			
		||||
      - name: Set up JDK 11
 | 
			
		||||
        uses: actions/setup-java@v2
 | 
			
		||||
        with:
 | 
			
		||||
          java-version: '11'
 | 
			
		||||
          distribution: 'adopt'
 | 
			
		||||
          server-id: github # Value of the distributionManagement/repository/id field of the pom.xml
 | 
			
		||||
          settings-path: ${{ github.workspace }} # location for the settings.xml file
 | 
			
		||||
 | 
			
		||||
      - uses: nrwl/last-successful-commit-action@v1
 | 
			
		||||
        id: last_successful_commit
 | 
			
		||||
        with:
 | 
			
		||||
          branch: 'master'
 | 
			
		||||
          workflow_id: 'closeYoutrackOnCommit.yml'
 | 
			
		||||
          github_token: ${{ secrets.GITHUB_TOKEN }}
 | 
			
		||||
 | 
			
		||||
      - name: Update YouTrack
 | 
			
		||||
        run: ./gradlew updateYoutrackOnCommit
 | 
			
		||||
        env:
 | 
			
		||||
          SUCCESS_COMMIT: ${{ steps.last_successful_commit.outputs.commit_hash }}
 | 
			
		||||
          YOUTRACK_TOKEN: ${{ secrets.YOUTRACK_TOKEN }}
 | 
			
		||||
							
								
								
									
										35
									
								
								.github/workflows/kover.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										35
									
								
								.github/workflows/kover.yml
									
									
									
									
										vendored
									
									
								
							@@ -1,35 +0,0 @@
 | 
			
		||||
# This workflow will build a package using Gradle and then publish it to GitHub packages when a release is created
 | 
			
		||||
# For more information see: https://github.com/actions/setup-java/blob/main/docs/advanced-usage.md#Publishing-using-gradle
 | 
			
		||||
 | 
			
		||||
name: Kover
 | 
			
		||||
 | 
			
		||||
on:
 | 
			
		||||
  workflow_dispatch:
 | 
			
		||||
  push:
 | 
			
		||||
    branches: [ master ]
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  build:
 | 
			
		||||
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/checkout@v2
 | 
			
		||||
        with:
 | 
			
		||||
          fetch-depth: 300
 | 
			
		||||
      - name: Set up JDK 11
 | 
			
		||||
        uses: actions/setup-java@v2
 | 
			
		||||
        with:
 | 
			
		||||
          java-version: '11'
 | 
			
		||||
          distribution: 'adopt'
 | 
			
		||||
          server-id: github # Value of the distributionManagement/repository/id field of the pom.xml
 | 
			
		||||
          settings-path: ${{ github.workspace }} # location for the settings.xml file
 | 
			
		||||
 | 
			
		||||
      - name: Run tests
 | 
			
		||||
        run: ./gradlew koverXmlReport
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      # Upload Kover report to CodeCov
 | 
			
		||||
      - uses: codecov/codecov-action@v3
 | 
			
		||||
        with:
 | 
			
		||||
          files: ${{ github.workspace }}/build/reports/kover/xml/report.xml
 | 
			
		||||
@@ -1,12 +1,10 @@
 | 
			
		||||
# This workflow will build a package using Gradle and then publish it to GitHub packages when a release is created
 | 
			
		||||
# For more information see: https://github.com/actions/setup-java/blob/main/docs/advanced-usage.md#Publishing-using-gradle
 | 
			
		||||
 | 
			
		||||
name: Testing CI integrations
 | 
			
		||||
name: Update Changelog On PR (Test)
 | 
			
		||||
 | 
			
		||||
on:
 | 
			
		||||
  workflow_dispatch:
 | 
			
		||||
  schedule:
 | 
			
		||||
    - cron: '0 5 * * *'
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  build:
 | 
			
		||||
@@ -16,7 +14,7 @@ jobs:
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/checkout@v2
 | 
			
		||||
        with:
 | 
			
		||||
          fetch-depth: 300
 | 
			
		||||
          fetch-depth: 50
 | 
			
		||||
      - name: Set up JDK 11
 | 
			
		||||
        uses: actions/setup-java@v2
 | 
			
		||||
        with:
 | 
			
		||||
@@ -25,8 +23,18 @@ jobs:
 | 
			
		||||
          server-id: github # Value of the distributionManagement/repository/id field of the pom.xml
 | 
			
		||||
          settings-path: ${{ github.workspace }} # location for the settings.xml file
 | 
			
		||||
 | 
			
		||||
      - name: Run tests
 | 
			
		||||
        run: ./gradlew integrationsTest
 | 
			
		||||
      - name: Update authors
 | 
			
		||||
        id: update_authors
 | 
			
		||||
        run: ./gradlew updateMergedPr -PprId=525
 | 
			
		||||
        env:
 | 
			
		||||
          YOUTRACK_TOKEN: ${{ secrets.YOUTRACK_TOKEN }}
 | 
			
		||||
          GITHUB_OAUTH: ${{ secrets.MERGE_PR }}
 | 
			
		||||
 | 
			
		||||
#      - name: Commit changes
 | 
			
		||||
#        uses: stefanzweifel/git-auto-commit-action@v4
 | 
			
		||||
#        with:
 | 
			
		||||
#          branch: master
 | 
			
		||||
#          commit_message: Update changelog  after merging PR
 | 
			
		||||
#          commit_user_name: Alex Plate
 | 
			
		||||
#          commit_user_email: aleksei.plate@jetbrains.com
 | 
			
		||||
#          commit_author: Alex Plate <aleksei.plate@jetbrains.com>
 | 
			
		||||
#          file_pattern: CHANGES.md
 | 
			
		||||
							
								
								
									
										42
									
								
								.github/workflows/syncDoc.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										42
									
								
								.github/workflows/syncDoc.yml
									
									
									
									
										vendored
									
									
								
							@@ -1,42 +0,0 @@
 | 
			
		||||
# This workflow will build a package using Gradle and then publish it to GitHub packages when a release is created
 | 
			
		||||
# For more information see: https://github.com/actions/setup-java/blob/main/docs/advanced-usage.md#Publishing-using-gradle
 | 
			
		||||
 | 
			
		||||
# This workflow syncs changes from the docs folder of IdeaVim to the IdeaVim.wiki repository
 | 
			
		||||
 | 
			
		||||
name: Sync docs
 | 
			
		||||
 | 
			
		||||
on:
 | 
			
		||||
  workflow_dispatch:
 | 
			
		||||
  push:
 | 
			
		||||
    branches: [ master ]
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  build:
 | 
			
		||||
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
 | 
			
		||||
    steps:
 | 
			
		||||
      - name: Fetch origin repo
 | 
			
		||||
        uses: actions/checkout@v3
 | 
			
		||||
        with:
 | 
			
		||||
          path: origin
 | 
			
		||||
 | 
			
		||||
      - name: Fetch docs repo
 | 
			
		||||
        uses: actions/checkout@v3
 | 
			
		||||
        with:
 | 
			
		||||
          repository: JetBrains/ideavim.wiki
 | 
			
		||||
          path: docs
 | 
			
		||||
 | 
			
		||||
      - name: Sync docs
 | 
			
		||||
        id: update_authors
 | 
			
		||||
        run: cp -a origin/doc/. docs
 | 
			
		||||
 | 
			
		||||
      - name: Commit changes
 | 
			
		||||
        uses: stefanzweifel/git-auto-commit-action@v4
 | 
			
		||||
        with:
 | 
			
		||||
          branch: master
 | 
			
		||||
          repository: docs
 | 
			
		||||
          commit_message: Update docs
 | 
			
		||||
          commit_user_name: Alex Plate
 | 
			
		||||
          commit_user_email: aleksei.plate@jetbrains.com
 | 
			
		||||
          commit_author: Alex Plate <aleksei.plate@jetbrains.com>
 | 
			
		||||
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -9,7 +9,6 @@
 | 
			
		||||
!/.idea/fileTemplates
 | 
			
		||||
!/.idea/runConfigurations
 | 
			
		||||
!/.idea/codeStyles
 | 
			
		||||
!/.idea/vcs.xml
 | 
			
		||||
 | 
			
		||||
**/build/
 | 
			
		||||
**/out/
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								.idea/copyright/IdeaVim.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2
									
								
								.idea/copyright/IdeaVim.xml
									
									
									
										generated
									
									
									
								
							@@ -1,6 +1,6 @@
 | 
			
		||||
<component name="CopyrightManager">
 | 
			
		||||
  <copyright>
 | 
			
		||||
    <option name="notice" value="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." />
 | 
			
		||||
    <option name="notice" value="IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
Copyright (C) 2003-&#36;today.year 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/>." />
 | 
			
		||||
    <option name="myName" value="IdeaVim" />
 | 
			
		||||
  </copyright>
 | 
			
		||||
</component>
 | 
			
		||||
							
								
								
									
										14
									
								
								.idea/inspectionProfiles/Qodana.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										14
									
								
								.idea/inspectionProfiles/Qodana.xml
									
									
									
										generated
									
									
									
								
							@@ -33,11 +33,9 @@
 | 
			
		||||
      <option name="ignoreToString" value="false" />
 | 
			
		||||
      <option name="nonNlsCommentPattern" value="NON-NLS" />
 | 
			
		||||
    </inspection_tool>
 | 
			
		||||
    <inspection_tool class="MagicConstant" enabled="false" level="WARNING" enabled_by_default="false" />
 | 
			
		||||
    <inspection_tool class="MissortedModifiers" enabled="true" level="WARNING" enabled_by_default="true">
 | 
			
		||||
      <option name="m_requireAnnotationsFirst" value="true" />
 | 
			
		||||
    </inspection_tool>
 | 
			
		||||
    <inspection_tool class="SameParameterValue" enabled="false" level="WARNING" enabled_by_default="false" />
 | 
			
		||||
    <inspection_tool class="SameReturnValue" enabled="false" level="WARNING" enabled_by_default="false" />
 | 
			
		||||
    <inspection_tool class="SpellCheckingInspection" enabled="false" level="TYPO" enabled_by_default="false">
 | 
			
		||||
      <option name="processCode" value="true" />
 | 
			
		||||
@@ -46,17 +44,5 @@
 | 
			
		||||
    </inspection_tool>
 | 
			
		||||
    <inspection_tool class="SuperTearDownInFinally" enabled="true" level="WARNING" enabled_by_default="true" />
 | 
			
		||||
    <inspection_tool class="UnstableApiUsage" enabled="false" level="WARNING" enabled_by_default="false" />
 | 
			
		||||
    <inspection_tool class="unused" enabled="false" level="WARNING" enabled_by_default="false" checkParameterExcludingHierarchy="false">
 | 
			
		||||
      <option name="LOCAL_VARIABLE" value="true" />
 | 
			
		||||
      <option name="FIELD" value="true" />
 | 
			
		||||
      <option name="METHOD" value="true" />
 | 
			
		||||
      <option name="CLASS" value="true" />
 | 
			
		||||
      <option name="PARAMETER" value="true" />
 | 
			
		||||
      <option name="REPORT_PARAMETER_FOR_PUBLIC_METHODS" value="true" />
 | 
			
		||||
      <option name="ADD_MAINS_TO_ENTRIES" value="true" />
 | 
			
		||||
      <option name="ADD_APPLET_TO_ENTRIES" value="true" />
 | 
			
		||||
      <option name="ADD_SERVLET_TO_ENTRIES" value="true" />
 | 
			
		||||
      <option name="ADD_NONJAVA_TO_ENTRIES" value="true" />
 | 
			
		||||
    </inspection_tool>
 | 
			
		||||
  </profile>
 | 
			
		||||
</component>
 | 
			
		||||
							
								
								
									
										2
									
								
								.idea/scopes/Copyright.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2
									
								
								.idea/scopes/Copyright.xml
									
									
									
										generated
									
									
									
								
							@@ -1,3 +1,3 @@
 | 
			
		||||
<component name="DependencyValidationManager">
 | 
			
		||||
  <scope name="Copyright" pattern="file:*/&&!file:.github//*&&!file:.idea//*&&!file:.teamcity//*&&!file:assets//*&&!file:config//*&&!file:doc//*&&!file:gradle//*&&!file:gradlew&&!file:gradlew.bat&&!file:src/main/resources//*&&!file:antlr//*&&!file:java/com/maddyhome/idea/vim/regexp/RegExp.kt" />
 | 
			
		||||
  <scope name="Copyright" pattern="(file[IdeaVIM.main]:*/||file[IdeaVIM.test]:*/)&&!file[IdeaVIM.main]:resources//*" />
 | 
			
		||||
</component>
 | 
			
		||||
							
								
								
									
										16
									
								
								.idea/vcs.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										16
									
								
								.idea/vcs.xml
									
									
									
										generated
									
									
									
								
							@@ -1,16 +0,0 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<project version="4">
 | 
			
		||||
  <component name="IssueNavigationConfiguration">
 | 
			
		||||
    <option name="links">
 | 
			
		||||
      <list>
 | 
			
		||||
        <IssueNavigationLink>
 | 
			
		||||
          <option name="issueRegexp" value="[A-Z]+\-\d+" />
 | 
			
		||||
          <option name="linkRegexp" value="https://youtrack.jetbrains.com/issue/$0" />
 | 
			
		||||
        </IssueNavigationLink>
 | 
			
		||||
      </list>
 | 
			
		||||
    </option>
 | 
			
		||||
  </component>
 | 
			
		||||
  <component name="VcsDirectoryMappings">
 | 
			
		||||
    <mapping directory="$PROJECT_DIR$" vcs="Git" />
 | 
			
		||||
  </component>
 | 
			
		||||
</project>
 | 
			
		||||
							
								
								
									
										4
									
								
								.teamcity/_Self/Constants.kt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.teamcity/_Self/Constants.kt
									
									
									
									
										vendored
									
									
								
							@@ -5,8 +5,8 @@ object Constants {
 | 
			
		||||
  const val EAP_CHANNEL = "eap"
 | 
			
		||||
  const val DEV_CHANNEL = "Dev"
 | 
			
		||||
 | 
			
		||||
  const val VERSION = "2.0.0"
 | 
			
		||||
  const val DEV_VERSION = "2.1.0"
 | 
			
		||||
  const val VERSION = "1.11.1"
 | 
			
		||||
  const val DEV_VERSION = "1.12.0"
 | 
			
		||||
 | 
			
		||||
  const val GITHUB_TESTS = "LATEST-EAP-SNAPSHOT"
 | 
			
		||||
  const val NVIM_TESTS = "LATEST-EAP-SNAPSHOT"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										12
									
								
								.teamcity/_Self/Project.kt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								.teamcity/_Self/Project.kt
									
									
									
									
										vendored
									
									
								
							@@ -11,7 +11,15 @@ import _Self.buildTypes.TestsForIntelliJEAP
 | 
			
		||||
import _Self.subprojects.GitHub
 | 
			
		||||
import _Self.subprojects.OldTests
 | 
			
		||||
import _Self.subprojects.Releases
 | 
			
		||||
import _Self.vcsRoots.*
 | 
			
		||||
import _Self.vcsRoots.Branch_181
 | 
			
		||||
import _Self.vcsRoots.Branch_183
 | 
			
		||||
import _Self.vcsRoots.Branch_191_193
 | 
			
		||||
import _Self.vcsRoots.Branch_201
 | 
			
		||||
import _Self.vcsRoots.Branch_202
 | 
			
		||||
import _Self.vcsRoots.Branch_203_212
 | 
			
		||||
import _Self.vcsRoots.Branch_213_221
 | 
			
		||||
import _Self.vcsRoots.Branch_Release
 | 
			
		||||
import _Self.vcsRoots.GitHubPullRequest
 | 
			
		||||
import jetbrains.buildServer.configs.kotlin.v2019_2.Project
 | 
			
		||||
 | 
			
		||||
object Project : Project({
 | 
			
		||||
@@ -27,12 +35,12 @@ object Project : Project({
 | 
			
		||||
  vcsRoot(Branch_202)
 | 
			
		||||
  vcsRoot(Branch_203_212)
 | 
			
		||||
  vcsRoot(Branch_213_221)
 | 
			
		||||
  vcsRoot(Branch_222)
 | 
			
		||||
  vcsRoot(Branch_Release)
 | 
			
		||||
  vcsRoot(GitHubPullRequest)
 | 
			
		||||
 | 
			
		||||
  // Builds
 | 
			
		||||
  buildType(TestsForIntelliJEAP)
 | 
			
		||||
  buildType(TestsForIntelliJ20222)
 | 
			
		||||
 | 
			
		||||
  buildType(PropertyBased)
 | 
			
		||||
  buildType(LongRunning)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1
									
								
								.teamcity/_Self/buildTypes/ActiveTests.kt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.teamcity/_Self/buildTypes/ActiveTests.kt
									
									
									
									
										vendored
									
									
								
							@@ -55,3 +55,4 @@ sealed class ActiveTests(buildName: String, ijVersion: String) : BuildType({
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
object TestsForIntelliJEAP : ActiveTests("Tests for IntelliJ Latest EAP", "LATEST-EAP-SNAPSHOT")
 | 
			
		||||
object TestsForIntelliJ20222 : ActiveTests("Tests for IntelliJ 2022.2", "2022.2.1")
 | 
			
		||||
 
 | 
			
		||||
@@ -1,57 +0,0 @@
 | 
			
		||||
@file:Suppress("ClassName")
 | 
			
		||||
 | 
			
		||||
package _Self.buildTypes
 | 
			
		||||
 | 
			
		||||
import jetbrains.buildServer.configs.kotlin.v2019_2.BuildType
 | 
			
		||||
import jetbrains.buildServer.configs.kotlin.v2019_2.CheckoutMode
 | 
			
		||||
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.gradle
 | 
			
		||||
import jetbrains.buildServer.configs.kotlin.v2019_2.failureConditions.BuildFailureOnMetric
 | 
			
		||||
import jetbrains.buildServer.configs.kotlin.v2019_2.failureConditions.failOnMetricChange
 | 
			
		||||
import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.vcs
 | 
			
		||||
 | 
			
		||||
sealed class TestsForIntelliJ_222_branch(private val version: String) : BuildType({
 | 
			
		||||
  name = "Tests for IntelliJ $version"
 | 
			
		||||
 | 
			
		||||
  params {
 | 
			
		||||
    param("env.ORG_GRADLE_PROJECT_downloadIdeaSources", "false")
 | 
			
		||||
    param("env.ORG_GRADLE_PROJECT_legacyNoJavaPlugin", "true")
 | 
			
		||||
    param("env.ORG_GRADLE_PROJECT_ideaVersion", "IC-$version")
 | 
			
		||||
    param("env.ORG_GRADLE_PROJECT_instrumentPluginCode", "false")
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  vcs {
 | 
			
		||||
    root(_Self.vcsRoots.Branch_222)
 | 
			
		||||
 | 
			
		||||
    checkoutMode = CheckoutMode.AUTO
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  steps {
 | 
			
		||||
    gradle {
 | 
			
		||||
      tasks = "clean test"
 | 
			
		||||
      buildFile = ""
 | 
			
		||||
      enableStacktrace = true
 | 
			
		||||
      param("org.jfrog.artifactory.selectedDeployableServer.defaultModuleVersionConfiguration", "GLOBAL")
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  triggers {
 | 
			
		||||
    vcs {
 | 
			
		||||
      branchFilter = ""
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  failureConditions {
 | 
			
		||||
    failOnMetricChange {
 | 
			
		||||
      metric = BuildFailureOnMetric.MetricType.TEST_COUNT
 | 
			
		||||
      threshold = 20
 | 
			
		||||
      units = BuildFailureOnMetric.MetricUnit.PERCENTS
 | 
			
		||||
      comparison = BuildFailureOnMetric.MetricComparison.LESS
 | 
			
		||||
      compareTo = build {
 | 
			
		||||
        buildRule = lastSuccessful()
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
object TestsForIntelliJ20222 : TestsForIntelliJ_222_branch("2022.2.3")
 | 
			
		||||
							
								
								
									
										2
									
								
								.teamcity/_Self/subprojects/OldTests.kt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.teamcity/_Self/subprojects/OldTests.kt
									
									
									
									
										vendored
									
									
								
							@@ -12,7 +12,6 @@ import _Self.buildTypes.TestsForIntelliJ20203
 | 
			
		||||
import _Self.buildTypes.TestsForIntelliJ20211
 | 
			
		||||
import _Self.buildTypes.TestsForIntelliJ20212
 | 
			
		||||
import _Self.buildTypes.TestsForIntelliJ20213
 | 
			
		||||
import _Self.buildTypes.TestsForIntelliJ20222
 | 
			
		||||
import jetbrains.buildServer.configs.kotlin.v2019_2.Project
 | 
			
		||||
 | 
			
		||||
object OldTests : Project({
 | 
			
		||||
@@ -31,5 +30,4 @@ object OldTests : Project({
 | 
			
		||||
  buildType(TestsForIntelliJ20211)
 | 
			
		||||
  buildType(TestsForIntelliJ20212)
 | 
			
		||||
  buildType(TestsForIntelliJ20213)
 | 
			
		||||
  buildType(TestsForIntelliJ20222)
 | 
			
		||||
})
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										12
									
								
								.teamcity/_Self/vcsRoots/Branch_222.kt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								.teamcity/_Self/vcsRoots/Branch_222.kt
									
									
									
									
										vendored
									
									
								
							@@ -1,12 +0,0 @@
 | 
			
		||||
@file:Suppress("ClassName")
 | 
			
		||||
 | 
			
		||||
package _Self.vcsRoots
 | 
			
		||||
 | 
			
		||||
import jetbrains.buildServer.configs.kotlin.v2019_2.vcs.GitVcsRoot
 | 
			
		||||
 | 
			
		||||
object Branch_222 : GitVcsRoot({
 | 
			
		||||
  id("HttpsGithubComJetBrainsIdeavimBranch222")
 | 
			
		||||
  name = "https://github.com/JetBrains/ideavim (branch 222)"
 | 
			
		||||
  url = "https://github.com/JetBrains/ideavim.git"
 | 
			
		||||
  branch = "222"
 | 
			
		||||
})
 | 
			
		||||
@@ -1,65 +0,0 @@
 | 
			
		||||
package patches.buildTypes
 | 
			
		||||
 | 
			
		||||
import jetbrains.buildServer.configs.kotlin.v2019_2.*
 | 
			
		||||
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.ScriptBuildStep
 | 
			
		||||
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.script
 | 
			
		||||
import jetbrains.buildServer.configs.kotlin.v2019_2.ui.*
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
This patch script was generated by TeamCity on settings change in UI.
 | 
			
		||||
To apply the patch, change the buildType with id = 'IdeaVimCompatibility'
 | 
			
		||||
accordingly, and delete the patch script.
 | 
			
		||||
*/
 | 
			
		||||
changeBuildType(RelativeId("IdeaVimCompatibility")) {
 | 
			
		||||
    vcs {
 | 
			
		||||
        remove(DslContext.settingsRoot.id!!)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    expectSteps {
 | 
			
		||||
        script {
 | 
			
		||||
            name = "Check"
 | 
			
		||||
            scriptContent = """
 | 
			
		||||
                java -jar verifier/verifier-cli-dev-all.jar check-plugin '${'$'}org.jetbrains.IdeaVim-EasyMotion' [latest-IU] -team-city
 | 
			
		||||
                java -jar verifier/verifier-cli-dev-all.jar check-plugin '${'$'}io.github.mishkun.ideavimsneak' [latest-IU] -team-city
 | 
			
		||||
                java -jar verifier/verifier-cli-dev-all.jar check-plugin '${'$'}eu.theblob42.idea.whichkey' [latest-IU] -team-city
 | 
			
		||||
                java -jar verifier/verifier-cli-dev-all.jar check-plugin '${'$'}IdeaVimExtension' [latest-IU] -team-city
 | 
			
		||||
                # Outdated java -jar verifier/verifier-cli-dev-all.jar check-plugin '${'$'}github.zgqq.intellij-enhance' [latest-IU] -team-city
 | 
			
		||||
                java -jar verifier/verifier-cli-dev-all.jar check-plugin '${'$'}com.github.copilot' [latest-IU] -team-city
 | 
			
		||||
                java -jar verifier/verifier-cli-dev-all.jar check-plugin '${'$'}com.github.dankinsoid.multicursor' [latest-IU] -team-city
 | 
			
		||||
                java -jar verifier/verifier-cli-dev-all.jar check-plugin '${'$'}com.joshestein.ideavim-quickscope' [latest-IU] -team-city
 | 
			
		||||
            """.trimIndent()
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    steps {
 | 
			
		||||
        update<ScriptBuildStep>(0) {
 | 
			
		||||
            name = "Load Verifier"
 | 
			
		||||
            clearConditions()
 | 
			
		||||
            scriptContent = """
 | 
			
		||||
                mkdir verifier1
 | 
			
		||||
                curl -f -L -o verifier1/verifier-cli-dev-all-1.jar "https://packages.jetbrains.team/files/p/ideavim/plugin-verifier/verifier-cli-dev-all-1.jar"
 | 
			
		||||
            """.trimIndent()
 | 
			
		||||
        }
 | 
			
		||||
        insert(1) {
 | 
			
		||||
            script {
 | 
			
		||||
                name = "Check"
 | 
			
		||||
                scriptContent = """
 | 
			
		||||
                    # We use a custom build of verifier that downloads IdeaVim from dev channel
 | 
			
		||||
                    # To create a custom build: Download plugin verifier repo, add an if that switches to dev channel for IdeaVim repo
 | 
			
		||||
                    # At the moment it's com.jetbrains.pluginverifier.repository.repositories.marketplace.MarketplaceRepository#getLastCompatibleVersionOfPlugin
 | 
			
		||||
                    # Build using gradlew :intellij-plugin-verifier:verifier-cli:shadowJar
 | 
			
		||||
                    # Upload verifier-cli-dev-all.jar artifact to the repo in IdeaVim space repo
 | 
			
		||||
                    
 | 
			
		||||
                    java --version
 | 
			
		||||
                    java -jar verifier1/verifier-cli-dev-all-1.jar check-plugin '${'$'}org.jetbrains.IdeaVim-EasyMotion' [latest-IU] -team-city
 | 
			
		||||
                    java -jar verifier1/verifier-cli-dev-all-1.jar check-plugin '${'$'}io.github.mishkun.ideavimsneak' [latest-IU] -team-city
 | 
			
		||||
                    java -jar verifier1/verifier-cli-dev-all-1.jar check-plugin '${'$'}eu.theblob42.idea.whichkey' [latest-IU] -team-city
 | 
			
		||||
                    java -jar verifier1/verifier-cli-dev-all-1.jar check-plugin '${'$'}IdeaVimExtension' [latest-IU] -team-city
 | 
			
		||||
                    # Outdated java -jar verifier/verifier-cli-dev-all.jar check-plugin '${'$'}github.zgqq.intellij-enhance' [latest-IU] -team-city
 | 
			
		||||
                    java -jar verifier1/verifier-cli-dev-all-1.jar check-plugin '${'$'}com.github.copilot' [latest-IU] -team-city
 | 
			
		||||
                    java -jar verifier1/verifier-cli-dev-all-1.jar check-plugin '${'$'}com.github.dankinsoid.multicursor' [latest-IU] -team-city
 | 
			
		||||
                    java -jar verifier1/verifier-cli-dev-all-1.jar check-plugin '${'$'}com.joshestein.ideavim-quickscope' [latest-IU] -team-city
 | 
			
		||||
                """.trimIndent()
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										50
									
								
								.teamcity/patches/buildTypes/Qodana.kts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										50
									
								
								.teamcity/patches/buildTypes/Qodana.kts
									
									
									
									
										vendored
									
									
								
							@@ -4,12 +4,6 @@ import jetbrains.buildServer.configs.kotlin.v2019_2.*
 | 
			
		||||
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.Qodana
 | 
			
		||||
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.gradle
 | 
			
		||||
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.qodana
 | 
			
		||||
import jetbrains.buildServer.configs.kotlin.v2019_2.failureConditions.BuildFailureOnMetric
 | 
			
		||||
import jetbrains.buildServer.configs.kotlin.v2019_2.failureConditions.failOnMetricChange
 | 
			
		||||
import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.ScheduleTrigger
 | 
			
		||||
import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.VcsTrigger
 | 
			
		||||
import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.schedule
 | 
			
		||||
import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.vcs
 | 
			
		||||
import jetbrains.buildServer.configs.kotlin.v2019_2.ui.*
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
@@ -47,8 +41,8 @@ changeBuildType(RelativeId("Qodana")) {
 | 
			
		||||
        update<Qodana>(1) {
 | 
			
		||||
            clearConditions()
 | 
			
		||||
            reportAsTests = true
 | 
			
		||||
            additionalDockerArguments = "-e QODANA_TOKEN=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJvcmdhbml6YXRpb24iOiIzUFZrQSIsInByb2plY3QiOiIzN1FlQSIsInRva2VuIjoiM0t2bXoifQ.uohp81tM7iAfvvB6k8faarfpV-OjusAaEbWQ8iNrOgs"
 | 
			
		||||
            additionalQodanaArguments = "--baseline qodana.sarif.json"
 | 
			
		||||
            argumentsCommandDocker = "-e QODANA_TOKEN=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJvcmdhbml6YXRpb24iOiIzUFZrQSIsInByb2plY3QiOiIzN1FlQSIsInRva2VuIjoiM0t2bXoifQ.uohp81tM7iAfvvB6k8faarfpV-OjusAaEbWQ8iNrOgs"
 | 
			
		||||
            argumentsEntryPointDocker = "--baseline qodana.sarif.json"
 | 
			
		||||
            param("clonefinder-languages", "")
 | 
			
		||||
            param("collect-anonymous-statistics", "")
 | 
			
		||||
            param("licenseaudit-enable", "")
 | 
			
		||||
@@ -58,44 +52,4 @@ changeBuildType(RelativeId("Qodana")) {
 | 
			
		||||
            param("clonefinder-reference-projects", "")
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    triggers {
 | 
			
		||||
        val trigger1 = find<VcsTrigger> {
 | 
			
		||||
            vcs {
 | 
			
		||||
                branchFilter = ""
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        trigger1.apply {
 | 
			
		||||
            enabled = false
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
        val trigger2 = find<ScheduleTrigger> {
 | 
			
		||||
            schedule {
 | 
			
		||||
                schedulingPolicy = weekly {
 | 
			
		||||
                    dayOfWeek = ScheduleTrigger.DAY.Tuesday
 | 
			
		||||
                }
 | 
			
		||||
                branchFilter = ""
 | 
			
		||||
                triggerBuild = always()
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        trigger2.apply {
 | 
			
		||||
            enabled = false
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    failureConditions {
 | 
			
		||||
        val feature1 = find<BuildFailureOnMetric> {
 | 
			
		||||
            failOnMetricChange {
 | 
			
		||||
                metric = BuildFailureOnMetric.MetricType.QODANA_TOTAL_PROBLEMS_COUNT
 | 
			
		||||
                threshold = 0
 | 
			
		||||
                units = BuildFailureOnMetric.MetricUnit.DEFAULT_UNIT
 | 
			
		||||
                comparison = BuildFailureOnMetric.MetricComparison.MORE
 | 
			
		||||
                compareTo = value()
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        feature1.apply {
 | 
			
		||||
            param("metricKey", "QodanaProblemsNew")
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										48
									
								
								.teamcity/patches/buildTypes/Release.kts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										48
									
								
								.teamcity/patches/buildTypes/Release.kts
									
									
									
									
										vendored
									
									
								
							@@ -1,48 +0,0 @@
 | 
			
		||||
package patches.buildTypes
 | 
			
		||||
 | 
			
		||||
import jetbrains.buildServer.configs.kotlin.v2019_2.*
 | 
			
		||||
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.GradleBuildStep
 | 
			
		||||
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.gradle
 | 
			
		||||
import jetbrains.buildServer.configs.kotlin.v2019_2.ui.*
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
This patch script was generated by TeamCity on settings change in UI.
 | 
			
		||||
To apply the patch, change the buildType with id = 'Release'
 | 
			
		||||
accordingly, and delete the patch script.
 | 
			
		||||
*/
 | 
			
		||||
changeBuildType(RelativeId("Release")) {
 | 
			
		||||
    params {
 | 
			
		||||
        add {
 | 
			
		||||
            password("env.ORG_GRADLE_PROJECT_youtrackToken", "credentialsJSON:3cd3e867-282c-451f-b958-bc95d56a8450", display = ParameterDisplay.HIDDEN)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    expectSteps {
 | 
			
		||||
        gradle {
 | 
			
		||||
            tasks = "clean publishPlugin slackNotification"
 | 
			
		||||
            buildFile = ""
 | 
			
		||||
            enableStacktrace = true
 | 
			
		||||
            param("org.jfrog.artifactory.selectedDeployableServer.defaultModuleVersionConfiguration", "GLOBAL")
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    steps {
 | 
			
		||||
        update<GradleBuildStep>(0) {
 | 
			
		||||
            clearConditions()
 | 
			
		||||
            tasks = "clean publishPlugin"
 | 
			
		||||
        }
 | 
			
		||||
        insert(1) {
 | 
			
		||||
            gradle {
 | 
			
		||||
                name = "Run Integrations"
 | 
			
		||||
                tasks = "releaseActions"
 | 
			
		||||
                param("org.jfrog.artifactory.selectedDeployableServer.defaultModuleVersionConfiguration", "GLOBAL")
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        insert(2) {
 | 
			
		||||
            gradle {
 | 
			
		||||
                name = "Slack Notification"
 | 
			
		||||
                tasks = "slackNotification"
 | 
			
		||||
                param("org.jfrog.artifactory.selectedDeployableServer.defaultModuleVersionConfiguration", "GLOBAL")
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										50
									
								
								.teamcity/patches/projects/_Self.kts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										50
									
								
								.teamcity/patches/projects/_Self.kts
									
									
									
									
										vendored
									
									
								
							@@ -1,50 +0,0 @@
 | 
			
		||||
package patches.projects
 | 
			
		||||
 | 
			
		||||
import jetbrains.buildServer.configs.kotlin.v2019_2.*
 | 
			
		||||
import jetbrains.buildServer.configs.kotlin.v2019_2.AmazonEC2CloudImage
 | 
			
		||||
import jetbrains.buildServer.configs.kotlin.v2019_2.Project
 | 
			
		||||
import jetbrains.buildServer.configs.kotlin.v2019_2.amazonEC2CloudImage
 | 
			
		||||
import jetbrains.buildServer.configs.kotlin.v2019_2.ui.*
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
This patch script was generated by TeamCity on settings change in UI.
 | 
			
		||||
To apply the patch, change the root project
 | 
			
		||||
accordingly, and delete the patch script.
 | 
			
		||||
*/
 | 
			
		||||
changeProject(DslContext.projectId) {
 | 
			
		||||
    features {
 | 
			
		||||
        val feature1 = find<AmazonEC2CloudImage> {
 | 
			
		||||
            amazonEC2CloudImage {
 | 
			
		||||
                id = "PROJECT_EXT_768"
 | 
			
		||||
                profileId = "amazon-48"
 | 
			
		||||
                agentPoolId = "41"
 | 
			
		||||
                name = "BuildAgentsIdeaVim"
 | 
			
		||||
                vpcSubnetId = "subnet-58839511"
 | 
			
		||||
                keyPairName = ""
 | 
			
		||||
                instanceType = "c5d.xlarge"
 | 
			
		||||
                securityGroups = listOf("sg-eda08696", "sg-7332cf0f")
 | 
			
		||||
                useSpotInstances = true
 | 
			
		||||
                instanceTags = mapOf(
 | 
			
		||||
                    "project" to "idea-vim"
 | 
			
		||||
                )
 | 
			
		||||
                source = Source("ami-0fa17ce8238eb8868")
 | 
			
		||||
                param("image-instances-limit", "")
 | 
			
		||||
                param("spot-instance-price", "")
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        feature1.apply {
 | 
			
		||||
            profileId = "amazon-48"
 | 
			
		||||
            agentPoolId = "41"
 | 
			
		||||
            name = "BuildAgentsIdeaVim"
 | 
			
		||||
            vpcSubnetId = "subnet-58839511"
 | 
			
		||||
            keyPairName = ""
 | 
			
		||||
            instanceType = "c5d.xlarge"
 | 
			
		||||
            securityGroups = listOf("sg-eda08696", "sg-7332cf0f")
 | 
			
		||||
            useSpotInstances = true
 | 
			
		||||
            instanceTags = mapOf(
 | 
			
		||||
                "project" to "idea-vim"
 | 
			
		||||
            )
 | 
			
		||||
            source = Source("ami-07c529efaddafcf86")
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										34
									
								
								AUTHORS.md
									
									
									
									
									
								
							
							
						
						
									
										34
									
								
								AUTHORS.md
									
									
									
									
									
								
							@@ -165,7 +165,7 @@ Contributors:
 | 
			
		||||
   
 | 
			
		||||
  Pavel Fatin
 | 
			
		||||
* [![icon][mail]](mailto:tietyt@gmail.com)
 | 
			
		||||
  [![icon][github-off]](https://github.com/DanKaplanSES)
 | 
			
		||||
  [![icon][github-off]](#)
 | 
			
		||||
   
 | 
			
		||||
  tieTYT
 | 
			
		||||
* [![icon][mail]](mailto:nickgieschen@gmail.com)
 | 
			
		||||
@@ -185,7 +185,7 @@ Contributors:
 | 
			
		||||
   
 | 
			
		||||
  Vladimir Parfinenko
 | 
			
		||||
* [![icon][mail]](mailto:hassmann@hwdev.de)
 | 
			
		||||
  [![icon][github-off]](https://github.com/lumie1337)
 | 
			
		||||
  [![icon][github-off]](#)
 | 
			
		||||
   
 | 
			
		||||
  Florian Hassmann
 | 
			
		||||
* [![icon][mail]](mailto:jpalus@fastmail.com)
 | 
			
		||||
@@ -193,7 +193,7 @@ Contributors:
 | 
			
		||||
   
 | 
			
		||||
  Jan Palus
 | 
			
		||||
* [![icon][mail]](mailto:kpetrov@ripe.net)
 | 
			
		||||
  [![icon][github-off]](https://github.com/constpetrov)
 | 
			
		||||
  [![icon][github-off]](#)
 | 
			
		||||
   
 | 
			
		||||
  Konstantin Petrov
 | 
			
		||||
* [![icon][mail]](mailto:ya-ikmik2012@yandex.ru)
 | 
			
		||||
@@ -220,6 +220,10 @@ Contributors:
 | 
			
		||||
  [![icon][github]](https://github.com/johngrib)
 | 
			
		||||
   
 | 
			
		||||
  John Grib
 | 
			
		||||
* [![icon][mail]](mailto:hild@b4mad.net)
 | 
			
		||||
  [![icon][github-off]](#)
 | 
			
		||||
   
 | 
			
		||||
  Marcel Hild
 | 
			
		||||
* [![icon][mail]](mailto:vedranb@gmail.com)
 | 
			
		||||
  [![icon][github]](https://github.com/vedran)
 | 
			
		||||
   
 | 
			
		||||
@@ -315,6 +319,10 @@ Contributors:
 | 
			
		||||
  [![icon][github]](https://github.com/angelbot)
 | 
			
		||||
   
 | 
			
		||||
  John Weigel
 | 
			
		||||
* [![icon][mail]](mailto:kevinz@weghst.com)
 | 
			
		||||
  [![icon][github]](https://github.com/kevin70)
 | 
			
		||||
   
 | 
			
		||||
  kk
 | 
			
		||||
* [![icon][mail]](mailto:runforprogram@163.com)
 | 
			
		||||
  [![icon][github]](https://github.com/runforprogram)
 | 
			
		||||
   
 | 
			
		||||
@@ -447,26 +455,6 @@ Contributors:
 | 
			
		||||
  [![icon][github]](https://github.com/lippfi)
 | 
			
		||||
   
 | 
			
		||||
  lippfi
 | 
			
		||||
* [![icon][mail]](mailto:3237686+Runinho@users.noreply.github.com)
 | 
			
		||||
  [![icon][github]](https://github.com/Runinho)
 | 
			
		||||
   
 | 
			
		||||
  Runinho
 | 
			
		||||
* [![icon][mail]](mailto:me@yuhaowen.com)
 | 
			
		||||
  [![icon][github]](https://github.com/adaext)
 | 
			
		||||
   
 | 
			
		||||
  Ada
 | 
			
		||||
 | 
			
		||||
Previous contributors:
 | 
			
		||||
 | 
			
		||||
* [![icon][mail]](mailto:hild@b4mad.net)
 | 
			
		||||
  [![icon][github-off]](#)
 | 
			
		||||
   
 | 
			
		||||
  Marcel Hild
 | 
			
		||||
* [![icon][mail]](mailto:kevinz@weghst.com)
 | 
			
		||||
  [![icon][github]](https://github.com/kevin70)
 | 
			
		||||
   
 | 
			
		||||
  kk
 | 
			
		||||
 | 
			
		||||
                        
 | 
			
		||||
If you are a contributor and your name is not listed here, feel free to
 | 
			
		||||
contact the maintainers.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										24
									
								
								CHANGES.md
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								CHANGES.md
									
									
									
									
									
								
							@@ -25,26 +25,6 @@ usual beta standards.
 | 
			
		||||
 | 
			
		||||
## To Be Released
 | 
			
		||||
 | 
			
		||||
### Fixes:
 | 
			
		||||
* [VIM-2797](https://youtrack.jetbrains.com/issue/VIM-2797) Introduce variable to mute default argtextobj mappings
 | 
			
		||||
* [VIM-758](https://youtrack.jetbrains.com/issue/VIM-758) Support d mappings
 | 
			
		||||
* [VIM-2577](https://youtrack.jetbrains.com/issue/VIM-2577) Fix paste at the end of notebook cell
 | 
			
		||||
* [VIM-2813](https://youtrack.jetbrains.com/issue/VIM-2813) Migrate update checker to VimStandalonePluginUpdateChecker
 | 
			
		||||
 | 
			
		||||
### Merged PRs:
 | 
			
		||||
* [558](https://github.com/JetBrains/ideavim/pull/558) by [Matt Ellis](https://github.com/citizenmatt): Fix incorrect normalising for trailing inlay
 | 
			
		||||
* [554](https://github.com/JetBrains/ideavim/pull/554) by [Matt Ellis](https://github.com/citizenmatt): Refactor "last column" calculations
 | 
			
		||||
* [553](https://github.com/JetBrains/ideavim/pull/553) by [Matt Ellis](https://github.com/citizenmatt): Rearrange and rename some code in engine
 | 
			
		||||
* [560](https://github.com/JetBrains/ideavim/pull/560) by [Runinho](https://github.com/Runinho): Fix(VIM-2577) paste not working at end of notebook cell
 | 
			
		||||
* [571](https://github.com/JetBrains/ideavim/pull/571) by [Ada](https://github.com/adaext): Remove the redundant quotation mark at the end of "packadd matchit" command
 | 
			
		||||
 | 
			
		||||
## 2.0.0, 2022-11-01
 | 
			
		||||
 | 
			
		||||
### Changes:
 | 
			
		||||
* IdeaVim changes license from GPL-2.0 or later to MIT. [VIM-2782](https://youtrack.jetbrains.com/issue/VIM-2782)
 | 
			
		||||
 | 
			
		||||
## 1.12.0, 2022-11-01
 | 
			
		||||
 | 
			
		||||
### Fixes:
 | 
			
		||||
* [VIM-1758](https://youtrack.jetbrains.com/issue/VIM-1758) Commentary plugin in rider
 | 
			
		||||
* [VIM-1903](https://youtrack.jetbrains.com/issue/VIM-1903) Autoindent now works in rider
 | 
			
		||||
@@ -53,10 +33,6 @@ usual beta standards.
 | 
			
		||||
* [VIM-2718](https://youtrack.jetbrains.com/issue/VIM-2718) Fixed case where the primary caret was changed
 | 
			
		||||
* [VIM-2766](https://youtrack.jetbrains.com/issue/VIM-2766) Move NERDTree update to background thread
 | 
			
		||||
* [VIM-2768](https://youtrack.jetbrains.com/issue/VIM-2768) Refactor listeners
 | 
			
		||||
* [VIM-2776](https://youtrack.jetbrains.com/issue/VIM-2776) Use filename index for file search
 | 
			
		||||
 | 
			
		||||
### Merged PRs:
 | 
			
		||||
* [550](https://github.com/JetBrains/ideavim/pull/550) by [Matt Ellis](https://github.com/citizenmatt): Fix(VIM-2778) Remove override of editor scroll setting
 | 
			
		||||
 | 
			
		||||
## 1.11.0, 2022-08-09
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										352
									
								
								LICENSE.txt
									
									
									
									
									
								
							
							
						
						
									
										352
									
								
								LICENSE.txt
									
									
									
									
									
								
							@@ -1,21 +1,339 @@
 | 
			
		||||
MIT License
 | 
			
		||||
                    GNU GENERAL PUBLIC LICENSE
 | 
			
		||||
                       Version 2, June 1991
 | 
			
		||||
 | 
			
		||||
Copyright (c) 2003-present The IdeaVim authors
 | 
			
		||||
 Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
 | 
			
		||||
 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 | 
			
		||||
 Everyone is permitted to copy and distribute verbatim copies
 | 
			
		||||
 of this license document, but changing it is not allowed.
 | 
			
		||||
 | 
			
		||||
Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
			
		||||
of this software and associated documentation files (the "Software"), to deal
 | 
			
		||||
in the Software without restriction, including without limitation the rights
 | 
			
		||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
			
		||||
copies of the Software, and to permit persons to whom the Software is
 | 
			
		||||
furnished to do so, subject to the following conditions:
 | 
			
		||||
                            Preamble
 | 
			
		||||
 | 
			
		||||
The above copyright notice and this permission notice shall be included in all
 | 
			
		||||
copies or substantial portions of the Software.
 | 
			
		||||
  The licenses for most software are designed to take away your
 | 
			
		||||
freedom to share and change it.  By contrast, the GNU General Public
 | 
			
		||||
License is intended to guarantee your freedom to share and change free
 | 
			
		||||
software--to make sure the software is free for all its users.  This
 | 
			
		||||
General Public License applies to most of the Free Software
 | 
			
		||||
Foundation's software and to any other program whose authors commit to
 | 
			
		||||
using it.  (Some other Free Software Foundation software is covered by
 | 
			
		||||
the GNU Lesser General Public License instead.)  You can apply it to
 | 
			
		||||
your programs, too.
 | 
			
		||||
 | 
			
		||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
			
		||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
			
		||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
			
		||||
SOFTWARE.
 | 
			
		||||
  When we speak of free software, we are referring to freedom, not
 | 
			
		||||
price.  Our General Public Licenses are designed to make sure that you
 | 
			
		||||
have the freedom to distribute copies of free software (and charge for
 | 
			
		||||
this service if you wish), that you receive source code or can get it
 | 
			
		||||
if you want it, that you can change the software or use pieces of it
 | 
			
		||||
in new free programs; and that you know you can do these things.
 | 
			
		||||
 | 
			
		||||
  To protect your rights, we need to make restrictions that forbid
 | 
			
		||||
anyone to deny you these rights or to ask you to surrender the rights.
 | 
			
		||||
These restrictions translate to certain responsibilities for you if you
 | 
			
		||||
distribute copies of the software, or if you modify it.
 | 
			
		||||
 | 
			
		||||
  For example, if you distribute copies of such a program, whether
 | 
			
		||||
gratis or for a fee, you must give the recipients all the rights that
 | 
			
		||||
you have.  You must make sure that they, too, receive or can get the
 | 
			
		||||
source code.  And you must show them these terms so they know their
 | 
			
		||||
rights.
 | 
			
		||||
 | 
			
		||||
  We protect your rights with two steps: (1) copyright the software, and
 | 
			
		||||
(2) offer you this license which gives you legal permission to copy,
 | 
			
		||||
distribute and/or modify the software.
 | 
			
		||||
 | 
			
		||||
  Also, for each author's protection and ours, we want to make certain
 | 
			
		||||
that everyone understands that there is no warranty for this free
 | 
			
		||||
software.  If the software is modified by someone else and passed on, we
 | 
			
		||||
want its recipients to know that what they have is not the original, so
 | 
			
		||||
that any problems introduced by others will not reflect on the original
 | 
			
		||||
authors' reputations.
 | 
			
		||||
 | 
			
		||||
  Finally, any free program is threatened constantly by software
 | 
			
		||||
patents.  We wish to avoid the danger that redistributors of a free
 | 
			
		||||
program will individually obtain patent licenses, in effect making the
 | 
			
		||||
program proprietary.  To prevent this, we have made it clear that any
 | 
			
		||||
patent must be licensed for everyone's free use or not licensed at all.
 | 
			
		||||
 | 
			
		||||
  The precise terms and conditions for copying, distribution and
 | 
			
		||||
modification follow.
 | 
			
		||||
 | 
			
		||||
                    GNU GENERAL PUBLIC LICENSE
 | 
			
		||||
   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
 | 
			
		||||
 | 
			
		||||
  0. This License applies to any program or other work which contains
 | 
			
		||||
a notice placed by the copyright holder saying it may be distributed
 | 
			
		||||
under the terms of this General Public License.  The "Program", below,
 | 
			
		||||
refers to any such program or work, and a "work based on the Program"
 | 
			
		||||
means either the Program or any derivative work under copyright law:
 | 
			
		||||
that is to say, a work containing the Program or a portion of it,
 | 
			
		||||
either verbatim or with modifications and/or translated into another
 | 
			
		||||
language.  (Hereinafter, translation is included without limitation in
 | 
			
		||||
the term "modification".)  Each licensee is addressed as "you".
 | 
			
		||||
 | 
			
		||||
Activities other than copying, distribution and modification are not
 | 
			
		||||
covered by this License; they are outside its scope.  The act of
 | 
			
		||||
running the Program is not restricted, and the output from the Program
 | 
			
		||||
is covered only if its contents constitute a work based on the
 | 
			
		||||
Program (independent of having been made by running the Program).
 | 
			
		||||
Whether that is true depends on what the Program does.
 | 
			
		||||
 | 
			
		||||
  1. You may copy and distribute verbatim copies of the Program's
 | 
			
		||||
source code as you receive it, in any medium, provided that you
 | 
			
		||||
conspicuously and appropriately publish on each copy an appropriate
 | 
			
		||||
copyright notice and disclaimer of warranty; keep intact all the
 | 
			
		||||
notices that refer to this License and to the absence of any warranty;
 | 
			
		||||
and give any other recipients of the Program a copy of this License
 | 
			
		||||
along with the Program.
 | 
			
		||||
 | 
			
		||||
You may charge a fee for the physical act of transferring a copy, and
 | 
			
		||||
you may at your option offer warranty protection in exchange for a fee.
 | 
			
		||||
 | 
			
		||||
  2. You may modify your copy or copies of the Program or any portion
 | 
			
		||||
of it, thus forming a work based on the Program, and copy and
 | 
			
		||||
distribute such modifications or work under the terms of Section 1
 | 
			
		||||
above, provided that you also meet all of these conditions:
 | 
			
		||||
 | 
			
		||||
    a) You must cause the modified files to carry prominent notices
 | 
			
		||||
    stating that you changed the files and the date of any change.
 | 
			
		||||
 | 
			
		||||
    b) You must cause any work that you distribute or publish, that in
 | 
			
		||||
    whole or in part contains or is derived from the Program or any
 | 
			
		||||
    part thereof, to be licensed as a whole at no charge to all third
 | 
			
		||||
    parties under the terms of this License.
 | 
			
		||||
 | 
			
		||||
    c) If the modified program normally reads commands interactively
 | 
			
		||||
    when run, you must cause it, when started running for such
 | 
			
		||||
    interactive use in the most ordinary way, to print or display an
 | 
			
		||||
    announcement including an appropriate copyright notice and a
 | 
			
		||||
    notice that there is no warranty (or else, saying that you provide
 | 
			
		||||
    a warranty) and that users may redistribute the program under
 | 
			
		||||
    these conditions, and telling the user how to view a copy of this
 | 
			
		||||
    License.  (Exception: if the Program itself is interactive but
 | 
			
		||||
    does not normally print such an announcement, your work based on
 | 
			
		||||
    the Program is not required to print an announcement.)
 | 
			
		||||
 | 
			
		||||
These requirements apply to the modified work as a whole.  If
 | 
			
		||||
identifiable sections of that work are not derived from the Program,
 | 
			
		||||
and can be reasonably considered independent and separate works in
 | 
			
		||||
themselves, then this License, and its terms, do not apply to those
 | 
			
		||||
sections when you distribute them as separate works.  But when you
 | 
			
		||||
distribute the same sections as part of a whole which is a work based
 | 
			
		||||
on the Program, the distribution of the whole must be on the terms of
 | 
			
		||||
this License, whose permissions for other licensees extend to the
 | 
			
		||||
entire whole, and thus to each and every part regardless of who wrote it.
 | 
			
		||||
 | 
			
		||||
Thus, it is not the intent of this section to claim rights or contest
 | 
			
		||||
your rights to work written entirely by you; rather, the intent is to
 | 
			
		||||
exercise the right to control the distribution of derivative or
 | 
			
		||||
collective works based on the Program.
 | 
			
		||||
 | 
			
		||||
In addition, mere aggregation of another work not based on the Program
 | 
			
		||||
with the Program (or with a work based on the Program) on a volume of
 | 
			
		||||
a storage or distribution medium does not bring the other work under
 | 
			
		||||
the scope of this License.
 | 
			
		||||
 | 
			
		||||
  3. You may copy and distribute the Program (or a work based on it,
 | 
			
		||||
under Section 2) in object code or executable form under the terms of
 | 
			
		||||
Sections 1 and 2 above provided that you also do one of the following:
 | 
			
		||||
 | 
			
		||||
    a) Accompany it with the complete corresponding machine-readable
 | 
			
		||||
    source code, which must be distributed under the terms of Sections
 | 
			
		||||
    1 and 2 above on a medium customarily used for software interchange; or,
 | 
			
		||||
 | 
			
		||||
    b) Accompany it with a written offer, valid for at least three
 | 
			
		||||
    years, to give any third party, for a charge no more than your
 | 
			
		||||
    cost of physically performing source distribution, a complete
 | 
			
		||||
    machine-readable copy of the corresponding source code, to be
 | 
			
		||||
    distributed under the terms of Sections 1 and 2 above on a medium
 | 
			
		||||
    customarily used for software interchange; or,
 | 
			
		||||
 | 
			
		||||
    c) Accompany it with the information you received as to the offer
 | 
			
		||||
    to distribute corresponding source code.  (This alternative is
 | 
			
		||||
    allowed only for noncommercial distribution and only if you
 | 
			
		||||
    received the program in object code or executable form with such
 | 
			
		||||
    an offer, in accord with Subsection b above.)
 | 
			
		||||
 | 
			
		||||
The source code for a work means the preferred form of the work for
 | 
			
		||||
making modifications to it.  For an executable work, complete source
 | 
			
		||||
code means all the source code for all modules it contains, plus any
 | 
			
		||||
associated interface definition files, plus the scripts used to
 | 
			
		||||
control compilation and installation of the executable.  However, as a
 | 
			
		||||
special exception, the source code distributed need not include
 | 
			
		||||
anything that is normally distributed (in either source or binary
 | 
			
		||||
form) with the major components (compiler, kernel, and so on) of the
 | 
			
		||||
operating system on which the executable runs, unless that component
 | 
			
		||||
itself accompanies the executable.
 | 
			
		||||
 | 
			
		||||
If distribution of executable or object code is made by offering
 | 
			
		||||
access to copy from a designated place, then offering equivalent
 | 
			
		||||
access to copy the source code from the same place counts as
 | 
			
		||||
distribution of the source code, even though third parties are not
 | 
			
		||||
compelled to copy the source along with the object code.
 | 
			
		||||
 | 
			
		||||
  4. You may not copy, modify, sublicense, or distribute the Program
 | 
			
		||||
except as expressly provided under this License.  Any attempt
 | 
			
		||||
otherwise to copy, modify, sublicense or distribute the Program is
 | 
			
		||||
void, and will automatically terminate your rights under this License.
 | 
			
		||||
However, parties who have received copies, or rights, from you under
 | 
			
		||||
this License will not have their licenses terminated so long as such
 | 
			
		||||
parties remain in full compliance.
 | 
			
		||||
 | 
			
		||||
  5. You are not required to accept this License, since you have not
 | 
			
		||||
signed it.  However, nothing else grants you permission to modify or
 | 
			
		||||
distribute the Program or its derivative works.  These actions are
 | 
			
		||||
prohibited by law if you do not accept this License.  Therefore, by
 | 
			
		||||
modifying or distributing the Program (or any work based on the
 | 
			
		||||
Program), you indicate your acceptance of this License to do so, and
 | 
			
		||||
all its terms and conditions for copying, distributing or modifying
 | 
			
		||||
the Program or works based on it.
 | 
			
		||||
 | 
			
		||||
  6. Each time you redistribute the Program (or any work based on the
 | 
			
		||||
Program), the recipient automatically receives a license from the
 | 
			
		||||
original licensor to copy, distribute or modify the Program subject to
 | 
			
		||||
these terms and conditions.  You may not impose any further
 | 
			
		||||
restrictions on the recipients' exercise of the rights granted herein.
 | 
			
		||||
You are not responsible for enforcing compliance by third parties to
 | 
			
		||||
this License.
 | 
			
		||||
 | 
			
		||||
  7. If, as a consequence of a court judgment or allegation of patent
 | 
			
		||||
infringement or for any other reason (not limited to patent issues),
 | 
			
		||||
conditions are imposed on you (whether by court order, agreement or
 | 
			
		||||
otherwise) that contradict the conditions of this License, they do not
 | 
			
		||||
excuse you from the conditions of this License.  If you cannot
 | 
			
		||||
distribute so as to satisfy simultaneously your obligations under this
 | 
			
		||||
License and any other pertinent obligations, then as a consequence you
 | 
			
		||||
may not distribute the Program at all.  For example, if a patent
 | 
			
		||||
license would not permit royalty-free redistribution of the Program by
 | 
			
		||||
all those who receive copies directly or indirectly through you, then
 | 
			
		||||
the only way you could satisfy both it and this License would be to
 | 
			
		||||
refrain entirely from distribution of the Program.
 | 
			
		||||
 | 
			
		||||
If any portion of this section is held invalid or unenforceable under
 | 
			
		||||
any particular circumstance, the balance of the section is intended to
 | 
			
		||||
apply and the section as a whole is intended to apply in other
 | 
			
		||||
circumstances.
 | 
			
		||||
 | 
			
		||||
It is not the purpose of this section to induce you to infringe any
 | 
			
		||||
patents or other property right claims or to contest validity of any
 | 
			
		||||
such claims; this section has the sole purpose of protecting the
 | 
			
		||||
integrity of the free software distribution system, which is
 | 
			
		||||
implemented by public license practices.  Many people have made
 | 
			
		||||
generous contributions to the wide range of software distributed
 | 
			
		||||
through that system in reliance on consistent application of that
 | 
			
		||||
system; it is up to the author/donor to decide if he or she is willing
 | 
			
		||||
to distribute software through any other system and a licensee cannot
 | 
			
		||||
impose that choice.
 | 
			
		||||
 | 
			
		||||
This section is intended to make thoroughly clear what is believed to
 | 
			
		||||
be a consequence of the rest of this License.
 | 
			
		||||
 | 
			
		||||
  8. If the distribution and/or use of the Program is restricted in
 | 
			
		||||
certain countries either by patents or by copyrighted interfaces, the
 | 
			
		||||
original copyright holder who places the Program under this License
 | 
			
		||||
may add an explicit geographical distribution limitation excluding
 | 
			
		||||
those countries, so that distribution is permitted only in or among
 | 
			
		||||
countries not thus excluded.  In such case, this License incorporates
 | 
			
		||||
the limitation as if written in the body of this License.
 | 
			
		||||
 | 
			
		||||
  9. The Free Software Foundation may publish revised and/or new versions
 | 
			
		||||
of the General Public License from time to time.  Such new versions will
 | 
			
		||||
be similar in spirit to the present version, but may differ in detail to
 | 
			
		||||
address new problems or concerns.
 | 
			
		||||
 | 
			
		||||
Each version is given a distinguishing version number.  If the Program
 | 
			
		||||
specifies a version number of this License which applies to it and "any
 | 
			
		||||
later version", you have the option of following the terms and conditions
 | 
			
		||||
either of that version or of any later version published by the Free
 | 
			
		||||
Software Foundation.  If the Program does not specify a version number of
 | 
			
		||||
this License, you may choose any version ever published by the Free Software
 | 
			
		||||
Foundation.
 | 
			
		||||
 | 
			
		||||
  10. If you wish to incorporate parts of the Program into other free
 | 
			
		||||
programs whose distribution conditions are different, write to the author
 | 
			
		||||
to ask for permission.  For software which is copyrighted by the Free
 | 
			
		||||
Software Foundation, write to the Free Software Foundation; we sometimes
 | 
			
		||||
make exceptions for this.  Our decision will be guided by the two goals
 | 
			
		||||
of preserving the free status of all derivatives of our free software and
 | 
			
		||||
of promoting the sharing and reuse of software generally.
 | 
			
		||||
 | 
			
		||||
                            NO WARRANTY
 | 
			
		||||
 | 
			
		||||
  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
 | 
			
		||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
 | 
			
		||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
 | 
			
		||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
 | 
			
		||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 | 
			
		||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
 | 
			
		||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
 | 
			
		||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
 | 
			
		||||
REPAIR OR CORRECTION.
 | 
			
		||||
 | 
			
		||||
  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
 | 
			
		||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
 | 
			
		||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
 | 
			
		||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
 | 
			
		||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
 | 
			
		||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
 | 
			
		||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
 | 
			
		||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
 | 
			
		||||
POSSIBILITY OF SUCH DAMAGES.
 | 
			
		||||
 | 
			
		||||
                     END OF TERMS AND CONDITIONS
 | 
			
		||||
 | 
			
		||||
            How to Apply These Terms to Your New Programs
 | 
			
		||||
 | 
			
		||||
  If you develop a new program, and you want it to be of the greatest
 | 
			
		||||
possible use to the public, the best way to achieve this is to make it
 | 
			
		||||
free software which everyone can redistribute and change under these terms.
 | 
			
		||||
 | 
			
		||||
  To do so, attach the following notices to the program.  It is safest
 | 
			
		||||
to attach them to the start of each source file to most effectively
 | 
			
		||||
convey the exclusion of warranty; and each file should have at least
 | 
			
		||||
the "copyright" line and a pointer to where the full notice is found.
 | 
			
		||||
 | 
			
		||||
    <one line to give the program's name and a brief idea of what it does.>
 | 
			
		||||
    Copyright (C) <year>  <name of author>
 | 
			
		||||
 | 
			
		||||
    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, write to the Free Software Foundation, Inc.,
 | 
			
		||||
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 | 
			
		||||
Also add information on how to contact you by electronic and paper mail.
 | 
			
		||||
 | 
			
		||||
If the program is interactive, make it output a short notice like this
 | 
			
		||||
when it starts in an interactive mode:
 | 
			
		||||
 | 
			
		||||
    Gnomovision version 69, Copyright (C) year name of author
 | 
			
		||||
    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
 | 
			
		||||
    This is free software, and you are welcome to redistribute it
 | 
			
		||||
    under certain conditions; type `show c' for details.
 | 
			
		||||
 | 
			
		||||
The hypothetical commands `show w' and `show c' should show the appropriate
 | 
			
		||||
parts of the General Public License.  Of course, the commands you use may
 | 
			
		||||
be called something other than `show w' and `show c'; they could even be
 | 
			
		||||
mouse-clicks or menu items--whatever suits your program.
 | 
			
		||||
 | 
			
		||||
You should also get your employer (if you work as a programmer) or your
 | 
			
		||||
school, if any, to sign a "copyright disclaimer" for the program, if
 | 
			
		||||
necessary.  Here is a sample; alter the names:
 | 
			
		||||
 | 
			
		||||
  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
 | 
			
		||||
  `Gnomovision' (which makes passes at compilers) written by James Hacker.
 | 
			
		||||
 | 
			
		||||
  <signature of Ty Coon>, 1 April 1989
 | 
			
		||||
  Ty Coon, President of Vice
 | 
			
		||||
 | 
			
		||||
This General Public License does not permit incorporating your program into
 | 
			
		||||
proprietary programs.  If your program is a subroutine library, you may
 | 
			
		||||
consider it more useful to permit linking proprietary applications with the
 | 
			
		||||
library.  If this is what you want to do, use the GNU Lesser General
 | 
			
		||||
Public License instead of this License.
 | 
			
		||||
							
								
								
									
										10
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								README.md
									
									
									
									
									
								
							@@ -9,7 +9,6 @@ IdeaVim
 | 
			
		||||
[![Rating][plugin-rating-svg]][plugin-repo]
 | 
			
		||||
[![Version][plugin-version-svg]][plugin-repo]
 | 
			
		||||
[![Gitter][gitter-svg]][gitter]
 | 
			
		||||
[](https://codecov.io/gh/JetBrains/ideavim)
 | 
			
		||||
[![Twitter][twitter-svg]][twitter]
 | 
			
		||||
 | 
			
		||||
IdeaVim is a Vim engine for JetBrains IDEs.
 | 
			
		||||
@@ -365,13 +364,8 @@ is the full list of synonyms.
 | 
			
		||||
License
 | 
			
		||||
-------
 | 
			
		||||
 | 
			
		||||
IdeaVim is licensed under the MIT license.
 | 
			
		||||
 | 
			
		||||
Third-party components and licenses are listed in [ThirdPartyLicenses.md](ThirdPartyLicenses.md).
 | 
			
		||||
 | 
			
		||||
All releases before 2.0.0 were licensed under terms of GPL-2.0 or later.
 | 
			
		||||
The last commit before switch to MIT is 05852b07c6090ad40fde7d3cafe0b074604f7ac5.
 | 
			
		||||
You can read more about the license change here: https://github.com/JetBrains/ideavim/discussions/543
 | 
			
		||||
IdeaVim is licensed under the terms of the GNU Public License version 2
 | 
			
		||||
or any later version.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<!-- Badges -->
 | 
			
		||||
 
 | 
			
		||||
@@ -1,84 +0,0 @@
 | 
			
		||||
IdeaVim project is licensed under MIT license except the following parts of it:
 | 
			
		||||
 | 
			
		||||
File [RegExp.kt](src/main/java/com/maddyhome/idea/vim/regexp/RegExp.kt) is licensed under Vim License.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
VIM LICENSE
 | 
			
		||||
 | 
			
		||||
I)  There are no restrictions on distributing unmodified copies of Vim except
 | 
			
		||||
    that they must include this license text.  You can also distribute
 | 
			
		||||
    unmodified parts of Vim, likewise unrestricted except that they must
 | 
			
		||||
    include this license text.  You are also allowed to include executables
 | 
			
		||||
    that you made from the unmodified Vim sources, plus your own usage
 | 
			
		||||
    examples and Vim scripts.
 | 
			
		||||
 | 
			
		||||
II) It is allowed to distribute a modified (or extended) version of Vim,
 | 
			
		||||
    including executables and/or source code, when the following four
 | 
			
		||||
    conditions are met:
 | 
			
		||||
    1) This license text must be included unmodified.
 | 
			
		||||
    2) The modified Vim must be distributed in one of the following five ways:
 | 
			
		||||
       a) If you make changes to Vim yourself, you must clearly describe in
 | 
			
		||||
          the distribution how to contact you.  When the maintainer asks you
 | 
			
		||||
          (in any way) for a copy of the modified Vim you distributed, you
 | 
			
		||||
          must make your changes, including source code, available to the
 | 
			
		||||
          maintainer without fee.  The maintainer reserves the right to
 | 
			
		||||
          include your changes in the official version of Vim.  What the
 | 
			
		||||
          maintainer will do with your changes and under what license they
 | 
			
		||||
          will be distributed is negotiable.  If there has been no negotiation
 | 
			
		||||
          then this license, or a later version, also applies to your changes.
 | 
			
		||||
          The current maintainer is Bram Moolenaar <Bram@vim.org>.  If this
 | 
			
		||||
          changes it will be announced in appropriate places (most likely
 | 
			
		||||
          vim.sf.net, www.vim.org and/or comp.editors). When it is completely
 | 
			
		||||
          impossible to contact the maintainer, the obligation to send him
 | 
			
		||||
          your changes ceases.  Once the maintainer has confirmed that he has
 | 
			
		||||
          received your changes they will not have to be sent again.
 | 
			
		||||
       b) If you have received a modified Vim that was distributed as
 | 
			
		||||
          mentioned under a) you are allowed to further distribute it
 | 
			
		||||
          unmodified, as mentioned at I).  If you make additional changes the
 | 
			
		||||
          text under a) applies to those changes.
 | 
			
		||||
       c) Provide all the changes, including source code, with every copy of
 | 
			
		||||
          the modified Vim you distribute.  This may be done in the form of a
 | 
			
		||||
          context diff.  You can choose what license to use for new code you
 | 
			
		||||
          add.  The changes and their license must not restrict others from
 | 
			
		||||
          making their own changes to the official version of Vim.
 | 
			
		||||
       d) When you have a modified Vim which includes changes as mentioned
 | 
			
		||||
          under c), you can distribute it without the source code for the
 | 
			
		||||
          changes if the following three conditions are met:
 | 
			
		||||
          - The license that applies to the changes permits you to distribute
 | 
			
		||||
            the changes to the Vim maintainer without fee or restriction, and
 | 
			
		||||
            permits the Vim maintainer to include the changes in the official
 | 
			
		||||
            version of Vim without fee or restriction.
 | 
			
		||||
          - You keep the changes for at least three years after last
 | 
			
		||||
            distributing the corresponding modified Vim.  When the maintainer
 | 
			
		||||
            or someone who you distributed the modified Vim to asks you (in
 | 
			
		||||
            any way) for the changes within this period, you must make them
 | 
			
		||||
            available to him.
 | 
			
		||||
          - You clearly describe in the distribution how to contact you.  This
 | 
			
		||||
            contact information must remain valid for at least three years
 | 
			
		||||
            after last distributing the corresponding modified Vim, or as long
 | 
			
		||||
            as possible.
 | 
			
		||||
       e) When the GNU General Public License (GPL) applies to the changes,
 | 
			
		||||
          you can distribute the modified Vim under the GNU GPL version 2 or
 | 
			
		||||
          any later version.
 | 
			
		||||
    3) A message must be added, at least in the output of the ":version"
 | 
			
		||||
       command and in the intro screen, such that the user of the modified Vim
 | 
			
		||||
       is able to see that it was modified.  When distributing as mentioned
 | 
			
		||||
       under 2)e) adding the message is only required for as far as this does
 | 
			
		||||
       not conflict with the license used for the changes.
 | 
			
		||||
    4) The contact information as required under 2)a) and 2)d) must not be
 | 
			
		||||
       removed or changed, except that the person himself can make
 | 
			
		||||
       corrections.
 | 
			
		||||
 | 
			
		||||
III) If you distribute a modified version of Vim, you are encouraged to use
 | 
			
		||||
     the Vim license for your changes and make them available to the
 | 
			
		||||
     maintainer, including the source code.  The preferred way to do this is
 | 
			
		||||
     by e-mail or by uploading the files to a server and e-mailing the URL.
 | 
			
		||||
     If the number of changes is small (e.g., a modified Makefile) e-mailing a
 | 
			
		||||
     context diff will do.  The e-mail address to be used is
 | 
			
		||||
     <maintainer@vim.org>
 | 
			
		||||
 | 
			
		||||
IV)  It is not allowed to remove this license from the distribution of the Vim
 | 
			
		||||
     sources, parts of it or from a modified version.  You may use this
 | 
			
		||||
     license for previous Vim releases instead of the license that they came
 | 
			
		||||
     with, at your option.
 | 
			
		||||
```
 | 
			
		||||
							
								
								
									
										380
									
								
								build.gradle.kts
									
									
									
									
									
								
							
							
						
						
									
										380
									
								
								build.gradle.kts
									
									
									
									
									
								
							@@ -1,35 +1,5 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import dev.feedforward.markdownto.DownParser
 | 
			
		||||
import io.ktor.client.*
 | 
			
		||||
import io.ktor.client.call.*
 | 
			
		||||
import io.ktor.client.engine.cio.*
 | 
			
		||||
import io.ktor.client.plugins.auth.*
 | 
			
		||||
import io.ktor.client.plugins.auth.providers.*
 | 
			
		||||
import io.ktor.client.plugins.contentnegotiation.*
 | 
			
		||||
import io.ktor.client.request.*
 | 
			
		||||
import io.ktor.http.*
 | 
			
		||||
import io.ktor.serialization.kotlinx.json.*
 | 
			
		||||
import kotlinx.coroutines.runBlocking
 | 
			
		||||
import kotlinx.serialization.json.Json
 | 
			
		||||
import kotlinx.serialization.json.JsonArray
 | 
			
		||||
import kotlinx.serialization.json.JsonObject
 | 
			
		||||
import kotlinx.serialization.json.addJsonObject
 | 
			
		||||
import kotlinx.serialization.json.buildJsonObject
 | 
			
		||||
import kotlinx.serialization.json.jsonArray
 | 
			
		||||
import kotlinx.serialization.json.jsonObject
 | 
			
		||||
import kotlinx.serialization.json.jsonPrimitive
 | 
			
		||||
import kotlinx.serialization.json.put
 | 
			
		||||
import kotlinx.serialization.json.putJsonArray
 | 
			
		||||
import kotlinx.serialization.json.putJsonObject
 | 
			
		||||
import org.eclipse.jgit.api.Git
 | 
			
		||||
import org.eclipse.jgit.lib.RepositoryBuilder
 | 
			
		||||
import org.intellij.markdown.ast.getTextInNode
 | 
			
		||||
import java.net.HttpURLConnection
 | 
			
		||||
import java.net.URL
 | 
			
		||||
@@ -41,17 +11,11 @@ buildscript {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    dependencies {
 | 
			
		||||
        classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.20")
 | 
			
		||||
        classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.21")
 | 
			
		||||
        classpath("com.github.AlexPl292:mark-down-to-slack:1.1.2")
 | 
			
		||||
        classpath("org.eclipse.jgit:org.eclipse.jgit:6.1.0.202203080745-r")
 | 
			
		||||
        classpath("org.kohsuke:github-api:1.305")
 | 
			
		||||
 | 
			
		||||
        classpath("io.ktor:ktor-client-core:2.1.3")
 | 
			
		||||
        classpath("io.ktor:ktor-client-cio:2.1.3")
 | 
			
		||||
        classpath("io.ktor:ktor-client-auth:2.1.3")
 | 
			
		||||
        classpath("io.ktor:ktor-client-content-negotiation:2.1.3")
 | 
			
		||||
        classpath("io.ktor:ktor-serialization-kotlinx-json:2.1.3")
 | 
			
		||||
 | 
			
		||||
        // This comes from the changelog plugin
 | 
			
		||||
//        classpath("org.jetbrains:markdown:0.3.1")
 | 
			
		||||
    }
 | 
			
		||||
@@ -60,16 +24,13 @@ buildscript {
 | 
			
		||||
plugins {
 | 
			
		||||
    antlr
 | 
			
		||||
    java
 | 
			
		||||
    kotlin("jvm") version "1.7.20"
 | 
			
		||||
    kotlin("jvm") version "1.6.21"
 | 
			
		||||
 | 
			
		||||
    id("org.jetbrains.intellij") version "1.11.1-SNAPSHOT"
 | 
			
		||||
    id("org.jetbrains.intellij") version "1.10.0-SNAPSHOT"
 | 
			
		||||
    id("org.jetbrains.changelog") version "1.3.1"
 | 
			
		||||
 | 
			
		||||
    // ktlint linter - read more: https://github.com/JLLeitschuh/ktlint-gradle
 | 
			
		||||
    id("org.jlleitschuh.gradle.ktlint") version "10.3.0"
 | 
			
		||||
 | 
			
		||||
    id("org.jetbrains.kotlinx.kover") version "0.6.1"
 | 
			
		||||
    id("com.dorongold.task-tree") version "2.1.0"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Import variables from gradle.properties file
 | 
			
		||||
@@ -85,7 +46,6 @@ val publishChannels: String by project
 | 
			
		||||
val publishToken: String by project
 | 
			
		||||
 | 
			
		||||
val slackUrl: String by project
 | 
			
		||||
val youtrackToken: String by project
 | 
			
		||||
 | 
			
		||||
repositories {
 | 
			
		||||
    mavenCentral()
 | 
			
		||||
@@ -214,7 +174,7 @@ java {
 | 
			
		||||
 | 
			
		||||
kotlin {
 | 
			
		||||
    jvmToolchain {
 | 
			
		||||
        languageVersion.set(JavaLanguageVersion.of(javaVersion))
 | 
			
		||||
        (this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(javaVersion))
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -272,13 +232,9 @@ tasks {
 | 
			
		||||
    named("compileKotlin") {
 | 
			
		||||
        dependsOn("generateGrammarSource")
 | 
			
		||||
    }
 | 
			
		||||
    named("compileTestKotlin") {
 | 
			
		||||
        dependsOn("generateTestGrammarSource")
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Add plugin open API sources to the plugin ZIP
 | 
			
		||||
    val createOpenApiSourceJar by registering(Jar::class) {
 | 
			
		||||
        dependsOn("generateGrammarSource")
 | 
			
		||||
        // Java sources
 | 
			
		||||
        from(sourceSets.main.get().java) {
 | 
			
		||||
            include("**/com/maddyhome/idea/vim/**/*.java")
 | 
			
		||||
@@ -298,7 +254,7 @@ tasks {
 | 
			
		||||
 | 
			
		||||
    // Don't forget to update plugin.xml
 | 
			
		||||
    patchPluginXml {
 | 
			
		||||
        sinceBuild.set("223.7401.7")
 | 
			
		||||
        sinceBuild.set("222")
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -344,22 +300,6 @@ tasks.register("getUnreleasedChangelog") {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// --- Kover
 | 
			
		||||
 | 
			
		||||
koverMerged {
 | 
			
		||||
    enable()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
kover {
 | 
			
		||||
    instrumentation {
 | 
			
		||||
        // set of test tasks names to exclude from instrumentation. The results of their execution will not be presented in the report
 | 
			
		||||
        excludeTasks += "testPropertyBased"
 | 
			
		||||
        excludeTasks += "testLongRunning"
 | 
			
		||||
        excludeTasks += "testWithNeovim"
 | 
			
		||||
        excludeTasks += "testUi"
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// --- Slack notification
 | 
			
		||||
 | 
			
		||||
tasks.register("slackNotification") {
 | 
			
		||||
@@ -424,7 +364,6 @@ tasks.register("updateAuthors") {
 | 
			
		||||
            "aleksei.plate@TeamCity",
 | 
			
		||||
            "alex.plate@192.168.0.109",
 | 
			
		||||
            "nikita.koshcheev@TeamCity",
 | 
			
		||||
            "TeamCity@TeamCity",
 | 
			
		||||
        )
 | 
			
		||||
        updateAuthors(uncheckedEmails)
 | 
			
		||||
    }
 | 
			
		||||
@@ -449,82 +388,6 @@ tasks.register("updateChangelog") {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
tasks.register("updateYoutrackOnCommit") {
 | 
			
		||||
    doLast {
 | 
			
		||||
        updateYoutrackOnCommit()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
val vimProjectId = "22-43"
 | 
			
		||||
val fixVersionsFieldId = "123-285"
 | 
			
		||||
val fixVersionsFieldType = "VersionProjectCustomField"
 | 
			
		||||
val fixVersionsElementType = "VersionBundleElement"
 | 
			
		||||
 | 
			
		||||
tasks.register("releaseActions") {
 | 
			
		||||
    group = "other"
 | 
			
		||||
    doLast {
 | 
			
		||||
        val tickets = getYoutrackTicketsByQuery("%23%7BReady+To+Release%7D")
 | 
			
		||||
        if (tickets.isNotEmpty()) {
 | 
			
		||||
            println("Updating statuses for tickets: $tickets")
 | 
			
		||||
            setYoutrackStatus(tickets, "Fixed")
 | 
			
		||||
            if (!checkReleaseVersionExists(version.toString())) {
 | 
			
		||||
                addReleaseToYoutrack(version.toString())
 | 
			
		||||
            } else {
 | 
			
		||||
                println("Version $version is already exists in YouTrack")
 | 
			
		||||
            }
 | 
			
		||||
            setYoutrackFixVersion(tickets, version.toString())
 | 
			
		||||
        } else {
 | 
			
		||||
            println("No tickets to update statuses")
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
tasks.register("integrationsTest") {
 | 
			
		||||
    group = "other"
 | 
			
		||||
    doLast {
 | 
			
		||||
        val testTicketId = "VIM-2784"
 | 
			
		||||
 | 
			
		||||
        // YouTrack set to Ready To Release on Fix commit
 | 
			
		||||
        setYoutrackStatus(listOf(testTicketId), "Ready To Release")
 | 
			
		||||
        if ("Ready To Release" != getYoutrackStatus(testTicketId)) {
 | 
			
		||||
            error("Ticket status was not updated")
 | 
			
		||||
        }
 | 
			
		||||
        setYoutrackStatus(listOf(testTicketId), "Open")
 | 
			
		||||
 | 
			
		||||
        // Check YouTrack requests
 | 
			
		||||
        val prevStatus = getYoutrackStatus(testTicketId)
 | 
			
		||||
        setYoutrackStatus(listOf(testTicketId), "Ready To Release")
 | 
			
		||||
        val tickets = getYoutrackTicketsByQuery("%23%7BReady+To+Release%7D")
 | 
			
		||||
        if (testTicketId !in tickets) {
 | 
			
		||||
            error("Test ticket is not found in request")
 | 
			
		||||
        }
 | 
			
		||||
        setYoutrackStatus(listOf(testTicketId), prevStatus)
 | 
			
		||||
 | 
			
		||||
        // Check adding and removing release
 | 
			
		||||
        guard(!checkReleaseVersionExists("TEST_VERSION")) { "Test version already exists" }
 | 
			
		||||
        val versionId = addReleaseToYoutrack("TEST_VERSION")
 | 
			
		||||
        guard(checkReleaseVersionExists("TEST_VERSION")) { "Test version isn't created" }
 | 
			
		||||
        setYoutrackStatus(listOf(testTicketId), "Fixed")
 | 
			
		||||
        setYoutrackFixVersion(listOf(testTicketId), "TEST_VERSION")
 | 
			
		||||
        deleteVersionById(versionId)
 | 
			
		||||
        setYoutrackStatus(listOf(testTicketId), "Open")
 | 
			
		||||
        guard(!checkReleaseVersionExists("TEST_VERSION")) { "Test version isn't deleted" }
 | 
			
		||||
 | 
			
		||||
        updateMergedPr(525)
 | 
			
		||||
        // TODO: test Ticket parsing
 | 
			
		||||
        // TODO: test Update CHANGES
 | 
			
		||||
        // TODO: test Update AUTHORS
 | 
			
		||||
        // TODO: test Slack notification
 | 
			
		||||
        // TODO: Add a comment on EAP release
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fun guard(check: Boolean, ifWrong: () -> String) {
 | 
			
		||||
    if (!check) {
 | 
			
		||||
        error(ifWrong())
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
tasks.register("testUpdateChangelog") {
 | 
			
		||||
    group = "verification"
 | 
			
		||||
    description = "This is a task to manually assert the correctness of the update tasks"
 | 
			
		||||
@@ -541,152 +404,37 @@ tasks.register("testUpdateChangelog") {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fun addReleaseToYoutrack(name: String): String {
 | 
			
		||||
    val client = httpClient()
 | 
			
		||||
    println("Creating new release version in YouTrack: $name")
 | 
			
		||||
 | 
			
		||||
    return runBlocking {
 | 
			
		||||
        val response = client.post("https://youtrack.jetbrains.com/api/admin/projects/$vimProjectId/customFields/$fixVersionsFieldId/bundle/values?fields=id,name") {
 | 
			
		||||
            contentType(ContentType.Application.Json)
 | 
			
		||||
            accept(ContentType.Application.Json)
 | 
			
		||||
            val request = buildJsonObject {
 | 
			
		||||
                put("name", name)
 | 
			
		||||
                put("\$type", fixVersionsElementType)
 | 
			
		||||
            }
 | 
			
		||||
            setBody(request)
 | 
			
		||||
        }
 | 
			
		||||
        response.body<JsonObject>().getValue("id").jsonPrimitive.content
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fun checkReleaseVersionExists(name: String): Boolean {
 | 
			
		||||
    val client = httpClient()
 | 
			
		||||
 | 
			
		||||
    return runBlocking {
 | 
			
		||||
        val response = client.get("https://youtrack.jetbrains.com/api/admin/projects/$vimProjectId/customFields/$fixVersionsFieldId/bundle/values?fields=id,name&query=$name")
 | 
			
		||||
        response.body<JsonArray>().isNotEmpty()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fun deleteVersionById(id: String) {
 | 
			
		||||
    val client = httpClient()
 | 
			
		||||
 | 
			
		||||
    runBlocking {
 | 
			
		||||
        client.delete("https://youtrack.jetbrains.com/api/admin/projects/$vimProjectId/customFields/$fixVersionsFieldId/bundle/values/$id")
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fun updateYoutrackOnCommit() {
 | 
			
		||||
    println("Start updating youtrack")
 | 
			
		||||
    println(projectDir)
 | 
			
		||||
 | 
			
		||||
    val newFixes = changes()
 | 
			
		||||
    val newTickets = newFixes.map { it.id }
 | 
			
		||||
    println("Set new status for $newTickets")
 | 
			
		||||
    setYoutrackStatus(newTickets, "Ready To Release")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fun getYoutrackTicketsByQuery(query: String): Set<String> {
 | 
			
		||||
    val client = httpClient()
 | 
			
		||||
 | 
			
		||||
    return runBlocking {
 | 
			
		||||
        val response = client.get("https://youtrack.jetbrains.com/api/issues/?fields=idReadable&query=project:VIM+$query")
 | 
			
		||||
        response.body<JsonArray>().mapTo(HashSet()) { it.jsonObject.getValue("idReadable").jsonPrimitive.content }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fun setYoutrackStatus(tickets: Collection<String>, status: String) {
 | 
			
		||||
    val client = httpClient()
 | 
			
		||||
 | 
			
		||||
    runBlocking {
 | 
			
		||||
        for (ticket in tickets) {
 | 
			
		||||
            println("Try to set $ticket to $status")
 | 
			
		||||
            val response = client.post("https://youtrack.jetbrains.com/api/issues/$ticket?fields=customFields(id,name,value(id,name))") {
 | 
			
		||||
                contentType(ContentType.Application.Json)
 | 
			
		||||
                accept(ContentType.Application.Json)
 | 
			
		||||
                val request = buildJsonObject {
 | 
			
		||||
                    putJsonArray("customFields") {
 | 
			
		||||
                        addJsonObject {
 | 
			
		||||
                            put("name", "State")
 | 
			
		||||
                            put("\$type", "SingleEnumIssueCustomField")
 | 
			
		||||
                            putJsonObject("value") {
 | 
			
		||||
                                put("name", status)
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                setBody(request)
 | 
			
		||||
            }
 | 
			
		||||
            println(response)
 | 
			
		||||
            println(response.body<String>())
 | 
			
		||||
            if (!response.status.isSuccess()) {
 | 
			
		||||
                error("Request failed. $ticket, ${response.body<String>()}")
 | 
			
		||||
            }
 | 
			
		||||
            val finalState = response.body<JsonObject>()["customFields"]!!.jsonArray
 | 
			
		||||
                .single { it.jsonObject["name"]!!.jsonPrimitive.content == "State" }
 | 
			
		||||
                .jsonObject["value"]!!
 | 
			
		||||
                .jsonObject["name"]!!
 | 
			
		||||
                .jsonPrimitive.content
 | 
			
		||||
            if (finalState != status) {
 | 
			
		||||
                error("Ticket $ticket is not updated! Expected status $status, but actually $finalState")
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fun setYoutrackFixVersion(tickets: Collection<String>, version: String) {
 | 
			
		||||
    val client = httpClient()
 | 
			
		||||
 | 
			
		||||
    runBlocking {
 | 
			
		||||
        for (ticket in tickets) {
 | 
			
		||||
            println("Try to set fix version $version for $ticket")
 | 
			
		||||
            val response = client.post("https://youtrack.jetbrains.com/api/issues/$ticket?fields=customFields(id,name,value(id,name))") {
 | 
			
		||||
                contentType(ContentType.Application.Json)
 | 
			
		||||
                accept(ContentType.Application.Json)
 | 
			
		||||
                val request = buildJsonObject {
 | 
			
		||||
                    putJsonArray("customFields") {
 | 
			
		||||
                        addJsonObject {
 | 
			
		||||
                            put("name", "Fix versions")
 | 
			
		||||
                            put("\$type", "MultiVersionIssueCustomField")
 | 
			
		||||
                            putJsonArray("value") {
 | 
			
		||||
                                addJsonObject { put("name", version) }
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                setBody(request)
 | 
			
		||||
            }
 | 
			
		||||
            println(response)
 | 
			
		||||
            println(response.body<String>())
 | 
			
		||||
            if (!response.status.isSuccess()) {
 | 
			
		||||
                error("Request failed. $ticket, ${response.body<String>()}")
 | 
			
		||||
            }
 | 
			
		||||
            val finalState = response.body<JsonObject>()["customFields"]!!.jsonArray
 | 
			
		||||
                .single { it.jsonObject["name"]!!.jsonPrimitive.content == "Fix versions" }
 | 
			
		||||
                .jsonObject["value"]!!
 | 
			
		||||
                .jsonArray[0]
 | 
			
		||||
                .jsonObject["name"]!!
 | 
			
		||||
                .jsonPrimitive.content
 | 
			
		||||
            if (finalState != version) {
 | 
			
		||||
                error("Ticket $ticket is not updated! Expected fix version $version, but actually $finalState")
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fun getYoutrackStatus(ticket: String): String {
 | 
			
		||||
    val client = httpClient()
 | 
			
		||||
 | 
			
		||||
    return runBlocking {
 | 
			
		||||
        val response = client.get("https://youtrack.jetbrains.com/api/issues/$ticket/customFields/123-129?fields=value(name)")
 | 
			
		||||
        response.body<JsonObject>()["value"]!!.jsonObject.getValue("name").jsonPrimitive.content
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fun updateChangelog() {
 | 
			
		||||
    println("Start update authors")
 | 
			
		||||
    println(projectDir)
 | 
			
		||||
    val newFixes = changes()
 | 
			
		||||
    val repository = org.eclipse.jgit.lib.RepositoryBuilder().setGitDir(File("$projectDir/.git")).build()
 | 
			
		||||
    val git = org.eclipse.jgit.api.Git(repository)
 | 
			
		||||
    val lastSuccessfulCommit = System.getenv("SUCCESS_COMMIT")!!
 | 
			
		||||
    val messages = git.log().call()
 | 
			
		||||
        .takeWhile {
 | 
			
		||||
            !it.id.name.equals(lastSuccessfulCommit, ignoreCase = true)
 | 
			
		||||
        }
 | 
			
		||||
        .map { it.shortMessage }
 | 
			
		||||
 | 
			
		||||
    // Collect fixes
 | 
			
		||||
    val newFixes = mutableListOf<Change>()
 | 
			
		||||
    println("Last successful commit: $lastSuccessfulCommit")
 | 
			
		||||
    println("Amount of commits: ${messages.size}")
 | 
			
		||||
    println("Start emails processing")
 | 
			
		||||
    for (message in messages) {
 | 
			
		||||
        println("Processing '$message'...")
 | 
			
		||||
        val lowercaseMessage = message.toLowerCase()
 | 
			
		||||
        val regex = "^fix\\((vim-\\d+)\\):".toRegex()
 | 
			
		||||
        val findResult = regex.find(lowercaseMessage)
 | 
			
		||||
        if (findResult != null) {
 | 
			
		||||
            println("Message matches")
 | 
			
		||||
            val value = findResult.groups[1]!!.value.toUpperCase()
 | 
			
		||||
            val shortMessage = message.drop(findResult.range.last + 1).trim()
 | 
			
		||||
            newFixes += Change(value, shortMessage)
 | 
			
		||||
        } else {
 | 
			
		||||
            println("Message doesn't match")
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Update changes file
 | 
			
		||||
    val changesFile = File("$projectDir/CHANGES.md")
 | 
			
		||||
@@ -712,8 +460,8 @@ fun updateChangelog() {
 | 
			
		||||
fun updateAuthors(uncheckedEmails: Set<String>) {
 | 
			
		||||
    println("Start update authors")
 | 
			
		||||
    println(projectDir)
 | 
			
		||||
    val repository = RepositoryBuilder().setGitDir(File("$projectDir/.git")).build()
 | 
			
		||||
    val git = Git(repository)
 | 
			
		||||
    val repository = org.eclipse.jgit.lib.RepositoryBuilder().setGitDir(File("$projectDir/.git")).build()
 | 
			
		||||
    val git = org.eclipse.jgit.api.Git(repository)
 | 
			
		||||
    val lastSuccessfulCommit = System.getenv("SUCCESS_COMMIT")!!
 | 
			
		||||
    val hashesAndEmailes = git.log().call()
 | 
			
		||||
        .takeWhile {
 | 
			
		||||
@@ -789,9 +537,7 @@ data class Author(val name: String, val url: String, val mail: String)
 | 
			
		||||
data class Change(val id: String, val text: String)
 | 
			
		||||
 | 
			
		||||
fun updateMergedPr(number: Int) {
 | 
			
		||||
    val token = System.getenv("GITHUB_OAUTH")
 | 
			
		||||
    println("Token size: ${token.length}")
 | 
			
		||||
    val gitHub = org.kohsuke.github.GitHubBuilder().withOAuthToken(token).build()
 | 
			
		||||
    val gitHub = org.kohsuke.github.GitHub.connect()
 | 
			
		||||
    println("Connecting to the repo...")
 | 
			
		||||
    val repository = gitHub.getRepository("JetBrains/ideavim")
 | 
			
		||||
    println("Getting pull requests...")
 | 
			
		||||
@@ -886,57 +632,3 @@ val sections = listOf(
 | 
			
		||||
    "### Fixes:",
 | 
			
		||||
    "### Merged PRs:",
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
fun changes(): List<Change> {
 | 
			
		||||
    val repository = RepositoryBuilder().setGitDir(File("$projectDir/.git")).build()
 | 
			
		||||
    val git = Git(repository)
 | 
			
		||||
    val lastSuccessfulCommit = System.getenv("SUCCESS_COMMIT")!!
 | 
			
		||||
    val messages = git.log().call()
 | 
			
		||||
        .takeWhile {
 | 
			
		||||
            !it.id.name.equals(lastSuccessfulCommit, ignoreCase = true)
 | 
			
		||||
        }
 | 
			
		||||
        .map { it.shortMessage }
 | 
			
		||||
 | 
			
		||||
    // Collect fixes
 | 
			
		||||
    val newFixes = mutableListOf<Change>()
 | 
			
		||||
    println("Last successful commit: $lastSuccessfulCommit")
 | 
			
		||||
    println("Amount of commits: ${messages.size}")
 | 
			
		||||
    println("Start emails processing")
 | 
			
		||||
    for (message in messages) {
 | 
			
		||||
        println("Processing '$message'...")
 | 
			
		||||
        val lowercaseMessage = message.toLowerCase()
 | 
			
		||||
        val regex = "^fix\\((vim-\\d+)\\):".toRegex()
 | 
			
		||||
        val findResult = regex.find(lowercaseMessage)
 | 
			
		||||
        if (findResult != null) {
 | 
			
		||||
            println("Message matches")
 | 
			
		||||
            val value = findResult.groups[1]!!.value.toUpperCase()
 | 
			
		||||
            val shortMessage = message.drop(findResult.range.last + 1).trim()
 | 
			
		||||
            newFixes += Change(value, shortMessage)
 | 
			
		||||
        } else {
 | 
			
		||||
            println("Message doesn't match")
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return newFixes
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fun httpClient(): HttpClient {
 | 
			
		||||
    return HttpClient(CIO) {
 | 
			
		||||
        expectSuccess = true
 | 
			
		||||
        install(Auth) {
 | 
			
		||||
            bearer {
 | 
			
		||||
                loadTokens {
 | 
			
		||||
                    val accessToken = youtrackToken.ifBlank { System.getenv("YOUTRACK_TOKEN")!! }
 | 
			
		||||
                    BearerTokens(accessToken, "")
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        install(ContentNegotiation) {
 | 
			
		||||
            json(
 | 
			
		||||
                Json {
 | 
			
		||||
                    prettyPrint = true
 | 
			
		||||
                    isLenient = true
 | 
			
		||||
                }
 | 
			
		||||
            )
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										248
									
								
								doc/Emulated-plugins.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										248
									
								
								doc/Emulated-plugins.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,248 @@
 | 
			
		||||
Emulated Vim Plugins
 | 
			
		||||
--------------------
 | 
			
		||||
 | 
			
		||||
IdeaVim extensions emulate plugins of the original Vim. In order to use
 | 
			
		||||
IdeaVim extensions, you have to enable them via this command in your `~/.ideavimrc`:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
Plug '<extension-github-reference>'
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
If you reuse your existing `.vimrc` file using `source ~/.vimrc`, IdeaVim can parse and enable plugins that are defined
 | 
			
		||||
using [vim-plug](https://github.com/junegunn/vim-plug) or [vundle](https://github.com/VundleVim/Vundle.vim).
 | 
			
		||||
No additional set commands in `~/.ideavimrc` are required.  
 | 
			
		||||
If you'd like to disable some plugin that's enabled in `.vimrc`, you can use `set no<extension-name>`
 | 
			
		||||
in `~/.ideavimrc`. E.g. `set nosurround`.
 | 
			
		||||
 | 
			
		||||
Available extensions:
 | 
			
		||||
 | 
			
		||||
## easymotion
 | 
			
		||||
 | 
			
		||||
* Setup:
 | 
			
		||||
    * Install [IdeaVim-EasyMotion](https://plugins.jetbrains.com/plugin/13360-ideavim-easymotion/)
 | 
			
		||||
      and [AceJump](https://plugins.jetbrains.com/plugin/7086-acejump/) plugins.
 | 
			
		||||
    * `Plug 'easymotion/vim-easymotion'`
 | 
			
		||||
    * <details>
 | 
			
		||||
      <summary>Alternative syntax</summary>
 | 
			
		||||
      <code>Plug 'https://github.com/easymotion/vim-easymotion'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>Plug 'vim-easymotion'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>set easymotion</code>
 | 
			
		||||
      </details>
 | 
			
		||||
* Emulates [vim-easymotion](https://github.com/easymotion/vim-easymotion)
 | 
			
		||||
* Commands: All commands with the mappings are supported. See the [full list of supported commands](https://github.com/AlexPl292/IdeaVim-EasyMotion#supported-commands).
 | 
			
		||||
 | 
			
		||||
## NERDTree
 | 
			
		||||
* Setup: `Plug 'preservim/nerdtree'`
 | 
			
		||||
    * <details>
 | 
			
		||||
      <summary>Alternative vim-plug / vundle syntax</summary>
 | 
			
		||||
      <code>Plug 'https://github.com/preservim/nerdtree'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>Plug 'nerdtree'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>set NERDTree</code>
 | 
			
		||||
      </details>
 | 
			
		||||
* Emulates [NERDTree](https://github.com/preservim/nerdtree)
 | 
			
		||||
* Commands: [[see here|NERDTree-support]]
 | 
			
		||||
 | 
			
		||||
## surround
 | 
			
		||||
 | 
			
		||||
* Setup: `Plug 'tpope/vim-surround'`
 | 
			
		||||
    * <details>
 | 
			
		||||
      <summary>Alternative vim-plug / vundle syntax</summary>
 | 
			
		||||
      <code>Plug 'https://github.com/tpope/vim-surround'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>Plug 'vim-surround'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>Plug 'https://www.vim.org/scripts/script.php?script_id=1697'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>set surround</code>
 | 
			
		||||
      </details>
 | 
			
		||||
* Emulates [vim-surround](https://github.com/tpope/vim-surround)
 | 
			
		||||
* Commands: `ys`, `cs`, `ds`, `S`
 | 
			
		||||
 | 
			
		||||
## multiple-cursors
 | 
			
		||||
 | 
			
		||||
* Setup: `Plug 'terryma/vim-multiple-cursors'`
 | 
			
		||||
    * <details>
 | 
			
		||||
      <summary>Alternative vim-plug / vundle syntax</summary>
 | 
			
		||||
      <code>Plug 'https://github.com/terryma/vim-multiple-cursors'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>Plug 'vim-multiple-cursors'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>set multiple-cursors</code>
 | 
			
		||||
      </details>
 | 
			
		||||
* Emulates [vim-multiple-cursors](https://github.com/terryma/vim-multiple-cursors)
 | 
			
		||||
* Commands: `<A-n>`, `<A-x>`, `<A-p>`, `g<A-n>`
 | 
			
		||||
 | 
			
		||||
## commentary
 | 
			
		||||
 | 
			
		||||
* Setup: `Plug 'tpope/vim-commentary'`
 | 
			
		||||
    * <details>
 | 
			
		||||
      <summary>Alternative vim-plug / vundle syntax</summary>
 | 
			
		||||
      <code>Plug 'https://github.com/tpope/vim-commentary'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>Plug 'vim-commentary'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>Plug 'https://www.vim.org/scripts/script.php?script_id=3695'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>Plug 'tomtom/tcomment_vim'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>Plug 'tcomment_vim'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>Plug 'https://www.vim.org/scripts/script.php?script_id=1173'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>set commentary</code>
 | 
			
		||||
      </details>
 | 
			
		||||
* Emulates [commentary.vim](https://github.com/tpope/vim-commentary)
 | 
			
		||||
* Commands: `gcc`, `gc + motion`, `v_gc`
 | 
			
		||||
* By [Daniel Leong](https://github.com/dhleong)
 | 
			
		||||
 | 
			
		||||
## ReplaceWithRegister
 | 
			
		||||
 | 
			
		||||
* Setup: `Plug 'vim-scripts/ReplaceWithRegister'`
 | 
			
		||||
    * <details>
 | 
			
		||||
      <summary>Alternative vim-plug / vundle syntax</summary>
 | 
			
		||||
      <code>Plug 'https://github.com/vim-scripts/ReplaceWithRegister'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>Plug 'ReplaceWithRegister'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>Plug 'https://github.com/inkarkat/vim-ReplaceWithRegister'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>Plug 'inkarkat/vim-ReplaceWithRegister'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>Plug 'vim-ReplaceWithRegister'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>Plug 'https://www.vim.org/scripts/script.php?script_id=2703'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>set ReplaceWithRegister</code>
 | 
			
		||||
      </details>
 | 
			
		||||
* Emulates [ReplaceWithRegister](https://github.com/vim-scripts/ReplaceWithRegister)
 | 
			
		||||
* Commands: `gr`, `grr`
 | 
			
		||||
* By [igrekster](https://github.com/igrekster)
 | 
			
		||||
 | 
			
		||||
## argtextobj
 | 
			
		||||
 | 
			
		||||
* Setup:
 | 
			
		||||
    * `Plug 'vim-scripts/argtextobj.vim'`
 | 
			
		||||
    * <details>
 | 
			
		||||
      <summary>Alternative vim-plug / vundle syntax</summary>
 | 
			
		||||
      <code>Plug 'https://github.com/vim-scripts/argtextobj.vim'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>Plug 'argtextobj.vim'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>Plug 'https://www.vim.org/scripts/script.php?script_id=2699'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>set argtextobj</code>
 | 
			
		||||
      </details>
 | 
			
		||||
    * By default, only the arguments inside parenthesis are considered. To extend the functionality
 | 
			
		||||
      to other types of brackets, set `g:argtextobj_pairs` variable to a comma-separated
 | 
			
		||||
      list of colon-separated pairs (same as VIM's `matchpairs` option), like
 | 
			
		||||
      `let g:argtextobj_pairs="(:),{:},<:>"`. The order of pairs matters when
 | 
			
		||||
      handling symbols that can also be operators: `func(x << 5, 20) >> 17`. To handle
 | 
			
		||||
      this syntax parenthesis, must come before angle brackets in the list.
 | 
			
		||||
* Emulates [argtextobj.vim](https://www.vim.org/scripts/script.php?script_id=2699)
 | 
			
		||||
* Additional text objects: `aa`, `ia`
 | 
			
		||||
 | 
			
		||||
## exchange
 | 
			
		||||
 | 
			
		||||
* Setup: `Plug 'tommcdo/vim-exchange'`
 | 
			
		||||
    * <details>
 | 
			
		||||
      <summary>Alternative vim-plug / vundle syntax</summary>
 | 
			
		||||
      <code>Plug 'https://github.com/tommcdo/vim-exchange'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>Plug 'vim-exchange'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>set exchange</code>
 | 
			
		||||
      </details>
 | 
			
		||||
* Emulates [vim-exchange](https://github.com/tommcdo/vim-exchange)
 | 
			
		||||
* Commands: `cx`, `cxx`, `X`, `cxc`
 | 
			
		||||
* By [fan-tom](https://github.com/fan-tom)
 | 
			
		||||
 | 
			
		||||
## textobj-entire
 | 
			
		||||
 | 
			
		||||
* Setup: `Plug 'kana/vim-textobj-entire'`
 | 
			
		||||
    * <details>
 | 
			
		||||
      <summary>Alternative vim-plug / vundle syntax</summary>
 | 
			
		||||
      <code>Plug 'https://github.com/kana/vim-textobj-entire'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>Plug 'vim-textobj-entire'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>Plug 'https://www.vim.org/scripts/script.php?script_id=2610'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>set textobj-entire</code>
 | 
			
		||||
      </details>
 | 
			
		||||
* Emulates [vim-textobj-entire](https://github.com/kana/vim-textobj-entire)
 | 
			
		||||
* Additional text objects: `ae`, `ie`
 | 
			
		||||
* By [Alexandre Grison](https://github.com/agrison)
 | 
			
		||||
 | 
			
		||||
## highlightedyank
 | 
			
		||||
 | 
			
		||||
* Setup:
 | 
			
		||||
    * `Plug 'machakann/vim-highlightedyank'`
 | 
			
		||||
    * <details>
 | 
			
		||||
      <summary>Alternative vim-plug / vundle syntax</summary>
 | 
			
		||||
      <code>Plug 'https://github.com/machakann/vim-highlightedyank'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>Plug 'vim-highlightedyank'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>set highlightedyank</code>
 | 
			
		||||
      </details>
 | 
			
		||||
    * if you want to optimize highlight duration, assign a time in milliseconds:  
 | 
			
		||||
      `let g:highlightedyank_highlight_duration = "1000"`  
 | 
			
		||||
      A negative number makes the highlight persistent.  
 | 
			
		||||
      `let g:highlightedyank_highlight_duration = "-1"`
 | 
			
		||||
    * if you want to change background color of highlight you can provide the rgba of the color you want e.g.  
 | 
			
		||||
      `let g:highlightedyank_highlight_color = "rgba(160, 160, 160, 155)"`
 | 
			
		||||
* Emulates [vim-highlightedyank](https://github.com/machakann/vim-highlightedyank)
 | 
			
		||||
* By [KostkaBrukowa](https://github.com/KostkaBrukowa)
 | 
			
		||||
 | 
			
		||||
## vim-paragraph-motion
 | 
			
		||||
 | 
			
		||||
* Setup: `Plug 'dbakker/vim-paragraph-motion'`
 | 
			
		||||
    * <details>
 | 
			
		||||
      <summary>Alternative vim-plug / vundle syntax</summary>
 | 
			
		||||
      <code>Plug 'https://github.com/dbakker/vim-paragraph-motion'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>Plug 'vim-paragraph-motion'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>Plug 'https://github.com/vim-scripts/Improved-paragraph-motion'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>Plug 'vim-scripts/Improved-paragraph-motion'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>Plug 'Improved-paragraph-motion'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>set vim-paragraph-motion</code>
 | 
			
		||||
      </details>
 | 
			
		||||
* Emulates [vim-paragraph-motion](https://github.com/dbakker/vim-paragraph-motion)
 | 
			
		||||
 | 
			
		||||
## vim-indent-object
 | 
			
		||||
 | 
			
		||||
* Setup: `Plug 'michaeljsmith/vim-indent-object'`
 | 
			
		||||
    * <details>
 | 
			
		||||
      <summary>Alternative vim-plug / vundle syntax</summary>
 | 
			
		||||
      <code>Plug 'https://github.com/michaeljsmith/vim-indent-object'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>Plug 'vim-indent-object'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>set textobj-indent</code>
 | 
			
		||||
      </details>
 | 
			
		||||
* Emulates [vim-indent-object](https://github.com/michaeljsmith/vim-indent-object)
 | 
			
		||||
* Additional text objects: `ai`, `ii`, `aI`
 | 
			
		||||
* By [Shrikant Sharat Kandula](https://github.com/sharat87)
 | 
			
		||||
 | 
			
		||||
## matchit.vim
 | 
			
		||||
 | 
			
		||||
* Setup: `packadd matchit`
 | 
			
		||||
    * <details>
 | 
			
		||||
      <summary>Alternative vim-plug / vundle syntax</summary>
 | 
			
		||||
      <code>Plug 'vim-matchit'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>Plug 'chrisbra/matchit'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>set matchit</code>
 | 
			
		||||
      </details>
 | 
			
		||||
* Emulates [matchit.vim](https://github.com/chrisbra/matchit)
 | 
			
		||||
* Currently works for HTML/XML and ruby
 | 
			
		||||
* By [Martin Yzeiri](https://github.com/myzeiri)
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
Welcome to the IdeaVim wiki!
 | 
			
		||||
 | 
			
		||||
- List of IdeaVim plugins: [[plugins|IdeaVim Plugins]]
 | 
			
		||||
- Examples of `ideajoin` option (also known as "smart join"): [["ideajoin" examples|ideajoin-examples]]
 | 
			
		||||
- List of "set" commands: [["set" commands|set-commands]]
 | 
			
		||||
- List of emulated plugins: [[plugins|Emulated-plugins]]
 | 
			
		||||
- Examples of `ideajoin` option (also known as "smart join"): [["ideajoin" examples|"ideajoin"-examples]]
 | 
			
		||||
- List of "set" commands: [["set" commands|"set"-commands]]
 | 
			
		||||
- Docs about "select" mode in vim: [[select mode|Select-mode]]
 | 
			
		||||
 
 | 
			
		||||
@@ -1,383 +0,0 @@
 | 
			
		||||
IdeaVim Plugins
 | 
			
		||||
--------------------
 | 
			
		||||
 | 
			
		||||
IdeaVim plugins work like the original Vim plugins. If you want to turn of any of them, you have to enable it via this command in your `~/.ideavimrc`:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
Plug '<plugin-github-reference>'
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
If you reuse your existing `.vimrc` file using `source ~/.vimrc`, IdeaVim can parse and enable plugins that are defined
 | 
			
		||||
using [vim-plug](https://github.com/junegunn/vim-plug) or [vundle](https://github.com/VundleVim/Vundle.vim).
 | 
			
		||||
No additional set commands in `~/.ideavimrc` are required.  
 | 
			
		||||
If you'd like to disable some plugin that's enabled in `.vimrc`, you can use `set no<extension-name>`
 | 
			
		||||
in `~/.ideavimrc`. E.g. `set nosurround`.
 | 
			
		||||
 | 
			
		||||
Available plugins:
 | 
			
		||||
 | 
			
		||||
<details>
 | 
			
		||||
<summary><h2>easymotion</h2></summary>
 | 
			
		||||
   
 | 
			
		||||
Original plugin: [vim-easymotion](https://github.com/easymotion/vim-easymotion).
 | 
			
		||||
   
 | 
			
		||||
### Setup:
 | 
			
		||||
- Install [IdeaVim-EasyMotion](https://plugins.jetbrains.com/plugin/13360-ideavim-easymotion/)
 | 
			
		||||
      and [AceJump](https://plugins.jetbrains.com/plugin/7086-acejump/) plugins.
 | 
			
		||||
- Add the following command to `~/.ideavimrc`: `Plug 'easymotion/vim-easymotion'`
 | 
			
		||||
    <details>
 | 
			
		||||
      <summary>Alternative syntax</summary>
 | 
			
		||||
      <code>Plugin 'easymotion/vim-easymotion'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>Plug 'https://github.com/easymotion/vim-easymotion'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>Plug 'vim-easymotion'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>set easymotion</code>
 | 
			
		||||
      </details>
 | 
			
		||||
   
 | 
			
		||||
### Instructions
 | 
			
		||||
   
 | 
			
		||||
All commands with the mappings are supported. See the [full list of supported commands](https://github.com/AlexPl292/IdeaVim-EasyMotion#supported-commands).
 | 
			
		||||
 | 
			
		||||
</details>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<details>
 | 
			
		||||
<summary><h2>sneak</h2></summary>
 | 
			
		||||
   
 | 
			
		||||
Original plugin: [vim-sneak](https://github.com/justinmk/vim-sneak).
 | 
			
		||||
   
 | 
			
		||||
### Setup:
 | 
			
		||||
- Install [IdeaVim-sneak](https://plugins.jetbrains.com/plugin/15348-ideavim-sneak) plugin.
 | 
			
		||||
- Add the following command to `~/.ideavimrc`: `set sneak`
 | 
			
		||||
   
 | 
			
		||||
### Instructions
 | 
			
		||||
   
 | 
			
		||||
See the [docs](https://github.com/Mishkun/ideavim-sneak#usage)
 | 
			
		||||
 | 
			
		||||
</details>
 | 
			
		||||
 | 
			
		||||
<details>
 | 
			
		||||
<summary><h2>NERDTree</h2></summary>
 | 
			
		||||
   
 | 
			
		||||
Original plugin: [NERDTree](https://github.com/preservim/nerdtree).
 | 
			
		||||
   
 | 
			
		||||
### Setup:
 | 
			
		||||
- Add the following command to `~/.ideavimrc`: `Plug 'preservim/nerdtree'`
 | 
			
		||||
    <details>
 | 
			
		||||
      <summary>Alternative syntax</summary>
 | 
			
		||||
      <code>Plugin 'preservim/nerdtree'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>Plug 'https://github.com/preservim/nerdtree'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>Plug 'nerdtree'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>set NERDTree</code>
 | 
			
		||||
      </details>
 | 
			
		||||
   
 | 
			
		||||
### Instructions
 | 
			
		||||
   
 | 
			
		||||
[[See here|NERDTree-support]].
 | 
			
		||||
 | 
			
		||||
</details>
 | 
			
		||||
 | 
			
		||||
<details>
 | 
			
		||||
<summary><h2>surround</h2></summary>
 | 
			
		||||
   
 | 
			
		||||
Original plugin: [vim-surround](https://github.com/tpope/vim-surround).
 | 
			
		||||
   
 | 
			
		||||
### Setup:
 | 
			
		||||
- Add the following command to `~/.ideavimrc`: `Plug 'tpope/vim-surround'`
 | 
			
		||||
    <details>
 | 
			
		||||
      <summary>Alternative syntax</summary>
 | 
			
		||||
      <code>Plugin 'tpope/vim-surround'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>Plug 'https://www.vim.org/scripts/script.php?script_id=1697'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>Plug 'vim-surround'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>set surround</code>
 | 
			
		||||
      </details>
 | 
			
		||||
   
 | 
			
		||||
### Instructions
 | 
			
		||||
   
 | 
			
		||||
https://github.com/tpope/vim-surround/blob/master/doc/surround.txt
 | 
			
		||||
 | 
			
		||||
</details>
 | 
			
		||||
 | 
			
		||||
<details>
 | 
			
		||||
<summary><h2>multiple-cursors</h2></summary>
 | 
			
		||||
   
 | 
			
		||||
Original plugin: [vim-multiple-cursors](https://github.com/terryma/vim-multiple-cursors).
 | 
			
		||||
   
 | 
			
		||||
### Setup:
 | 
			
		||||
- Add the following command to `~/.ideavimrc`: `Plug 'terryma/vim-multiple-cursors'`
 | 
			
		||||
    <details>
 | 
			
		||||
      <summary>Alternative syntax</summary>
 | 
			
		||||
      <code>Plugin 'terryma/vim-multiple-cursors'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>Plug 'https://github.com/terryma/vim-multiple-cursors'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>Plug 'vim-multiple-cursors'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>set multiple-cursors</code>
 | 
			
		||||
      </details>
 | 
			
		||||
   
 | 
			
		||||
### Instructions
 | 
			
		||||
   
 | 
			
		||||
https://github.com/terryma/vim-multiple-cursors/blob/master/doc/multiple_cursors.txt
 | 
			
		||||
 | 
			
		||||
</details>
 | 
			
		||||
 | 
			
		||||
<details>
 | 
			
		||||
<summary><h2>commentary</h2></summary>
 | 
			
		||||
 | 
			
		||||
By [Daniel Leong](https://github.com/dhleong)  
 | 
			
		||||
Original plugin: [commentary.vim](https://github.com/tpope/vim-commentary).
 | 
			
		||||
   
 | 
			
		||||
### Setup:
 | 
			
		||||
- Add the following command to `~/.ideavimrc`: `Plug 'tpope/vim-commentary'`
 | 
			
		||||
    <details>
 | 
			
		||||
      <summary>Alternative syntax</summary>
 | 
			
		||||
      <code>Plugin 'tpope/vim-commentary'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>Plug 'https://github.com/tpope/vim-commentary'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>Plug 'vim-commentary'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>Plug 'tcomment_vim'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>set commentary</code>
 | 
			
		||||
      </details>
 | 
			
		||||
   
 | 
			
		||||
### Instructions
 | 
			
		||||
   
 | 
			
		||||
https://github.com/tpope/vim-commentary/blob/master/doc/commentary.txt
 | 
			
		||||
 | 
			
		||||
</details>
 | 
			
		||||
 | 
			
		||||
<details>
 | 
			
		||||
<summary><h2>ReplaceWithRegister</h2></summary>
 | 
			
		||||
   
 | 
			
		||||
By [igrekster](https://github.com/igrekster)  
 | 
			
		||||
Original plugin: [ReplaceWithRegister](https://github.com/vim-scripts/ReplaceWithRegister).
 | 
			
		||||
   
 | 
			
		||||
### Setup:
 | 
			
		||||
- Add the following command to `~/.ideavimrc`: `Plug 'vim-scripts/ReplaceWithRegister'`
 | 
			
		||||
    <details>
 | 
			
		||||
      <summary>Alternative syntax</summary>
 | 
			
		||||
      <code>Plugin 'vim-scripts/ReplaceWithRegister'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>Plug 'ReplaceWithRegister'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>Plug 'https://github.com/inkarkat/vim-ReplaceWithRegister'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>Plug 'inkarkat/vim-ReplaceWithRegister'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>Plug 'vim-ReplaceWithRegister'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>Plug 'https://www.vim.org/scripts/script.php?script_id=2703'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>set ReplaceWithRegister</code>
 | 
			
		||||
      </details>
 | 
			
		||||
   
 | 
			
		||||
### Instructions
 | 
			
		||||
   
 | 
			
		||||
https://github.com/vim-scripts/ReplaceWithRegister/blob/master/doc/ReplaceWithRegister.txt
 | 
			
		||||
 | 
			
		||||
</details>
 | 
			
		||||
 | 
			
		||||
<details>
 | 
			
		||||
<summary><h2>argtextobj</h2></summary>
 | 
			
		||||
 | 
			
		||||
Original plugin: [argtextobj.vim](https://www.vim.org/scripts/script.php?script_id=2699).
 | 
			
		||||
   
 | 
			
		||||
### Setup:
 | 
			
		||||
- Add the following command to `~/.ideavimrc`: `Plug 'vim-scripts/argtextobj.vim'`
 | 
			
		||||
    <details>
 | 
			
		||||
      <summary>Alternative syntax</summary>
 | 
			
		||||
      <code>Plugin 'vim-scripts/argtextobj.vim'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>Plug 'https://github.com/vim-scripts/argtextobj.vim'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>Plug 'argtextobj.vim'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>Plug 'https://www.vim.org/scripts/script.php?script_id=2699'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>set argtextobj</code>
 | 
			
		||||
      </details>
 | 
			
		||||
   
 | 
			
		||||
### Instructions
 | 
			
		||||
   
 | 
			
		||||
By default, only the arguments inside parenthesis are considered. To extend the functionality
 | 
			
		||||
      to other types of brackets, set `g:argtextobj_pairs` variable to a comma-separated
 | 
			
		||||
      list of colon-separated pairs (same as VIM's `matchpairs` option), like
 | 
			
		||||
      `let g:argtextobj_pairs="(:),{:},<:>"`. The order of pairs matters when
 | 
			
		||||
      handling symbols that can also be operators: `func(x << 5, 20) >> 17`. To handle
 | 
			
		||||
      this syntax parenthesis, must come before angle brackets in the list.
 | 
			
		||||
   
 | 
			
		||||
https://www.vim.org/scripts/script.php?script_id=2699
 | 
			
		||||
 | 
			
		||||
</details>
 | 
			
		||||
   
 | 
			
		||||
 | 
			
		||||
<details>
 | 
			
		||||
<summary><h2>exchange</h2></summary>
 | 
			
		||||
 | 
			
		||||
By [fan-tom](https://github.com/fan-tom)  
 | 
			
		||||
Original plugin: [vim-exchange](https://github.com/tommcdo/vim-exchange).
 | 
			
		||||
   
 | 
			
		||||
### Setup:
 | 
			
		||||
- Add the following command to `~/.ideavimrc`: `Plug 'tommcdo/vim-exchange'`
 | 
			
		||||
    <details>
 | 
			
		||||
      <summary>Alternative syntax</summary>
 | 
			
		||||
      <code>Plugin 'tommcdo/vim-exchange'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>Plug 'https://github.com/tommcdo/vim-exchange'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>Plug 'vim-exchange'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>set exchange</code>
 | 
			
		||||
      </details>
 | 
			
		||||
   
 | 
			
		||||
### Instructions
 | 
			
		||||
   
 | 
			
		||||
https://github.com/tommcdo/vim-exchange/blob/master/doc/exchange.txt
 | 
			
		||||
 | 
			
		||||
</details>
 | 
			
		||||
   
 | 
			
		||||
<details>
 | 
			
		||||
<summary><h2>textobj-entire</h2></summary>
 | 
			
		||||
 | 
			
		||||
By [Alexandre Grison](https://github.com/agrison)  
 | 
			
		||||
Original plugin: [vim-textobj-entire](https://github.com/kana/vim-textobj-entire).
 | 
			
		||||
   
 | 
			
		||||
### Setup:
 | 
			
		||||
- Add the following command to `~/.ideavimrc`: `Plug 'kana/vim-textobj-entire'`
 | 
			
		||||
    <details>
 | 
			
		||||
      <summary>Alternative syntax</summary>
 | 
			
		||||
      <code>Plugin 'kana/vim-textobj-entire'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>Plug 'vim-textobj-entire'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>Plug 'https://www.vim.org/scripts/script.php?script_id=2610'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>set textobj-entire</code>
 | 
			
		||||
      </details>
 | 
			
		||||
   
 | 
			
		||||
### Instructions
 | 
			
		||||
   
 | 
			
		||||
https://github.com/kana/vim-textobj-entire/blob/master/doc/textobj-entire.txt
 | 
			
		||||
 | 
			
		||||
</details>
 | 
			
		||||
   
 | 
			
		||||
<details>
 | 
			
		||||
<summary><h2>highlightedyank</h2></summary>
 | 
			
		||||
 | 
			
		||||
By [KostkaBrukowa](https://github.com/KostkaBrukowa)  
 | 
			
		||||
Original plugin: [vim-highlightedyank](https://github.com/machakann/vim-highlightedyank).
 | 
			
		||||
   
 | 
			
		||||
### Setup:
 | 
			
		||||
- Add the following command to `~/.ideavimrc`: `Plug 'machakann/vim-highlightedyank'`
 | 
			
		||||
    <details>
 | 
			
		||||
      <summary>Alternative syntax</summary>
 | 
			
		||||
      <code>Plugin 'machakann/vim-highlightedyank'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>Plug 'https://github.com/machakann/vim-highlightedyank'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>Plug 'vim-highlightedyank'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>set highlightedyank</code>
 | 
			
		||||
      </details>
 | 
			
		||||
   
 | 
			
		||||
### Instructions
 | 
			
		||||
   
 | 
			
		||||
If you want to optimize highlight duration, assign a time in milliseconds:  
 | 
			
		||||
      `let g:highlightedyank_highlight_duration = "1000"`  
 | 
			
		||||
      A negative number makes the highlight persistent.  
 | 
			
		||||
   
 | 
			
		||||
If you want to change background color of highlight you can provide the rgba of the color you want e.g.  
 | 
			
		||||
      `let g:highlightedyank_highlight_color = "rgba(160, 160, 160, 155)"`
 | 
			
		||||
   
 | 
			
		||||
https://github.com/machakann/vim-highlightedyank/blob/master/doc/highlightedyank.txt
 | 
			
		||||
 | 
			
		||||
</details>
 | 
			
		||||
 | 
			
		||||
<details>
 | 
			
		||||
<summary><h2>vim-paragraph-motion</h2></summary>
 | 
			
		||||
 | 
			
		||||
Original plugin: [vim-paragraph-motion](https://github.com/dbakker/vim-paragraph-motion).
 | 
			
		||||
   
 | 
			
		||||
### Setup:
 | 
			
		||||
- Add the following command to `~/.ideavimrc`: `Plug 'dbakker/vim-paragraph-motion'`
 | 
			
		||||
    <details>
 | 
			
		||||
      <summary>Alternative syntax</summary>
 | 
			
		||||
      <code>Plugin 'dbakker/vim-paragraph-motion'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>Plug 'https://github.com/dbakker/vim-paragraph-motion'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>Plug 'vim-paragraph-motion'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>Plug 'https://github.com/vim-scripts/Improved-paragraph-motion'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>Plug 'vim-scripts/Improved-paragraph-motion'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>Plug 'Improved-paragraph-motion'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>set vim-paragraph-motion</code>
 | 
			
		||||
      </details>
 | 
			
		||||
   
 | 
			
		||||
### Instructions
 | 
			
		||||
   
 | 
			
		||||
https://github.com/dbakker/vim-paragraph-motion#vim-paragraph-motion
 | 
			
		||||
 | 
			
		||||
</details>
 | 
			
		||||
   
 | 
			
		||||
<details>
 | 
			
		||||
<summary><h2>vim-indent-object</h2></summary>
 | 
			
		||||
 | 
			
		||||
By [Shrikant Sharat Kandula](https://github.com/sharat87)  
 | 
			
		||||
Original plugin: [vim-indent-object](https://github.com/michaeljsmith/vim-indent-object).
 | 
			
		||||
   
 | 
			
		||||
### Setup:
 | 
			
		||||
- Add the following command to `~/.ideavimrc`: `Plug 'michaeljsmith/vim-indent-object'`
 | 
			
		||||
    <details>
 | 
			
		||||
      <summary>Alternative syntax</summary>
 | 
			
		||||
      <code>Plugin 'michaeljsmith/vim-indent-object'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>Plug 'https://github.com/michaeljsmith/vim-indent-object'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>Plug 'vim-indent-object'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>set textobj-indent</code>
 | 
			
		||||
      </details>
 | 
			
		||||
   
 | 
			
		||||
### Instructions
 | 
			
		||||
   
 | 
			
		||||
https://github.com/michaeljsmith/vim-indent-object/blob/master/doc/indent-object.txt
 | 
			
		||||
 | 
			
		||||
</details>
 | 
			
		||||
   
 | 
			
		||||
   
 | 
			
		||||
<details>
 | 
			
		||||
<summary><h2>matchit.vim</h2></summary>
 | 
			
		||||
 | 
			
		||||
By [Martin Yzeiri](https://github.com/myzeiri)
 | 
			
		||||
Original plugin: [matchit.vim](https://github.com/chrisbra/matchit).
 | 
			
		||||
   
 | 
			
		||||
### Setup:
 | 
			
		||||
- Add the following command to `~/.ideavimrc`: `packadd matchit`
 | 
			
		||||
    <details>
 | 
			
		||||
      <summary>Alternative syntax</summary>
 | 
			
		||||
      <code>Plug 'vim-matchit'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>Plug 'chrisbra/matchit'</code>
 | 
			
		||||
      <br/>
 | 
			
		||||
      <code>set matchit</code>
 | 
			
		||||
      </details>
 | 
			
		||||
   
 | 
			
		||||
### Instructions
 | 
			
		||||
   
 | 
			
		||||
https://github.com/adelarsq/vim-matchit/blob/master/doc/matchit.txt
 | 
			
		||||
 | 
			
		||||
</details>
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
# NERDTree
 | 
			
		||||
 | 
			
		||||
IdeaVim supports the NERDTree plugin. Update your `~/.ideavimrc` to turn it on:
 | 
			
		||||
IdeaVim supports emulation of the NERDTree plugin. Update your `~/.ideavimrc` to turn it on:
 | 
			
		||||
```vim
 | 
			
		||||
Plug 'preservim/nerdtree`
 | 
			
		||||
```
 | 
			
		||||
 
 | 
			
		||||
@@ -1,31 +1,19 @@
 | 
			
		||||
#
 | 
			
		||||
# 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.
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
# suppress inspection "UnusedProperty" for whole file
 | 
			
		||||
 | 
			
		||||
ideaVersion=2022.3
 | 
			
		||||
ideaVersion=2022.2.2
 | 
			
		||||
downloadIdeaSources=true
 | 
			
		||||
instrumentPluginCode=true
 | 
			
		||||
version=chylex-14
 | 
			
		||||
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.7.20
 | 
			
		||||
kotlinVersion=1.6.21
 | 
			
		||||
publishToken=token
 | 
			
		||||
publishChannels=eap
 | 
			
		||||
 | 
			
		||||
slackUrl=
 | 
			
		||||
youtrackToken=
 | 
			
		||||
 | 
			
		||||
# Gradle settings
 | 
			
		||||
org.gradle.jvmargs='-Dfile.encoding=UTF-8'
 | 
			
		||||
 | 
			
		||||
# Disable warning from gradle-intellij-plugin. Kotlin stdlib is included as compileOnly, so the warning is unnecessary
 | 
			
		||||
kotlin.stdlib.default.dependency=false
 | 
			
		||||
							
								
								
									
										11
									
								
								qodana.yaml
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								qodana.yaml
									
									
									
									
									
								
							@@ -19,10 +19,7 @@ exclude:
 | 
			
		||||
      - src/test/java/org/jetbrains/plugins/ideavim/propertybased/samples/JavaText.kt
 | 
			
		||||
      - src/test/java/org/jetbrains/plugins/ideavim/propertybased/samples/LoremText.kt
 | 
			
		||||
      - src/test/java/org/jetbrains/plugins/ideavim/propertybased/samples/SimpleText.kt
 | 
			
		||||
      - src/main/java/com/maddyhome/idea/vim/vimscript/parser/generated
 | 
			
		||||
      - src/main/java/com/maddyhome/idea/vim/package-info.java
 | 
			
		||||
dependencyIgnores:
 | 
			
		||||
  - name: "acejump"
 | 
			
		||||
  - name: "icu4j"
 | 
			
		||||
  - name: "antlr-runtime"
 | 
			
		||||
  - name: "javax.json"
 | 
			
		||||
      - src/main/java/com/maddyhome/idea/vim/vimscript/parser/generated/VimscriptListener.java
 | 
			
		||||
      - src/main/java/com/maddyhome/idea/vim/vimscript/parser/generated/VimscriptLexer.java
 | 
			
		||||
      - src/main/java/com/maddyhome/idea/vim/vimscript/parser/generated/VimscriptParser.java
 | 
			
		||||
      - src/main/java/com/maddyhome/idea/vim/vimscript/parser/generated/VimscriptVisitor.java
 | 
			
		||||
@@ -1,9 +1,19 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,19 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,19 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,19 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,19 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,19 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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;
 | 
			
		||||
 | 
			
		||||
@@ -31,6 +41,7 @@ import com.maddyhome.idea.vim.config.migration.ApplicationConfigurationMigrator;
 | 
			
		||||
import com.maddyhome.idea.vim.extension.VimExtensionRegistrar;
 | 
			
		||||
import com.maddyhome.idea.vim.group.*;
 | 
			
		||||
import com.maddyhome.idea.vim.group.copy.PutGroup;
 | 
			
		||||
import com.maddyhome.idea.vim.group.copy.YankGroup;
 | 
			
		||||
import com.maddyhome.idea.vim.group.visual.VisualMotionGroup;
 | 
			
		||||
import com.maddyhome.idea.vim.helper.MacKeyRepeat;
 | 
			
		||||
import com.maddyhome.idea.vim.listener.VimListenerManager;
 | 
			
		||||
@@ -41,7 +52,6 @@ import com.maddyhome.idea.vim.vimscript.services.FunctionStorage;
 | 
			
		||||
import com.maddyhome.idea.vim.vimscript.services.IjVimOptionService;
 | 
			
		||||
import com.maddyhome.idea.vim.vimscript.services.OptionService;
 | 
			
		||||
import com.maddyhome.idea.vim.vimscript.services.VariableService;
 | 
			
		||||
import com.maddyhome.idea.vim.yank.YankGroupBase;
 | 
			
		||||
import org.jdom.Element;
 | 
			
		||||
import org.jetbrains.annotations.Nls;
 | 
			
		||||
import org.jetbrains.annotations.NotNull;
 | 
			
		||||
@@ -189,6 +199,10 @@ public class VimPlugin implements PersistentStateComponent<Element>, Disposable
 | 
			
		||||
    return ((WindowGroup)VimInjectorKt.getInjector().getWindow());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public static @NotNull TabService getTabService() {
 | 
			
		||||
    return ApplicationManager.getApplication().getService(TabService.class);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public static @NotNull EditorGroup getEditor() {
 | 
			
		||||
    return ApplicationManager.getApplication().getService(EditorGroup.class);
 | 
			
		||||
  }
 | 
			
		||||
@@ -201,8 +215,8 @@ public class VimPlugin implements PersistentStateComponent<Element>, Disposable
 | 
			
		||||
    return (VisualMotionGroup)VimInjectorKt.getInjector().getVisualMotionGroup();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public static @NotNull YankGroupBase getYank() {
 | 
			
		||||
    return (YankGroupBase)VimInjectorKt.getInjector().getYank();
 | 
			
		||||
  public static @NotNull YankGroup getYank() {
 | 
			
		||||
    return (YankGroup)VimInjectorKt.getInjector().getYank();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public static @NotNull PutGroup getPut() {
 | 
			
		||||
@@ -289,8 +303,12 @@ public class VimPlugin implements PersistentStateComponent<Element>, Disposable
 | 
			
		||||
    VimInjectorKt.getInjector().getMessages().clearError();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public static void showMode(String msg) {
 | 
			
		||||
    VimInjectorKt.getInjector().getMessages().showMode(msg);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public static void showMessage(@Nls(capitalization = Nls.Capitalization.Sentence) @Nullable String msg) {
 | 
			
		||||
    VimInjectorKt.getInjector().getMessages().showStatusBarMessage(null, msg);
 | 
			
		||||
    VimInjectorKt.getInjector().getMessages().showStatusBarMessage(msg);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public static @NotNull VimPlugin getInstance() {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,19 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,19 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,19 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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.action
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,19 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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.action
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,19 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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.action
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,19 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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.action.change
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,19 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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.action.change
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,19 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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.action.change.delete
 | 
			
		||||
 | 
			
		||||
@@ -18,28 +28,8 @@ import com.maddyhome.idea.vim.handler.ChangeEditorActionHandler
 | 
			
		||||
import com.maddyhome.idea.vim.options.OptionScope
 | 
			
		||||
import com.maddyhome.idea.vim.vimscript.services.IjVimOptionService
 | 
			
		||||
 | 
			
		||||
class DeleteJoinLinesAction : ChangeEditorActionHandler.ConditionalSingleExecution() {
 | 
			
		||||
class DeleteJoinLinesAction : ChangeEditorActionHandler.SingleExecution() {
 | 
			
		||||
  override val type: Command.Type = Command.Type.DELETE
 | 
			
		||||
  override fun runAsMulticaret(
 | 
			
		||||
    editor: VimEditor,
 | 
			
		||||
    context: ExecutionContext,
 | 
			
		||||
    cmd: Command,
 | 
			
		||||
    operatorArguments: OperatorArguments,
 | 
			
		||||
  ): Boolean {
 | 
			
		||||
    return !injector.optionService.isSet(OptionScope.LOCAL(editor), IjVimOptionService.ideajoinName)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  override fun execute(
 | 
			
		||||
    editor: VimEditor,
 | 
			
		||||
    caret: VimCaret,
 | 
			
		||||
    context: ExecutionContext,
 | 
			
		||||
    argument: Argument?,
 | 
			
		||||
    operatorArguments: OperatorArguments,
 | 
			
		||||
  ): Boolean {
 | 
			
		||||
    injector.editorGroup.notifyIdeaJoin(editor)
 | 
			
		||||
 | 
			
		||||
    return injector.changeGroup.deleteJoinLines(editor, caret, operatorArguments.count1, false, operatorArguments)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  override fun execute(
 | 
			
		||||
    editor: VimEditor,
 | 
			
		||||
@@ -48,6 +38,17 @@ class DeleteJoinLinesAction : ChangeEditorActionHandler.ConditionalSingleExecuti
 | 
			
		||||
    operatorArguments: OperatorArguments,
 | 
			
		||||
  ): Boolean {
 | 
			
		||||
    if (editor.isOneLineMode()) return false
 | 
			
		||||
    return injector.changeGroup.joinViaIdeaByCount(editor, context, operatorArguments.count1)
 | 
			
		||||
    if (injector.optionService.isSet(OptionScope.LOCAL(editor), IjVimOptionService.ideajoinName)) {
 | 
			
		||||
      return injector.changeGroup.joinViaIdeaByCount(editor, context, operatorArguments.count1)
 | 
			
		||||
    }
 | 
			
		||||
    injector.editorGroup.notifyIdeaJoin(editor)
 | 
			
		||||
    val res = arrayOf(true)
 | 
			
		||||
    editor.forEachNativeCaret(
 | 
			
		||||
      { caret: VimCaret ->
 | 
			
		||||
        if (!injector.changeGroup.deleteJoinLines(editor, caret, operatorArguments.count1, false, operatorArguments)) res[0] = false
 | 
			
		||||
      },
 | 
			
		||||
      true
 | 
			
		||||
    )
 | 
			
		||||
    return res[0]
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,19 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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.action.change.delete
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,19 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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.action.change.delete
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,19 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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.action.change.delete
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,19 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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.action.editor
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,19 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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.action.ex
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,19 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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.action.internal
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,19 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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.action.internal
 | 
			
		||||
@@ -15,10 +25,8 @@ import com.intellij.openapi.actionSystem.CommonDataKeys
 | 
			
		||||
import com.intellij.openapi.actionSystem.DataContext
 | 
			
		||||
import com.intellij.openapi.editor.Editor
 | 
			
		||||
import com.intellij.openapi.editor.VisualPosition
 | 
			
		||||
import com.maddyhome.idea.vim.api.lineLength
 | 
			
		||||
import com.maddyhome.idea.vim.api.visualLineToBufferLine
 | 
			
		||||
import com.maddyhome.idea.vim.helper.EditorHelper
 | 
			
		||||
import com.maddyhome.idea.vim.helper.VimNlsSafe
 | 
			
		||||
import com.maddyhome.idea.vim.newapi.vim
 | 
			
		||||
import java.util.*
 | 
			
		||||
import kotlin.math.max
 | 
			
		||||
 | 
			
		||||
@@ -30,18 +38,17 @@ class AddInlineInlaysAction : AnAction() {
 | 
			
		||||
  override fun actionPerformed(e: AnActionEvent) {
 | 
			
		||||
    val dataContext = e.dataContext
 | 
			
		||||
    val editor = getEditor(dataContext) ?: return
 | 
			
		||||
    val vimEditor = editor.vim
 | 
			
		||||
    val inlayModel = editor.inlayModel
 | 
			
		||||
    val currentVisualLine = editor.caretModel.primaryCaret.visualPosition.line
 | 
			
		||||
    var i = random.nextInt(10)
 | 
			
		||||
    val lineLength = vimEditor.lineLength(vimEditor.visualLineToBufferLine(currentVisualLine))
 | 
			
		||||
    val lineLength = EditorHelper.getLineLength(editor, EditorHelper.visualLineToLogicalLine(editor, currentVisualLine))
 | 
			
		||||
    while (i < lineLength) {
 | 
			
		||||
      val relatesToPrecedingText = random.nextInt(10) > 7
 | 
			
		||||
 | 
			
		||||
      @VimNlsSafe
 | 
			
		||||
      val text = "a".repeat(max(1, random.nextInt(7)))
 | 
			
		||||
 | 
			
		||||
      val offset = editor.visualPositionToOffset(VisualPosition(currentVisualLine, i))
 | 
			
		||||
      val offset = EditorHelper.visualPositionToOffset(editor, VisualPosition(currentVisualLine, i))
 | 
			
		||||
      // We don't need a custom renderer, just use the standard parameter hint renderer
 | 
			
		||||
      inlayModel.addInlineElement(
 | 
			
		||||
        offset,
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,19 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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.command
 | 
			
		||||
 
 | 
			
		||||
@@ -1,25 +1,35 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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.common
 | 
			
		||||
 | 
			
		||||
import com.intellij.openapi.editor.Editor
 | 
			
		||||
import com.intellij.openapi.editor.LogicalPosition
 | 
			
		||||
import com.maddyhome.idea.vim.newapi.vim
 | 
			
		||||
import com.maddyhome.idea.vim.helper.EditorHelper.getLineStartOffset
 | 
			
		||||
 | 
			
		||||
class CharacterPosition(line: Int, col: Int) : LogicalPosition(line, col) {
 | 
			
		||||
  fun toOffset(editor: Editor) = editor.vim.getLineStartOffset(line) + column
 | 
			
		||||
  fun toOffset(editor: Editor) = getLineStartOffset(editor, line) + column
 | 
			
		||||
 | 
			
		||||
  companion object {
 | 
			
		||||
    fun fromOffset(editor: Editor, offset: Int): CharacterPosition {
 | 
			
		||||
      // logical position "expands" tabs
 | 
			
		||||
      val logicalPosition = editor.offsetToLogicalPosition(offset)
 | 
			
		||||
      val lineStartOffset = editor.vim.getLineStartOffset(logicalPosition.line)
 | 
			
		||||
      val lineStartOffset = getLineStartOffset(editor, logicalPosition.line)
 | 
			
		||||
      return CharacterPosition(logicalPosition.line, offset - lineStartOffset)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,19 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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.common
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,19 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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.config
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,19 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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.config.migration
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,19 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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.config.migration
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,19 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
@file:Suppress("ClassName")
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,19 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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.ex
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,19 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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.ex.vimscript;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,19 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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.extension
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,19 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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.extension;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,19 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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.extension
 | 
			
		||||
 | 
			
		||||
@@ -13,7 +23,6 @@ import com.intellij.openapi.editor.Editor
 | 
			
		||||
import com.maddyhome.idea.vim.KeyHandler
 | 
			
		||||
import com.maddyhome.idea.vim.VimPlugin
 | 
			
		||||
import com.maddyhome.idea.vim.action.change.Extension
 | 
			
		||||
import com.maddyhome.idea.vim.api.ImmutableVimCaret
 | 
			
		||||
import com.maddyhome.idea.vim.api.VimCaret
 | 
			
		||||
import com.maddyhome.idea.vim.command.MappingMode
 | 
			
		||||
import com.maddyhome.idea.vim.command.SelectionType
 | 
			
		||||
@@ -189,7 +198,7 @@ object VimExtensionFacade {
 | 
			
		||||
 | 
			
		||||
  /** Set the current contents of the given register */
 | 
			
		||||
  @JvmStatic
 | 
			
		||||
  fun setRegisterForCaret(register: Char, caret: ImmutableVimCaret, keys: List<KeyStroke?>?) {
 | 
			
		||||
  fun setRegisterForCaret(register: Char, caret: VimCaret, keys: List<KeyStroke?>?) {
 | 
			
		||||
    caret.registerStorage.setKeys(caret, register, keys?.filterNotNull() ?: emptyList())
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,19 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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.extension
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,19 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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.extension
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,20 +1,32 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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.extension.argtextobj;
 | 
			
		||||
 | 
			
		||||
import com.intellij.openapi.editor.Caret;
 | 
			
		||||
import com.intellij.openapi.editor.Document;
 | 
			
		||||
import com.maddyhome.idea.vim.VimPlugin;
 | 
			
		||||
import com.maddyhome.idea.vim.api.*;
 | 
			
		||||
import com.maddyhome.idea.vim.command.*;
 | 
			
		||||
import com.maddyhome.idea.vim.command.MappingMode;
 | 
			
		||||
import com.maddyhome.idea.vim.common.TextRange;
 | 
			
		||||
import com.maddyhome.idea.vim.extension.ExtensionHandler;
 | 
			
		||||
import com.maddyhome.idea.vim.extension.VimExtension;
 | 
			
		||||
import com.maddyhome.idea.vim.extension.ExtensionHandler;
 | 
			
		||||
import com.maddyhome.idea.vim.handler.TextObjectActionHandler;
 | 
			
		||||
import com.maddyhome.idea.vim.helper.InlayHelperKt;
 | 
			
		||||
import com.maddyhome.idea.vim.helper.MessageHelper;
 | 
			
		||||
@@ -24,7 +36,6 @@ import com.maddyhome.idea.vim.listener.VimListenerSuppressor;
 | 
			
		||||
import com.maddyhome.idea.vim.newapi.IjVimCaret;
 | 
			
		||||
import com.maddyhome.idea.vim.newapi.IjVimEditor;
 | 
			
		||||
import com.maddyhome.idea.vim.vimscript.model.datatypes.VimString;
 | 
			
		||||
import kotlin.Unit;
 | 
			
		||||
import org.jetbrains.annotations.Nls;
 | 
			
		||||
import org.jetbrains.annotations.NotNull;
 | 
			
		||||
import org.jetbrains.annotations.Nullable;
 | 
			
		||||
@@ -34,7 +45,8 @@ import java.util.Deque;
 | 
			
		||||
import java.util.EnumSet;
 | 
			
		||||
 | 
			
		||||
import static com.maddyhome.idea.vim.extension.VimExtensionFacade.putExtensionHandlerMapping;
 | 
			
		||||
import static com.maddyhome.idea.vim.extension.VimExtensionFacade.putKeyMappingIfMissing;
 | 
			
		||||
import static com.maddyhome.idea.vim.extension.VimExtensionFacade.putKeyMapping;
 | 
			
		||||
import static com.maddyhome.idea.vim.group.visual.VisualGroupKt.vimSetSelection;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author igrekster
 | 
			
		||||
@@ -53,8 +65,9 @@ public class VimArgTextObjExtension implements VimExtension {
 | 
			
		||||
    putExtensionHandlerMapping(MappingMode.XO, VimInjectorKt.getInjector().getParser().parseKeys("<Plug>InnerArgument"), getOwner(), new VimArgTextObjExtension.ArgumentHandler(true), false);
 | 
			
		||||
    putExtensionHandlerMapping(MappingMode.XO, VimInjectorKt.getInjector().getParser().parseKeys("<Plug>OuterArgument"), getOwner(), new VimArgTextObjExtension.ArgumentHandler(false), false);
 | 
			
		||||
 | 
			
		||||
    putKeyMappingIfMissing(MappingMode.XO, VimInjectorKt.getInjector().getParser().parseKeys("ia"), getOwner(), VimInjectorKt.getInjector().getParser().parseKeys("<Plug>InnerArgument"), true);
 | 
			
		||||
    putKeyMappingIfMissing(MappingMode.XO, VimInjectorKt.getInjector().getParser().parseKeys("aa"), getOwner(), VimInjectorKt.getInjector().getParser().parseKeys("<Plug>OuterArgument"), true);
 | 
			
		||||
    putKeyMapping(MappingMode.XO, VimInjectorKt.getInjector().getParser().parseKeys("ia"), getOwner(), VimInjectorKt.getInjector().getParser().parseKeys("<Plug>InnerArgument"), true);
 | 
			
		||||
    putKeyMapping(MappingMode.XO, VimInjectorKt.getInjector().getParser().parseKeys("aa"), getOwner(), VimInjectorKt.getInjector().getParser().parseKeys("<Plug>OuterArgument"), true);
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
@@ -161,8 +174,8 @@ public class VimArgTextObjExtension implements VimExtension {
 | 
			
		||||
  @Nullable
 | 
			
		||||
  private static String bracketPairsVariable() {
 | 
			
		||||
    final Object value = VimPlugin.getVariableService().getGlobalVariableValue("argtextobj_pairs");
 | 
			
		||||
    if (value instanceof VimString vimValue) {
 | 
			
		||||
      return vimValue.getValue();
 | 
			
		||||
    if (value instanceof VimString) {
 | 
			
		||||
      return ((VimString)value).getValue();
 | 
			
		||||
    }
 | 
			
		||||
    return null;
 | 
			
		||||
  }
 | 
			
		||||
@@ -193,7 +206,7 @@ public class VimArgTextObjExtension implements VimExtension {
 | 
			
		||||
      @Nullable
 | 
			
		||||
      @Override
 | 
			
		||||
      public TextRange getRange(@NotNull VimEditor editor,
 | 
			
		||||
                                @NotNull ImmutableVimCaret caret,
 | 
			
		||||
                                @NotNull VimCaret caret,
 | 
			
		||||
                                @NotNull ExecutionContext context,
 | 
			
		||||
                                int count,
 | 
			
		||||
                                int rawCount,
 | 
			
		||||
@@ -252,18 +265,18 @@ public class VimArgTextObjExtension implements VimExtension {
 | 
			
		||||
      final ArgumentTextObjectHandler textObjectHandler = new ArgumentTextObjectHandler(isInner);
 | 
			
		||||
      //noinspection DuplicatedCode
 | 
			
		||||
      if (!vimStateMachine.isOperatorPending()) {
 | 
			
		||||
        editor.forEachNativeCaret((VimCaret caret) -> {
 | 
			
		||||
          final TextRange range = textObjectHandler.getRange(editor, caret, context, count, 0, null);
 | 
			
		||||
        vimEditor.getEditor().getCaretModel().runForEachCaret((Caret caret) -> {
 | 
			
		||||
          final TextRange range = textObjectHandler.getRange(vimEditor, new IjVimCaret(caret), context, count, 0, null);
 | 
			
		||||
          if (range != null) {
 | 
			
		||||
            try (VimListenerSuppressor.Locked ignored = SelectionVimListenerSuppressor.INSTANCE.lock()) {
 | 
			
		||||
              if (vimStateMachine.getMode() == VimStateMachine.Mode.VISUAL) {
 | 
			
		||||
                com.maddyhome.idea.vim.group.visual.EngineVisualGroupKt.vimSetSelection(caret, range.getStartOffset(), range.getEndOffset() - 1, true);
 | 
			
		||||
                vimSetSelection(caret, range.getStartOffset(), range.getEndOffset() - 1, true);
 | 
			
		||||
              } else {
 | 
			
		||||
                InlayHelperKt.moveToInlayAwareOffset(((IjVimCaret)caret).getCaret(), range.getStartOffset());
 | 
			
		||||
                InlayHelperKt.moveToInlayAwareOffset(caret, range.getStartOffset());
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
          return Unit.INSTANCE;
 | 
			
		||||
 | 
			
		||||
        });
 | 
			
		||||
      } else {
 | 
			
		||||
        vimStateMachine.getCommandBuilder().completeCommandPart(new Argument(new Command(count,
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,19 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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.extension.commentary
 | 
			
		||||
 | 
			
		||||
@@ -19,9 +29,8 @@ import com.intellij.psi.PsiWhiteSpace
 | 
			
		||||
import com.intellij.psi.util.PsiTreeUtil
 | 
			
		||||
import com.maddyhome.idea.vim.VimPlugin
 | 
			
		||||
import com.maddyhome.idea.vim.api.ExecutionContext
 | 
			
		||||
import com.maddyhome.idea.vim.api.ImmutableVimCaret
 | 
			
		||||
import com.maddyhome.idea.vim.api.VimCaret
 | 
			
		||||
import com.maddyhome.idea.vim.api.VimEditor
 | 
			
		||||
import com.maddyhome.idea.vim.api.getLineEndOffset
 | 
			
		||||
import com.maddyhome.idea.vim.api.injector
 | 
			
		||||
import com.maddyhome.idea.vim.command.Argument
 | 
			
		||||
import com.maddyhome.idea.vim.command.Command
 | 
			
		||||
@@ -42,12 +51,12 @@ import com.maddyhome.idea.vim.extension.VimExtensionFacade.putKeyMapping
 | 
			
		||||
import com.maddyhome.idea.vim.extension.VimExtensionFacade.putKeyMappingIfMissing
 | 
			
		||||
import com.maddyhome.idea.vim.extension.VimExtensionFacade.setOperatorFunction
 | 
			
		||||
import com.maddyhome.idea.vim.handler.TextObjectActionHandler
 | 
			
		||||
import com.maddyhome.idea.vim.helper.EditorHelper
 | 
			
		||||
import com.maddyhome.idea.vim.helper.PsiHelper
 | 
			
		||||
import com.maddyhome.idea.vim.helper.vimStateMachine
 | 
			
		||||
import com.maddyhome.idea.vim.key.OperatorFunction
 | 
			
		||||
import com.maddyhome.idea.vim.newapi.IjVimEditor
 | 
			
		||||
import com.maddyhome.idea.vim.newapi.ij
 | 
			
		||||
import com.maddyhome.idea.vim.newapi.vim
 | 
			
		||||
import java.util.*
 | 
			
		||||
 | 
			
		||||
class CommentaryExtension : VimExtension {
 | 
			
		||||
@@ -191,7 +200,7 @@ class CommentaryExtension : VimExtension {
 | 
			
		||||
 | 
			
		||||
    override fun getRange(
 | 
			
		||||
      editor: VimEditor,
 | 
			
		||||
      caret: ImmutableVimCaret,
 | 
			
		||||
      caret: VimCaret,
 | 
			
		||||
      context: ExecutionContext,
 | 
			
		||||
      count: Int,
 | 
			
		||||
      rawCount: Int,
 | 
			
		||||
@@ -202,14 +211,14 @@ class CommentaryExtension : VimExtension {
 | 
			
		||||
      val file = PsiHelper.getFile(nativeEditor) ?: return null
 | 
			
		||||
      val lastLine = editor.lineCount()
 | 
			
		||||
 | 
			
		||||
      var startLine = caret.getBufferPosition().line
 | 
			
		||||
      var startLine = caret.getLogicalPosition().line
 | 
			
		||||
      while (startLine > 0 && isCommentLine(file, nativeEditor, startLine - 1)) startLine--
 | 
			
		||||
      var endLine = caret.getBufferPosition().line - 1
 | 
			
		||||
      var endLine = caret.getLogicalPosition().line - 1
 | 
			
		||||
      while (endLine < lastLine && isCommentLine(file, nativeEditor, endLine + 1)) endLine++
 | 
			
		||||
 | 
			
		||||
      if (startLine <= endLine) {
 | 
			
		||||
        val startOffset = editor.getLineStartOffset(startLine)
 | 
			
		||||
        val endOffset = editor.getLineStartOffset(endLine + 1)
 | 
			
		||||
        val startOffset = EditorHelper.getLineStartOffset(nativeEditor, startLine)
 | 
			
		||||
        val endOffset = EditorHelper.getLineStartOffset(nativeEditor, endLine + 1)
 | 
			
		||||
        return TextRange(startOffset, endOffset)
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
@@ -218,8 +227,8 @@ class CommentaryExtension : VimExtension {
 | 
			
		||||
 | 
			
		||||
    // Check all leaf nodes in the given line are whitespace, comments, or are owned by comments
 | 
			
		||||
    private fun isCommentLine(file: PsiFile, editor: Editor, logicalLine: Int): Boolean {
 | 
			
		||||
      val startOffset = editor.vim.getLineStartOffset(logicalLine)
 | 
			
		||||
      val endOffset = editor.vim.getLineEndOffset(logicalLine, true)
 | 
			
		||||
      val startOffset = EditorHelper.getLineStartOffset(editor, logicalLine)
 | 
			
		||||
      val endOffset = EditorHelper.getLineEndOffset(editor, logicalLine, true)
 | 
			
		||||
      val startElement = file.findElementAt(startOffset) ?: return false
 | 
			
		||||
      var next: PsiElement? = startElement
 | 
			
		||||
      while (next != null && next.textRange.startOffset <= endOffset) {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,19 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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.extension.exchange
 | 
			
		||||
@@ -19,7 +29,6 @@ import com.intellij.openapi.util.Key
 | 
			
		||||
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.getOffset
 | 
			
		||||
import com.maddyhome.idea.vim.api.injector
 | 
			
		||||
import com.maddyhome.idea.vim.command.MappingMode
 | 
			
		||||
import com.maddyhome.idea.vim.command.SelectionType
 | 
			
		||||
@@ -33,6 +42,7 @@ 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.setRegister
 | 
			
		||||
import com.maddyhome.idea.vim.helper.EditorHelper
 | 
			
		||||
import com.maddyhome.idea.vim.helper.fileSize
 | 
			
		||||
import com.maddyhome.idea.vim.helper.moveToInlayAwareLogicalPosition
 | 
			
		||||
import com.maddyhome.idea.vim.helper.moveToInlayAwareOffset
 | 
			
		||||
@@ -40,7 +50,6 @@ import com.maddyhome.idea.vim.helper.subMode
 | 
			
		||||
import com.maddyhome.idea.vim.key.OperatorFunction
 | 
			
		||||
import com.maddyhome.idea.vim.mark.Mark
 | 
			
		||||
import com.maddyhome.idea.vim.mark.VimMarkConstants
 | 
			
		||||
import com.maddyhome.idea.vim.newapi.IjVimEditor
 | 
			
		||||
import com.maddyhome.idea.vim.newapi.ij
 | 
			
		||||
import com.maddyhome.idea.vim.newapi.vim
 | 
			
		||||
import org.jetbrains.annotations.NonNls
 | 
			
		||||
@@ -129,7 +138,7 @@ class VimExchangeExtension : VimExtension {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private class Operator(private val isVisual: Boolean) : OperatorFunction {
 | 
			
		||||
    fun Editor.getMarkOffset(mark: Mark) = IjVimEditor(this).getOffset(mark.line, mark.col)
 | 
			
		||||
    fun Editor.getMarkOffset(mark: Mark) = EditorHelper.getOffset(this, mark.logicalLine, mark.col)
 | 
			
		||||
    fun VimStateMachine.SubMode.getString() = when (this) {
 | 
			
		||||
      VimStateMachine.SubMode.VISUAL_CHARACTER -> "v"
 | 
			
		||||
      VimStateMachine.SubMode.VISUAL_LINE -> "V"
 | 
			
		||||
@@ -208,19 +217,19 @@ class VimExchangeExtension : VimExtension {
 | 
			
		||||
        if (reverse) {
 | 
			
		||||
          primaryCaret.moveToInlayAwareOffset(editor.getMarkOffset(ex1.start))
 | 
			
		||||
        } else {
 | 
			
		||||
          if (ex1.start.line == ex2.start.line) {
 | 
			
		||||
          if (ex1.start.logicalLine == ex2.start.logicalLine) {
 | 
			
		||||
            val horizontalOffset = ex1.end.col - ex2.end.col
 | 
			
		||||
            primaryCaret.moveToInlayAwareLogicalPosition(
 | 
			
		||||
              LogicalPosition(
 | 
			
		||||
                ex1.start.line,
 | 
			
		||||
                ex1.start.logicalLine,
 | 
			
		||||
                ex1.start.col - horizontalOffset
 | 
			
		||||
              )
 | 
			
		||||
            )
 | 
			
		||||
          } else if (ex1.end.line - ex1.start.line != ex2.end.line - ex2.start.line) {
 | 
			
		||||
            val verticalOffset = ex1.end.line - ex2.end.line
 | 
			
		||||
          } else if (ex1.end.logicalLine - ex1.start.logicalLine != ex2.end.logicalLine - ex2.start.logicalLine) {
 | 
			
		||||
            val verticalOffset = ex1.end.logicalLine - ex2.end.logicalLine
 | 
			
		||||
            primaryCaret.moveToInlayAwareLogicalPosition(
 | 
			
		||||
              LogicalPosition(
 | 
			
		||||
                ex1.start.line - verticalOffset,
 | 
			
		||||
                ex1.start.logicalLine - verticalOffset,
 | 
			
		||||
                ex1.start.col
 | 
			
		||||
              )
 | 
			
		||||
            )
 | 
			
		||||
@@ -253,16 +262,16 @@ class VimExchangeExtension : VimExtension {
 | 
			
		||||
 | 
			
		||||
    private fun compareExchanges(x: Exchange, y: Exchange): ExchangeCompareResult {
 | 
			
		||||
      fun intersects(x: Exchange, y: Exchange) =
 | 
			
		||||
        x.end.line < y.start.line ||
 | 
			
		||||
          x.start.line > y.end.line ||
 | 
			
		||||
        x.end.logicalLine < y.start.logicalLine ||
 | 
			
		||||
          x.start.logicalLine > y.end.logicalLine ||
 | 
			
		||||
          x.end.col < y.start.col ||
 | 
			
		||||
          x.start.col > y.end.col
 | 
			
		||||
 | 
			
		||||
      fun comparePos(x: Mark, y: Mark): Int =
 | 
			
		||||
        if (x.line == y.line) {
 | 
			
		||||
        if (x.logicalLine == y.logicalLine) {
 | 
			
		||||
          x.col - y.col
 | 
			
		||||
        } else {
 | 
			
		||||
          x.line - y.line
 | 
			
		||||
          x.logicalLine - y.logicalLine
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      return if (x.type == VimStateMachine.SubMode.VISUAL_BLOCK && y.type == VimStateMachine.SubMode.VISUAL_BLOCK) {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,19 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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.extension.highlightedyank
 | 
			
		||||
@@ -21,15 +31,15 @@ import com.intellij.openapi.editor.markup.TextAttributes
 | 
			
		||||
import com.intellij.openapi.util.Disposer
 | 
			
		||||
import com.maddyhome.idea.vim.VimPlugin
 | 
			
		||||
import com.maddyhome.idea.vim.VimProjectService
 | 
			
		||||
import com.maddyhome.idea.vim.api.VimEditor
 | 
			
		||||
import com.maddyhome.idea.vim.api.injector
 | 
			
		||||
import com.maddyhome.idea.vim.common.TextRange
 | 
			
		||||
import com.maddyhome.idea.vim.extension.VimExtension
 | 
			
		||||
import com.maddyhome.idea.vim.helper.MessageHelper
 | 
			
		||||
import com.maddyhome.idea.vim.helper.VimNlsSafe
 | 
			
		||||
import com.maddyhome.idea.vim.listener.VimInsertListener
 | 
			
		||||
import com.maddyhome.idea.vim.listener.VimYankListener
 | 
			
		||||
import com.maddyhome.idea.vim.newapi.ij
 | 
			
		||||
import com.maddyhome.idea.vim.options.helpers.StrictMode
 | 
			
		||||
import com.maddyhome.idea.vim.options.OptionConstants
 | 
			
		||||
import com.maddyhome.idea.vim.options.OptionScope
 | 
			
		||||
import com.maddyhome.idea.vim.vimscript.model.datatypes.VimString
 | 
			
		||||
import org.jetbrains.annotations.NonNls
 | 
			
		||||
import java.awt.Color
 | 
			
		||||
@@ -91,8 +101,8 @@ class VimHighlightedYank : VimExtension, VimYankListener, VimInsertListener {
 | 
			
		||||
    VimPlugin.getChange().removeInsertListener(this)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  override fun yankPerformed(editor: VimEditor, range: TextRange) {
 | 
			
		||||
    highlightHandler.highlightYankRange(editor.ij, range)
 | 
			
		||||
  override fun yankPerformed(editor: Editor, range: TextRange) {
 | 
			
		||||
    highlightHandler.highlightYankRange(editor, range)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  override fun insertModeStarted(editor: Editor) {
 | 
			
		||||
@@ -129,12 +139,18 @@ class VimHighlightedYank : VimExtension, VimYankListener, VimInsertListener {
 | 
			
		||||
 | 
			
		||||
    fun clearAllYankHighlighters() {
 | 
			
		||||
      yankHighlighters.forEach { highlighter ->
 | 
			
		||||
        editor?.markupModel?.removeHighlighter(highlighter) ?: StrictMode.fail("Highlighters without an editor")
 | 
			
		||||
        editor?.markupModel?.removeHighlighter(highlighter) ?: failIfStrictMode("Highlighters without an editor")
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      yankHighlighters.clear()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun failIfStrictMode(value: String) {
 | 
			
		||||
      if (injector.optionService.isSet(OptionScope.GLOBAL, OptionConstants.ideastrictmodeName)) {
 | 
			
		||||
        error(value)
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun highlightSingleRange(editor: Editor, range: ClosedRange<Int>) {
 | 
			
		||||
      val highlighter = editor.markupModel.addRangeHighlighter(
 | 
			
		||||
        range.start,
 | 
			
		||||
@@ -157,7 +173,7 @@ class VimHighlightedYank : VimExtension, VimYankListener, VimInsertListener {
 | 
			
		||||
        Executors.newSingleThreadScheduledExecutor().schedule(
 | 
			
		||||
          {
 | 
			
		||||
            ApplicationManager.getApplication().invokeLater {
 | 
			
		||||
              editor?.markupModel?.removeHighlighter(highlighter) ?: StrictMode.fail("Highlighters without an editor")
 | 
			
		||||
              editor?.markupModel?.removeHighlighter(highlighter) ?: failIfStrictMode("Highlighters without an editor")
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
          timeout, TimeUnit.MILLISECONDS
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,19 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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.extension.matchit
 | 
			
		||||
@@ -17,13 +27,9 @@ import com.intellij.psi.util.PsiTreeUtil
 | 
			
		||||
import com.intellij.psi.util.elementType
 | 
			
		||||
import com.maddyhome.idea.vim.VimPlugin
 | 
			
		||||
import com.maddyhome.idea.vim.api.ExecutionContext
 | 
			
		||||
import com.maddyhome.idea.vim.api.ImmutableVimCaret
 | 
			
		||||
import com.maddyhome.idea.vim.api.VimCaret
 | 
			
		||||
import com.maddyhome.idea.vim.api.VimEditor
 | 
			
		||||
import com.maddyhome.idea.vim.api.getLineEndForOffset
 | 
			
		||||
import com.maddyhome.idea.vim.api.getLineEndOffset
 | 
			
		||||
import com.maddyhome.idea.vim.api.getLineStartForOffset
 | 
			
		||||
import com.maddyhome.idea.vim.api.injector
 | 
			
		||||
import com.maddyhome.idea.vim.api.normalizeOffset
 | 
			
		||||
import com.maddyhome.idea.vim.command.Argument
 | 
			
		||||
import com.maddyhome.idea.vim.command.Command
 | 
			
		||||
import com.maddyhome.idea.vim.command.CommandFlags
 | 
			
		||||
@@ -42,7 +48,6 @@ import com.maddyhome.idea.vim.helper.EditorHelper
 | 
			
		||||
import com.maddyhome.idea.vim.helper.PsiHelper
 | 
			
		||||
import com.maddyhome.idea.vim.helper.enumSetOf
 | 
			
		||||
import com.maddyhome.idea.vim.helper.vimStateMachine
 | 
			
		||||
import com.maddyhome.idea.vim.newapi.IjVimEditor
 | 
			
		||||
import com.maddyhome.idea.vim.newapi.ij
 | 
			
		||||
import com.maddyhome.idea.vim.newapi.vim
 | 
			
		||||
import java.util.*
 | 
			
		||||
@@ -74,7 +79,7 @@ class Matchit : VimExtension {
 | 
			
		||||
 | 
			
		||||
    override fun getOffset(
 | 
			
		||||
      editor: VimEditor,
 | 
			
		||||
      caret: ImmutableVimCaret,
 | 
			
		||||
      caret: VimCaret,
 | 
			
		||||
      context: ExecutionContext,
 | 
			
		||||
      argument: Argument?,
 | 
			
		||||
      operatorArguments: OperatorArguments,
 | 
			
		||||
@@ -118,7 +123,7 @@ class Matchit : VimExtension {
 | 
			
		||||
      } else {
 | 
			
		||||
        editor.forEachCaret { caret ->
 | 
			
		||||
          VimPlugin.getMark().saveJumpLocation(editor)
 | 
			
		||||
          caret.moveToOffset(getMatchitOffset(editor.ij, caret.ij, count, isInOpPending, reverse))
 | 
			
		||||
          injector.motion.moveCaret(editor, caret, getMatchitOffset(editor.ij, caret.ij, count, isInOpPending, reverse))
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
@@ -321,7 +326,7 @@ private fun getMatchitOffset(editor: Editor, caret: Caret, count: Int, isInOpPen
 | 
			
		||||
  var caretOffset = caret.offset
 | 
			
		||||
 | 
			
		||||
  // Handle the case where visual mode has brought the cursor past the end of the line.
 | 
			
		||||
  val lineEndOffset = editor.vim.getLineEndOffset(caret.logicalPosition.line, true)
 | 
			
		||||
  val lineEndOffset = EditorHelper.getLineEndOffset(editor, caret.logicalPosition.line, true)
 | 
			
		||||
  if (caretOffset > 0 && caretOffset == lineEndOffset) {
 | 
			
		||||
    caretOffset--
 | 
			
		||||
  }
 | 
			
		||||
@@ -354,7 +359,7 @@ private fun getMatchitOffset(editor: Editor, caret: Caret, count: Int, isInOpPen
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (motion >= 0) {
 | 
			
		||||
    motion = editor.vim.normalizeOffset(motion, false)
 | 
			
		||||
    motion = EditorHelper.normalizeOffset(editor, motion, false)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return motion
 | 
			
		||||
@@ -369,8 +374,8 @@ private fun findMatchingPair(
 | 
			
		||||
): Int {
 | 
			
		||||
  // For better performance, we limit our search to the current line. This way we don't have to scan the entire file
 | 
			
		||||
  // to determine if we're on a pattern or not. The original plugin behaves the same way.
 | 
			
		||||
  val currentLineStart = IjVimEditor(editor).getLineStartForOffset(caretOffset)
 | 
			
		||||
  val currentLineEnd = IjVimEditor(editor).getLineEndForOffset(caretOffset)
 | 
			
		||||
  val currentLineStart = EditorHelper.getLineStartForOffset(editor, caretOffset)
 | 
			
		||||
  val currentLineEnd = EditorHelper.getLineEndForOffset(editor, caretOffset)
 | 
			
		||||
  val currentLineChars = editor.document.charsSequence.subSequence(currentLineStart, currentLineEnd)
 | 
			
		||||
  val offset = caretOffset - currentLineStart
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,19 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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.extension.multiplecursors
 | 
			
		||||
@@ -18,7 +28,6 @@ import com.maddyhome.idea.vim.KeyHandler
 | 
			
		||||
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.getText
 | 
			
		||||
import com.maddyhome.idea.vim.api.injector
 | 
			
		||||
import com.maddyhome.idea.vim.command.MappingMode
 | 
			
		||||
import com.maddyhome.idea.vim.command.VimStateMachine
 | 
			
		||||
@@ -29,6 +38,7 @@ import com.maddyhome.idea.vim.extension.VimExtensionFacade.putExtensionHandlerMa
 | 
			
		||||
import com.maddyhome.idea.vim.extension.VimExtensionFacade.putKeyMappingIfMissing
 | 
			
		||||
import com.maddyhome.idea.vim.group.MotionGroup
 | 
			
		||||
import com.maddyhome.idea.vim.group.visual.vimSetSelection
 | 
			
		||||
import com.maddyhome.idea.vim.helper.EditorHelper
 | 
			
		||||
import com.maddyhome.idea.vim.helper.MessageHelper
 | 
			
		||||
import com.maddyhome.idea.vim.helper.SearchHelper
 | 
			
		||||
import com.maddyhome.idea.vim.helper.SearchOptions
 | 
			
		||||
@@ -157,12 +167,12 @@ class VimMultipleCursorsExtension : VimExtension {
 | 
			
		||||
            for (line in startPosition.line + 1..startPosition.line + lines) {
 | 
			
		||||
              newPositions.add(VisualPosition(line, startPosition.column))
 | 
			
		||||
            }
 | 
			
		||||
            caret.vim.moveToOffset(selectionStart)
 | 
			
		||||
            MotionGroup.moveCaret(editor, caret, selectionStart)
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (newPositions.size > 0) {
 | 
			
		||||
          editor.vim.exitVisualMode()
 | 
			
		||||
          editor.exitVisualMode()
 | 
			
		||||
          newPositions.forEach { editor.caretModel.addCaret(it, true) ?: return }
 | 
			
		||||
          editor.updateCaretsVisualAttributes()
 | 
			
		||||
          return
 | 
			
		||||
@@ -195,7 +205,7 @@ class VimMultipleCursorsExtension : VimExtension {
 | 
			
		||||
 | 
			
		||||
        // Always work on the text in the last visual selection range, so we work with any changed text, even if it's no
 | 
			
		||||
        // longer selected
 | 
			
		||||
        val pattern = editor.vim.getText(lastSelection)
 | 
			
		||||
        val pattern = EditorHelper.getText(editor, lastSelection)
 | 
			
		||||
 | 
			
		||||
        val primaryCaret = editor.caretModel.primaryCaret
 | 
			
		||||
        val nextOffset = findNextOccurrence(editor, primaryCaret.offset, pattern, wholeWord)
 | 
			
		||||
@@ -228,7 +238,7 @@ class VimMultipleCursorsExtension : VimExtension {
 | 
			
		||||
      } else {
 | 
			
		||||
        val range = SearchHelper.findWordUnderCursor(editor, primaryCaret) ?: return
 | 
			
		||||
        if (range.startOffset > primaryCaret.offset) return
 | 
			
		||||
        IjVimEditor(editor).getText(range)
 | 
			
		||||
        EditorHelper.getText(editor, range)
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (!editor.inVisualMode) {
 | 
			
		||||
@@ -240,7 +250,7 @@ class VimMultipleCursorsExtension : VimExtension {
 | 
			
		||||
      val matches = SearchHelper.findAll(editor, pattern, 0, -1, false)
 | 
			
		||||
      for (match in matches) {
 | 
			
		||||
        if (match.contains(primaryCaret.offset)) {
 | 
			
		||||
          primaryCaret.vim.moveToOffset(match.startOffset)
 | 
			
		||||
          MotionGroup.moveCaret(editor, primaryCaret, match.startOffset)
 | 
			
		||||
          selectText(primaryCaret, text, match.startOffset)
 | 
			
		||||
        } else {
 | 
			
		||||
          val caret = editor.caretModel.addCaret(editor.offsetToVisualPosition(match.startOffset), true) ?: return
 | 
			
		||||
@@ -277,7 +287,7 @@ class VimMultipleCursorsExtension : VimExtension {
 | 
			
		||||
      val caret = editor.caretModel.primaryCaret
 | 
			
		||||
      if (caret.selectedText == null) return
 | 
			
		||||
      if (!editor.caretModel.removeCaret(caret)) {
 | 
			
		||||
        editor.vim.exitVisualMode()
 | 
			
		||||
        editor.exitVisualMode()
 | 
			
		||||
      }
 | 
			
		||||
      MotionGroup.scrollCaretIntoView(caret.editor)
 | 
			
		||||
    }
 | 
			
		||||
@@ -285,7 +295,7 @@ class VimMultipleCursorsExtension : VimExtension {
 | 
			
		||||
 | 
			
		||||
  private fun selectText(caret: Caret, text: String, offset: Int): TextRange? {
 | 
			
		||||
    if (text.isEmpty()) return null
 | 
			
		||||
    caret.vim.vimSetSelection(offset, offset + text.length - 1, true)
 | 
			
		||||
    caret.vimSetSelection(offset, offset + text.length - 1, true)
 | 
			
		||||
    MotionGroup.scrollCaretIntoView(caret.editor)
 | 
			
		||||
    return TextRange(caret.selectionStart, caret.selectionEnd)
 | 
			
		||||
  }
 | 
			
		||||
@@ -297,7 +307,7 @@ class VimMultipleCursorsExtension : VimExtension {
 | 
			
		||||
    enterVisualMode(editor.vim)
 | 
			
		||||
 | 
			
		||||
    // Select the word under the caret, moving the caret to the end of the selection
 | 
			
		||||
    caret.vim.vimSetSelection(range.startOffset, range.endOffsetInclusive, true)
 | 
			
		||||
    caret.vimSetSelection(range.startOffset, range.endOffsetInclusive, true)
 | 
			
		||||
    return TextRange(caret.selectionStart, caret.selectionEnd)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,19 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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.extension.nerdtree
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,19 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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.extension.nerdtree
 | 
			
		||||
@@ -14,7 +24,6 @@ import com.intellij.openapi.actionSystem.ActionManager
 | 
			
		||||
import com.intellij.openapi.actionSystem.ActionUpdateThread
 | 
			
		||||
import com.intellij.openapi.actionSystem.AnActionEvent
 | 
			
		||||
import com.intellij.openapi.actionSystem.CommonDataKeys
 | 
			
		||||
import com.intellij.openapi.actionSystem.PlatformDataKeys
 | 
			
		||||
import com.intellij.openapi.application.ApplicationManager
 | 
			
		||||
import com.intellij.openapi.diagnostic.logger
 | 
			
		||||
import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx
 | 
			
		||||
@@ -137,7 +146,7 @@ class NerdTree : VimExtension {
 | 
			
		||||
 | 
			
		||||
  class IjCommandHandler(private val actionId: String) : CommandAliasHandler {
 | 
			
		||||
    override fun execute(command: String, ranges: Ranges, editor: VimEditor, context: ExecutionContext) {
 | 
			
		||||
      callAction(editor, actionId, context)
 | 
			
		||||
      callAction(actionId, context)
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -148,7 +157,7 @@ class NerdTree : VimExtension {
 | 
			
		||||
      if (toolWindow.isVisible) {
 | 
			
		||||
        toolWindow.hide()
 | 
			
		||||
      } else {
 | 
			
		||||
        callAction(editor, "ActivateProjectToolWindow", context)
 | 
			
		||||
        callAction("ActivateProjectToolWindow", context)
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
@@ -210,7 +219,7 @@ class NerdTree : VimExtension {
 | 
			
		||||
 | 
			
		||||
          val action = nextNode.actionHolder
 | 
			
		||||
          when (action) {
 | 
			
		||||
            is NerdAction.ToIj -> callAction(null, action.name, e.dataContext.vim)
 | 
			
		||||
            is NerdAction.ToIj -> callAction(action.name, e.dataContext.vim)
 | 
			
		||||
            is NerdAction.Code -> e.project?.let { action.action(it, e.dataContext, e) }
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
@@ -231,14 +240,14 @@ class NerdTree : VimExtension {
 | 
			
		||||
        e.presentation.isEnabled = false
 | 
			
		||||
        return
 | 
			
		||||
      }
 | 
			
		||||
      e.presentation.isEnabled = !speedSearchIsHere(e)
 | 
			
		||||
      e.presentation.isEnabled = !speedSearchIsHere(project)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun getActionUpdateThread() = ActionUpdateThread.BGT
 | 
			
		||||
    override fun getActionUpdateThread() = ActionUpdateThread.EDT
 | 
			
		||||
 | 
			
		||||
    private fun speedSearchIsHere(e: AnActionEvent): Boolean {
 | 
			
		||||
      val searchText = e.getData(PlatformDataKeys.SPEED_SEARCH_TEXT)
 | 
			
		||||
      return !searchText.isNullOrEmpty()
 | 
			
		||||
    private fun speedSearchIsHere(project: Project): Boolean {
 | 
			
		||||
      val component = ProjectView.getInstance(project).currentProjectViewPane.tree ?: return false
 | 
			
		||||
      return SpeedSearchSupply.getSupply(component) != null
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    companion object {
 | 
			
		||||
@@ -348,7 +357,7 @@ class NerdTree : VimExtension {
 | 
			
		||||
        currentWindow?.split(SwingConstants.VERTICAL, true, file, true)
 | 
			
		||||
 | 
			
		||||
        // FIXME: 22.01.2021 This solution bouncing a bit
 | 
			
		||||
        callAction(null, "ActivateProjectToolWindow", context.vim)
 | 
			
		||||
        callAction("ActivateProjectToolWindow", context.vim)
 | 
			
		||||
      }
 | 
			
		||||
    )
 | 
			
		||||
    registerCommand(
 | 
			
		||||
@@ -359,7 +368,7 @@ class NerdTree : VimExtension {
 | 
			
		||||
        val currentWindow = splitters.currentWindow
 | 
			
		||||
        currentWindow?.split(SwingConstants.HORIZONTAL, true, file, true)
 | 
			
		||||
 | 
			
		||||
        callAction(null, "ActivateProjectToolWindow", context.vim)
 | 
			
		||||
        callAction("ActivateProjectToolWindow", context.vim)
 | 
			
		||||
      }
 | 
			
		||||
    )
 | 
			
		||||
    registerCommand(
 | 
			
		||||
@@ -497,17 +506,20 @@ class NerdTree : VimExtension {
 | 
			
		||||
 | 
			
		||||
    private val LOG = logger<NerdTree>()
 | 
			
		||||
 | 
			
		||||
    fun callAction(editor: VimEditor?, name: String, context: ExecutionContext) {
 | 
			
		||||
    fun callAction(name: String, context: ExecutionContext) {
 | 
			
		||||
      val action = ActionManager.getInstance().getAction(name) ?: run {
 | 
			
		||||
        VimPlugin.showMessage(MessageHelper.message("action.not.found.0", name))
 | 
			
		||||
        return
 | 
			
		||||
      }
 | 
			
		||||
      val application = ApplicationManager.getApplication()
 | 
			
		||||
      if (application.isUnitTestMode) {
 | 
			
		||||
        injector.actionExecutor.executeAction(editor, action.vim, context)
 | 
			
		||||
        injector.actionExecutor.executeAction(action.vim, context)
 | 
			
		||||
      } else {
 | 
			
		||||
        runAfterGotFocus {
 | 
			
		||||
          injector.actionExecutor.executeAction(editor, action.vim, context)
 | 
			
		||||
          injector.actionExecutor.executeAction(
 | 
			
		||||
            action.vim,
 | 
			
		||||
            context,
 | 
			
		||||
          )
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,19 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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.extension.paragraphmotion
 | 
			
		||||
@@ -13,16 +23,16 @@ import com.intellij.openapi.editor.Editor
 | 
			
		||||
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.api.normalizeOffset
 | 
			
		||||
import com.maddyhome.idea.vim.command.MappingMode
 | 
			
		||||
import com.maddyhome.idea.vim.extension.ExtensionHandler
 | 
			
		||||
import com.maddyhome.idea.vim.extension.VimExtension
 | 
			
		||||
import com.maddyhome.idea.vim.extension.VimExtensionFacade
 | 
			
		||||
import com.maddyhome.idea.vim.extension.VimExtensionFacade.putKeyMappingIfMissing
 | 
			
		||||
import com.maddyhome.idea.vim.group.MotionGroup
 | 
			
		||||
import com.maddyhome.idea.vim.helper.EditorHelper
 | 
			
		||||
import com.maddyhome.idea.vim.helper.SearchHelper
 | 
			
		||||
import com.maddyhome.idea.vim.helper.vimForEachCaret
 | 
			
		||||
import com.maddyhome.idea.vim.newapi.ij
 | 
			
		||||
import com.maddyhome.idea.vim.newapi.vim
 | 
			
		||||
 | 
			
		||||
class ParagraphMotion : VimExtension {
 | 
			
		||||
  override fun getName(): String = "vim-paragraph-motion"
 | 
			
		||||
@@ -40,7 +50,7 @@ class ParagraphMotion : VimExtension {
 | 
			
		||||
      editor.ij.vimForEachCaret { caret ->
 | 
			
		||||
        val motion = moveCaretToNextParagraph(editor.ij, caret, count)
 | 
			
		||||
        if (motion >= 0) {
 | 
			
		||||
          caret.vim.moveToOffset(motion)
 | 
			
		||||
          MotionGroup.moveCaret(editor.ij, caret, motion)
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
@@ -48,7 +58,7 @@ class ParagraphMotion : VimExtension {
 | 
			
		||||
    fun moveCaretToNextParagraph(editor: Editor, caret: Caret, count: Int): Int {
 | 
			
		||||
      var res = SearchHelper.findNextParagraph(editor, caret, count, true)
 | 
			
		||||
      res = if (res >= 0) {
 | 
			
		||||
        editor.vim.normalizeOffset(res, true)
 | 
			
		||||
        EditorHelper.normalizeOffset(editor, res, true)
 | 
			
		||||
      } else {
 | 
			
		||||
        -1
 | 
			
		||||
      }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,19 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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.extension.replacewithregister
 | 
			
		||||
@@ -11,9 +21,8 @@ package com.maddyhome.idea.vim.extension.replacewithregister
 | 
			
		||||
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.ImmutableVimCaret
 | 
			
		||||
import com.maddyhome.idea.vim.api.VimCaret
 | 
			
		||||
import com.maddyhome.idea.vim.api.VimEditor
 | 
			
		||||
import com.maddyhome.idea.vim.api.getLineEndOffset
 | 
			
		||||
import com.maddyhome.idea.vim.api.injector
 | 
			
		||||
import com.maddyhome.idea.vim.command.MappingMode
 | 
			
		||||
import com.maddyhome.idea.vim.command.OperatorArguments
 | 
			
		||||
@@ -30,7 +39,6 @@ import com.maddyhome.idea.vim.extension.VimExtensionFacade.setOperatorFunction
 | 
			
		||||
import com.maddyhome.idea.vim.group.visual.VimSelection
 | 
			
		||||
import com.maddyhome.idea.vim.helper.EditorDataContext
 | 
			
		||||
import com.maddyhome.idea.vim.helper.editorMode
 | 
			
		||||
import com.maddyhome.idea.vim.helper.exitVisualMode
 | 
			
		||||
import com.maddyhome.idea.vim.helper.mode
 | 
			
		||||
import com.maddyhome.idea.vim.helper.subMode
 | 
			
		||||
import com.maddyhome.idea.vim.helper.vimStateMachine
 | 
			
		||||
@@ -67,7 +75,7 @@ class ReplaceWithRegister : VimExtension {
 | 
			
		||||
        val visualSelection = caret to VimSelection.create(selectionStart, selectionEnd - 1, typeInEditor, editor)
 | 
			
		||||
        doReplace(editor.ij, caret, PutData.VisualSelection(mapOf(visualSelection), typeInEditor))
 | 
			
		||||
      }
 | 
			
		||||
      editor.exitVisualMode()
 | 
			
		||||
      editor.exitVisualModeNative()
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -84,9 +92,9 @@ class ReplaceWithRegister : VimExtension {
 | 
			
		||||
    override val isRepeatable: Boolean = true
 | 
			
		||||
 | 
			
		||||
    override fun execute(editor: VimEditor, context: ExecutionContext) {
 | 
			
		||||
      val caretsAndSelections = mutableMapOf<ImmutableVimCaret, VimSelection>()
 | 
			
		||||
      val caretsAndSelections = mutableMapOf<VimCaret, VimSelection>()
 | 
			
		||||
      editor.forEachCaret { caret ->
 | 
			
		||||
        val logicalLine = caret.getBufferPosition().line
 | 
			
		||||
        val logicalLine = caret.getLogicalPosition().line
 | 
			
		||||
        val lineStart = editor.getLineStartOffset(logicalLine)
 | 
			
		||||
        val lineEnd = editor.getLineEndOffset(logicalLine, true)
 | 
			
		||||
 | 
			
		||||
@@ -142,7 +150,7 @@ class ReplaceWithRegister : VimExtension {
 | 
			
		||||
    @NonNls
 | 
			
		||||
    private const val RWR_VISUAL = "<Plug>ReplaceWithRegisterVisual"
 | 
			
		||||
 | 
			
		||||
    private fun doReplace(editor: Editor, caret: ImmutableVimCaret, visualSelection: PutData.VisualSelection) {
 | 
			
		||||
    private fun doReplace(editor: Editor, caret: VimCaret, visualSelection: PutData.VisualSelection) {
 | 
			
		||||
      val lastRegisterChar = injector.registerGroup.lastRegisterChar
 | 
			
		||||
      val savedRegister = caret.registerStorage.getRegister(caret, lastRegisterChar) ?: return
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,19 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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.extension.surround
 | 
			
		||||
 | 
			
		||||
@@ -14,7 +24,6 @@ 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
 | 
			
		||||
import com.maddyhome.idea.vim.command.MappingMode
 | 
			
		||||
import com.maddyhome.idea.vim.command.SelectionType
 | 
			
		||||
@@ -132,7 +141,7 @@ class VimSurroundExtension : VimExtension {
 | 
			
		||||
          val innerValue = if (registerValue.isNullOrEmpty()) null else registerValue
 | 
			
		||||
          it.innerText = innerValue
 | 
			
		||||
 | 
			
		||||
          val lineEndOffset = editor.getLineEndOffset(it.caret.getLine().line, false)
 | 
			
		||||
          val lineEndOffset = injector.engineEditorHelper.getLineEndOffset(editor, it.caret.getLine().line, false)
 | 
			
		||||
          if (lineEndOffset == it.caret.offset.point) {
 | 
			
		||||
            it.isLineEnd = true
 | 
			
		||||
          }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,15 +1,28 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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.extension.textobjentire;
 | 
			
		||||
 | 
			
		||||
import com.intellij.openapi.editor.Caret;
 | 
			
		||||
import com.maddyhome.idea.vim.api.*;
 | 
			
		||||
import com.maddyhome.idea.vim.api.ExecutionContext;
 | 
			
		||||
import com.maddyhome.idea.vim.api.VimCaret;
 | 
			
		||||
import com.maddyhome.idea.vim.api.VimEditor;
 | 
			
		||||
import com.maddyhome.idea.vim.api.VimInjectorKt;
 | 
			
		||||
import com.maddyhome.idea.vim.command.*;
 | 
			
		||||
import com.maddyhome.idea.vim.command.MappingMode;
 | 
			
		||||
import com.maddyhome.idea.vim.common.TextRange;
 | 
			
		||||
@@ -28,6 +41,7 @@ import java.util.EnumSet;
 | 
			
		||||
 | 
			
		||||
import static com.maddyhome.idea.vim.extension.VimExtensionFacade.putExtensionHandlerMapping;
 | 
			
		||||
import static com.maddyhome.idea.vim.extension.VimExtensionFacade.putKeyMappingIfMissing;
 | 
			
		||||
import static com.maddyhome.idea.vim.group.visual.VisualGroupKt.vimSetSelection;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Port of vim-entire:
 | 
			
		||||
@@ -92,7 +106,7 @@ public class VimTextObjEntireExtension implements VimExtension {
 | 
			
		||||
      @Nullable
 | 
			
		||||
      @Override
 | 
			
		||||
      public TextRange getRange(@NotNull VimEditor editor,
 | 
			
		||||
                                @NotNull ImmutableVimCaret caret,
 | 
			
		||||
                                @NotNull VimCaret caret,
 | 
			
		||||
                                @NotNull ExecutionContext context,
 | 
			
		||||
                                int count,
 | 
			
		||||
                                int rawCount,
 | 
			
		||||
@@ -141,7 +155,7 @@ public class VimTextObjEntireExtension implements VimExtension {
 | 
			
		||||
          if (range != null) {
 | 
			
		||||
            try (VimListenerSuppressor.Locked ignored = SelectionVimListenerSuppressor.INSTANCE.lock()) {
 | 
			
		||||
              if (vimStateMachine.getMode() == VimStateMachine.Mode.VISUAL) {
 | 
			
		||||
                com.maddyhome.idea.vim.group.visual.EngineVisualGroupKt.vimSetSelection(new IjVimCaret(caret), range.getStartOffset(), range.getEndOffset() - 1, true);
 | 
			
		||||
                vimSetSelection(caret, range.getStartOffset(), range.getEndOffset() - 1, true);
 | 
			
		||||
              } else {
 | 
			
		||||
                InlayHelperKt.moveToInlayAwareOffset(caret, range.getStartOffset());
 | 
			
		||||
              }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,20 +1,33 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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.extension.textobjindent;
 | 
			
		||||
 | 
			
		||||
import com.intellij.openapi.editor.Caret;
 | 
			
		||||
import com.maddyhome.idea.vim.api.*;
 | 
			
		||||
import com.maddyhome.idea.vim.api.ExecutionContext;
 | 
			
		||||
import com.maddyhome.idea.vim.api.VimCaret;
 | 
			
		||||
import com.maddyhome.idea.vim.api.VimEditor;
 | 
			
		||||
import com.maddyhome.idea.vim.api.VimInjectorKt;
 | 
			
		||||
import com.maddyhome.idea.vim.command.*;
 | 
			
		||||
import com.maddyhome.idea.vim.command.MappingMode;
 | 
			
		||||
import com.maddyhome.idea.vim.common.TextRange;
 | 
			
		||||
import com.maddyhome.idea.vim.extension.ExtensionHandler;
 | 
			
		||||
import com.maddyhome.idea.vim.extension.VimExtension;
 | 
			
		||||
import com.maddyhome.idea.vim.group.visual.EngineVisualGroupKt;
 | 
			
		||||
import com.maddyhome.idea.vim.extension.ExtensionHandler;
 | 
			
		||||
import com.maddyhome.idea.vim.handler.TextObjectActionHandler;
 | 
			
		||||
import com.maddyhome.idea.vim.helper.InlayHelperKt;
 | 
			
		||||
import com.maddyhome.idea.vim.listener.SelectionVimListenerSuppressor;
 | 
			
		||||
@@ -28,6 +41,7 @@ import java.util.EnumSet;
 | 
			
		||||
 | 
			
		||||
import static com.maddyhome.idea.vim.extension.VimExtensionFacade.putExtensionHandlerMapping;
 | 
			
		||||
import static com.maddyhome.idea.vim.extension.VimExtensionFacade.putKeyMapping;
 | 
			
		||||
import static com.maddyhome.idea.vim.group.visual.VisualGroupKt.vimSetSelection;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Port of vim-indent-object:
 | 
			
		||||
@@ -95,7 +109,7 @@ public class VimIndentObject implements VimExtension {
 | 
			
		||||
      @Nullable
 | 
			
		||||
      @Override
 | 
			
		||||
      public TextRange getRange(@NotNull VimEditor editor,
 | 
			
		||||
                                @NotNull ImmutableVimCaret caret,
 | 
			
		||||
                                @NotNull VimCaret caret,
 | 
			
		||||
                                @NotNull ExecutionContext context,
 | 
			
		||||
                                int count,
 | 
			
		||||
                                int rawCount,
 | 
			
		||||
@@ -269,7 +283,7 @@ public class VimIndentObject implements VimExtension {
 | 
			
		||||
          if (range != null) {
 | 
			
		||||
            try (VimListenerSuppressor.Locked ignored = SelectionVimListenerSuppressor.INSTANCE.lock()) {
 | 
			
		||||
              if (vimStateMachine.getMode() == VimStateMachine.Mode.VISUAL) {
 | 
			
		||||
                EngineVisualGroupKt.vimSetSelection(new IjVimCaret(caret), range.getStartOffset(), range.getEndOffset() - 1, true);
 | 
			
		||||
                vimSetSelection(caret, range.getStartOffset(), range.getEndOffset() - 1, true);
 | 
			
		||||
              } else {
 | 
			
		||||
                InlayHelperKt.moveToInlayAwareOffset(caret, range.getStartOffset());
 | 
			
		||||
              }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,13 +1,24 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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.group;
 | 
			
		||||
 | 
			
		||||
import com.google.common.base.Splitter;
 | 
			
		||||
import com.google.common.collect.ImmutableSet;
 | 
			
		||||
import com.google.common.collect.Lists;
 | 
			
		||||
import com.intellij.codeInsight.actions.AsyncActionExecutionService;
 | 
			
		||||
import com.intellij.openapi.Disposable;
 | 
			
		||||
@@ -17,6 +28,7 @@ import com.intellij.openapi.application.ApplicationManager;
 | 
			
		||||
import com.intellij.openapi.command.CommandProcessor;
 | 
			
		||||
import com.intellij.openapi.command.UndoConfirmationPolicy;
 | 
			
		||||
import com.intellij.openapi.diagnostic.Logger;
 | 
			
		||||
import com.intellij.openapi.editor.Caret;
 | 
			
		||||
import com.intellij.openapi.editor.Document;
 | 
			
		||||
import com.intellij.openapi.editor.Editor;
 | 
			
		||||
import com.intellij.openapi.editor.LogicalPosition;
 | 
			
		||||
@@ -33,6 +45,7 @@ import com.intellij.psi.codeStyle.CodeStyleManager;
 | 
			
		||||
import com.intellij.psi.util.PsiUtilBase;
 | 
			
		||||
import com.intellij.util.containers.ContainerUtil;
 | 
			
		||||
import com.maddyhome.idea.vim.EventFacade;
 | 
			
		||||
import com.maddyhome.idea.vim.VimPlugin;
 | 
			
		||||
import com.maddyhome.idea.vim.api.*;
 | 
			
		||||
import com.maddyhome.idea.vim.command.*;
 | 
			
		||||
import com.maddyhome.idea.vim.common.IndentConfig;
 | 
			
		||||
@@ -55,27 +68,80 @@ import kotlin.Pair;
 | 
			
		||||
import kotlin.Unit;
 | 
			
		||||
import kotlin.jvm.functions.Function0;
 | 
			
		||||
import kotlin.text.StringsKt;
 | 
			
		||||
import org.jetbrains.annotations.NonNls;
 | 
			
		||||
import org.jetbrains.annotations.NotNull;
 | 
			
		||||
import org.jetbrains.annotations.Nullable;
 | 
			
		||||
import org.jetbrains.annotations.TestOnly;
 | 
			
		||||
 | 
			
		||||
import java.math.BigInteger;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.Comparator;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.*;
 | 
			
		||||
 | 
			
		||||
import static com.maddyhome.idea.vim.api.VimInjectorKt.injector;
 | 
			
		||||
import static com.maddyhome.idea.vim.mark.VimMarkConstants.MARK_CHANGE_POS;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Provides all the insert/replace related functionality
 | 
			
		||||
 */
 | 
			
		||||
public class ChangeGroup extends VimChangeGroupBase {
 | 
			
		||||
 | 
			
		||||
  public static final String VIM_MOTION_BIG_WORD_RIGHT = "VimMotionBigWordRightAction";
 | 
			
		||||
  public static final String VIM_MOTION_WORD_RIGHT = "VimMotionWordRightAction";
 | 
			
		||||
  public static final String VIM_MOTION_CAMEL_RIGHT = "VimMotionCamelRightAction";
 | 
			
		||||
  private static final String VIM_MOTION_WORD_END_RIGHT = "VimMotionWordEndRightAction";
 | 
			
		||||
  private static final String VIM_MOTION_BIG_WORD_END_RIGHT = "VimMotionBigWordEndRightAction";
 | 
			
		||||
  private static final String VIM_MOTION_CAMEL_END_RIGHT = "VimMotionCamelEndRightAction";
 | 
			
		||||
  private static final ImmutableSet<String> wordMotions = ImmutableSet.of(VIM_MOTION_WORD_RIGHT, VIM_MOTION_BIG_WORD_RIGHT, VIM_MOTION_CAMEL_RIGHT);
 | 
			
		||||
 | 
			
		||||
  @NonNls private static final String HEX_START = "0x";
 | 
			
		||||
  @NonNls private static final String MAX_HEX_INTEGER = "ffffffffffffffff";
 | 
			
		||||
 | 
			
		||||
  private final List<VimInsertListener> insertListeners = ContainerUtil.createLockFreeCopyOnWriteList();
 | 
			
		||||
 | 
			
		||||
  private long lastShownTime = 0L;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Inserts a new line above the caret position
 | 
			
		||||
   *
 | 
			
		||||
   * @param editor The editor to insert into
 | 
			
		||||
   * @param caret  The caret to insert above
 | 
			
		||||
   * @param col    The column to indent to
 | 
			
		||||
   */
 | 
			
		||||
  private void insertNewLineAbove(@NotNull VimEditor editor, @NotNull VimCaret caret, int col) {
 | 
			
		||||
    if (((IjVimEditor) editor).getEditor().isOneLineMode()) return;
 | 
			
		||||
 | 
			
		||||
    boolean firstLiner = false;
 | 
			
		||||
    if (((IjVimCaret) caret).getCaret().getVisualPosition().line == 0) {
 | 
			
		||||
      injector.getMotion().moveCaret(editor, caret, VimPlugin.getMotion().moveCaretToLineStart(editor,
 | 
			
		||||
                                                                                      caret));
 | 
			
		||||
      firstLiner = true;
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
      injector.getMotion().moveCaret(editor, caret, VimPlugin.getMotion().getVerticalMotionOffset(editor, caret, -1));
 | 
			
		||||
      injector.getMotion().moveCaret(editor, caret, VimPlugin.getMotion().moveCaretToLineEnd(editor, caret));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    UserDataManager.setVimChangeActionSwitchMode(((IjVimEditor) editor).getEditor(), VimStateMachine.Mode.INSERT);
 | 
			
		||||
    insertText(editor, caret, "\n" + IndentConfig.create(((IjVimEditor) editor).getEditor()).createIndentBySize(col));
 | 
			
		||||
 | 
			
		||||
    if (firstLiner) {
 | 
			
		||||
      injector.getMotion().moveCaret(editor, caret, VimPlugin.getMotion().getVerticalMotionOffset(editor, caret, -1));
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Inserts a new line below the caret position
 | 
			
		||||
   *
 | 
			
		||||
   * @param editor The editor to insert into
 | 
			
		||||
   * @param caret  The caret to insert after
 | 
			
		||||
   * @param col    The column to indent to
 | 
			
		||||
   */
 | 
			
		||||
  private void insertNewLineBelow(@NotNull VimEditor editor, @NotNull VimCaret caret, int col) {
 | 
			
		||||
    if (editor.isOneLineMode()) return;
 | 
			
		||||
 | 
			
		||||
    caret.moveToOffset(injector.getMotion().moveCaretToLineEnd(editor, caret));
 | 
			
		||||
    editor.setVimChangeActionSwitchMode(VimStateMachine.Mode.INSERT);
 | 
			
		||||
    insertText(editor, caret, "\n" + IndentConfig.create(((IjVimEditor) editor).getEditor()).createIndentBySize(col));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -134,15 +200,12 @@ public class ChangeGroup extends VimChangeGroupBase {
 | 
			
		||||
    }
 | 
			
		||||
    final Command motion = argument.getMotion();
 | 
			
		||||
    if (!isChange && !motion.isLinewiseMotion()) {
 | 
			
		||||
      BufferPosition start = editor.offsetToBufferPosition(range.getStartOffset());
 | 
			
		||||
      BufferPosition end = editor.offsetToBufferPosition(range.getEndOffset());
 | 
			
		||||
      VimLogicalPosition start = editor.offsetToLogicalPosition(range.getStartOffset());
 | 
			
		||||
      VimLogicalPosition end = editor.offsetToLogicalPosition(range.getEndOffset());
 | 
			
		||||
      if (start.getLine() != end.getLine()) {
 | 
			
		||||
        int offset1 = range.getStartOffset();
 | 
			
		||||
        if (!EngineEditorHelperKt.anyNonWhitespace(editor, offset1, -1)) {
 | 
			
		||||
          int offset = range.getEndOffset();
 | 
			
		||||
          if (!EngineEditorHelperKt.anyNonWhitespace(editor, offset, 1)) {
 | 
			
		||||
            type = SelectionType.LINE_WISE;
 | 
			
		||||
          }
 | 
			
		||||
        if (!SearchHelper.anyNonWhitespace(((IjVimEditor) editor).getEditor(), range.getStartOffset(), -1) &&
 | 
			
		||||
            !SearchHelper.anyNonWhitespace(((IjVimEditor) editor).getEditor(), range.getEndOffset(), 1)) {
 | 
			
		||||
          type = SelectionType.LINE_WISE;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
@@ -172,6 +235,93 @@ public class ChangeGroup extends VimChangeGroupBase {
 | 
			
		||||
   * @param argument The motion command
 | 
			
		||||
   * @return true if able to delete the text, false if not
 | 
			
		||||
   */
 | 
			
		||||
  @Override
 | 
			
		||||
  public boolean changeMotion(@NotNull VimEditor editor,
 | 
			
		||||
                              @NotNull VimCaret caret,
 | 
			
		||||
                              @NotNull ExecutionContext context,
 | 
			
		||||
                              @NotNull Argument argument,
 | 
			
		||||
                              @NotNull OperatorArguments operatorArguments) {
 | 
			
		||||
    int count0 = operatorArguments.getCount0();
 | 
			
		||||
    // Vim treats cw as ce and cW as cE if cursor is on a non-blank character
 | 
			
		||||
    final Command motion = argument.getMotion();
 | 
			
		||||
 | 
			
		||||
    String id = motion.getAction().getId();
 | 
			
		||||
    boolean kludge = false;
 | 
			
		||||
    boolean bigWord = id.equals(VIM_MOTION_BIG_WORD_RIGHT);
 | 
			
		||||
    final CharSequence chars = editor.text();
 | 
			
		||||
    final int offset = caret.getOffset().getPoint();
 | 
			
		||||
    int fileSize = ((int)editor.fileSize());
 | 
			
		||||
    if (fileSize > 0 && offset < fileSize) {
 | 
			
		||||
      final CharacterHelper.CharacterType charType = CharacterHelper.charType(chars.charAt(offset), bigWord);
 | 
			
		||||
      if (charType != CharacterHelper.CharacterType.WHITESPACE) {
 | 
			
		||||
        final boolean lastWordChar =
 | 
			
		||||
          offset >= fileSize - 1 || CharacterHelper.charType(chars.charAt(offset + 1), bigWord) != charType;
 | 
			
		||||
        if (wordMotions.contains(id) && lastWordChar && motion.getCount() == 1) {
 | 
			
		||||
          final boolean res = deleteCharacter(editor, caret, 1, true, operatorArguments);
 | 
			
		||||
          if (res) {
 | 
			
		||||
            editor.setVimChangeActionSwitchMode(VimStateMachine.Mode.INSERT);
 | 
			
		||||
          }
 | 
			
		||||
          return res;
 | 
			
		||||
        }
 | 
			
		||||
        switch (id) {
 | 
			
		||||
          case VIM_MOTION_WORD_RIGHT:
 | 
			
		||||
            kludge = true;
 | 
			
		||||
            motion.setAction(injector.getActionExecutor().findVimActionOrDie(VIM_MOTION_WORD_END_RIGHT));
 | 
			
		||||
 | 
			
		||||
            break;
 | 
			
		||||
          case VIM_MOTION_BIG_WORD_RIGHT:
 | 
			
		||||
            kludge = true;
 | 
			
		||||
            motion.setAction(injector.getActionExecutor().findVimActionOrDie(VIM_MOTION_BIG_WORD_END_RIGHT));
 | 
			
		||||
 | 
			
		||||
            break;
 | 
			
		||||
          case VIM_MOTION_CAMEL_RIGHT:
 | 
			
		||||
            kludge = true;
 | 
			
		||||
            motion.setAction(injector.getActionExecutor().findVimActionOrDie(VIM_MOTION_CAMEL_END_RIGHT));
 | 
			
		||||
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (kludge) {
 | 
			
		||||
      int cnt = operatorArguments.getCount1() * motion.getCount();
 | 
			
		||||
      int pos1 = injector.getSearchHelper().findNextWordEnd(chars, offset, fileSize, cnt, bigWord, false);
 | 
			
		||||
      int pos2 = injector.getSearchHelper().findNextWordEnd(chars, pos1, fileSize, -cnt, bigWord, false);
 | 
			
		||||
      if (logger.isDebugEnabled()) {
 | 
			
		||||
        logger.debug("pos=" + offset);
 | 
			
		||||
        logger.debug("pos1=" + pos1);
 | 
			
		||||
        logger.debug("pos2=" + pos2);
 | 
			
		||||
        logger.debug("count=" + operatorArguments.getCount1());
 | 
			
		||||
        logger.debug("arg.count=" + motion.getCount());
 | 
			
		||||
      }
 | 
			
		||||
      if (pos2 == offset) {
 | 
			
		||||
        if (operatorArguments.getCount1() > 1) {
 | 
			
		||||
          count0--;
 | 
			
		||||
        }
 | 
			
		||||
        else if (motion.getCount() > 1) {
 | 
			
		||||
          motion.setCount(motion.getCount() - 1);
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
          motion.setFlags(EnumSet.noneOf(CommandFlags.class));
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (injector.getOptionService().isSet(OptionScope.GLOBAL.INSTANCE, OptionConstants.experimentalapiName, OptionConstants.experimentalapiName)) {
 | 
			
		||||
      Pair<TextRange, SelectionType> deleteRangeAndType =
 | 
			
		||||
        getDeleteRangeAndType2(editor, caret, context, argument, true, operatorArguments.withCount0(count0));
 | 
			
		||||
      if (deleteRangeAndType == null) return false;
 | 
			
		||||
      //ChangeGroupKt.changeRange(((IjVimEditor) editor).getEditor(), ((IjVimCaret) caret).getCaret(), deleteRangeAndType.getFirst(), deleteRangeAndType.getSecond(), ((IjExecutionContext) context).getContext());
 | 
			
		||||
      return true;
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
      Pair<TextRange, SelectionType> deleteRangeAndType =
 | 
			
		||||
        getDeleteRangeAndType(editor, caret, context, argument, true, operatorArguments.withCount0(count0));
 | 
			
		||||
      if (deleteRangeAndType == null) return false;
 | 
			
		||||
      return changeRange(editor, caret, deleteRangeAndType.getFirst(), deleteRangeAndType.getSecond(), context,
 | 
			
		||||
                         operatorArguments);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Toggles the case of count characters
 | 
			
		||||
@@ -183,12 +333,12 @@ public class ChangeGroup extends VimChangeGroupBase {
 | 
			
		||||
   */
 | 
			
		||||
  @Override
 | 
			
		||||
  public boolean changeCaseToggleCharacter(@NotNull VimEditor editor, @NotNull VimCaret caret, int count) {
 | 
			
		||||
    final int offset = injector.getMotion().getOffsetOfHorizontalMotion(editor, caret, count, true);
 | 
			
		||||
    final int offset = VimPlugin.getMotion().getOffsetOfHorizontalMotion(editor, caret, count, true);
 | 
			
		||||
    if (offset == -1) {
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
    changeCase(editor, editor.currentCaret().getOffset().getPoint(), offset, CharacterHelper.CASE_TOGGLE);
 | 
			
		||||
    caret.moveToOffset(EngineEditorHelperKt.normalizeOffset(editor, offset, false));
 | 
			
		||||
    changeCase(editor, ((IjVimCaret) caret).getCaret().getOffset(), offset, CharacterHelper.CASE_TOGGLE);
 | 
			
		||||
    injector.getMotion().moveCaret(editor, caret, EditorHelper.normalizeOffset(((IjVimEditor) editor).getEditor(), offset, false));
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -199,11 +349,11 @@ public class ChangeGroup extends VimChangeGroupBase {
 | 
			
		||||
                             boolean append,
 | 
			
		||||
                             @NotNull OperatorArguments operatorArguments) {
 | 
			
		||||
    final int lines = VimChangeGroupBase.Companion.getLinesCountInVisualBlock(editor, range);
 | 
			
		||||
    final BufferPosition startPosition = editor.offsetToBufferPosition(range.getStartOffset());
 | 
			
		||||
    final VimLogicalPosition startPosition = editor.offsetToLogicalPosition(range.getStartOffset());
 | 
			
		||||
 | 
			
		||||
    boolean visualBlockMode = operatorArguments.getMode() == VimStateMachine.Mode.VISUAL &&
 | 
			
		||||
                              operatorArguments.getSubMode() == VimStateMachine.SubMode.VISUAL_BLOCK;
 | 
			
		||||
    for (VimCaret caret : editor.carets()) {
 | 
			
		||||
    for (Caret caret : ((IjVimEditor) editor).getEditor().getCaretModel().getAllCarets()) {
 | 
			
		||||
      final int line = startPosition.getLine();
 | 
			
		||||
      int column = startPosition.getColumn();
 | 
			
		||||
      if (!visualBlockMode) {
 | 
			
		||||
@@ -211,20 +361,20 @@ public class ChangeGroup extends VimChangeGroupBase {
 | 
			
		||||
      }
 | 
			
		||||
      else if (append) {
 | 
			
		||||
        column += range.getMaxLength();
 | 
			
		||||
        if (caret.getVimLastColumn() == VimMotionGroupBase.LAST_COLUMN) {
 | 
			
		||||
        if (UserDataManager.getVimLastColumn(caret) == VimMotionGroupBase.LAST_COLUMN) {
 | 
			
		||||
          column = VimMotionGroupBase.LAST_COLUMN;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      final int lineLength = EngineEditorHelperKt.lineLength(editor, line);
 | 
			
		||||
      final int lineLength = EditorHelper.getLineLength(((IjVimEditor) editor).getEditor(), line);
 | 
			
		||||
      if (column < VimMotionGroupBase.LAST_COLUMN && lineLength < column) {
 | 
			
		||||
        final String pad = EditorHelper.pad(((IjVimEditor) editor).getEditor(), ((IjExecutionContext) context).getContext(), line, column);
 | 
			
		||||
        final int offset = editor.getLineEndOffset(line);
 | 
			
		||||
        insertText(editor, caret, offset, pad);
 | 
			
		||||
        final int offset = ((IjVimEditor) editor).getEditor().getDocument().getLineEndOffset(line);
 | 
			
		||||
        insertText(editor, new IjVimCaret(caret), offset, pad);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (visualBlockMode || !append) {
 | 
			
		||||
        InlayHelperKt.moveToInlayAwareLogicalPosition(((IjVimCaret)caret).getCaret(), new LogicalPosition(line, column));
 | 
			
		||||
        InlayHelperKt.moveToInlayAwareLogicalPosition(caret, new LogicalPosition(line, column));
 | 
			
		||||
      }
 | 
			
		||||
      if (visualBlockMode) {
 | 
			
		||||
        setInsertRepeat(lines, column, append);
 | 
			
		||||
@@ -257,7 +407,7 @@ public class ChangeGroup extends VimChangeGroupBase {
 | 
			
		||||
    for (int i = ends.length - 1; i >= 0; i--) {
 | 
			
		||||
      changeCase(editor, starts[i], ends[i], type);
 | 
			
		||||
    }
 | 
			
		||||
    caret.moveToOffset(range.getStartOffset());
 | 
			
		||||
    injector.getMotion().moveCaret(editor, caret, range.getStartOffset());
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -275,9 +425,9 @@ public class ChangeGroup extends VimChangeGroupBase {
 | 
			
		||||
      end = start;
 | 
			
		||||
      start = t;
 | 
			
		||||
    }
 | 
			
		||||
    end = EngineEditorHelperKt.normalizeOffset(editor, end, true);
 | 
			
		||||
    end = EditorHelper.normalizeOffset(((IjVimEditor) editor).getEditor(), end);
 | 
			
		||||
 | 
			
		||||
    CharSequence chars = editor.text();
 | 
			
		||||
    CharSequence chars = ((IjVimEditor) editor).getEditor().getDocument().getCharsSequence();
 | 
			
		||||
    StringBuilder sb = new StringBuilder();
 | 
			
		||||
    for (int i = start; i < end; i++) {
 | 
			
		||||
      sb.append(CharacterHelper.changeCase(chars.charAt(i), type));
 | 
			
		||||
@@ -285,10 +435,68 @@ public class ChangeGroup extends VimChangeGroupBase {
 | 
			
		||||
    replaceText(editor, start, end, sb.toString());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Deletes the range of text and enters insert mode
 | 
			
		||||
   *
 | 
			
		||||
   * @param editor            The editor to change
 | 
			
		||||
   * @param caret             The caret to be moved after range deletion
 | 
			
		||||
   * @param range             The range to change
 | 
			
		||||
   * @param type              The type of the range
 | 
			
		||||
   * @param operatorArguments
 | 
			
		||||
   * @return true if able to delete the range, false if not
 | 
			
		||||
   */
 | 
			
		||||
  @Override
 | 
			
		||||
  public boolean changeRange(@NotNull VimEditor editor,
 | 
			
		||||
                             @NotNull VimCaret caret,
 | 
			
		||||
                             @NotNull TextRange range,
 | 
			
		||||
                             @NotNull SelectionType type,
 | 
			
		||||
                             @Nullable ExecutionContext context,
 | 
			
		||||
                             @NotNull OperatorArguments operatorArguments) {
 | 
			
		||||
    int col = 0;
 | 
			
		||||
    int lines = 0;
 | 
			
		||||
    if (type == SelectionType.BLOCK_WISE) {
 | 
			
		||||
      lines = VimChangeGroupBase.Companion.getLinesCountInVisualBlock(editor, range);
 | 
			
		||||
      col = editor.offsetToLogicalPosition(range.getStartOffset()).getColumn();
 | 
			
		||||
      if (caret.getVimLastColumn() == VimMotionGroupBase.LAST_COLUMN) {
 | 
			
		||||
        col = VimMotionGroupBase.LAST_COLUMN;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    boolean after = range.getEndOffset() >= editor.fileSize();
 | 
			
		||||
 | 
			
		||||
    final VimLogicalPosition lp = editor.offsetToLogicalPosition(injector.getMotion().moveCaretToLineStartSkipLeading(editor, caret));
 | 
			
		||||
 | 
			
		||||
    boolean res = deleteRange(editor, caret, range, type, true, operatorArguments);
 | 
			
		||||
    if (res) {
 | 
			
		||||
      if (type == SelectionType.LINE_WISE) {
 | 
			
		||||
        // Please don't use `getDocument().getText().isEmpty()` because it converts CharSequence into String
 | 
			
		||||
        if (editor.fileSize() == 0) {
 | 
			
		||||
          insertBeforeCursor(editor, context);
 | 
			
		||||
        }
 | 
			
		||||
        else if (after && !EngineEditorHelperKt.endsWithNewLine(editor)) {
 | 
			
		||||
          insertNewLineBelow(editor, caret, lp.getColumn());
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
          insertNewLineAbove(editor, caret, lp.getColumn());
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      else {
 | 
			
		||||
        if (type == SelectionType.BLOCK_WISE) {
 | 
			
		||||
          setInsertRepeat(lines, col, false);
 | 
			
		||||
        }
 | 
			
		||||
        UserDataManager.setVimChangeActionSwitchMode(((IjVimEditor) editor).getEditor(), VimStateMachine.Mode.INSERT);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
      insertBeforeCursor(editor, context);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private void restoreCursor(@NotNull VimEditor editor, @NotNull VimCaret caret, int startLine) {
 | 
			
		||||
    if (!caret.equals(editor.primaryCaret())) {
 | 
			
		||||
      ((IjVimEditor) editor).getEditor().getCaretModel().addCaret(
 | 
			
		||||
        ((IjVimEditor) editor).getEditor().offsetToVisualPosition(injector.getMotion().moveCaretToLineStartSkipLeading(editor, startLine)), false);
 | 
			
		||||
        ((IjVimEditor) editor).getEditor().offsetToVisualPosition(VimPlugin.getMotion().moveCaretToLineStartSkipLeading(editor, startLine)), false);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -334,15 +542,14 @@ public class ChangeGroup extends VimChangeGroupBase {
 | 
			
		||||
  private boolean reformatCodeRange(@NotNull VimEditor editor, @NotNull VimCaret caret, @NotNull TextRange range) {
 | 
			
		||||
    int[] starts = range.getStartOffsets();
 | 
			
		||||
    int[] ends = range.getEndOffsets();
 | 
			
		||||
    final int firstLine = editor.offsetToBufferPosition(range.getStartOffset()).getLine();
 | 
			
		||||
    final int firstLine = editor.offsetToLogicalPosition(range.getStartOffset()).getLine();
 | 
			
		||||
    for (int i = ends.length - 1; i >= 0; i--) {
 | 
			
		||||
      final int startOffset = EngineEditorHelperKt.getLineStartForOffset(editor, starts[i]);
 | 
			
		||||
      final int offset = ends[i] - (startOffset == ends[i] ? 0 : 1);
 | 
			
		||||
      final int endOffset = EngineEditorHelperKt.getLineEndForOffset(editor, offset);
 | 
			
		||||
      final int startOffset = EditorHelper.getLineStartForOffset(((IjVimEditor) editor).getEditor(), starts[i]);
 | 
			
		||||
      final int endOffset = EditorHelper.getLineEndForOffset(((IjVimEditor) editor).getEditor(), ends[i] - (startOffset == ends[i] ? 0 : 1));
 | 
			
		||||
      reformatCode(editor, startOffset, endOffset);
 | 
			
		||||
    }
 | 
			
		||||
    final int newOffset = injector.getMotion().moveCaretToLineStartSkipLeading(editor, firstLine);
 | 
			
		||||
    caret.moveToOffset(newOffset);
 | 
			
		||||
    final int newOffset = VimPlugin.getMotion().moveCaretToLineStartSkipLeading(editor, firstLine);
 | 
			
		||||
    injector.getMotion().moveCaret(editor, caret, newOffset);
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -373,8 +580,8 @@ public class ChangeGroup extends VimChangeGroupBase {
 | 
			
		||||
                              @NotNull VimCaret caret,
 | 
			
		||||
                              @NotNull ExecutionContext context,
 | 
			
		||||
                              @NotNull TextRange range) {
 | 
			
		||||
    final int startOffset = EngineEditorHelperKt.getLineStartForOffset(editor, range.getStartOffset());
 | 
			
		||||
    final int endOffset = EngineEditorHelperKt.getLineEndForOffset(editor, range.getEndOffset());
 | 
			
		||||
    final int startOffset = injector.getEngineEditorHelper().getLineStartForOffset(editor, range.getStartOffset());
 | 
			
		||||
    final int endOffset = injector.getEngineEditorHelper().getLineEndForOffset(editor, range.getEndOffset());
 | 
			
		||||
 | 
			
		||||
    Editor ijEditor = ((IjVimEditor)editor).getEditor();
 | 
			
		||||
    VisualModeHelperKt.vimSetSystemSelectionSilently(ijEditor.getSelectionModel(), startOffset, endOffset);
 | 
			
		||||
@@ -383,14 +590,14 @@ public class ChangeGroup extends VimChangeGroupBase {
 | 
			
		||||
    Function0<Unit> actionExecution = () -> {
 | 
			
		||||
      NativeAction joinLinesAction = VimInjectorKt.getInjector().getNativeActionManager().getIndentLines();
 | 
			
		||||
      if (joinLinesAction != null) {
 | 
			
		||||
        VimInjectorKt.getInjector().getActionExecutor().executeAction(editor, joinLinesAction, context);
 | 
			
		||||
        VimInjectorKt.getInjector().getActionExecutor().executeAction(joinLinesAction, context);
 | 
			
		||||
      }
 | 
			
		||||
      return null;
 | 
			
		||||
    };
 | 
			
		||||
    Function0<Unit> afterAction = () -> {
 | 
			
		||||
      final int firstLine = editor.offsetToBufferPosition(Math.min(startOffset, endOffset)).getLine();
 | 
			
		||||
      final int newOffset = injector.getMotion().moveCaretToLineStartSkipLeading(editor, firstLine);
 | 
			
		||||
      caret.moveToOffset(newOffset);
 | 
			
		||||
      final int firstLine = editor.offsetToLogicalPosition(Math.min(startOffset, endOffset)).getLine();
 | 
			
		||||
      final int newOffset = VimPlugin.getMotion().moveCaretToLineStartSkipLeading(editor, firstLine);
 | 
			
		||||
      injector.getMotion().moveCaret(editor, caret, newOffset);
 | 
			
		||||
      restoreCursor(editor, caret, ((IjVimCaret)caret).getCaret().getLogicalPosition().line);
 | 
			
		||||
      return null;
 | 
			
		||||
    };
 | 
			
		||||
@@ -410,8 +617,8 @@ public class ChangeGroup extends VimChangeGroupBase {
 | 
			
		||||
                          int lines,
 | 
			
		||||
                          int dir,
 | 
			
		||||
                          @NotNull OperatorArguments operatorArguments) {
 | 
			
		||||
    int start = caret.getOffset().getPoint();
 | 
			
		||||
    int end = injector.getMotion().moveCaretToRelativeLineEnd(editor, caret, lines - 1, true);
 | 
			
		||||
    int start = ((IjVimCaret) caret).getCaret().getOffset();
 | 
			
		||||
    int end = VimPlugin.getMotion().moveCaretToLineEndOffset(editor, caret, lines - 1, true);
 | 
			
		||||
    indentRange(editor, caret, context, new TextRange(start, end), 1, dir, operatorArguments);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -429,6 +636,23 @@ public class ChangeGroup extends VimChangeGroupBase {
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Replace text in the editor
 | 
			
		||||
   *
 | 
			
		||||
   * @param editor The editor to replace text in
 | 
			
		||||
   * @param start  The start offset to change
 | 
			
		||||
   * @param end    The end offset to change
 | 
			
		||||
   * @param str    The new text
 | 
			
		||||
   */
 | 
			
		||||
  @Override
 | 
			
		||||
  public void replaceText(@NotNull VimEditor editor, int start, int end, @NotNull String str) {
 | 
			
		||||
    ((IjVimEditor) editor).getEditor().getDocument().replaceString(start, end, str);
 | 
			
		||||
 | 
			
		||||
    final int newEnd = start + str.length();
 | 
			
		||||
    VimPlugin.getMark().setChangeMarks(editor, new TextRange(start, newEnd));
 | 
			
		||||
    VimPlugin.getMark().setMark(editor, MARK_CHANGE_POS, newEnd);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public void indentRange(@NotNull VimEditor editor,
 | 
			
		||||
                          @NotNull VimCaret caret,
 | 
			
		||||
@@ -441,40 +665,40 @@ public class ChangeGroup extends VimChangeGroupBase {
 | 
			
		||||
      logger.debug("count=" + count);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Remember the current caret column
 | 
			
		||||
    final int intendedColumn = caret.getVimLastColumn();
 | 
			
		||||
    // Update the last column before we indent, or we might be retrieving the data for a line that no longer exists
 | 
			
		||||
    UserDataManager.setVimLastColumn(((IjVimCaret) caret).getCaret(), InlayHelperKt.getInlayAwareVisualColumn(((IjVimCaret) caret).getCaret()));
 | 
			
		||||
 | 
			
		||||
    IndentConfig indentConfig = IndentConfig.create(((IjVimEditor) editor).getEditor(), ((IjExecutionContext) context).getContext());
 | 
			
		||||
 | 
			
		||||
    final int sline = editor.offsetToBufferPosition(range.getStartOffset()).getLine();
 | 
			
		||||
    final BufferPosition endLogicalPosition = editor.offsetToBufferPosition(range.getEndOffset());
 | 
			
		||||
    final int sline = editor.offsetToLogicalPosition(range.getStartOffset()).getLine();
 | 
			
		||||
    final VimLogicalPosition endLogicalPosition = editor.offsetToLogicalPosition(range.getEndOffset());
 | 
			
		||||
    final int eline =
 | 
			
		||||
      endLogicalPosition.getColumn() == 0 ? Math.max(endLogicalPosition.getLine() - 1, 0) : endLogicalPosition.getLine();
 | 
			
		||||
 | 
			
		||||
    if (range.isMultiple()) {
 | 
			
		||||
      final int from = editor.offsetToBufferPosition(range.getStartOffset()).getColumn();
 | 
			
		||||
      final int from = editor.offsetToLogicalPosition(range.getStartOffset()).getColumn();
 | 
			
		||||
      if (dir == 1) {
 | 
			
		||||
        // Right shift blockwise selection
 | 
			
		||||
        final String indent = indentConfig.createIndentByCount(count);
 | 
			
		||||
 | 
			
		||||
        for (int l = sline; l <= eline; l++) {
 | 
			
		||||
          int len = EngineEditorHelperKt.lineLength(editor, l);
 | 
			
		||||
          int len = EditorHelper.getLineLength(((IjVimEditor) editor).getEditor(), l);
 | 
			
		||||
          if (len > from) {
 | 
			
		||||
            BufferPosition spos = new BufferPosition(l, from, false);
 | 
			
		||||
            VimLogicalPosition spos = new VimLogicalPosition(l, from, false);
 | 
			
		||||
            insertText(editor, caret, spos, indent);
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      else {
 | 
			
		||||
        // Left shift blockwise selection
 | 
			
		||||
        CharSequence chars = editor.text();
 | 
			
		||||
        CharSequence chars = ((IjVimEditor) editor).getEditor().getDocument().getCharsSequence();
 | 
			
		||||
        for (int l = sline; l <= eline; l++) {
 | 
			
		||||
          int len = EngineEditorHelperKt.lineLength(editor, l);
 | 
			
		||||
          int len = EditorHelper.getLineLength(((IjVimEditor) editor).getEditor(), l);
 | 
			
		||||
          if (len > from) {
 | 
			
		||||
            BufferPosition spos = new BufferPosition(l, from, false);
 | 
			
		||||
            BufferPosition epos = new BufferPosition(l, from + indentConfig.getTotalIndent(count) - 1, false);
 | 
			
		||||
            int wsoff = editor.bufferPositionToOffset(spos);
 | 
			
		||||
            int weoff = editor.bufferPositionToOffset(epos);
 | 
			
		||||
            VimLogicalPosition spos = new VimLogicalPosition(l, from, false);
 | 
			
		||||
            VimLogicalPosition epos = new VimLogicalPosition(l, from + indentConfig.getTotalIndent(count) - 1, false);
 | 
			
		||||
            int wsoff = editor.logicalPositionToOffset(spos);
 | 
			
		||||
            int weoff = editor.logicalPositionToOffset(epos);
 | 
			
		||||
            int pos;
 | 
			
		||||
            for (pos = wsoff; pos <= weoff; pos++) {
 | 
			
		||||
              if (CharacterHelper.charType(chars.charAt(pos), false) != CharacterHelper.CharacterType.WHITESPACE) {
 | 
			
		||||
@@ -491,10 +715,10 @@ public class ChangeGroup extends VimChangeGroupBase {
 | 
			
		||||
    else {
 | 
			
		||||
      // Shift non-blockwise selection
 | 
			
		||||
      for (int l = sline; l <= eline; l++) {
 | 
			
		||||
        final int soff = editor.getLineStartOffset(l);
 | 
			
		||||
        final int eoff = EngineEditorHelperKt.getLineEndOffset(editor, l, true);
 | 
			
		||||
        final int woff = injector.getMotion().moveCaretToLineStartSkipLeading(editor, l);
 | 
			
		||||
        final int col = editor.offsetToVisualPosition(woff).getColumn();
 | 
			
		||||
        final int soff = injector.getEngineEditorHelper().getLineStartOffset(editor, l);
 | 
			
		||||
        final int eoff = injector.getEngineEditorHelper().getLineEndOffset(editor, l, true);
 | 
			
		||||
        final int woff = VimPlugin.getMotion().moveCaretToLineStartSkipLeading(editor, l);
 | 
			
		||||
        final int col = ((IjVimEditor) editor).getEditor().offsetToVisualPosition(woff).getColumn();
 | 
			
		||||
        final int limit = Math.max(0, col + dir * indentConfig.getTotalIndent(count));
 | 
			
		||||
        if (col > 0 || soff != eoff) {
 | 
			
		||||
          final String indent = indentConfig.createIndentBySize(limit);
 | 
			
		||||
@@ -505,15 +729,14 @@ public class ChangeGroup extends VimChangeGroupBase {
 | 
			
		||||
 | 
			
		||||
    if (!CommandStateHelper.inInsertMode(((IjVimEditor) editor).getEditor())) {
 | 
			
		||||
      if (!range.isMultiple()) {
 | 
			
		||||
        // The caret has moved, so reset the intended column before trying to get the expected offset
 | 
			
		||||
        VimCaret newCaret = caret.setVimLastColumnAndGetCaret(intendedColumn);
 | 
			
		||||
        final int offset = injector.getMotion().moveCaretToLineWithStartOfLineOption(editor, sline, caret);
 | 
			
		||||
        newCaret.moveToOffset(offset);
 | 
			
		||||
        injector.getMotion().moveCaret(editor, caret, VimPlugin.getMotion().moveCaretToLineWithStartOfLineOption(editor, sline, caret));
 | 
			
		||||
      }
 | 
			
		||||
      else {
 | 
			
		||||
        caret.moveToOffset(range.getStartOffset());
 | 
			
		||||
        injector.getMotion().moveCaret(editor, caret, range.getStartOffset());
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    UserDataManager.setVimLastColumn(((IjVimCaret) caret).getCaret(), caret.getVisualPosition().getColumn());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -533,8 +756,8 @@ public class ChangeGroup extends VimChangeGroupBase {
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    final int startOffset = editor.getLineStartOffset(startLine);
 | 
			
		||||
    final int endOffset = editor.getLineEndOffset(endLine);
 | 
			
		||||
    final int startOffset = ((IjVimEditor) editor).getEditor().getDocument().getLineStartOffset(startLine);
 | 
			
		||||
    final int endOffset = ((IjVimEditor) editor).getEditor().getDocument().getLineEndOffset(endLine);
 | 
			
		||||
 | 
			
		||||
    return sortTextRange(editor, startOffset, endOffset, lineComparator);
 | 
			
		||||
  }
 | 
			
		||||
@@ -593,17 +816,17 @@ public class ChangeGroup extends VimChangeGroupBase {
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    String nf = ((VimString) injector.getOptionService().getOptionValue(new OptionScope.LOCAL(editor), OptionConstants.nrformatsName, OptionConstants.nrformatsName)).getValue();
 | 
			
		||||
    String nf = ((VimString) VimPlugin.getOptionService().getOptionValue(new OptionScope.LOCAL(editor), OptionConstants.nrformatsName, OptionConstants.nrformatsName)).getValue();
 | 
			
		||||
    boolean alpha = nf.contains("alpha");
 | 
			
		||||
    boolean hex = nf.contains("hex");
 | 
			
		||||
    boolean octal = nf.contains("octal");
 | 
			
		||||
 | 
			
		||||
    @NotNull List<Pair<TextRange, NumberType>> numberRanges =
 | 
			
		||||
    @NotNull List<Pair<TextRange, SearchHelper.NumberType>> numberRanges =
 | 
			
		||||
      SearchHelper.findNumbersInRange(((IjVimEditor) editor).getEditor(), selectedRange, alpha, hex, octal);
 | 
			
		||||
 | 
			
		||||
    List<String> newNumbers = new ArrayList<>();
 | 
			
		||||
    for (int i = 0; i < numberRanges.size(); i++) {
 | 
			
		||||
      Pair<TextRange, NumberType> numberRange = numberRanges.get(i);
 | 
			
		||||
      Pair<TextRange, SearchHelper.NumberType> numberRange = numberRanges.get(i);
 | 
			
		||||
      int iCount = avalanche ? (i + 1) * count : count;
 | 
			
		||||
      String newNumber = changeNumberInRange(editor, numberRange, iCount, alpha, hex, octal);
 | 
			
		||||
      newNumbers.add(newNumber);
 | 
			
		||||
@@ -611,7 +834,7 @@ public class ChangeGroup extends VimChangeGroupBase {
 | 
			
		||||
 | 
			
		||||
    for (int i = newNumbers.size() - 1; i >= 0; i--) {
 | 
			
		||||
      // Replace text bottom up. In other direction ranges will be desynchronized after inc numbers like 99
 | 
			
		||||
      Pair<TextRange, NumberType> rangeToReplace = numberRanges.get(i);
 | 
			
		||||
      Pair<TextRange, SearchHelper.NumberType> rangeToReplace = numberRanges.get(i);
 | 
			
		||||
      String newNumber = newNumbers.get(i);
 | 
			
		||||
      replaceText(editor, rangeToReplace.getFirst().getStartOffset(), rangeToReplace.getFirst().getEndOffset(), newNumber);
 | 
			
		||||
    }
 | 
			
		||||
@@ -623,12 +846,12 @@ public class ChangeGroup extends VimChangeGroupBase {
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public boolean changeNumber(final @NotNull VimEditor editor, @NotNull VimCaret caret, final int count) {
 | 
			
		||||
    final String nf = ((VimString) injector.getOptionService().getOptionValue(new OptionScope.LOCAL(editor), OptionConstants.nrformatsName, OptionConstants.nrformatsName)).getValue();
 | 
			
		||||
    final String nf = ((VimString) VimPlugin.getOptionService().getOptionValue(new OptionScope.LOCAL(editor), OptionConstants.nrformatsName, OptionConstants.nrformatsName)).getValue();
 | 
			
		||||
    final boolean alpha = nf.contains("alpha");
 | 
			
		||||
    final boolean hex = nf.contains("hex");
 | 
			
		||||
    final boolean octal = nf.contains("octal");
 | 
			
		||||
 | 
			
		||||
    @Nullable Pair<TextRange, NumberType> range =
 | 
			
		||||
    @Nullable Pair<TextRange, SearchHelper.NumberType> range =
 | 
			
		||||
      SearchHelper.findNumberUnderCursor(((IjVimEditor) editor).getEditor(), ((IjVimCaret) caret).getCaret(), alpha, hex, octal);
 | 
			
		||||
    if (range == null) {
 | 
			
		||||
      logger.debug("no number on line");
 | 
			
		||||
@@ -661,14 +884,14 @@ public class ChangeGroup extends VimChangeGroupBase {
 | 
			
		||||
    strokes.add(chars);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private @Nullable String changeNumberInRange(final @NotNull VimEditor editor,
 | 
			
		||||
                                              Pair<TextRange, NumberType> range,
 | 
			
		||||
  public @Nullable String changeNumberInRange(final @NotNull VimEditor editor,
 | 
			
		||||
                                              Pair<TextRange, SearchHelper.NumberType> range,
 | 
			
		||||
                                              final int count,
 | 
			
		||||
                                              boolean alpha,
 | 
			
		||||
                                              boolean hex,
 | 
			
		||||
                                              boolean octal) {
 | 
			
		||||
    String text = EngineEditorHelperKt.getText(editor, range.getFirst());
 | 
			
		||||
    NumberType numberType = range.getSecond();
 | 
			
		||||
    String text = EditorHelper.getText(((IjVimEditor) editor).getEditor(), range.getFirst());
 | 
			
		||||
    SearchHelper.NumberType numberType = range.getSecond();
 | 
			
		||||
    if (logger.isDebugEnabled()) {
 | 
			
		||||
      logger.debug("found range " + range);
 | 
			
		||||
      logger.debug("text=" + text);
 | 
			
		||||
@@ -679,7 +902,7 @@ public class ChangeGroup extends VimChangeGroupBase {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    char ch = text.charAt(0);
 | 
			
		||||
    if (hex && NumberType.HEX.equals(numberType)) {
 | 
			
		||||
    if (hex && SearchHelper.NumberType.HEX.equals(numberType)) {
 | 
			
		||||
      if (!text.toLowerCase().startsWith(HEX_START)) {
 | 
			
		||||
        throw new RuntimeException("Hex number should start with 0x: " + text);
 | 
			
		||||
      }
 | 
			
		||||
@@ -705,7 +928,7 @@ public class ChangeGroup extends VimChangeGroupBase {
 | 
			
		||||
 | 
			
		||||
      number = text.substring(0, 2) + number;
 | 
			
		||||
    }
 | 
			
		||||
    else if (octal && NumberType.OCT.equals(numberType) && text.length() > 1) {
 | 
			
		||||
    else if (octal && SearchHelper.NumberType.OCT.equals(numberType) && text.length() > 1) {
 | 
			
		||||
      if (!text.startsWith("0")) throw new RuntimeException("Oct number should start with 0: " + text);
 | 
			
		||||
      BigInteger num = new BigInteger(text, 8).add(BigInteger.valueOf(count));
 | 
			
		||||
 | 
			
		||||
@@ -715,14 +938,14 @@ public class ChangeGroup extends VimChangeGroupBase {
 | 
			
		||||
      number = num.toString(8);
 | 
			
		||||
      number = "0" + StringsKt.padStart(number, text.length() - 1, '0');
 | 
			
		||||
    }
 | 
			
		||||
    else if (alpha && NumberType.ALPHA.equals(numberType)) {
 | 
			
		||||
    else if (alpha && SearchHelper.NumberType.ALPHA.equals(numberType)) {
 | 
			
		||||
      if (!Character.isLetter(ch)) throw new RuntimeException("Not alpha number : " + text);
 | 
			
		||||
      ch += count;
 | 
			
		||||
      if (Character.isLetter(ch)) {
 | 
			
		||||
        number = String.valueOf(ch);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    else if (NumberType.DEC.equals(numberType)) {
 | 
			
		||||
    else if (SearchHelper.NumberType.DEC.equals(numberType)) {
 | 
			
		||||
      if (ch != '-' && !Character.isDigit(ch)) throw new RuntimeException("Not dec number : " + text);
 | 
			
		||||
      boolean pad = ch == '0';
 | 
			
		||||
      int len = text.length();
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,19 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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.group
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,19 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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.group;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,19 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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.group;
 | 
			
		||||
@@ -49,8 +59,10 @@ import static com.maddyhome.idea.vim.helper.CaretVisualAttributesHelperKt.update
 | 
			
		||||
 */
 | 
			
		||||
@State(name = "VimEditorSettings", storages = {@Storage(value = "$APP_CONFIG$/vim_settings.xml")})
 | 
			
		||||
public class EditorGroup implements PersistentStateComponent<Element>, VimEditorGroup {
 | 
			
		||||
  private static final boolean REFRAIN_FROM_SCROLLING_VIM_VALUE = true;
 | 
			
		||||
  public static final @NonNls String EDITOR_STORE_ELEMENT = "editor";
 | 
			
		||||
 | 
			
		||||
  private boolean isRefrainFromScrolling = false;
 | 
			
		||||
  private Boolean isKeyRepeat = null;
 | 
			
		||||
 | 
			
		||||
  private final CaretListener myLineNumbersCaretListener = new CaretListener() {
 | 
			
		||||
@@ -207,6 +219,7 @@ public class EditorGroup implements PersistentStateComponent<Element>, VimEditor
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public void editorCreated(@NotNull Editor editor) {
 | 
			
		||||
    isRefrainFromScrolling = editor.getSettings().isRefrainFromScrolling();
 | 
			
		||||
    DocumentManager.INSTANCE.addListeners(editor.getDocument());
 | 
			
		||||
    VimPlugin.getKey().registerRequiredShortcutKeys(new IjVimEditor(editor));
 | 
			
		||||
 | 
			
		||||
@@ -219,12 +232,14 @@ public class EditorGroup implements PersistentStateComponent<Element>, VimEditor
 | 
			
		||||
      KeyHandler.getInstance().reset(new IjVimEditor(editor));
 | 
			
		||||
    }
 | 
			
		||||
    updateCaretsVisualAttributes(editor);
 | 
			
		||||
    //editor.getSettings().setRefrainFromScrolling(REFRAIN_FROM_SCROLLING_VIM_VALUE);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public void editorDeinit(@NotNull Editor editor, boolean isReleased) {
 | 
			
		||||
    deinitLineNumbers(editor, isReleased);
 | 
			
		||||
    UserDataManager.unInitializeEditor(editor);
 | 
			
		||||
    VimPlugin.getKey().unregisterShortcutKeys(new IjVimEditor(editor));
 | 
			
		||||
    editor.getSettings().setRefrainFromScrolling(isRefrainFromScrolling);
 | 
			
		||||
    DocumentManager.INSTANCE.removeListeners(editor.getDocument());
 | 
			
		||||
    CaretVisualAttributesHelperKt.removeCaretsVisualAttributes(editor);
 | 
			
		||||
  }
 | 
			
		||||
@@ -294,8 +309,8 @@ public class EditorGroup implements PersistentStateComponent<Element>, VimEditor
 | 
			
		||||
        return lineNumber;
 | 
			
		||||
      }
 | 
			
		||||
      else {
 | 
			
		||||
        final int visualLine = new IjVimEditor(editor).bufferLineToVisualLine(lineNumber - 1);
 | 
			
		||||
        final int currentVisualLine = new IjVimEditor(editor).bufferLineToVisualLine(caretLine);
 | 
			
		||||
        final int visualLine = EditorHelper.logicalLineToVisualLine(editor, lineNumber - 1);
 | 
			
		||||
        final int currentVisualLine = EditorHelper.logicalLineToVisualLine(editor, caretLine);
 | 
			
		||||
        return Math.abs(currentVisualLine - visualLine);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,19 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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.group
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,19 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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.group;
 | 
			
		||||
@@ -23,11 +33,11 @@ import com.intellij.openapi.fileTypes.FileType;
 | 
			
		||||
import com.intellij.openapi.fileTypes.FileTypeManager;
 | 
			
		||||
import com.intellij.openapi.project.Project;
 | 
			
		||||
import com.intellij.openapi.roots.ProjectRootManager;
 | 
			
		||||
import com.intellij.openapi.util.Ref;
 | 
			
		||||
import com.intellij.openapi.vfs.LocalFileSystem;
 | 
			
		||||
import com.intellij.openapi.vfs.VfsUtilCore;
 | 
			
		||||
import com.intellij.openapi.vfs.VirtualFile;
 | 
			
		||||
import com.intellij.psi.search.FilenameIndex;
 | 
			
		||||
import com.intellij.psi.search.GlobalSearchScope;
 | 
			
		||||
import com.intellij.psi.search.ProjectScope;
 | 
			
		||||
import com.intellij.openapi.vfs.VirtualFileVisitor;
 | 
			
		||||
import com.maddyhome.idea.vim.VimPlugin;
 | 
			
		||||
import com.maddyhome.idea.vim.api.*;
 | 
			
		||||
import com.maddyhome.idea.vim.command.VimStateMachine;
 | 
			
		||||
@@ -46,7 +56,6 @@ import org.jetbrains.annotations.NotNull;
 | 
			
		||||
import org.jetbrains.annotations.Nullable;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
 | 
			
		||||
public class FileGroup extends VimFileBase {
 | 
			
		||||
  public boolean openFile(@NotNull String filename, @NotNull ExecutionContext context) {
 | 
			
		||||
@@ -98,44 +107,44 @@ public class FileGroup extends VimFileBase {
 | 
			
		||||
      found = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(new File(dir, homefile));
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
      found = LocalFileSystem.getInstance().findFileByIoFile(new File(filename));
 | 
			
		||||
 | 
			
		||||
      if (found == null) {
 | 
			
		||||
        found = findByNameInContentRoots(filename, project);
 | 
			
		||||
        if (found == null) {
 | 
			
		||||
          found = findByNameInProject(filename, project);
 | 
			
		||||
      ProjectRootManager prm = ProjectRootManager.getInstance(project);
 | 
			
		||||
      VirtualFile[] roots = prm.getContentRoots();
 | 
			
		||||
      for (int i = 0; i < roots.length; i++) {
 | 
			
		||||
        if (logger.isDebugEnabled()) {
 | 
			
		||||
          logger.debug("root[" + i + "] = " + roots[i].getPath());
 | 
			
		||||
        }
 | 
			
		||||
        found = findFile(roots[i], filename);
 | 
			
		||||
        if (found != null) {
 | 
			
		||||
          break;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (found == null) {
 | 
			
		||||
        found = LocalFileSystem.getInstance().findFileByIoFile(new File(filename));
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return found;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Nullable
 | 
			
		||||
  private VirtualFile findByNameInContentRoots(@NotNull String filename, @NotNull Project project) {
 | 
			
		||||
    VirtualFile found = null;
 | 
			
		||||
    ProjectRootManager prm = ProjectRootManager.getInstance(project);
 | 
			
		||||
    VirtualFile[] roots = prm.getContentRoots();
 | 
			
		||||
    for (int i = 0; i < roots.length; i++) {
 | 
			
		||||
      if (logger.isDebugEnabled()) {
 | 
			
		||||
        logger.debug("root[" + i + "] = " + roots[i].getPath());
 | 
			
		||||
      }
 | 
			
		||||
      found = roots[i].findFileByRelativePath(filename);
 | 
			
		||||
      if (found != null) {
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
  private @Nullable VirtualFile findFile(@NotNull VirtualFile root, @NotNull String filename) {
 | 
			
		||||
    VirtualFile res = root.findFileByRelativePath(filename);
 | 
			
		||||
    if (res != null) {
 | 
			
		||||
      return res;
 | 
			
		||||
    }
 | 
			
		||||
    return found;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Nullable
 | 
			
		||||
  private static VirtualFile findByNameInProject(@NotNull String filename, @NotNull Project project) {
 | 
			
		||||
    GlobalSearchScope projectScope = ProjectScope.getProjectScope(project);
 | 
			
		||||
    Collection<VirtualFile> names = FilenameIndex.getVirtualFilesByName(filename, projectScope);
 | 
			
		||||
    if (!names.isEmpty()) {
 | 
			
		||||
      return names.stream().findFirst().get();
 | 
			
		||||
    }
 | 
			
		||||
    return null;
 | 
			
		||||
    final Ref<VirtualFile> result = Ref.create();
 | 
			
		||||
    final VirtualFileVisitor<Object> visitor = new VirtualFileVisitor<>() {
 | 
			
		||||
      @Override
 | 
			
		||||
      public boolean visitFile(@NotNull VirtualFile file) {
 | 
			
		||||
        if (file.getName().equals(filename)) {
 | 
			
		||||
          result.set(file);
 | 
			
		||||
          return false;
 | 
			
		||||
        }
 | 
			
		||||
        return true;
 | 
			
		||||
      }
 | 
			
		||||
    };
 | 
			
		||||
    VfsUtilCore.visitChildrenRecursively(root, visitor);
 | 
			
		||||
    return result.get();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
@@ -310,7 +319,7 @@ public class FileGroup extends VimFileBase {
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      int lline = editor.getCaretModel().getLogicalPosition().line;
 | 
			
		||||
      int total = new IjVimEditor(editor).lineCount();
 | 
			
		||||
      int total = EditorHelper.getLineCount(editor);
 | 
			
		||||
 | 
			
		||||
      msg.append("; Line ").append(lline + 1).append(" of ").append(total);
 | 
			
		||||
 | 
			
		||||
@@ -355,7 +364,7 @@ public class FileGroup extends VimFileBase {
 | 
			
		||||
        word = cp.getCount();
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      int total = new IjVimEditor(editor).lineCount();
 | 
			
		||||
      int total = EditorHelper.getLineCount(editor);
 | 
			
		||||
 | 
			
		||||
      msg.append(lines).append(" of ").append(total).append(" Lines");
 | 
			
		||||
 | 
			
		||||
@@ -407,7 +416,7 @@ public class FileGroup extends VimFileBase {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    int lline = editor.getCaretModel().getLogicalPosition().line;
 | 
			
		||||
    int total = new IjVimEditor(editor).lineCount();
 | 
			
		||||
    int total = EditorHelper.getLineCount(editor);
 | 
			
		||||
    int pct = (int)((float)lline / (float)total * 100f + 0.5);
 | 
			
		||||
 | 
			
		||||
    msg.append("line ").append(lline + 1).append(" of ").append(total);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,19 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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.group;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,37 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 2003-2022 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.group
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,19 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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.group
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,19 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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.group
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,19 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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.group;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,19 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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.group
 | 
			
		||||
 
 | 
			
		||||
@@ -1,25 +1,40 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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.group;
 | 
			
		||||
 | 
			
		||||
import com.intellij.openapi.application.ApplicationManager;
 | 
			
		||||
import com.intellij.openapi.command.CommandProcessor;
 | 
			
		||||
import com.intellij.openapi.diagnostic.Logger;
 | 
			
		||||
import com.intellij.openapi.progress.ProcessCanceledException;
 | 
			
		||||
import com.intellij.openapi.progress.ProgressManager;
 | 
			
		||||
import com.intellij.openapi.progress.util.PotemkinProgress;
 | 
			
		||||
import com.intellij.openapi.project.Project;
 | 
			
		||||
import com.maddyhome.idea.vim.KeyHandler;
 | 
			
		||||
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.helper.MessageHelper;
 | 
			
		||||
import com.maddyhome.idea.vim.key.KeyStack;
 | 
			
		||||
import com.maddyhome.idea.vim.macro.VimMacroBase;
 | 
			
		||||
import com.maddyhome.idea.vim.newapi.IjVimEditor;
 | 
			
		||||
import com.maddyhome.idea.vim.options.OptionConstants;
 | 
			
		||||
import com.maddyhome.idea.vim.options.OptionScope;
 | 
			
		||||
import org.jetbrains.annotations.NotNull;
 | 
			
		||||
 | 
			
		||||
import javax.swing.*;
 | 
			
		||||
@@ -46,30 +61,57 @@ public class MacroGroup extends VimMacroBase {
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    PotemkinProgress potemkinProgress =
 | 
			
		||||
      new PotemkinProgress(MessageHelper.message("progress.title.macro.execution"), project, null,
 | 
			
		||||
                           MessageHelper.message("stop"));
 | 
			
		||||
    potemkinProgress.setIndeterminate(false);
 | 
			
		||||
    potemkinProgress.setFraction(0);
 | 
			
		||||
    potemkinProgress.runInSwingThread(() -> {
 | 
			
		||||
      // Handle one keystroke then queue up the next key
 | 
			
		||||
      for (int i = 0; i < total; ++i) {
 | 
			
		||||
        potemkinProgress.setFraction((double)(i + 1) / total);
 | 
			
		||||
        while (keyStack.hasStroke()) {
 | 
			
		||||
          KeyStroke key = keyStack.feedStroke();
 | 
			
		||||
          try {
 | 
			
		||||
            potemkinProgress.checkCanceled();
 | 
			
		||||
          }
 | 
			
		||||
          catch (ProcessCanceledException e) {
 | 
			
		||||
            return;
 | 
			
		||||
          }
 | 
			
		||||
          ProgressManager.getInstance().executeNonCancelableSection(() -> {
 | 
			
		||||
            KeyHandler.getInstance().handleKey(editor, key, context);
 | 
			
		||||
          });
 | 
			
		||||
    if (VimPlugin.getOptionService().isSet(OptionScope.GLOBAL.INSTANCE, OptionConstants.ideadelaymacroName, OptionConstants.ideadelaymacroName)) {
 | 
			
		||||
      // This took a while to get just right. The original approach has a loop that made a runnable for each
 | 
			
		||||
      // character. It worked except for one case - if the macro had a complete ex command, the editor did not
 | 
			
		||||
      // end up with the focus and I couldn't find anyway to get it to have focus. This approach was the only
 | 
			
		||||
      // solution. This makes the most sense now (of course it took hours of trial and error to come up with
 | 
			
		||||
      // this one). Each key gets added, one at a time, to the event queue. If a given key results in other
 | 
			
		||||
      // events getting queued, they get queued before the next key, just what would happen if the user was typing
 | 
			
		||||
      // the keys one at a time. With the old loop approach, all the keys got queued, then any events they caused
 | 
			
		||||
      // were queued - after the keys. This is what caused the problem.
 | 
			
		||||
      final Runnable run = () -> {
 | 
			
		||||
        // Handle one keystroke then queue up the next key
 | 
			
		||||
        if (keyStack.hasStroke()) {
 | 
			
		||||
          KeyHandler.getInstance().handleKey(editor, keyStack.feedStroke(), context);
 | 
			
		||||
        }
 | 
			
		||||
        keyStack.resetFirst();
 | 
			
		||||
      }
 | 
			
		||||
      keyStack.removeFirst();
 | 
			
		||||
    });
 | 
			
		||||
        if (keyStack.hasStroke()) {
 | 
			
		||||
          playbackKeys(editor, context, cnt, total);
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
          keyStack.resetFirst();
 | 
			
		||||
          playbackKeys(editor, context, cnt + 1, total);
 | 
			
		||||
        }
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      ApplicationManager.getApplication().invokeLater(() -> CommandProcessor.getInstance()
 | 
			
		||||
        .executeCommand(project, run, MessageHelper.message("command.name.vim.macro.playback"), null));
 | 
			
		||||
    } else {
 | 
			
		||||
      PotemkinProgress potemkinProgress =
 | 
			
		||||
        new PotemkinProgress(MessageHelper.message("progress.title.macro.execution"), project, null,
 | 
			
		||||
                             MessageHelper.message("stop"));
 | 
			
		||||
      potemkinProgress.setIndeterminate(false);
 | 
			
		||||
      potemkinProgress.setFraction(0);
 | 
			
		||||
      potemkinProgress.runInSwingThread(() -> {
 | 
			
		||||
        // Handle one keystroke then queue up the next key
 | 
			
		||||
        for (int i = 0; i < total; ++i) {
 | 
			
		||||
          potemkinProgress.setFraction((double)(i + 1) / total);
 | 
			
		||||
          while (keyStack.hasStroke()) {
 | 
			
		||||
            KeyStroke key = keyStack.feedStroke();
 | 
			
		||||
            try {
 | 
			
		||||
              potemkinProgress.checkCanceled();
 | 
			
		||||
            }
 | 
			
		||||
            catch (ProcessCanceledException e) {
 | 
			
		||||
              return;
 | 
			
		||||
            }
 | 
			
		||||
            ProgressManager.getInstance().executeNonCancelableSection(() -> {
 | 
			
		||||
              KeyHandler.getInstance().handleKey(editor, key, context);
 | 
			
		||||
            });
 | 
			
		||||
          }
 | 
			
		||||
          keyStack.resetFirst();
 | 
			
		||||
        }
 | 
			
		||||
        keyStack.removeFirst();
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,19 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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.group;
 | 
			
		||||
@@ -121,7 +131,7 @@ public class MarkGroup extends VimMarkGroupBase implements PersistentStateCompon
 | 
			
		||||
        if (!mark.isClear()) {
 | 
			
		||||
          Element markElem = new Element("mark");
 | 
			
		||||
          markElem.setAttribute("key", Character.toString(mark.getKey()));
 | 
			
		||||
          markElem.setAttribute("line", Integer.toString(mark.getLine()));
 | 
			
		||||
          markElem.setAttribute("line", Integer.toString(mark.getLogicalLine()));
 | 
			
		||||
          markElem.setAttribute("column", Integer.toString(mark.getCol()));
 | 
			
		||||
          markElem.setAttribute("filename", StringUtil.notNullize(mark.getFilename()));
 | 
			
		||||
          markElem.setAttribute("protocol", StringUtil.notNullize(mark.getProtocol(), "file"));
 | 
			
		||||
@@ -157,7 +167,7 @@ public class MarkGroup extends VimMarkGroupBase implements PersistentStateCompon
 | 
			
		||||
          if (!mark.isClear() && !Character.isUpperCase(mark.getKey()) && SAVE_FILE_MARKS.indexOf(mark.getKey()) >= 0) {
 | 
			
		||||
            Element markElem = new Element("mark");
 | 
			
		||||
            markElem.setAttribute("key", Character.toString(mark.getKey()));
 | 
			
		||||
            markElem.setAttribute("line", Integer.toString(mark.getLine()));
 | 
			
		||||
            markElem.setAttribute("line", Integer.toString(mark.getLogicalLine()));
 | 
			
		||||
            markElem.setAttribute("column", Integer.toString(mark.getCol()));
 | 
			
		||||
            fileMarkElem.addContent(markElem);
 | 
			
		||||
          }
 | 
			
		||||
@@ -170,7 +180,7 @@ public class MarkGroup extends VimMarkGroupBase implements PersistentStateCompon
 | 
			
		||||
    Element jumpsElem = new Element("jumps");
 | 
			
		||||
    for (Jump jump : jumps) {
 | 
			
		||||
      Element jumpElem = new Element("jump");
 | 
			
		||||
      jumpElem.setAttribute("line", Integer.toString(jump.getLine()));
 | 
			
		||||
      jumpElem.setAttribute("line", Integer.toString(jump.getLogicalLine()));
 | 
			
		||||
      jumpElem.setAttribute("column", Integer.toString(jump.getCol()));
 | 
			
		||||
      jumpElem.setAttribute("filename", StringUtil.notNullize(jump.getFilepath()));
 | 
			
		||||
      jumpsElem.addContent(jumpElem);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,14 +1,25 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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.group;
 | 
			
		||||
 | 
			
		||||
import com.intellij.openapi.actionSystem.DataContext;
 | 
			
		||||
import com.intellij.openapi.editor.*;
 | 
			
		||||
import com.intellij.openapi.editor.ex.util.EditorUtil;
 | 
			
		||||
import com.intellij.openapi.fileEditor.FileEditor;
 | 
			
		||||
import com.intellij.openapi.fileEditor.FileEditorManagerEvent;
 | 
			
		||||
import com.intellij.openapi.fileEditor.TextEditor;
 | 
			
		||||
@@ -28,6 +39,7 @@ import com.maddyhome.idea.vim.command.*;
 | 
			
		||||
import com.maddyhome.idea.vim.common.TextRange;
 | 
			
		||||
import com.maddyhome.idea.vim.ex.ExOutputModel;
 | 
			
		||||
import com.maddyhome.idea.vim.group.visual.VimSelection;
 | 
			
		||||
import com.maddyhome.idea.vim.group.visual.VisualGroupKt;
 | 
			
		||||
import com.maddyhome.idea.vim.handler.Motion;
 | 
			
		||||
import com.maddyhome.idea.vim.handler.MotionActionHandler;
 | 
			
		||||
import com.maddyhome.idea.vim.handler.TextObjectActionHandler;
 | 
			
		||||
@@ -64,6 +76,123 @@ import static java.lang.Math.min;
 | 
			
		||||
 */
 | 
			
		||||
public class MotionGroup extends VimMotionGroupBase {
 | 
			
		||||
 | 
			
		||||
  public @Nullable TextRange getMotionRange(@NotNull VimEditor editor,
 | 
			
		||||
                                            @NotNull VimCaret caret,
 | 
			
		||||
                                            ExecutionContext context,
 | 
			
		||||
                                            @NotNull Argument argument,
 | 
			
		||||
                                            @NotNull OperatorArguments operatorArguments) {
 | 
			
		||||
    return getMotionRange(((IjVimEditor) editor).getEditor(), ((IjVimCaret) caret).getCaret(), ((IjExecutionContext) context).getContext(), argument, operatorArguments);
 | 
			
		||||
  }
 | 
			
		||||
  /**
 | 
			
		||||
   * This helper method calculates the complete range a motion will move over taking into account whether
 | 
			
		||||
   * the motion is FLAG_MOT_LINEWISE or FLAG_MOT_CHARACTERWISE (FLAG_MOT_INCLUSIVE or FLAG_MOT_EXCLUSIVE).
 | 
			
		||||
   *
 | 
			
		||||
   * @param editor   The editor the motion takes place in
 | 
			
		||||
   * @param caret    The caret the motion takes place on
 | 
			
		||||
   * @param context  The data context
 | 
			
		||||
   * @param argument Any argument needed by the motion
 | 
			
		||||
   * @param operatorArguments
 | 
			
		||||
   * @return The motion's range
 | 
			
		||||
   */
 | 
			
		||||
  public static @Nullable TextRange getMotionRange(@NotNull Editor editor,
 | 
			
		||||
                                                   @NotNull Caret caret,
 | 
			
		||||
                                                   DataContext context,
 | 
			
		||||
                                                   @NotNull Argument argument,
 | 
			
		||||
                                                   @NotNull OperatorArguments operatorArguments) {
 | 
			
		||||
    int start;
 | 
			
		||||
    int end;
 | 
			
		||||
    if (argument.getType() == Argument.Type.OFFSETS) {
 | 
			
		||||
      final VimSelection offsets = argument.getOffsets().get(new IjVimCaret(caret));
 | 
			
		||||
      if (offsets == null) return null;
 | 
			
		||||
 | 
			
		||||
      final Pair<Integer, Integer> nativeStartAndEnd = offsets.getNativeStartAndEnd();
 | 
			
		||||
      start = nativeStartAndEnd.getFirst();
 | 
			
		||||
      end = nativeStartAndEnd.getSecond();
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
      final Command cmd = argument.getMotion();
 | 
			
		||||
      // Normalize the counts between the command and the motion argument
 | 
			
		||||
      int cnt = cmd.getCount() * operatorArguments.getCount1();
 | 
			
		||||
      int raw = operatorArguments.getCount0() == 0 && cmd.getRawCount() == 0 ? 0 : cnt;
 | 
			
		||||
      if (cmd.getAction() instanceof MotionActionHandler) {
 | 
			
		||||
        MotionActionHandler action = (MotionActionHandler)cmd.getAction();
 | 
			
		||||
 | 
			
		||||
        // This is where we are now
 | 
			
		||||
        start = caret.getOffset();
 | 
			
		||||
 | 
			
		||||
        // Execute the motion (without moving the cursor) and get where we end
 | 
			
		||||
        Motion motion =
 | 
			
		||||
          action.getHandlerOffset(new IjVimEditor(editor), new IjVimCaret(caret), new IjExecutionContext(context), cmd.getArgument(), operatorArguments.withCount0(raw));
 | 
			
		||||
 | 
			
		||||
        // Invalid motion
 | 
			
		||||
        if (Motion.Error.INSTANCE.equals(motion)) return null;
 | 
			
		||||
        if (Motion.NoMotion.INSTANCE.equals(motion)) return null;
 | 
			
		||||
        end = ((Motion.AbsoluteOffset)motion).getOffset();
 | 
			
		||||
 | 
			
		||||
        // If inclusive, add the last character to the range
 | 
			
		||||
        if (action.getMotionType() == MotionType.INCLUSIVE && end < EditorHelperRt.getFileSize(editor)) {
 | 
			
		||||
          if (start > end) {
 | 
			
		||||
            start++;
 | 
			
		||||
          }
 | 
			
		||||
          else {
 | 
			
		||||
            end++;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      else if (cmd.getAction() instanceof TextObjectActionHandler) {
 | 
			
		||||
        TextObjectActionHandler action = (TextObjectActionHandler)cmd.getAction();
 | 
			
		||||
 | 
			
		||||
        TextRange range = action.getRange(new IjVimEditor(editor), new IjVimCaret(caret), new IjExecutionContext(context), cnt, raw, cmd.getArgument());
 | 
			
		||||
 | 
			
		||||
        if (range == null) return null;
 | 
			
		||||
 | 
			
		||||
        start = range.getStartOffset();
 | 
			
		||||
        end = range.getEndOffset();
 | 
			
		||||
 | 
			
		||||
        if (cmd.isLinewiseMotion()) end--;
 | 
			
		||||
      }
 | 
			
		||||
      else {
 | 
			
		||||
        throw new RuntimeException(
 | 
			
		||||
          "Commands doesn't take " + cmd.getAction().getClass().getSimpleName() + " as an operator");
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // Normalize the range
 | 
			
		||||
      if (start > end) {
 | 
			
		||||
        int t = start;
 | 
			
		||||
        start = end;
 | 
			
		||||
        end = t;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // If we are a linewise motion we need to normalize the start and stop then move the start to the beginning
 | 
			
		||||
      // of the line and move the end to the end of the line.
 | 
			
		||||
      if (cmd.isLinewiseMotion()) {
 | 
			
		||||
        if (caret.getLogicalPosition().line != getLineCount(editor) - 1) {
 | 
			
		||||
          start = getLineStartForOffset(editor, start);
 | 
			
		||||
          end = min(getLineEndForOffset(editor, end) + 1, EditorHelperRt.getFileSize(editor));
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
          start = getLineStartForOffset(editor, start);
 | 
			
		||||
          end = getLineEndForOffset(editor, end);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // This is a kludge for dw, dW, and d[w. Without this kludge, an extra newline is operated when it shouldn't be.
 | 
			
		||||
    String text = editor.getDocument().getCharsSequence().subSequence(start, end).toString();
 | 
			
		||||
    final int lastNewLine = text.lastIndexOf('\n');
 | 
			
		||||
    if (lastNewLine > 0) {
 | 
			
		||||
      String id = argument.getMotion().getAction().getId();
 | 
			
		||||
      if (id.equals(VIM_MOTION_WORD_RIGHT) ||
 | 
			
		||||
          id.equals(VIM_MOTION_BIG_WORD_RIGHT) ||
 | 
			
		||||
          id.equals(VIM_MOTION_CAMEL_RIGHT)) {
 | 
			
		||||
        if (!SearchHelper.anyNonWhitespace(editor, end, -1)) {
 | 
			
		||||
          end = start + lastNewLine;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return new TextRange(start, end);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public static @Nullable TextRange getMotionRange2(@NotNull Editor editor,
 | 
			
		||||
                                                    @NotNull Caret caret,
 | 
			
		||||
@@ -141,7 +270,7 @@ public class MotionGroup extends VimMotionGroupBase {
 | 
			
		||||
      String text = editor.getDocument().getCharsSequence().subSequence(start, end).toString();
 | 
			
		||||
      final int lastNewLine = text.lastIndexOf('\n');
 | 
			
		||||
      if (lastNewLine > 0) {
 | 
			
		||||
        if (!EngineEditorHelperKt.anyNonWhitespace(new IjVimEditor(editor), end, -1)) {
 | 
			
		||||
        if (!SearchHelper.anyNonWhitespace(editor, end, -1)) {
 | 
			
		||||
          end = start + lastNewLine;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
@@ -156,16 +285,14 @@ public class MotionGroup extends VimMotionGroupBase {
 | 
			
		||||
    final int topVisualLine = getVisualLineAtTopOfScreen(editor);
 | 
			
		||||
    final int bottomVisualLine = getVisualLineAtBottomOfScreen(editor);
 | 
			
		||||
    final int caretVisualLine = editor.getCaretModel().getVisualPosition().line;
 | 
			
		||||
    @NotNull final VimEditor editor1 = new IjVimEditor(editor);
 | 
			
		||||
    final int lastVisualLine = EngineEditorHelperKt.getVisualLineCount(editor1) - 1;
 | 
			
		||||
    final int lastVisualLine = EditorHelper.getVisualLineCount(new IjVimEditor(editor)) - 1;
 | 
			
		||||
 | 
			
		||||
    final int newVisualLine;
 | 
			
		||||
    if (caretVisualLine < topVisualLine + scrollOffset) {
 | 
			
		||||
      newVisualLine = EngineEditorHelperKt.normalizeVisualLine(new IjVimEditor(editor), topVisualLine + scrollOffset);
 | 
			
		||||
      newVisualLine = normalizeVisualLine(editor, topVisualLine + scrollOffset);
 | 
			
		||||
    }
 | 
			
		||||
    else if (bottomVisualLine < lastVisualLine && caretVisualLine > bottomVisualLine - scrollOffset) {
 | 
			
		||||
      newVisualLine =
 | 
			
		||||
        EngineEditorHelperKt.normalizeVisualLine(new IjVimEditor(editor), bottomVisualLine - scrollOffset);
 | 
			
		||||
      newVisualLine = normalizeVisualLine(editor, bottomVisualLine - scrollOffset);
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
      newVisualLine = caretVisualLine;
 | 
			
		||||
@@ -175,12 +302,12 @@ public class MotionGroup extends VimMotionGroupBase {
 | 
			
		||||
 | 
			
		||||
    final int oldColumn = editor.getCaretModel().getVisualPosition().column;
 | 
			
		||||
    int col = oldColumn;
 | 
			
		||||
    if (col >= EngineEditorHelperKt.lineLength(new IjVimEditor(editor), new IjVimEditor(editor).currentCaret().getBufferPosition().getLine()) - 1) {
 | 
			
		||||
    if (col >= getLineLength(editor) - 1) {
 | 
			
		||||
      col = UserDataManager.getVimLastColumn(editor.getCaretModel().getPrimaryCaret());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    final int leftVisualColumn = getVisualColumnAtLeftOfDisplay(editor, newVisualLine);
 | 
			
		||||
    final int rightVisualColumn = getVisualColumnAtRightOfDisplay(editor, newVisualLine);
 | 
			
		||||
    final int leftVisualColumn = getVisualColumnAtLeftOfScreen(editor, newVisualLine);
 | 
			
		||||
    final int rightVisualColumn = getVisualColumnAtRightOfScreen(editor, newVisualLine);
 | 
			
		||||
    int caretColumn = col;
 | 
			
		||||
    int newColumn = caretColumn;
 | 
			
		||||
 | 
			
		||||
@@ -196,11 +323,11 @@ public class MotionGroup extends VimMotionGroupBase {
 | 
			
		||||
      col = newColumn;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    newColumn = EngineEditorHelperKt.normalizeVisualColumn(new IjVimEditor(editor), newVisualLine, newColumn, CommandStateHelper.isEndAllowed(editor));
 | 
			
		||||
    newColumn = normalizeVisualColumn(editor, newVisualLine, newColumn, CommandStateHelper.isEndAllowed(editor));
 | 
			
		||||
 | 
			
		||||
    if (newVisualLine != caretVisualLine || newColumn != oldColumn) {
 | 
			
		||||
      int offset = editor.visualPositionToOffset(new VisualPosition(newVisualLine, newColumn));
 | 
			
		||||
      new IjVimCaret(editor.getCaretModel().getPrimaryCaret()).moveToOffset(offset);
 | 
			
		||||
      int offset = visualPositionToOffset(editor, new VisualPosition(newVisualLine, newColumn));
 | 
			
		||||
      moveCaret(editor, editor.getCaretModel().getPrimaryCaret(), offset);
 | 
			
		||||
 | 
			
		||||
      UserDataManager.setVimLastColumn(editor.getCaretModel().getPrimaryCaret(), col);
 | 
			
		||||
    }
 | 
			
		||||
@@ -223,7 +350,7 @@ public class MotionGroup extends VimMotionGroupBase {
 | 
			
		||||
      targetCaretVisualLine = down ? caretVisualLine + scrollOption : caretVisualLine - scrollOption;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return EngineEditorHelperKt.normalizeVisualLine(new IjVimEditor(editor), targetCaretVisualLine);
 | 
			
		||||
    return EditorHelper.normalizeVisualLine(editor, targetCaretVisualLine);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private static int getScrollOption(int rawCount) {
 | 
			
		||||
@@ -245,9 +372,43 @@ public class MotionGroup extends VimMotionGroupBase {
 | 
			
		||||
    return normalizeSideScrollOffset(editor, sideScrollOffset);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public void onAppCodeMovement(@NotNull VimEditor editor, @NotNull VimCaret caret, int offset, int oldOffset) {
 | 
			
		||||
    AppCodeTemplates.onMovement(((IjVimEditor)editor).getEditor(), ((IjVimCaret)caret).getCaret(), oldOffset < offset);
 | 
			
		||||
  public void moveCaret(@NotNull VimEditor editor, @NotNull VimCaret caret, int offset) {
 | 
			
		||||
    moveCaret(((IjVimEditor) editor).getEditor(), ((IjVimCaret) caret).getCaret(), offset);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public static void moveCaret(@NotNull Editor editor, @NotNull Caret caret, int offset) {
 | 
			
		||||
    if (offset < 0 || offset > editor.getDocument().getTextLength() || !caret.isValid()) return;
 | 
			
		||||
 | 
			
		||||
    if (CommandStateHelper.inBlockSubMode(editor)) {
 | 
			
		||||
      VisualGroupKt.vimMoveBlockSelectionToOffset(editor, offset);
 | 
			
		||||
      Caret primaryCaret = editor.getCaretModel().getPrimaryCaret();
 | 
			
		||||
      UserDataManager.setVimLastColumn(primaryCaret, primaryCaret.getVisualPosition().column);
 | 
			
		||||
      scrollCaretIntoView(editor);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Make sure to always reposition the caret, even if the offset hasn't changed. We might need to reposition due to
 | 
			
		||||
    // changes in surrounding text, especially with inline inlays.
 | 
			
		||||
    final int oldOffset = caret.getOffset();
 | 
			
		||||
    InlayHelperKt.moveToInlayAwareOffset(caret, offset);
 | 
			
		||||
    if (oldOffset != offset) {
 | 
			
		||||
      UserDataManager.setVimLastColumn(caret, InlayHelperKt.getInlayAwareVisualColumn(caret));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Similarly, always make sure the caret is positioned within the view. Adding or removing text could move the caret
 | 
			
		||||
    // position relative to the view, without changing offset.
 | 
			
		||||
    if (caret == editor.getCaretModel().getPrimaryCaret()) {
 | 
			
		||||
      scrollCaretIntoView(editor);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (CommandStateHelper.inVisualMode(editor) || CommandStateHelper.inSelectMode(editor)) {
 | 
			
		||||
      VisualGroupKt.vimMoveSelectionToCaret(caret);
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
      ModeHelper.exitVisualMode(editor);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    AppCodeTemplates.onMovement(editor, caret, oldOffset < offset);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private @Nullable Editor selectEditor(@NotNull Editor editor, @NotNull Mark mark) {
 | 
			
		||||
@@ -271,7 +432,7 @@ public class MotionGroup extends VimMotionGroupBase {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public int moveCaretToMatchingPair(@NotNull VimEditor editor, @NotNull ImmutableVimCaret caret) {
 | 
			
		||||
  public int moveCaretToMatchingPair(@NotNull VimEditor editor, @NotNull VimCaret caret) {
 | 
			
		||||
    int pos = SearchHelper.findMatchingPairOnCurrentLine(((IjVimEditor)editor).getEditor(), ((IjVimCaret)caret).getCaret());
 | 
			
		||||
    if (pos >= 0) {
 | 
			
		||||
      return pos;
 | 
			
		||||
@@ -317,26 +478,70 @@ public class MotionGroup extends VimMotionGroupBase {
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * This moves the caret to the end of the next/previous word/WORD.
 | 
			
		||||
   *
 | 
			
		||||
   * @param editor  The editor to move in
 | 
			
		||||
   * @param caret   The caret to be moved
 | 
			
		||||
   * @param count   The number of words to skip
 | 
			
		||||
   * @param bigWord If true then find WORD, if false then find word
 | 
			
		||||
   * @return position
 | 
			
		||||
   */
 | 
			
		||||
  public Motion moveCaretToNextWordEnd(@NotNull Editor editor, @NotNull Caret caret, int count, boolean bigWord) {
 | 
			
		||||
    if ((caret.getOffset() == 0 && count < 0) ||
 | 
			
		||||
        (caret.getOffset() >= EditorHelperRt.getFileSize(editor) - 1 && count > 0)) {
 | 
			
		||||
      return Motion.Error.INSTANCE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // If we are doing this move as part of a change command (e.q. cw), we need to count the current end of
 | 
			
		||||
    // word if the cursor happens to be on the end of a word already. If this is a normal move, we don't count
 | 
			
		||||
    // the current word.
 | 
			
		||||
    int pos = SearchHelper.findNextWordEnd(editor, caret, count, bigWord);
 | 
			
		||||
    if (pos == -1) {
 | 
			
		||||
      if (count < 0) {
 | 
			
		||||
        return new Motion.AbsoluteOffset(moveCaretToLineStart(new IjVimEditor(editor), 0));
 | 
			
		||||
      }
 | 
			
		||||
      else {
 | 
			
		||||
        return new Motion.AbsoluteOffset(moveCaretToLineEnd(new IjVimEditor(editor), getLineCount(editor) - 1, false));
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
      return new Motion.AbsoluteOffset(pos);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public int moveCaretToNextSentenceStart(@NotNull Editor editor, @NotNull Caret caret, int count) {
 | 
			
		||||
    int res = SearchHelper.findNextSentenceStart(editor, caret, count, false, true);
 | 
			
		||||
    if (res >= 0) {
 | 
			
		||||
      res = normalizeOffset(editor, res, true);
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
      res = -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return res;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public boolean scrollCurrentLineToDisplayTop(@NotNull VimEditor editor, int rawCount, boolean start) {
 | 
			
		||||
  public boolean scrollLineToFirstScreenLine(@NotNull VimEditor editor, int rawCount, boolean start) {
 | 
			
		||||
    scrollLineToScreenLocation(((IjVimEditor)editor).getEditor(), ScreenLocation.TOP, rawCount, start);
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public boolean scrollCurrentLineToDisplayMiddle(@NotNull VimEditor editor, int rawCount, boolean start) {
 | 
			
		||||
  public boolean scrollLineToMiddleScreenLine(@NotNull VimEditor editor, int rawCount, boolean start) {
 | 
			
		||||
    scrollLineToScreenLocation(((IjVimEditor)editor).getEditor(), ScreenLocation.MIDDLE, rawCount, start);
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public boolean scrollCurrentLineToDisplayBottom(@NotNull VimEditor editor, int rawCount, boolean start) {
 | 
			
		||||
  public boolean scrollLineToLastScreenLine(@NotNull VimEditor editor, int rawCount, boolean start) {
 | 
			
		||||
    scrollLineToScreenLocation(((IjVimEditor)editor).getEditor(), ScreenLocation.BOTTOM, rawCount, start);
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public boolean scrollCaretColumnToDisplayLeftEdge(@NotNull VimEditor vimEditor) {
 | 
			
		||||
  public boolean scrollCaretColumnToFirstScreenColumn(@NotNull VimEditor vimEditor) {
 | 
			
		||||
    Editor editor = ((IjVimEditor)vimEditor).getEditor();
 | 
			
		||||
    final VisualPosition caretVisualPosition = editor.getCaretModel().getVisualPosition();
 | 
			
		||||
    final int scrollOffset = getNormalizedSideScrollOffset(editor);
 | 
			
		||||
@@ -347,13 +552,13 @@ public class MotionGroup extends VimMotionGroupBase {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public boolean scrollCaretColumnToDisplayRightEdge(@NotNull VimEditor editor) {
 | 
			
		||||
  public boolean scrollCaretColumnToLastScreenColumn(@NotNull VimEditor editor) {
 | 
			
		||||
    Editor ijEditor = ((IjVimEditor)editor).getEditor();
 | 
			
		||||
    final VisualPosition caretVisualPosition = ijEditor.getCaretModel().getVisualPosition();
 | 
			
		||||
    final int scrollOffset = getNormalizedSideScrollOffset(ijEditor);
 | 
			
		||||
    // TODO: Should the offset be applied to visual columns? This includes inline inlays and folds
 | 
			
		||||
    final int column =
 | 
			
		||||
      EngineEditorHelperKt.normalizeVisualColumn(editor, caretVisualPosition.line, caretVisualPosition.column + scrollOffset, false);
 | 
			
		||||
      normalizeVisualColumn(ijEditor, caretVisualPosition.line, caretVisualPosition.column + scrollOffset, false);
 | 
			
		||||
    scrollColumnToRightOfScreen(ijEditor, caretVisualPosition.line, column);
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
@@ -381,8 +586,7 @@ public class MotionGroup extends VimMotionGroupBase {
 | 
			
		||||
 | 
			
		||||
    final int topLine = getVisualLineAtTopOfScreen(editor);
 | 
			
		||||
    final int bottomLine = getVisualLineAtBottomOfScreen(editor);
 | 
			
		||||
    @NotNull final VimEditor editor2 = new IjVimEditor(editor);
 | 
			
		||||
    final int lastLine = EngineEditorHelperKt.getVisualLineCount(editor2) - 1;
 | 
			
		||||
    final int lastLine = EditorHelper.getVisualLineCount(new IjVimEditor(editor)) - 1;
 | 
			
		||||
 | 
			
		||||
    // We need the non-normalised value here, so we can handle cases such as so=999 to keep the current line centred
 | 
			
		||||
    final int scrollOffset = ((VimInt) VimPlugin.getOptionService().getOptionValue(new OptionScope.LOCAL(new IjVimEditor(editor)), OptionConstants.scrolloffName, OptionConstants.scrolloffName)).getValue();
 | 
			
		||||
@@ -458,8 +662,7 @@ public class MotionGroup extends VimMotionGroupBase {
 | 
			
		||||
        // the line heights of the lines above and below caretLine (up to scrolloff or end of file).
 | 
			
		||||
        // Our implementation ignores soft wrap line heights. Folds already have a line height of 1.
 | 
			
		||||
        final int usedAbove = caretLine - newTopLine;
 | 
			
		||||
        @NotNull final VimEditor editor1 = new IjVimEditor(editor);
 | 
			
		||||
        final int usedBelow = min(scrollOffset, EngineEditorHelperKt.getVisualLineCount(editor1) - caretLine);
 | 
			
		||||
        final int usedBelow = min(scrollOffset, getVisualLineCount(new IjVimEditor(editor)) - caretLine);
 | 
			
		||||
        final int used = 1 + usedAbove + usedBelow;
 | 
			
		||||
        if (used > height) {
 | 
			
		||||
          scrollVisualLineToMiddleOfScreen(editor, caretLine, false);
 | 
			
		||||
@@ -493,8 +696,7 @@ public class MotionGroup extends VimMotionGroupBase {
 | 
			
		||||
        // The minus one is for the current line
 | 
			
		||||
        //noinspection UnnecessaryLocalVariable
 | 
			
		||||
        final int usedAbove = scrolledAbove;
 | 
			
		||||
        @NotNull final VimEditor editor1 = new IjVimEditor(editor);
 | 
			
		||||
        final int usedBelow = min(EngineEditorHelperKt.getVisualLineCount(editor1) - caretLine, usedAbove - 1);
 | 
			
		||||
        final int usedBelow = min(getVisualLineCount(new IjVimEditor(editor)) - caretLine, usedAbove - 1);
 | 
			
		||||
        final int used = min(height + 1, usedAbove + usedBelow);
 | 
			
		||||
 | 
			
		||||
        // If we've expanded more than a screen full, redraw with the cursor in the middle of the screen. If we're going
 | 
			
		||||
@@ -529,8 +731,8 @@ public class MotionGroup extends VimMotionGroupBase {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private static void scrollCaretIntoViewHorizontally(@NotNull Editor editor, @NotNull VisualPosition position) {
 | 
			
		||||
    final int currentVisualLeftColumn = getVisualColumnAtLeftOfDisplay(editor, position.line);
 | 
			
		||||
    final int currentVisualRightColumn = getVisualColumnAtRightOfDisplay(editor, position.line);
 | 
			
		||||
    final int currentVisualLeftColumn = getVisualColumnAtLeftOfScreen(editor, position.line);
 | 
			
		||||
    final int currentVisualRightColumn = getVisualColumnAtRightOfScreen(editor, position.line);
 | 
			
		||||
    final int caretColumn = position.column;
 | 
			
		||||
 | 
			
		||||
    final int halfWidth = getApproximateScreenWidth(editor) / 2;
 | 
			
		||||
@@ -557,7 +759,7 @@ public class MotionGroup extends VimMotionGroupBase {
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
          scrollColumnToRightOfScreen(editor, position.line,
 | 
			
		||||
                                      EngineEditorHelperKt.normalizeVisualColumn(new IjVimEditor(editor), position.line, currentVisualRightColumn + diff,
 | 
			
		||||
                                      normalizeVisualColumn(editor, position.line, currentVisualRightColumn + diff,
 | 
			
		||||
                                                            false));
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
@@ -565,31 +767,31 @@ public class MotionGroup extends VimMotionGroupBase {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public int moveCaretToFirstDisplayLine(@NotNull VimEditor editor,
 | 
			
		||||
                                         @NotNull ImmutableVimCaret caret,
 | 
			
		||||
                                         int count,
 | 
			
		||||
                                         boolean normalizeToScreen) {
 | 
			
		||||
  public int moveCaretToFirstScreenLine(@NotNull VimEditor editor,
 | 
			
		||||
                                        @NotNull VimCaret caret,
 | 
			
		||||
                                        int count,
 | 
			
		||||
                                        boolean normalizeToScreen) {
 | 
			
		||||
    return moveCaretToScreenLocation(((IjVimEditor)editor).getEditor(), ((IjVimCaret)caret).getCaret(),
 | 
			
		||||
                                     ScreenLocation.TOP, count - 1, normalizeToScreen);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public int moveCaretToLastDisplayLine(@NotNull VimEditor editor,
 | 
			
		||||
                                        @NotNull ImmutableVimCaret caret,
 | 
			
		||||
                                        int count,
 | 
			
		||||
                                        boolean normalizeToScreen) {
 | 
			
		||||
  public int moveCaretToLastScreenLine(@NotNull VimEditor editor,
 | 
			
		||||
                                       @NotNull VimCaret caret,
 | 
			
		||||
                                       int count,
 | 
			
		||||
                                       boolean normalizeToScreen) {
 | 
			
		||||
    return moveCaretToScreenLocation(((IjVimEditor)editor).getEditor(), ((IjVimCaret)caret).getCaret(),
 | 
			
		||||
                                     ScreenLocation.BOTTOM, count - 1, normalizeToScreen);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public int moveCaretToMiddleDisplayLine(@NotNull VimEditor editor, @NotNull ImmutableVimCaret caret) {
 | 
			
		||||
  public int moveCaretToMiddleScreenLine(@NotNull VimEditor editor, @NotNull VimCaret caret) {
 | 
			
		||||
    return moveCaretToScreenLocation(((IjVimEditor)editor).getEditor(), ((IjVimCaret)caret).getCaret(),
 | 
			
		||||
                                     ScreenLocation.MIDDLE, 0, false);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public boolean scrollLines(@NotNull VimEditor editor, int lines) {
 | 
			
		||||
  public boolean scrollLine(@NotNull VimEditor editor, int lines) {
 | 
			
		||||
    assert lines != 0 : "lines cannot be 0";
 | 
			
		||||
    Editor ijEditor = ((IjVimEditor)editor).getEditor();
 | 
			
		||||
 | 
			
		||||
@@ -612,10 +814,10 @@ public class MotionGroup extends VimMotionGroupBase {
 | 
			
		||||
    final Mark mark = VimPlugin.getMark().getFileMark(editor, ch);
 | 
			
		||||
    if (mark == null) return -1;
 | 
			
		||||
 | 
			
		||||
    final int line = mark.getLine();
 | 
			
		||||
    final int line = mark.getLogicalLine();
 | 
			
		||||
    return toLineStart
 | 
			
		||||
           ? moveCaretToLineStartSkipLeading(editor, line)
 | 
			
		||||
           : editor.bufferPositionToOffset(new BufferPosition(line, mark.getCol(), false));
 | 
			
		||||
           : editor.logicalPositionToOffset(new VimLogicalPosition(line, mark.getCol(), false));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
@@ -626,20 +828,20 @@ public class MotionGroup extends VimMotionGroupBase {
 | 
			
		||||
    final VirtualFile vf = getVirtualFile(((IjVimEditor)editor).getEditor());
 | 
			
		||||
    if (vf == null) return -1;
 | 
			
		||||
 | 
			
		||||
    final int line = mark.getLine();
 | 
			
		||||
    final int line = mark.getLogicalLine();
 | 
			
		||||
    if (vf.getPath().equals(mark.getFilename())) {
 | 
			
		||||
      return toLineStart
 | 
			
		||||
             ? moveCaretToLineStartSkipLeading(editor, line)
 | 
			
		||||
             : editor.bufferPositionToOffset(new BufferPosition(line, mark.getCol(), false));
 | 
			
		||||
             : editor.logicalPositionToOffset(new VimLogicalPosition(line, mark.getCol(), false));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    final Editor selectedEditor = selectEditor(((IjVimEditor)editor).getEditor(), mark);
 | 
			
		||||
    if (selectedEditor != null) {
 | 
			
		||||
      for (Caret caret : selectedEditor.getCaretModel().getAllCarets()) {
 | 
			
		||||
        new IjVimCaret(caret).moveToOffset(toLineStart
 | 
			
		||||
                                           ? moveCaretToLineStartSkipLeading(new IjVimEditor(selectedEditor), line)
 | 
			
		||||
                                           : selectedEditor.logicalPositionToOffset(
 | 
			
		||||
                                             new LogicalPosition(line, mark.getCol())));
 | 
			
		||||
        moveCaret(selectedEditor, caret, toLineStart
 | 
			
		||||
                                         ? moveCaretToLineStartSkipLeading(new IjVimEditor(selectedEditor), line)
 | 
			
		||||
                                         : selectedEditor.logicalPositionToOffset(
 | 
			
		||||
                                           new LogicalPosition(line, mark.getCol())));
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return -2;
 | 
			
		||||
@@ -659,8 +861,8 @@ public class MotionGroup extends VimMotionGroupBase {
 | 
			
		||||
      return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    final BufferPosition lp = new BufferPosition(jump.getLine(), jump.getCol(), false);
 | 
			
		||||
    final LogicalPosition lpnative = new LogicalPosition(jump.getLine(), jump.getCol(), false);
 | 
			
		||||
    final VimLogicalPosition lp = new VimLogicalPosition(jump.getLogicalLine(), jump.getCol(), false);
 | 
			
		||||
    final LogicalPosition lpnative = new LogicalPosition(jump.getLogicalLine(), jump.getCol(), false);
 | 
			
		||||
    final String fileName = jump.getFilepath();
 | 
			
		||||
    if (!vf.getPath().equals(fileName)) {
 | 
			
		||||
      final VirtualFile newFile =
 | 
			
		||||
@@ -674,9 +876,8 @@ public class MotionGroup extends VimMotionGroupBase {
 | 
			
		||||
        if (spot == -1) {
 | 
			
		||||
          VimPlugin.getMark().addJump(editor, false);
 | 
			
		||||
        }
 | 
			
		||||
        new IjVimCaret(newEditor.getCaretModel().getCurrentCaret()).moveToOffset(
 | 
			
		||||
          EngineEditorHelperKt.normalizeOffset(new IjVimEditor(newEditor), newEditor.logicalPositionToOffset(lpnative),
 | 
			
		||||
                                               false));
 | 
			
		||||
        moveCaret(newEditor, newEditor.getCaretModel().getCurrentCaret(),
 | 
			
		||||
                  normalizeOffset(newEditor, newEditor.logicalPositionToOffset(lpnative), false));
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return -2;
 | 
			
		||||
@@ -686,29 +887,38 @@ public class MotionGroup extends VimMotionGroupBase {
 | 
			
		||||
        VimPlugin.getMark().addJump(editor, false);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return editor.bufferPositionToOffset(lp);
 | 
			
		||||
      return editor.logicalPositionToOffset(lp);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public @NotNull Motion moveCaretToCurrentDisplayLineMiddle(@NotNull VimEditor editor, @NotNull ImmutableVimCaret caret) {
 | 
			
		||||
  public @NotNull Motion moveCaretToMiddleColumn(@NotNull VimEditor editor, @NotNull VimCaret caret) {
 | 
			
		||||
    final int width = getApproximateScreenWidth(((IjVimEditor)editor).getEditor()) / 2;
 | 
			
		||||
    final int len = EngineEditorHelperKt.lineLength(editor, editor.currentCaret().getBufferPosition().getLine());
 | 
			
		||||
    final int len = getLineLength(((IjVimEditor)editor).getEditor());
 | 
			
		||||
 | 
			
		||||
    return moveCaretToColumn(editor, caret, max(0, min(len - 1, width)), false);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public Motion moveCaretToColumn(@NotNull VimEditor editor, @NotNull ImmutableVimCaret caret, int count, boolean allowEnd) {
 | 
			
		||||
    final int line = caret.getLine().getLine();
 | 
			
		||||
    final int column = EngineEditorHelperKt.normalizeColumn(editor, line, count, allowEnd);
 | 
			
		||||
    final int offset = editor.bufferPositionToOffset(new BufferPosition(line, column, false));
 | 
			
		||||
    if (column != count) {
 | 
			
		||||
      return new Motion.AdjustedOffset(offset, count);
 | 
			
		||||
    }
 | 
			
		||||
    return new Motion.AbsoluteOffset(offset);
 | 
			
		||||
  public Motion moveCaretToColumn(@NotNull VimEditor editor, @NotNull VimCaret caret, int count, boolean allowEnd) {
 | 
			
		||||
    int line = caret.getLine().getLine();
 | 
			
		||||
    int pos = normalizeColumn(((IjVimEditor)editor).getEditor(), line, count, allowEnd);
 | 
			
		||||
 | 
			
		||||
    return new Motion.AbsoluteOffset(editor.logicalPositionToOffset(new VimLogicalPosition(line, pos, false)));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public @Range(from = 0, to = Integer.MAX_VALUE) int moveCaretToLineStartSkipLeading(@NotNull VimEditor editor,
 | 
			
		||||
                                                                                      int line) {
 | 
			
		||||
    return getLeadingCharacterOffset(((IjVimEditor)editor).getEditor(), line);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public int moveCaretToLineEnd(@NotNull VimEditor editor, @NotNull VimCaret caret) {
 | 
			
		||||
    final VisualPosition visualPosition = ((IjVimCaret) caret).getCaret().getVisualPosition();
 | 
			
		||||
    final int lastVisualLineColumn = EditorUtil.getLastVisualLineColumnNumber(((IjVimEditor) editor).getEditor(), visualPosition.line);
 | 
			
		||||
    final VisualPosition visualEndOfLine = new VisualPosition(visualPosition.line, lastVisualLineColumn, true);
 | 
			
		||||
    return moveCaretToLineEnd(editor, ((IjVimEditor) editor).getEditor().visualToLogicalPosition(visualEndOfLine).line, true);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public boolean scrollColumns(@NotNull VimEditor editor, int columns) {
 | 
			
		||||
@@ -716,8 +926,8 @@ public class MotionGroup extends VimMotionGroupBase {
 | 
			
		||||
    final VisualPosition caretVisualPosition = ijEditor.getCaretModel().getVisualPosition();
 | 
			
		||||
    if (columns > 0) {
 | 
			
		||||
      // TODO: Don't add columns to visual position. This includes inlays and folds
 | 
			
		||||
      int visualColumn = EngineEditorHelperKt.normalizeVisualColumn(editor, caretVisualPosition.line,
 | 
			
		||||
                                               getVisualColumnAtLeftOfDisplay(ijEditor, caretVisualPosition.line) +
 | 
			
		||||
      int visualColumn = normalizeVisualColumn(ijEditor, caretVisualPosition.line,
 | 
			
		||||
                                               getVisualColumnAtLeftOfScreen(ijEditor, caretVisualPosition.line) +
 | 
			
		||||
                                               columns, false);
 | 
			
		||||
 | 
			
		||||
      // If the target column has an inlay preceding it, move passed it. This inlay will have been (incorrectly)
 | 
			
		||||
@@ -734,7 +944,7 @@ public class MotionGroup extends VimMotionGroupBase {
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
      // Don't normalise the rightmost column, or we break virtual space
 | 
			
		||||
      final int visualColumn = getVisualColumnAtRightOfDisplay(ijEditor, caretVisualPosition.line) + columns;
 | 
			
		||||
      final int visualColumn = getVisualColumnAtRightOfScreen(ijEditor, caretVisualPosition.line) + columns;
 | 
			
		||||
      scrollColumnToRightOfScreen(ijEditor, caretVisualPosition.line, visualColumn);
 | 
			
		||||
    }
 | 
			
		||||
    moveCaretToView(ijEditor);
 | 
			
		||||
@@ -742,26 +952,26 @@ public class MotionGroup extends VimMotionGroupBase {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public @NotNull Motion moveCaretToCurrentDisplayLineStart(@NotNull VimEditor editor, ImmutableVimCaret caret) {
 | 
			
		||||
  public @NotNull Motion moveCaretToLineScreenStart(@NotNull VimEditor editor, @NotNull VimCaret caret) {
 | 
			
		||||
    final int col =
 | 
			
		||||
      getVisualColumnAtLeftOfDisplay(((IjVimEditor)editor).getEditor(), caret.getVisualPosition().getLine());
 | 
			
		||||
      getVisualColumnAtLeftOfScreen(((IjVimEditor)editor).getEditor(), caret.getVisualPosition().getLine());
 | 
			
		||||
    return moveCaretToColumn(editor, caret, col, false);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public @Range(from = 0, to = Integer.MAX_VALUE) int moveCaretToCurrentDisplayLineStartSkipLeading(@NotNull VimEditor editor,
 | 
			
		||||
                                                                                                    ImmutableVimCaret caret) {
 | 
			
		||||
    final int col = getVisualColumnAtLeftOfDisplay(((IjVimEditor)editor).getEditor(), caret.getVisualPosition().getLine());
 | 
			
		||||
  public @Range(from = 0, to = Integer.MAX_VALUE) int moveCaretToLineScreenStartSkipLeading(@NotNull VimEditor editor,
 | 
			
		||||
                                                                                            @NotNull VimCaret caret) {
 | 
			
		||||
    final int col = getVisualColumnAtLeftOfScreen(((IjVimEditor)editor).getEditor(), caret.getVisualPosition().getLine());
 | 
			
		||||
    final int logicalLine = caret.getLine().getLine();
 | 
			
		||||
    return EngineEditorHelperKt.getLeadingCharacterOffset(editor, logicalLine, col);
 | 
			
		||||
    return getLeadingCharacterOffset(((IjVimEditor)editor).getEditor(), logicalLine, col);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public @NotNull Motion moveCaretToCurrentDisplayLineEnd(@NotNull VimEditor editor,
 | 
			
		||||
                                                          ImmutableVimCaret caret,
 | 
			
		||||
                                                          boolean allowEnd) {
 | 
			
		||||
  public @NotNull Motion moveCaretToLineScreenEnd(@NotNull VimEditor editor,
 | 
			
		||||
                                                  @NotNull VimCaret caret,
 | 
			
		||||
                                                  boolean allowEnd) {
 | 
			
		||||
    final int col =
 | 
			
		||||
      getVisualColumnAtRightOfDisplay(((IjVimEditor)editor).getEditor(), caret.getVisualPosition().getLine());
 | 
			
		||||
      getVisualColumnAtRightOfScreen(((IjVimEditor)editor).getEditor(), caret.getVisualPosition().getLine());
 | 
			
		||||
    return moveCaretToColumn(editor, caret, col, allowEnd);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -775,14 +985,13 @@ public class MotionGroup extends VimMotionGroupBase {
 | 
			
		||||
    final int topVisualLine = getVisualLineAtTopOfScreen(ijEditor);
 | 
			
		||||
    int caretVisualLine = result.getSecond();
 | 
			
		||||
    if (caretVisualLine < topVisualLine + scrollOffset) {
 | 
			
		||||
      caretVisualLine =
 | 
			
		||||
        EngineEditorHelperKt.normalizeVisualLine(new IjVimEditor(ijEditor), caretVisualLine + scrollOffset);
 | 
			
		||||
      caretVisualLine = normalizeVisualLine(ijEditor, caretVisualLine + scrollOffset);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (caretVisualLine != ijCaret.getVisualPosition().line) {
 | 
			
		||||
      final int offset =
 | 
			
		||||
        moveCaretToLineWithStartOfLineOption(editor, EngineEditorHelperKt.visualLineToBufferLine(editor, caretVisualLine), caret);
 | 
			
		||||
      caret.moveToOffset(offset);
 | 
			
		||||
        moveCaretToLineWithStartOfLineOption(editor, visualLineToLogicalLine(ijEditor, caretVisualLine), caret);
 | 
			
		||||
      moveCaret(ijEditor, ijCaret, offset);
 | 
			
		||||
      return result.getFirst();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -799,14 +1008,13 @@ public class MotionGroup extends VimMotionGroupBase {
 | 
			
		||||
    final int bottomVisualLine = getVisualLineAtBottomOfScreen(ijEditor);
 | 
			
		||||
    int caretVisualLine = result.getSecond();
 | 
			
		||||
    if (caretVisualLine > bottomVisualLine - scrollOffset) {
 | 
			
		||||
      caretVisualLine =
 | 
			
		||||
        EngineEditorHelperKt.normalizeVisualLine(new IjVimEditor(ijEditor), caretVisualLine - scrollOffset);
 | 
			
		||||
      caretVisualLine = normalizeVisualLine(ijEditor, caretVisualLine - scrollOffset);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (caretVisualLine != ijCaret.getVisualPosition().line && caretVisualLine != -1) {
 | 
			
		||||
      final int offset =
 | 
			
		||||
        moveCaretToLineWithStartOfLineOption(editor, EngineEditorHelperKt.visualLineToBufferLine(editor, caretVisualLine), caret);
 | 
			
		||||
      caret.moveToOffset(offset);
 | 
			
		||||
        moveCaretToLineWithStartOfLineOption(editor, visualLineToLogicalLine(ijEditor, caretVisualLine), caret);
 | 
			
		||||
      moveCaret(ijEditor, ijCaret, offset);
 | 
			
		||||
      return result.getFirst();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -814,12 +1022,12 @@ public class MotionGroup extends VimMotionGroupBase {
 | 
			
		||||
    // lines of the file and virtual space. Vim normally scrolls window height minus two, but when the caret is on last
 | 
			
		||||
    // line minus one, this becomes window height minus one, meaning the top line of the current page becomes the bottom
 | 
			
		||||
    // line of the new page, and the caret doesn't move. Make sure we don't beep in this scenario.
 | 
			
		||||
    return caretVisualLine == EngineEditorHelperKt.getVisualLineCount(editor) - 2;
 | 
			
		||||
    return caretVisualLine == EditorHelper.getVisualLineCount(editor) - 2;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public @Range(from = 0, to = Integer.MAX_VALUE) int moveCaretToLineWithSameColumn(@NotNull VimEditor editor,
 | 
			
		||||
                                                                                    int logicalLine,
 | 
			
		||||
                                                                                    @NotNull ImmutableVimCaret caret) {
 | 
			
		||||
                                                                                    @NotNull VimCaret caret) {
 | 
			
		||||
    int col = UserDataManager.getVimLastColumn(((IjVimCaret) caret).getCaret());
 | 
			
		||||
    int line = logicalLine;
 | 
			
		||||
    if (logicalLine < 0) {
 | 
			
		||||
@@ -827,35 +1035,35 @@ public class MotionGroup extends VimMotionGroupBase {
 | 
			
		||||
      col = 0;
 | 
			
		||||
    }
 | 
			
		||||
    else if (logicalLine >= editor.lineCount()) {
 | 
			
		||||
      line = EngineEditorHelperKt.normalizeLine(editor, editor.lineCount() - 1);
 | 
			
		||||
      col = EngineEditorHelperKt.lineLength(editor, line);
 | 
			
		||||
      line = normalizeLine(((IjVimEditor) editor).getEditor(), editor.lineCount() - 1);
 | 
			
		||||
      col = getLineLength(((IjVimEditor) editor).getEditor(), line);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    LogicalPosition newPos = new LogicalPosition(line, EngineEditorHelperKt.normalizeColumn(editor, line, col, false));
 | 
			
		||||
    LogicalPosition newPos = new LogicalPosition(line, normalizeColumn(((IjVimEditor) editor).getEditor(), line, col, false));
 | 
			
		||||
 | 
			
		||||
    return ((IjVimEditor) editor).getEditor().logicalPositionToOffset(newPos);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public @Range(from = 0, to = Integer.MAX_VALUE) int moveCaretToLineWithStartOfLineOption(@NotNull VimEditor editor,
 | 
			
		||||
                                                                                           int line,
 | 
			
		||||
                                                                                           @NotNull ImmutableVimCaret caret) {
 | 
			
		||||
                                                                                           int logicalLine,
 | 
			
		||||
                                                                                           @NotNull VimCaret caret) {
 | 
			
		||||
    if (VimPlugin.getOptionService().isSet(new OptionScope.LOCAL(editor), OptionConstants.startoflineName, OptionConstants.startoflineName)) {
 | 
			
		||||
      return moveCaretToLineStartSkipLeading(editor, line);
 | 
			
		||||
      return moveCaretToLineStartSkipLeading(editor, logicalLine);
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
      return moveCaretToLineWithSameColumn(editor, line, caret);
 | 
			
		||||
      return moveCaretToLineWithSameColumn(editor, logicalLine, caret);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public boolean scrollHalfPage(final @NotNull VimEditor editor, final @NotNull VimCaret caret, int rawCount, boolean down) {
 | 
			
		||||
  public boolean scrollScreen(final @NotNull VimEditor editor, final @NotNull VimCaret caret, int rawCount, boolean down) {
 | 
			
		||||
    Editor ijEditor = ((IjVimEditor)editor).getEditor();
 | 
			
		||||
    Caret ijCaret = ((IjVimCaret)caret).getCaret();
 | 
			
		||||
    final CaretModel caretModel = ijEditor.getCaretModel();
 | 
			
		||||
    final int currentLogicalLine = caretModel.getLogicalPosition().line;
 | 
			
		||||
 | 
			
		||||
    if ((!down && currentLogicalLine <= 0) || (down && currentLogicalLine >= editor.lineCount() - 1)) {
 | 
			
		||||
    if ((!down && currentLogicalLine <= 0) || (down && currentLogicalLine >= getLineCount(ijEditor) - 1)) {
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -895,9 +1103,9 @@ public class MotionGroup extends VimMotionGroupBase {
 | 
			
		||||
      targetCaretVisualLine = max(visualTop, min(visualBottom, targetCaretVisualLine));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    int logicalLine = EngineEditorHelperKt.visualLineToBufferLine(editor, targetCaretVisualLine);
 | 
			
		||||
    int logicalLine = visualLineToLogicalLine(ijEditor, targetCaretVisualLine);
 | 
			
		||||
    int caretOffset = moveCaretToLineWithStartOfLineOption(editor, logicalLine, caret);
 | 
			
		||||
    caret.moveToOffset(caretOffset);
 | 
			
		||||
    moveCaret(ijEditor, ijCaret, caretOffset);
 | 
			
		||||
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
@@ -910,14 +1118,9 @@ public class MotionGroup extends VimMotionGroupBase {
 | 
			
		||||
                                          boolean start) {
 | 
			
		||||
    final int scrollOffset = getNormalizedScrollOffset(editor);
 | 
			
		||||
 | 
			
		||||
    int visualLine;
 | 
			
		||||
    if (rawCount == 0) {
 | 
			
		||||
      visualLine = editor.getCaretModel().getVisualPosition().line;
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
      final int line = EngineEditorHelperKt.normalizeLine(new IjVimEditor(editor), rawCount - 1);
 | 
			
		||||
      visualLine = new IjVimEditor(editor).bufferLineToVisualLine(line);
 | 
			
		||||
    }
 | 
			
		||||
    int visualLine = rawCount == 0
 | 
			
		||||
                     ? editor.getCaretModel().getVisualPosition().line
 | 
			
		||||
                     : logicalLineToVisualLine(editor, normalizeLine(editor, rawCount - 1));
 | 
			
		||||
 | 
			
		||||
    // This method moves the current (or [count]) line to the specified screen location
 | 
			
		||||
    // Scroll offset is applicable, but scroll jump isn't. Offset is applied to screen lines (visual lines)
 | 
			
		||||
@@ -930,24 +1133,22 @@ public class MotionGroup extends VimMotionGroupBase {
 | 
			
		||||
        break;
 | 
			
		||||
      case BOTTOM:
 | 
			
		||||
        // Make sure we scroll to an actual line, not virtual space
 | 
			
		||||
        scrollVisualLineToBottomOfScreen(editor, EngineEditorHelperKt.normalizeVisualLine(new IjVimEditor(editor),
 | 
			
		||||
                                                                                          visualLine + scrollOffset));
 | 
			
		||||
        scrollVisualLineToBottomOfScreen(editor, normalizeVisualLine(editor, visualLine + scrollOffset));
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (visualLine != editor.getCaretModel().getVisualPosition().line || start) {
 | 
			
		||||
      int offset;
 | 
			
		||||
      if (start) {
 | 
			
		||||
        offset = moveCaretToLineStartSkipLeading(new IjVimEditor(editor), EngineEditorHelperKt.visualLineToBufferLine(
 | 
			
		||||
          new IjVimEditor(editor), visualLine));
 | 
			
		||||
        offset = moveCaretToLineStartSkipLeading(new IjVimEditor(editor), visualLineToLogicalLine(editor, visualLine));
 | 
			
		||||
      }
 | 
			
		||||
      else {
 | 
			
		||||
        offset = moveCaretToLineWithSameColumn(new IjVimEditor(editor),
 | 
			
		||||
                                               EngineEditorHelperKt.visualLineToBufferLine(new IjVimEditor(editor), visualLine),
 | 
			
		||||
                                               new IjVimCaret(editor.getCaretModel().getPrimaryCaret()));
 | 
			
		||||
        offset = getVerticalMotionOffset(new IjVimEditor(editor), new IjVimCaret(editor.getCaretModel().getPrimaryCaret()),
 | 
			
		||||
                                   visualLineToLogicalLine(editor, visualLine) -
 | 
			
		||||
                                   editor.getCaretModel().getLogicalPosition().line);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      new IjVimCaret(editor.getCaretModel().getPrimaryCaret()).moveToOffset(offset);
 | 
			
		||||
      moveCaret(editor, editor.getCaretModel().getPrimaryCaret(), offset);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -993,10 +1194,10 @@ public class MotionGroup extends VimMotionGroupBase {
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public @Range(from = 0, to = Integer.MAX_VALUE) int moveCaretToLinePercent(@NotNull VimEditor editor,
 | 
			
		||||
                                                                             @NotNull ImmutableVimCaret caret,
 | 
			
		||||
                                                                             @NotNull VimCaret caret,
 | 
			
		||||
                                                                             int count) {
 | 
			
		||||
    return moveCaretToLineWithStartOfLineOption(editor,
 | 
			
		||||
                                                EngineEditorHelperKt.normalizeLine(editor,
 | 
			
		||||
                                                normalizeLine(((IjVimEditor)editor).getEditor(),
 | 
			
		||||
                                                              (editor.lineCount() * MathUtil.clamp(count, 0, 100) +
 | 
			
		||||
                                                               99) / 100 - 1), caret);
 | 
			
		||||
  }
 | 
			
		||||
@@ -1012,7 +1213,7 @@ public class MotionGroup extends VimMotionGroupBase {
 | 
			
		||||
      final Editor editor = ((TextEditor)fileEditor).getEditor();
 | 
			
		||||
      ExOutputModel.getInstance(editor).clear();
 | 
			
		||||
      if (VimStateMachine.getInstance(new IjVimEditor(editor)).getMode() == VimStateMachine.Mode.VISUAL) {
 | 
			
		||||
        EngineModeExtensionsKt.exitVisualMode(new IjVimEditor(editor));
 | 
			
		||||
        ModeHelper.exitVisualMode(editor);
 | 
			
		||||
        KeyHandler.getInstance().reset(new IjVimEditor(editor));
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
@@ -1031,8 +1232,7 @@ public class MotionGroup extends VimMotionGroupBase {
 | 
			
		||||
 | 
			
		||||
    final int scrollOffset = normalizeToScreen ? getNormalizedScrollOffset(editor) : 0;
 | 
			
		||||
 | 
			
		||||
    @NotNull final VimEditor editor1 = new IjVimEditor(editor);
 | 
			
		||||
    final int maxVisualLine = EngineEditorHelperKt.getVisualLineCount(editor1);
 | 
			
		||||
    final int maxVisualLine = getVisualLineCount(new IjVimEditor(editor));
 | 
			
		||||
 | 
			
		||||
    final int topVisualLine = getVisualLineAtTopOfScreen(editor);
 | 
			
		||||
    final int topScrollOff = topVisualLine > 0 ? scrollOffset : 0;
 | 
			
		||||
@@ -1056,7 +1256,7 @@ public class MotionGroup extends VimMotionGroupBase {
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    final int targetLogicalLine = EngineEditorHelperKt.visualLineToBufferLine(new IjVimEditor(editor), targetVisualLine);
 | 
			
		||||
    final int targetLogicalLine = visualLineToLogicalLine(editor, targetVisualLine);
 | 
			
		||||
    return moveCaretToLineWithStartOfLineOption(new IjVimEditor(editor), targetLogicalLine, new IjVimCaret(caret));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,19 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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.group
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,19 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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.group;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,19 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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.group;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,19 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2003-2022 The IdeaVim authors
 | 
			
		||||
 * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
 | 
			
		||||
 * Copyright (C) 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.
 | 
			
		||||
 * 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.group;
 | 
			
		||||
 | 
			
		||||
@@ -62,6 +72,7 @@ import java.text.NumberFormat;
 | 
			
		||||
import java.text.ParsePosition;
 | 
			
		||||
import java.util.*;
 | 
			
		||||
 | 
			
		||||
import static com.maddyhome.idea.vim.api.VimInjectorKt.injector;
 | 
			
		||||
import static com.maddyhome.idea.vim.helper.HelperKt.localEditors;
 | 
			
		||||
import static com.maddyhome.idea.vim.helper.SearchHelperKtKt.shouldIgnoreCase;
 | 
			
		||||
import static com.maddyhome.idea.vim.register.RegisterConstants.LAST_SEARCH_REGISTER;
 | 
			
		||||
@@ -277,20 +288,20 @@ public class SearchGroup extends VimSearchGroupBase implements PersistentStateCo
 | 
			
		||||
 | 
			
		||||
        if (logger.isDebugEnabled()) logger.debug("pattern=" + pattern);
 | 
			
		||||
 | 
			
		||||
        if (p.charAt() == type) {
 | 
			
		||||
        if (p.charAt() != type) {
 | 
			
		||||
          if (end.charAt() == type) {
 | 
			
		||||
            end.inc();
 | 
			
		||||
            patternOffset = end.toString();
 | 
			
		||||
          } else {
 | 
			
		||||
            logger.debug("no offset");
 | 
			
		||||
            patternOffset = "";
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
          p.inc();
 | 
			
		||||
          patternOffset = p.toString();
 | 
			
		||||
          if (logger.isDebugEnabled()) logger.debug("offset=" + patternOffset);
 | 
			
		||||
        }
 | 
			
		||||
        if (end.charAt(0) == type) {
 | 
			
		||||
          end.inc();
 | 
			
		||||
          patternOffset = end.toString();
 | 
			
		||||
          if (logger.isDebugEnabled()) logger.debug("Pattern contains offset " + patternOffset);
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
          logger.debug("no offset");
 | 
			
		||||
          patternOffset = "";
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      else if (command.length() == 1) {
 | 
			
		||||
        patternOffset = "";
 | 
			
		||||
@@ -420,18 +431,14 @@ public class SearchGroup extends VimSearchGroupBase implements PersistentStateCo
 | 
			
		||||
   * @return        The offset of the result or the start of the word under the caret if not found. Returns -1 on error
 | 
			
		||||
   */
 | 
			
		||||
  @Override
 | 
			
		||||
  public int searchWord(@NotNull VimEditor editor, @NotNull ImmutableVimCaret caret, int count, boolean whole, @NotNull Direction dir) {
 | 
			
		||||
  public int searchWord(@NotNull VimEditor editor, @NotNull VimCaret caret, int count, boolean whole, Direction dir) {
 | 
			
		||||
    TextRange range = SearchHelper.findWordUnderCursor(((IjVimEditor)editor).getEditor(), ((IjVimCaret)caret).getCaret());
 | 
			
		||||
    if (range == null) {
 | 
			
		||||
      logger.warn("No range was found");
 | 
			
		||||
      return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @NotNull final Editor editor1 = ((IjVimEditor)editor).getEditor();
 | 
			
		||||
    final int start = range.getStartOffset();
 | 
			
		||||
    final int end = range.getEndOffset();
 | 
			
		||||
    final String pattern = SearchHelper.makeSearchPattern(
 | 
			
		||||
      EngineEditorHelperKt.getText(new IjVimEditor(editor1), start, end), whole);
 | 
			
		||||
    final String pattern = SearchHelper.makeSearchPattern(EditorHelper.getText(((IjVimEditor)editor).getEditor(), range.getStartOffset(), range.getEndOffset()), whole);
 | 
			
		||||
 | 
			
		||||
    // Updates RE_LAST, ready for findItOffset
 | 
			
		||||
    // Direction is always saved
 | 
			
		||||
@@ -461,7 +468,7 @@ public class SearchGroup extends VimSearchGroupBase implements PersistentStateCo
 | 
			
		||||
   * @return        The offset of the next match, or -1 if not found
 | 
			
		||||
   */
 | 
			
		||||
  @Override
 | 
			
		||||
  public int searchNext(@NotNull VimEditor editor, @NotNull ImmutableVimCaret caret, int count) {
 | 
			
		||||
  public int searchNext(@NotNull VimEditor editor, @NotNull VimCaret caret, int count) {
 | 
			
		||||
    return searchNextWithDirection(((IjVimEditor)editor).getEditor(), ((IjVimCaret)caret).getCaret(), count, lastDir);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -477,7 +484,7 @@ public class SearchGroup extends VimSearchGroupBase implements PersistentStateCo
 | 
			
		||||
   * @return        The offset of the next match, or -1 if not found
 | 
			
		||||
   */
 | 
			
		||||
  @Override
 | 
			
		||||
  public int searchPrevious(@NotNull VimEditor editor, @NotNull ImmutableVimCaret caret, int count) {
 | 
			
		||||
  public int searchPrevious(@NotNull VimEditor editor, @NotNull VimCaret caret, int count) {
 | 
			
		||||
    return searchNextWithDirection(((IjVimEditor)editor).getEditor(), ((IjVimCaret)caret).getCaret(), count,
 | 
			
		||||
                                   lastDir.reverse());
 | 
			
		||||
  }
 | 
			
		||||
@@ -534,7 +541,7 @@ public class SearchGroup extends VimSearchGroupBase implements PersistentStateCo
 | 
			
		||||
    // Explicitly exit visual mode here, so that visual mode marks don't change when we move the cursor to a match.
 | 
			
		||||
    List<ExException> exceptions = new ArrayList<>();
 | 
			
		||||
    if (CommandStateHelper.inVisualMode(((IjVimEditor) editor).getEditor())) {
 | 
			
		||||
      EngineModeExtensionsKt.exitVisualMode(editor);
 | 
			
		||||
      ModeHelper.exitVisualMode(((IjVimEditor) editor).getEditor());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    CharPointer cmd = new CharPointer(new StringBuffer(exarg));
 | 
			
		||||
@@ -681,7 +688,7 @@ public class SearchGroup extends VimSearchGroupBase implements PersistentStateCo
 | 
			
		||||
        return false;
 | 
			
		||||
      }
 | 
			
		||||
      line1 = line2;
 | 
			
		||||
      line2 = EngineEditorHelperKt.normalizeLine(editor, line1 + i - 1);
 | 
			
		||||
      line2 = EditorHelper.normalizeLine(((IjVimEditor) editor).getEditor(), line1 + i - 1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
@@ -751,7 +758,7 @@ public class SearchGroup extends VimSearchGroupBase implements PersistentStateCo
 | 
			
		||||
    int searchcol = 0;
 | 
			
		||||
    boolean firstMatch = true;
 | 
			
		||||
    boolean got_quit = false;
 | 
			
		||||
    int lcount = editor.lineCount();
 | 
			
		||||
    int lcount = EditorHelper.getLineCount(((IjVimEditor) editor).getEditor());
 | 
			
		||||
    Expression expression = null;
 | 
			
		||||
    for (int lnum = line1; lnum <= line2 && !got_quit; ) {
 | 
			
		||||
      CharacterPosition newpos = null;
 | 
			
		||||
@@ -810,7 +817,7 @@ public class SearchGroup extends VimSearchGroupBase implements PersistentStateCo
 | 
			
		||||
          }
 | 
			
		||||
          if (doReplace) {
 | 
			
		||||
            SubmatchFunctionHandler.INSTANCE.setLatestMatch(((IjVimEditor) editor).getEditor().getDocument().getText(new com.intellij.openapi.util.TextRange(startoff, endoff)));
 | 
			
		||||
            caret.moveToOffset(startoff);
 | 
			
		||||
            injector.getMotion().moveCaret(editor, caret, startoff);
 | 
			
		||||
            if (expression != null) {
 | 
			
		||||
              try {
 | 
			
		||||
              match = expression
 | 
			
		||||
@@ -859,8 +866,8 @@ public class SearchGroup extends VimSearchGroupBase implements PersistentStateCo
 | 
			
		||||
 | 
			
		||||
    if (!got_quit) {
 | 
			
		||||
      if (lastMatch != -1) {
 | 
			
		||||
        caret.moveToOffset(
 | 
			
		||||
          VimPlugin.getMotion().moveCaretToLineStartSkipLeading(editor, editor.offsetToBufferPosition(lastMatch).getLine()));
 | 
			
		||||
        injector.getMotion().moveCaret(editor, caret,
 | 
			
		||||
          VimPlugin.getMotion().moveCaretToLineStartSkipLeading(editor, editor.offsetToLogicalPosition(lastMatch).getLine()));
 | 
			
		||||
      }
 | 
			
		||||
      else {
 | 
			
		||||
        VimPlugin.showMessage(MessageHelper.message(Msg.e_patnotf2, pattern));
 | 
			
		||||
@@ -979,7 +986,7 @@ public class SearchGroup extends VimSearchGroupBase implements PersistentStateCo
 | 
			
		||||
      return false;
 | 
			
		||||
    };
 | 
			
		||||
    if (ApplicationManager.getApplication().isUnitTestMode()) {
 | 
			
		||||
      new IjVimCaret(caret).moveToOffset(startoff);
 | 
			
		||||
      MotionGroup.moveCaret(editor, caret, startoff);
 | 
			
		||||
      final TestInputModel inputModel = TestInputModel.getInstance(editor);
 | 
			
		||||
      for (KeyStroke key = inputModel.nextKeyStroke(); key != null; key = inputModel.nextKeyStroke()) {
 | 
			
		||||
        if (!keyStrokeProcessor.invoke(key)) {
 | 
			
		||||
@@ -991,7 +998,7 @@ public class SearchGroup extends VimSearchGroupBase implements PersistentStateCo
 | 
			
		||||
      // XXX: The Ex entry panel is used only for UI here, its logic might be inappropriate for this method
 | 
			
		||||
      final ExEntryPanel exEntryPanel = ExEntryPanel.getInstanceWithoutShortcuts();
 | 
			
		||||
      exEntryPanel.activate(editor, EditorDataContext.init(editor, null), MessageHelper.message("replace.with.0", match), "", 1);
 | 
			
		||||
      new IjVimCaret(caret).moveToOffset(startoff);
 | 
			
		||||
      MotionGroup.moveCaret(editor, caret, startoff);
 | 
			
		||||
      ModalEntry.INSTANCE.activate(new IjVimEditor(editor), keyStrokeProcessor);
 | 
			
		||||
      exEntryPanel.deactivate(true, false);
 | 
			
		||||
    }
 | 
			
		||||
@@ -1126,7 +1133,7 @@ public class SearchGroup extends VimSearchGroupBase implements PersistentStateCo
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public Integer findDecimalNumber(@NotNull String line) {
 | 
			
		||||
    Pair<TextRange, NumberType> searchResult = SearchHelper.findNumberInText(line, 0, false, false, false);
 | 
			
		||||
    Pair<TextRange, SearchHelper.NumberType> searchResult = SearchHelper.findNumberInText(line, 0, false, false, false);
 | 
			
		||||
    if (searchResult != null) {
 | 
			
		||||
      TextRange range = searchResult.component1();
 | 
			
		||||
      return Integer.parseInt(line.substring(range.getStartOffset(), range.getEndOffset()));
 | 
			
		||||
@@ -1284,7 +1291,7 @@ public class SearchGroup extends VimSearchGroupBase implements PersistentStateCo
 | 
			
		||||
 | 
			
		||||
    if (offsetIsLineOffset) {
 | 
			
		||||
      int line = editor.offsetToLogicalPosition(range.getStartOffset()).line;
 | 
			
		||||
      int newLine = EngineEditorHelperKt.normalizeLine(new IjVimEditor(editor), line + offset);
 | 
			
		||||
      int newLine = EditorHelper.normalizeLine(editor, line + offset);
 | 
			
		||||
 | 
			
		||||
      // TODO: Don't move the caret!
 | 
			
		||||
      res = VimPlugin.getMotion().moveCaretToLineStart(new IjVimEditor(editor), newLine);
 | 
			
		||||
 
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user