mirror of
				https://github.com/chylex/IntelliJ-IdeaVim.git
				synced 2025-10-31 11:17:13 +01:00 
			
		
		
		
	Compare commits
	
		
			8 Commits
		
	
	
		
			customized
			...
			9f469d0eb2
		
	
	| 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 | # 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 | # 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: | on: | ||||||
|   workflow_dispatch: |   workflow_dispatch: | ||||||
|   schedule: |  | ||||||
|     - cron: '0 5 * * *' |  | ||||||
| 
 | 
 | ||||||
| jobs: | jobs: | ||||||
|   build: |   build: | ||||||
| @@ -16,7 +14,7 @@ jobs: | |||||||
|     steps: |     steps: | ||||||
|       - uses: actions/checkout@v2 |       - uses: actions/checkout@v2 | ||||||
|         with: |         with: | ||||||
|           fetch-depth: 300 |           fetch-depth: 50 | ||||||
|       - name: Set up JDK 11 |       - name: Set up JDK 11 | ||||||
|         uses: actions/setup-java@v2 |         uses: actions/setup-java@v2 | ||||||
|         with: |         with: | ||||||
| @@ -25,8 +23,18 @@ jobs: | |||||||
|           server-id: github # Value of the distributionManagement/repository/id field of the pom.xml |           server-id: github # Value of the distributionManagement/repository/id field of the pom.xml | ||||||
|           settings-path: ${{ github.workspace }} # location for the settings.xml file |           settings-path: ${{ github.workspace }} # location for the settings.xml file | ||||||
| 
 | 
 | ||||||
|       - name: Run tests |       - name: Update authors | ||||||
|         run: ./gradlew integrationsTest |         id: update_authors | ||||||
|  |         run: ./gradlew updateMergedPr -PprId=525 | ||||||
|         env: |         env: | ||||||
|           YOUTRACK_TOKEN: ${{ secrets.YOUTRACK_TOKEN }} |  | ||||||
|           GITHUB_OAUTH: ${{ secrets.MERGE_PR }} |           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/fileTemplates | ||||||
| !/.idea/runConfigurations | !/.idea/runConfigurations | ||||||
| !/.idea/codeStyles | !/.idea/codeStyles | ||||||
| !/.idea/vcs.xml |  | ||||||
|  |  | ||||||
| **/build/ | **/build/ | ||||||
| **/out/ | **/out/ | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								.idea/copyright/IdeaVim.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2
									
								
								.idea/copyright/IdeaVim.xml
									
									
									
										generated
									
									
									
								
							| @@ -1,6 +1,6 @@ | |||||||
| <component name="CopyrightManager"> | <component name="CopyrightManager"> | ||||||
|   <copyright> |   <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" /> |     <option name="myName" value="IdeaVim" /> | ||||||
|   </copyright> |   </copyright> | ||||||
| </component> | </component> | ||||||
							
								
								
									
										14
									
								
								.idea/inspectionProfiles/Qodana.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										14
									
								
								.idea/inspectionProfiles/Qodana.xml
									
									
									
										generated
									
									
									
								
							| @@ -33,11 +33,9 @@ | |||||||
|       <option name="ignoreToString" value="false" /> |       <option name="ignoreToString" value="false" /> | ||||||
|       <option name="nonNlsCommentPattern" value="NON-NLS" /> |       <option name="nonNlsCommentPattern" value="NON-NLS" /> | ||||||
|     </inspection_tool> |     </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"> |     <inspection_tool class="MissortedModifiers" enabled="true" level="WARNING" enabled_by_default="true"> | ||||||
|       <option name="m_requireAnnotationsFirst" value="true" /> |       <option name="m_requireAnnotationsFirst" value="true" /> | ||||||
|     </inspection_tool> |     </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="SameReturnValue" enabled="false" level="WARNING" enabled_by_default="false" /> | ||||||
|     <inspection_tool class="SpellCheckingInspection" enabled="false" level="TYPO" enabled_by_default="false"> |     <inspection_tool class="SpellCheckingInspection" enabled="false" level="TYPO" enabled_by_default="false"> | ||||||
|       <option name="processCode" value="true" /> |       <option name="processCode" value="true" /> | ||||||
| @@ -46,17 +44,5 @@ | |||||||
|     </inspection_tool> |     </inspection_tool> | ||||||
|     <inspection_tool class="SuperTearDownInFinally" enabled="true" level="WARNING" enabled_by_default="true" /> |     <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="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> |   </profile> | ||||||
| </component> | </component> | ||||||
							
								
								
									
										2
									
								
								.idea/scopes/Copyright.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2
									
								
								.idea/scopes/Copyright.xml
									
									
									
										generated
									
									
									
								
							| @@ -1,3 +1,3 @@ | |||||||
| <component name="DependencyValidationManager"> | <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> | </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 EAP_CHANNEL = "eap" | ||||||
|   const val DEV_CHANNEL = "Dev" |   const val DEV_CHANNEL = "Dev" | ||||||
|  |  | ||||||
|   const val VERSION = "2.0.0" |   const val VERSION = "1.11.1" | ||||||
|   const val DEV_VERSION = "2.1.0" |   const val DEV_VERSION = "1.12.0" | ||||||
|  |  | ||||||
|   const val GITHUB_TESTS = "LATEST-EAP-SNAPSHOT" |   const val GITHUB_TESTS = "LATEST-EAP-SNAPSHOT" | ||||||
|   const val NVIM_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.GitHub | ||||||
| import _Self.subprojects.OldTests | import _Self.subprojects.OldTests | ||||||
| import _Self.subprojects.Releases | 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 | import jetbrains.buildServer.configs.kotlin.v2019_2.Project | ||||||
|  |  | ||||||
| object Project : Project({ | object Project : Project({ | ||||||
| @@ -27,12 +35,12 @@ object Project : Project({ | |||||||
|   vcsRoot(Branch_202) |   vcsRoot(Branch_202) | ||||||
|   vcsRoot(Branch_203_212) |   vcsRoot(Branch_203_212) | ||||||
|   vcsRoot(Branch_213_221) |   vcsRoot(Branch_213_221) | ||||||
|   vcsRoot(Branch_222) |  | ||||||
|   vcsRoot(Branch_Release) |   vcsRoot(Branch_Release) | ||||||
|   vcsRoot(GitHubPullRequest) |   vcsRoot(GitHubPullRequest) | ||||||
|  |  | ||||||
|   // Builds |   // Builds | ||||||
|   buildType(TestsForIntelliJEAP) |   buildType(TestsForIntelliJEAP) | ||||||
|  |   buildType(TestsForIntelliJ20222) | ||||||
|  |  | ||||||
|   buildType(PropertyBased) |   buildType(PropertyBased) | ||||||
|   buildType(LongRunning) |   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 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.TestsForIntelliJ20211 | ||||||
| import _Self.buildTypes.TestsForIntelliJ20212 | import _Self.buildTypes.TestsForIntelliJ20212 | ||||||
| import _Self.buildTypes.TestsForIntelliJ20213 | import _Self.buildTypes.TestsForIntelliJ20213 | ||||||
| import _Self.buildTypes.TestsForIntelliJ20222 |  | ||||||
| import jetbrains.buildServer.configs.kotlin.v2019_2.Project | import jetbrains.buildServer.configs.kotlin.v2019_2.Project | ||||||
|  |  | ||||||
| object OldTests : Project({ | object OldTests : Project({ | ||||||
| @@ -31,5 +30,4 @@ object OldTests : Project({ | |||||||
|   buildType(TestsForIntelliJ20211) |   buildType(TestsForIntelliJ20211) | ||||||
|   buildType(TestsForIntelliJ20212) |   buildType(TestsForIntelliJ20212) | ||||||
|   buildType(TestsForIntelliJ20213) |   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.Qodana | ||||||
| import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.gradle | 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.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.* | import jetbrains.buildServer.configs.kotlin.v2019_2.ui.* | ||||||
|  |  | ||||||
| /* | /* | ||||||
| @@ -47,8 +41,8 @@ changeBuildType(RelativeId("Qodana")) { | |||||||
|         update<Qodana>(1) { |         update<Qodana>(1) { | ||||||
|             clearConditions() |             clearConditions() | ||||||
|             reportAsTests = true |             reportAsTests = true | ||||||
|             additionalDockerArguments = "-e QODANA_TOKEN=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJvcmdhbml6YXRpb24iOiIzUFZrQSIsInByb2plY3QiOiIzN1FlQSIsInRva2VuIjoiM0t2bXoifQ.uohp81tM7iAfvvB6k8faarfpV-OjusAaEbWQ8iNrOgs" |             argumentsCommandDocker = "-e QODANA_TOKEN=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJvcmdhbml6YXRpb24iOiIzUFZrQSIsInByb2plY3QiOiIzN1FlQSIsInRva2VuIjoiM0t2bXoifQ.uohp81tM7iAfvvB6k8faarfpV-OjusAaEbWQ8iNrOgs" | ||||||
|             additionalQodanaArguments = "--baseline qodana.sarif.json" |             argumentsEntryPointDocker = "--baseline qodana.sarif.json" | ||||||
|             param("clonefinder-languages", "") |             param("clonefinder-languages", "") | ||||||
|             param("collect-anonymous-statistics", "") |             param("collect-anonymous-statistics", "") | ||||||
|             param("licenseaudit-enable", "") |             param("licenseaudit-enable", "") | ||||||
| @@ -58,44 +52,4 @@ changeBuildType(RelativeId("Qodana")) { | |||||||
|             param("clonefinder-reference-projects", "") |             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 |   Pavel Fatin | ||||||
| * [![icon][mail]](mailto:tietyt@gmail.com) | * [![icon][mail]](mailto:tietyt@gmail.com) | ||||||
|   [![icon][github-off]](https://github.com/DanKaplanSES) |   [![icon][github-off]](#) | ||||||
|     |     | ||||||
|   tieTYT |   tieTYT | ||||||
| * [![icon][mail]](mailto:nickgieschen@gmail.com) | * [![icon][mail]](mailto:nickgieschen@gmail.com) | ||||||
| @@ -185,7 +185,7 @@ Contributors: | |||||||
|     |     | ||||||
|   Vladimir Parfinenko |   Vladimir Parfinenko | ||||||
| * [![icon][mail]](mailto:hassmann@hwdev.de) | * [![icon][mail]](mailto:hassmann@hwdev.de) | ||||||
|   [![icon][github-off]](https://github.com/lumie1337) |   [![icon][github-off]](#) | ||||||
|     |     | ||||||
|   Florian Hassmann |   Florian Hassmann | ||||||
| * [![icon][mail]](mailto:jpalus@fastmail.com) | * [![icon][mail]](mailto:jpalus@fastmail.com) | ||||||
| @@ -193,7 +193,7 @@ Contributors: | |||||||
|     |     | ||||||
|   Jan Palus |   Jan Palus | ||||||
| * [![icon][mail]](mailto:kpetrov@ripe.net) | * [![icon][mail]](mailto:kpetrov@ripe.net) | ||||||
|   [![icon][github-off]](https://github.com/constpetrov) |   [![icon][github-off]](#) | ||||||
|     |     | ||||||
|   Konstantin Petrov |   Konstantin Petrov | ||||||
| * [![icon][mail]](mailto:ya-ikmik2012@yandex.ru) | * [![icon][mail]](mailto:ya-ikmik2012@yandex.ru) | ||||||
| @@ -220,6 +220,10 @@ Contributors: | |||||||
|   [![icon][github]](https://github.com/johngrib) |   [![icon][github]](https://github.com/johngrib) | ||||||
|     |     | ||||||
|   John Grib |   John Grib | ||||||
|  | * [![icon][mail]](mailto:hild@b4mad.net) | ||||||
|  |   [![icon][github-off]](#) | ||||||
|  |     | ||||||
|  |   Marcel Hild | ||||||
| * [![icon][mail]](mailto:vedranb@gmail.com) | * [![icon][mail]](mailto:vedranb@gmail.com) | ||||||
|   [![icon][github]](https://github.com/vedran) |   [![icon][github]](https://github.com/vedran) | ||||||
|     |     | ||||||
| @@ -315,6 +319,10 @@ Contributors: | |||||||
|   [![icon][github]](https://github.com/angelbot) |   [![icon][github]](https://github.com/angelbot) | ||||||
|     |     | ||||||
|   John Weigel |   John Weigel | ||||||
|  | * [![icon][mail]](mailto:kevinz@weghst.com) | ||||||
|  |   [![icon][github]](https://github.com/kevin70) | ||||||
|  |     | ||||||
|  |   kk | ||||||
| * [![icon][mail]](mailto:runforprogram@163.com) | * [![icon][mail]](mailto:runforprogram@163.com) | ||||||
|   [![icon][github]](https://github.com/runforprogram) |   [![icon][github]](https://github.com/runforprogram) | ||||||
|     |     | ||||||
| @@ -447,26 +455,6 @@ Contributors: | |||||||
|   [![icon][github]](https://github.com/lippfi) |   [![icon][github]](https://github.com/lippfi) | ||||||
|     |     | ||||||
|   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 | If you are a contributor and your name is not listed here, feel free to | ||||||
| contact the maintainers. | contact the maintainers. | ||||||
|   | |||||||
							
								
								
									
										24
									
								
								CHANGES.md
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								CHANGES.md
									
									
									
									
									
								
							| @@ -25,26 +25,6 @@ usual beta standards. | |||||||
|  |  | ||||||
| ## To Be Released | ## 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: | ### Fixes: | ||||||
| * [VIM-1758](https://youtrack.jetbrains.com/issue/VIM-1758) Commentary plugin in rider | * [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 | * [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-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-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-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 | ## 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 |                             Preamble | ||||||
| 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: |  | ||||||
|  |  | ||||||
| The above copyright notice and this permission notice shall be included in all |   The licenses for most software are designed to take away your | ||||||
| copies or substantial portions of the Software. | 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 |   When we speak of free software, we are referring to freedom, not | ||||||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | price.  Our General Public Licenses are designed to make sure that you | ||||||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | have the freedom to distribute copies of free software (and charge for | ||||||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | this service if you wish), that you receive source code or can get it | ||||||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | if you want it, that you can change the software or use pieces of it | ||||||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | in new free programs; and that you know you can do these things. | ||||||
| SOFTWARE. |  | ||||||
|  |   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] | [![Rating][plugin-rating-svg]][plugin-repo] | ||||||
| [![Version][plugin-version-svg]][plugin-repo] | [![Version][plugin-version-svg]][plugin-repo] | ||||||
| [![Gitter][gitter-svg]][gitter] | [![Gitter][gitter-svg]][gitter] | ||||||
| [](https://codecov.io/gh/JetBrains/ideavim) |  | ||||||
| [![Twitter][twitter-svg]][twitter] | [![Twitter][twitter-svg]][twitter] | ||||||
|  |  | ||||||
| IdeaVim is a Vim engine for JetBrains IDEs. | IdeaVim is a Vim engine for JetBrains IDEs. | ||||||
| @@ -365,13 +364,8 @@ is the full list of synonyms. | |||||||
| License | License | ||||||
| ------- | ------- | ||||||
|  |  | ||||||
| IdeaVim is licensed under the MIT license. | IdeaVim is licensed under the terms of the GNU Public License version 2 | ||||||
|  | or any later version. | ||||||
| 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 |  | ||||||
|  |  | ||||||
|  |  | ||||||
| <!-- Badges --> | <!-- 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 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 org.intellij.markdown.ast.getTextInNode | ||||||
| import java.net.HttpURLConnection | import java.net.HttpURLConnection | ||||||
| import java.net.URL | import java.net.URL | ||||||
| @@ -41,17 +11,11 @@ buildscript { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     dependencies { |     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("com.github.AlexPl292:mark-down-to-slack:1.1.2") | ||||||
|         classpath("org.eclipse.jgit:org.eclipse.jgit:6.1.0.202203080745-r") |         classpath("org.eclipse.jgit:org.eclipse.jgit:6.1.0.202203080745-r") | ||||||
|         classpath("org.kohsuke:github-api:1.305") |         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 |         // This comes from the changelog plugin | ||||||
| //        classpath("org.jetbrains:markdown:0.3.1") | //        classpath("org.jetbrains:markdown:0.3.1") | ||||||
|     } |     } | ||||||
| @@ -60,16 +24,13 @@ buildscript { | |||||||
| plugins { | plugins { | ||||||
|     antlr |     antlr | ||||||
|     java |     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" |     id("org.jetbrains.changelog") version "1.3.1" | ||||||
|  |  | ||||||
|     // ktlint linter - read more: https://github.com/JLLeitschuh/ktlint-gradle |     // ktlint linter - read more: https://github.com/JLLeitschuh/ktlint-gradle | ||||||
|     id("org.jlleitschuh.gradle.ktlint") version "10.3.0" |     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 | // Import variables from gradle.properties file | ||||||
| @@ -85,7 +46,6 @@ val publishChannels: String by project | |||||||
| val publishToken: String by project | val publishToken: String by project | ||||||
|  |  | ||||||
| val slackUrl: String by project | val slackUrl: String by project | ||||||
| val youtrackToken: String by project |  | ||||||
|  |  | ||||||
| repositories { | repositories { | ||||||
|     mavenCentral() |     mavenCentral() | ||||||
| @@ -214,7 +174,7 @@ java { | |||||||
|  |  | ||||||
| kotlin { | kotlin { | ||||||
|     jvmToolchain { |     jvmToolchain { | ||||||
|         languageVersion.set(JavaLanguageVersion.of(javaVersion)) |         (this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(javaVersion)) | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -272,13 +232,9 @@ tasks { | |||||||
|     named("compileKotlin") { |     named("compileKotlin") { | ||||||
|         dependsOn("generateGrammarSource") |         dependsOn("generateGrammarSource") | ||||||
|     } |     } | ||||||
|     named("compileTestKotlin") { |  | ||||||
|         dependsOn("generateTestGrammarSource") |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     // Add plugin open API sources to the plugin ZIP |     // Add plugin open API sources to the plugin ZIP | ||||||
|     val createOpenApiSourceJar by registering(Jar::class) { |     val createOpenApiSourceJar by registering(Jar::class) { | ||||||
|         dependsOn("generateGrammarSource") |  | ||||||
|         // Java sources |         // Java sources | ||||||
|         from(sourceSets.main.get().java) { |         from(sourceSets.main.get().java) { | ||||||
|             include("**/com/maddyhome/idea/vim/**/*.java") |             include("**/com/maddyhome/idea/vim/**/*.java") | ||||||
| @@ -298,7 +254,7 @@ tasks { | |||||||
|  |  | ||||||
|     // Don't forget to update plugin.xml |     // Don't forget to update plugin.xml | ||||||
|     patchPluginXml { |     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 | // --- Slack notification | ||||||
|  |  | ||||||
| tasks.register("slackNotification") { | tasks.register("slackNotification") { | ||||||
| @@ -424,7 +364,6 @@ tasks.register("updateAuthors") { | |||||||
|             "aleksei.plate@TeamCity", |             "aleksei.plate@TeamCity", | ||||||
|             "alex.plate@192.168.0.109", |             "alex.plate@192.168.0.109", | ||||||
|             "nikita.koshcheev@TeamCity", |             "nikita.koshcheev@TeamCity", | ||||||
|             "TeamCity@TeamCity", |  | ||||||
|         ) |         ) | ||||||
|         updateAuthors(uncheckedEmails) |         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") { | tasks.register("testUpdateChangelog") { | ||||||
|     group = "verification" |     group = "verification" | ||||||
|     description = "This is a task to manually assert the correctness of the update tasks" |     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() { | fun updateChangelog() { | ||||||
|     println("Start update authors") |     println("Start update authors") | ||||||
|     println(projectDir) |     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 |     // Update changes file | ||||||
|     val changesFile = File("$projectDir/CHANGES.md") |     val changesFile = File("$projectDir/CHANGES.md") | ||||||
| @@ -712,8 +460,8 @@ fun updateChangelog() { | |||||||
| fun updateAuthors(uncheckedEmails: Set<String>) { | fun updateAuthors(uncheckedEmails: Set<String>) { | ||||||
|     println("Start update authors") |     println("Start update authors") | ||||||
|     println(projectDir) |     println(projectDir) | ||||||
|     val repository = RepositoryBuilder().setGitDir(File("$projectDir/.git")).build() |     val repository = org.eclipse.jgit.lib.RepositoryBuilder().setGitDir(File("$projectDir/.git")).build() | ||||||
|     val git = Git(repository) |     val git = org.eclipse.jgit.api.Git(repository) | ||||||
|     val lastSuccessfulCommit = System.getenv("SUCCESS_COMMIT")!! |     val lastSuccessfulCommit = System.getenv("SUCCESS_COMMIT")!! | ||||||
|     val hashesAndEmailes = git.log().call() |     val hashesAndEmailes = git.log().call() | ||||||
|         .takeWhile { |         .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) | data class Change(val id: String, val text: String) | ||||||
|  |  | ||||||
| fun updateMergedPr(number: Int) { | fun updateMergedPr(number: Int) { | ||||||
|     val token = System.getenv("GITHUB_OAUTH") |     val gitHub = org.kohsuke.github.GitHub.connect() | ||||||
|     println("Token size: ${token.length}") |  | ||||||
|     val gitHub = org.kohsuke.github.GitHubBuilder().withOAuthToken(token).build() |  | ||||||
|     println("Connecting to the repo...") |     println("Connecting to the repo...") | ||||||
|     val repository = gitHub.getRepository("JetBrains/ideavim") |     val repository = gitHub.getRepository("JetBrains/ideavim") | ||||||
|     println("Getting pull requests...") |     println("Getting pull requests...") | ||||||
| @@ -886,57 +632,3 @@ val sections = listOf( | |||||||
|     "### Fixes:", |     "### Fixes:", | ||||||
|     "### Merged PRs:", |     "### 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! | Welcome to the IdeaVim wiki! | ||||||
|  |  | ||||||
| - List of IdeaVim plugins: [[plugins|IdeaVim Plugins]] | - List of emulated plugins: [[plugins|Emulated-plugins]] | ||||||
| - Examples of `ideajoin` option (also known as "smart join"): [["ideajoin" examples|ideajoin-examples]] | - Examples of `ideajoin` option (also known as "smart join"): [["ideajoin" examples|"ideajoin"-examples]] | ||||||
| - List of "set" commands: [["set" commands|set-commands]] | - List of "set" commands: [["set" commands|"set"-commands]] | ||||||
| - Docs about "select" mode in vim: [[select mode|Select-mode]] | - 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 | # 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 | ```vim | ||||||
| Plug 'preservim/nerdtree` | 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 | # suppress inspection "UnusedProperty" for whole file | ||||||
|  |  | ||||||
| ideaVersion=2022.3 | ideaVersion=2022.2.2 | ||||||
| downloadIdeaSources=true | downloadIdeaSources=true | ||||||
| instrumentPluginCode=true | instrumentPluginCode=true | ||||||
| version=chylex-14 | version=chylex-13 | ||||||
| javaVersion=17 | javaVersion=17 | ||||||
| remoteRobotVersion=0.11.15 | remoteRobotVersion=0.11.15 | ||||||
| antlrVersion=4.10.1 | antlrVersion=4.10.1 | ||||||
|  |  | ||||||
| # Please don't forget to update kotlin version in buildscript section | # Please don't forget to update kotlin version in buildscript section | ||||||
| kotlinVersion=1.7.20 | kotlinVersion=1.6.21 | ||||||
| publishToken=token | publishToken=token | ||||||
| publishChannels=eap | publishChannels=eap | ||||||
|  |  | ||||||
| slackUrl= | slackUrl= | ||||||
| youtrackToken= |  | ||||||
|  |  | ||||||
| # Gradle settings | # Gradle settings | ||||||
| org.gradle.jvmargs='-Dfile.encoding=UTF-8' | 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/JavaText.kt | ||||||
|       - src/test/java/org/jetbrains/plugins/ideavim/propertybased/samples/LoremText.kt |       - src/test/java/org/jetbrains/plugins/ideavim/propertybased/samples/LoremText.kt | ||||||
|       - src/test/java/org/jetbrains/plugins/ideavim/propertybased/samples/SimpleText.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/vimscript/parser/generated/VimscriptListener.java | ||||||
|       - src/main/java/com/maddyhome/idea/vim/package-info.java |       - src/main/java/com/maddyhome/idea/vim/vimscript/parser/generated/VimscriptLexer.java | ||||||
| dependencyIgnores: |       - src/main/java/com/maddyhome/idea/vim/vimscript/parser/generated/VimscriptParser.java | ||||||
|   - name: "acejump" |       - src/main/java/com/maddyhome/idea/vim/vimscript/parser/generated/VimscriptVisitor.java | ||||||
|   - name: "icu4j" |  | ||||||
|   - name: "antlr-runtime" |  | ||||||
|   - name: "javax.json" |  | ||||||
| @@ -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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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 | 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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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; | 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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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 | 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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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; | 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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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 | 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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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; | 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.extension.VimExtensionRegistrar; | ||||||
| import com.maddyhome.idea.vim.group.*; | import com.maddyhome.idea.vim.group.*; | ||||||
| import com.maddyhome.idea.vim.group.copy.PutGroup; | 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.group.visual.VisualMotionGroup; | ||||||
| import com.maddyhome.idea.vim.helper.MacKeyRepeat; | import com.maddyhome.idea.vim.helper.MacKeyRepeat; | ||||||
| import com.maddyhome.idea.vim.listener.VimListenerManager; | 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.IjVimOptionService; | ||||||
| import com.maddyhome.idea.vim.vimscript.services.OptionService; | import com.maddyhome.idea.vim.vimscript.services.OptionService; | ||||||
| import com.maddyhome.idea.vim.vimscript.services.VariableService; | import com.maddyhome.idea.vim.vimscript.services.VariableService; | ||||||
| import com.maddyhome.idea.vim.yank.YankGroupBase; |  | ||||||
| import org.jdom.Element; | import org.jdom.Element; | ||||||
| import org.jetbrains.annotations.Nls; | import org.jetbrains.annotations.Nls; | ||||||
| import org.jetbrains.annotations.NotNull; | import org.jetbrains.annotations.NotNull; | ||||||
| @@ -189,6 +199,10 @@ public class VimPlugin implements PersistentStateComponent<Element>, Disposable | |||||||
|     return ((WindowGroup)VimInjectorKt.getInjector().getWindow()); |     return ((WindowGroup)VimInjectorKt.getInjector().getWindow()); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   public static @NotNull TabService getTabService() { | ||||||
|  |     return ApplicationManager.getApplication().getService(TabService.class); | ||||||
|  |   } | ||||||
|  |  | ||||||
|   public static @NotNull EditorGroup getEditor() { |   public static @NotNull EditorGroup getEditor() { | ||||||
|     return ApplicationManager.getApplication().getService(EditorGroup.class); |     return ApplicationManager.getApplication().getService(EditorGroup.class); | ||||||
|   } |   } | ||||||
| @@ -201,8 +215,8 @@ public class VimPlugin implements PersistentStateComponent<Element>, Disposable | |||||||
|     return (VisualMotionGroup)VimInjectorKt.getInjector().getVisualMotionGroup(); |     return (VisualMotionGroup)VimInjectorKt.getInjector().getVisualMotionGroup(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   public static @NotNull YankGroupBase getYank() { |   public static @NotNull YankGroup getYank() { | ||||||
|     return (YankGroupBase)VimInjectorKt.getInjector().getYank(); |     return (YankGroup)VimInjectorKt.getInjector().getYank(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   public static @NotNull PutGroup getPut() { |   public static @NotNull PutGroup getPut() { | ||||||
| @@ -289,8 +303,12 @@ public class VimPlugin implements PersistentStateComponent<Element>, Disposable | |||||||
|     VimInjectorKt.getInjector().getMessages().clearError(); |     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) { |   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() { |   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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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 | 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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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 | 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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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 | 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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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 | 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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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 | 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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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 | 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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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 | 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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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 | 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.options.OptionScope | ||||||
| import com.maddyhome.idea.vim.vimscript.services.IjVimOptionService | 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 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( |   override fun execute( | ||||||
|     editor: VimEditor, |     editor: VimEditor, | ||||||
| @@ -48,6 +38,17 @@ class DeleteJoinLinesAction : ChangeEditorActionHandler.ConditionalSingleExecuti | |||||||
|     operatorArguments: OperatorArguments, |     operatorArguments: OperatorArguments, | ||||||
|   ): Boolean { |   ): Boolean { | ||||||
|     if (editor.isOneLineMode()) return false |     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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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 | 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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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 | 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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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 | 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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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 | 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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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 | 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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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 | 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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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 | 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.actionSystem.DataContext | ||||||
| import com.intellij.openapi.editor.Editor | import com.intellij.openapi.editor.Editor | ||||||
| import com.intellij.openapi.editor.VisualPosition | import com.intellij.openapi.editor.VisualPosition | ||||||
| import com.maddyhome.idea.vim.api.lineLength | import com.maddyhome.idea.vim.helper.EditorHelper | ||||||
| import com.maddyhome.idea.vim.api.visualLineToBufferLine |  | ||||||
| import com.maddyhome.idea.vim.helper.VimNlsSafe | import com.maddyhome.idea.vim.helper.VimNlsSafe | ||||||
| import com.maddyhome.idea.vim.newapi.vim |  | ||||||
| import java.util.* | import java.util.* | ||||||
| import kotlin.math.max | import kotlin.math.max | ||||||
|  |  | ||||||
| @@ -30,18 +38,17 @@ class AddInlineInlaysAction : AnAction() { | |||||||
|   override fun actionPerformed(e: AnActionEvent) { |   override fun actionPerformed(e: AnActionEvent) { | ||||||
|     val dataContext = e.dataContext |     val dataContext = e.dataContext | ||||||
|     val editor = getEditor(dataContext) ?: return |     val editor = getEditor(dataContext) ?: return | ||||||
|     val vimEditor = editor.vim |  | ||||||
|     val inlayModel = editor.inlayModel |     val inlayModel = editor.inlayModel | ||||||
|     val currentVisualLine = editor.caretModel.primaryCaret.visualPosition.line |     val currentVisualLine = editor.caretModel.primaryCaret.visualPosition.line | ||||||
|     var i = random.nextInt(10) |     var i = random.nextInt(10) | ||||||
|     val lineLength = vimEditor.lineLength(vimEditor.visualLineToBufferLine(currentVisualLine)) |     val lineLength = EditorHelper.getLineLength(editor, EditorHelper.visualLineToLogicalLine(editor, currentVisualLine)) | ||||||
|     while (i < lineLength) { |     while (i < lineLength) { | ||||||
|       val relatesToPrecedingText = random.nextInt(10) > 7 |       val relatesToPrecedingText = random.nextInt(10) > 7 | ||||||
|  |  | ||||||
|       @VimNlsSafe |       @VimNlsSafe | ||||||
|       val text = "a".repeat(max(1, random.nextInt(7))) |       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 |       // We don't need a custom renderer, just use the standard parameter hint renderer | ||||||
|       inlayModel.addInlineElement( |       inlayModel.addInlineElement( | ||||||
|         offset, |         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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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 | 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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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 | package com.maddyhome.idea.vim.common | ||||||
|  |  | ||||||
| import com.intellij.openapi.editor.Editor | import com.intellij.openapi.editor.Editor | ||||||
| import com.intellij.openapi.editor.LogicalPosition | 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) { | 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 { |   companion object { | ||||||
|     fun fromOffset(editor: Editor, offset: Int): CharacterPosition { |     fun fromOffset(editor: Editor, offset: Int): CharacterPosition { | ||||||
|       // logical position "expands" tabs |       // logical position "expands" tabs | ||||||
|       val logicalPosition = editor.offsetToLogicalPosition(offset) |       val logicalPosition = editor.offsetToLogicalPosition(offset) | ||||||
|       val lineStartOffset = editor.vim.getLineStartOffset(logicalPosition.line) |       val lineStartOffset = getLineStartOffset(editor, logicalPosition.line) | ||||||
|       return CharacterPosition(logicalPosition.line, offset - lineStartOffset) |       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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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 | 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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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 | 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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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 | 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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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 | 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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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") | @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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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 | 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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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; | 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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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 | 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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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; | 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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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 | 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.KeyHandler | ||||||
| import com.maddyhome.idea.vim.VimPlugin | import com.maddyhome.idea.vim.VimPlugin | ||||||
| import com.maddyhome.idea.vim.action.change.Extension | 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.api.VimCaret | ||||||
| import com.maddyhome.idea.vim.command.MappingMode | import com.maddyhome.idea.vim.command.MappingMode | ||||||
| import com.maddyhome.idea.vim.command.SelectionType | import com.maddyhome.idea.vim.command.SelectionType | ||||||
| @@ -189,7 +198,7 @@ object VimExtensionFacade { | |||||||
|  |  | ||||||
|   /** Set the current contents of the given register */ |   /** Set the current contents of the given register */ | ||||||
|   @JvmStatic |   @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()) |     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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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 | 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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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 | 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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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; | package com.maddyhome.idea.vim.extension.argtextobj; | ||||||
|  |  | ||||||
|  | import com.intellij.openapi.editor.Caret; | ||||||
| import com.intellij.openapi.editor.Document; | import com.intellij.openapi.editor.Document; | ||||||
| import com.maddyhome.idea.vim.VimPlugin; | import com.maddyhome.idea.vim.VimPlugin; | ||||||
| import com.maddyhome.idea.vim.api.*; | import com.maddyhome.idea.vim.api.*; | ||||||
| import com.maddyhome.idea.vim.command.*; | 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.common.TextRange; | ||||||
| import com.maddyhome.idea.vim.extension.ExtensionHandler; |  | ||||||
| import com.maddyhome.idea.vim.extension.VimExtension; | 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.handler.TextObjectActionHandler; | ||||||
| import com.maddyhome.idea.vim.helper.InlayHelperKt; | import com.maddyhome.idea.vim.helper.InlayHelperKt; | ||||||
| import com.maddyhome.idea.vim.helper.MessageHelper; | 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.IjVimCaret; | ||||||
| import com.maddyhome.idea.vim.newapi.IjVimEditor; | import com.maddyhome.idea.vim.newapi.IjVimEditor; | ||||||
| import com.maddyhome.idea.vim.vimscript.model.datatypes.VimString; | import com.maddyhome.idea.vim.vimscript.model.datatypes.VimString; | ||||||
| import kotlin.Unit; |  | ||||||
| import org.jetbrains.annotations.Nls; | import org.jetbrains.annotations.Nls; | ||||||
| import org.jetbrains.annotations.NotNull; | import org.jetbrains.annotations.NotNull; | ||||||
| import org.jetbrains.annotations.Nullable; | import org.jetbrains.annotations.Nullable; | ||||||
| @@ -34,7 +45,8 @@ import java.util.Deque; | |||||||
| import java.util.EnumSet; | import java.util.EnumSet; | ||||||
|  |  | ||||||
| import static com.maddyhome.idea.vim.extension.VimExtensionFacade.putExtensionHandlerMapping; | 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 |  * @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>InnerArgument"), getOwner(), new VimArgTextObjExtension.ArgumentHandler(true), false); | ||||||
|     putExtensionHandlerMapping(MappingMode.XO, VimInjectorKt.getInjector().getParser().parseKeys("<Plug>OuterArgument"), getOwner(), new VimArgTextObjExtension.ArgumentHandler(false), 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); |     putKeyMapping(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("aa"), getOwner(), VimInjectorKt.getInjector().getParser().parseKeys("<Plug>OuterArgument"), true); | ||||||
|  |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
| @@ -161,8 +174,8 @@ public class VimArgTextObjExtension implements VimExtension { | |||||||
|   @Nullable |   @Nullable | ||||||
|   private static String bracketPairsVariable() { |   private static String bracketPairsVariable() { | ||||||
|     final Object value = VimPlugin.getVariableService().getGlobalVariableValue("argtextobj_pairs"); |     final Object value = VimPlugin.getVariableService().getGlobalVariableValue("argtextobj_pairs"); | ||||||
|     if (value instanceof VimString vimValue) { |     if (value instanceof VimString) { | ||||||
|       return vimValue.getValue(); |       return ((VimString)value).getValue(); | ||||||
|     } |     } | ||||||
|     return null; |     return null; | ||||||
|   } |   } | ||||||
| @@ -193,7 +206,7 @@ public class VimArgTextObjExtension implements VimExtension { | |||||||
|       @Nullable |       @Nullable | ||||||
|       @Override |       @Override | ||||||
|       public TextRange getRange(@NotNull VimEditor editor, |       public TextRange getRange(@NotNull VimEditor editor, | ||||||
|                                 @NotNull ImmutableVimCaret caret, |                                 @NotNull VimCaret caret, | ||||||
|                                 @NotNull ExecutionContext context, |                                 @NotNull ExecutionContext context, | ||||||
|                                 int count, |                                 int count, | ||||||
|                                 int rawCount, |                                 int rawCount, | ||||||
| @@ -252,18 +265,18 @@ public class VimArgTextObjExtension implements VimExtension { | |||||||
|       final ArgumentTextObjectHandler textObjectHandler = new ArgumentTextObjectHandler(isInner); |       final ArgumentTextObjectHandler textObjectHandler = new ArgumentTextObjectHandler(isInner); | ||||||
|       //noinspection DuplicatedCode |       //noinspection DuplicatedCode | ||||||
|       if (!vimStateMachine.isOperatorPending()) { |       if (!vimStateMachine.isOperatorPending()) { | ||||||
|         editor.forEachNativeCaret((VimCaret caret) -> { |         vimEditor.getEditor().getCaretModel().runForEachCaret((Caret caret) -> { | ||||||
|           final TextRange range = textObjectHandler.getRange(editor, caret, context, count, 0, null); |           final TextRange range = textObjectHandler.getRange(vimEditor, new IjVimCaret(caret), context, count, 0, null); | ||||||
|           if (range != null) { |           if (range != null) { | ||||||
|             try (VimListenerSuppressor.Locked ignored = SelectionVimListenerSuppressor.INSTANCE.lock()) { |             try (VimListenerSuppressor.Locked ignored = SelectionVimListenerSuppressor.INSTANCE.lock()) { | ||||||
|               if (vimStateMachine.getMode() == VimStateMachine.Mode.VISUAL) { |               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 { |               } else { | ||||||
|                 InlayHelperKt.moveToInlayAwareOffset(((IjVimCaret)caret).getCaret(), range.getStartOffset()); |                 InlayHelperKt.moveToInlayAwareOffset(caret, range.getStartOffset()); | ||||||
|               } |               } | ||||||
|             } |             } | ||||||
|           } |           } | ||||||
|           return Unit.INSTANCE; |  | ||||||
|         }); |         }); | ||||||
|       } else { |       } else { | ||||||
|         vimStateMachine.getCommandBuilder().completeCommandPart(new Argument(new Command(count, |         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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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 | package com.maddyhome.idea.vim.extension.commentary | ||||||
|  |  | ||||||
| @@ -19,9 +29,8 @@ import com.intellij.psi.PsiWhiteSpace | |||||||
| import com.intellij.psi.util.PsiTreeUtil | import com.intellij.psi.util.PsiTreeUtil | ||||||
| import com.maddyhome.idea.vim.VimPlugin | import com.maddyhome.idea.vim.VimPlugin | ||||||
| import com.maddyhome.idea.vim.api.ExecutionContext | 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.VimEditor | ||||||
| import com.maddyhome.idea.vim.api.getLineEndOffset |  | ||||||
| import com.maddyhome.idea.vim.api.injector | import com.maddyhome.idea.vim.api.injector | ||||||
| import com.maddyhome.idea.vim.command.Argument | import com.maddyhome.idea.vim.command.Argument | ||||||
| import com.maddyhome.idea.vim.command.Command | 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.putKeyMappingIfMissing | ||||||
| import com.maddyhome.idea.vim.extension.VimExtensionFacade.setOperatorFunction | import com.maddyhome.idea.vim.extension.VimExtensionFacade.setOperatorFunction | ||||||
| import com.maddyhome.idea.vim.handler.TextObjectActionHandler | 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.PsiHelper | ||||||
| import com.maddyhome.idea.vim.helper.vimStateMachine | import com.maddyhome.idea.vim.helper.vimStateMachine | ||||||
| import com.maddyhome.idea.vim.key.OperatorFunction | import com.maddyhome.idea.vim.key.OperatorFunction | ||||||
| import com.maddyhome.idea.vim.newapi.IjVimEditor | import com.maddyhome.idea.vim.newapi.IjVimEditor | ||||||
| import com.maddyhome.idea.vim.newapi.ij | import com.maddyhome.idea.vim.newapi.ij | ||||||
| import com.maddyhome.idea.vim.newapi.vim |  | ||||||
| import java.util.* | import java.util.* | ||||||
|  |  | ||||||
| class CommentaryExtension : VimExtension { | class CommentaryExtension : VimExtension { | ||||||
| @@ -191,7 +200,7 @@ class CommentaryExtension : VimExtension { | |||||||
|  |  | ||||||
|     override fun getRange( |     override fun getRange( | ||||||
|       editor: VimEditor, |       editor: VimEditor, | ||||||
|       caret: ImmutableVimCaret, |       caret: VimCaret, | ||||||
|       context: ExecutionContext, |       context: ExecutionContext, | ||||||
|       count: Int, |       count: Int, | ||||||
|       rawCount: Int, |       rawCount: Int, | ||||||
| @@ -202,14 +211,14 @@ class CommentaryExtension : VimExtension { | |||||||
|       val file = PsiHelper.getFile(nativeEditor) ?: return null |       val file = PsiHelper.getFile(nativeEditor) ?: return null | ||||||
|       val lastLine = editor.lineCount() |       val lastLine = editor.lineCount() | ||||||
|  |  | ||||||
|       var startLine = caret.getBufferPosition().line |       var startLine = caret.getLogicalPosition().line | ||||||
|       while (startLine > 0 && isCommentLine(file, nativeEditor, startLine - 1)) startLine-- |       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++ |       while (endLine < lastLine && isCommentLine(file, nativeEditor, endLine + 1)) endLine++ | ||||||
|  |  | ||||||
|       if (startLine <= endLine) { |       if (startLine <= endLine) { | ||||||
|         val startOffset = editor.getLineStartOffset(startLine) |         val startOffset = EditorHelper.getLineStartOffset(nativeEditor, startLine) | ||||||
|         val endOffset = editor.getLineStartOffset(endLine + 1) |         val endOffset = EditorHelper.getLineStartOffset(nativeEditor, endLine + 1) | ||||||
|         return TextRange(startOffset, endOffset) |         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 |     // 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 { |     private fun isCommentLine(file: PsiFile, editor: Editor, logicalLine: Int): Boolean { | ||||||
|       val startOffset = editor.vim.getLineStartOffset(logicalLine) |       val startOffset = EditorHelper.getLineStartOffset(editor, logicalLine) | ||||||
|       val endOffset = editor.vim.getLineEndOffset(logicalLine, true) |       val endOffset = EditorHelper.getLineEndOffset(editor, logicalLine, true) | ||||||
|       val startElement = file.findElementAt(startOffset) ?: return false |       val startElement = file.findElementAt(startOffset) ?: return false | ||||||
|       var next: PsiElement? = startElement |       var next: PsiElement? = startElement | ||||||
|       while (next != null && next.textRange.startOffset <= endOffset) { |       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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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 | 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.VimPlugin | ||||||
| import com.maddyhome.idea.vim.api.ExecutionContext | import com.maddyhome.idea.vim.api.ExecutionContext | ||||||
| import com.maddyhome.idea.vim.api.VimEditor | 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.api.injector | ||||||
| import com.maddyhome.idea.vim.command.MappingMode | import com.maddyhome.idea.vim.command.MappingMode | ||||||
| import com.maddyhome.idea.vim.command.SelectionType | 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.putKeyMappingIfMissing | ||||||
| import com.maddyhome.idea.vim.extension.VimExtensionFacade.setOperatorFunction | import com.maddyhome.idea.vim.extension.VimExtensionFacade.setOperatorFunction | ||||||
| import com.maddyhome.idea.vim.extension.VimExtensionFacade.setRegister | 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.fileSize | ||||||
| import com.maddyhome.idea.vim.helper.moveToInlayAwareLogicalPosition | import com.maddyhome.idea.vim.helper.moveToInlayAwareLogicalPosition | ||||||
| import com.maddyhome.idea.vim.helper.moveToInlayAwareOffset | 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.key.OperatorFunction | ||||||
| import com.maddyhome.idea.vim.mark.Mark | import com.maddyhome.idea.vim.mark.Mark | ||||||
| import com.maddyhome.idea.vim.mark.VimMarkConstants | 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.ij | ||||||
| import com.maddyhome.idea.vim.newapi.vim | import com.maddyhome.idea.vim.newapi.vim | ||||||
| import org.jetbrains.annotations.NonNls | import org.jetbrains.annotations.NonNls | ||||||
| @@ -129,7 +138,7 @@ class VimExchangeExtension : VimExtension { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   private class Operator(private val isVisual: Boolean) : OperatorFunction { |   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) { |     fun VimStateMachine.SubMode.getString() = when (this) { | ||||||
|       VimStateMachine.SubMode.VISUAL_CHARACTER -> "v" |       VimStateMachine.SubMode.VISUAL_CHARACTER -> "v" | ||||||
|       VimStateMachine.SubMode.VISUAL_LINE -> "V" |       VimStateMachine.SubMode.VISUAL_LINE -> "V" | ||||||
| @@ -208,19 +217,19 @@ class VimExchangeExtension : VimExtension { | |||||||
|         if (reverse) { |         if (reverse) { | ||||||
|           primaryCaret.moveToInlayAwareOffset(editor.getMarkOffset(ex1.start)) |           primaryCaret.moveToInlayAwareOffset(editor.getMarkOffset(ex1.start)) | ||||||
|         } else { |         } else { | ||||||
|           if (ex1.start.line == ex2.start.line) { |           if (ex1.start.logicalLine == ex2.start.logicalLine) { | ||||||
|             val horizontalOffset = ex1.end.col - ex2.end.col |             val horizontalOffset = ex1.end.col - ex2.end.col | ||||||
|             primaryCaret.moveToInlayAwareLogicalPosition( |             primaryCaret.moveToInlayAwareLogicalPosition( | ||||||
|               LogicalPosition( |               LogicalPosition( | ||||||
|                 ex1.start.line, |                 ex1.start.logicalLine, | ||||||
|                 ex1.start.col - horizontalOffset |                 ex1.start.col - horizontalOffset | ||||||
|               ) |               ) | ||||||
|             ) |             ) | ||||||
|           } else if (ex1.end.line - ex1.start.line != ex2.end.line - ex2.start.line) { |           } else if (ex1.end.logicalLine - ex1.start.logicalLine != ex2.end.logicalLine - ex2.start.logicalLine) { | ||||||
|             val verticalOffset = ex1.end.line - ex2.end.line |             val verticalOffset = ex1.end.logicalLine - ex2.end.logicalLine | ||||||
|             primaryCaret.moveToInlayAwareLogicalPosition( |             primaryCaret.moveToInlayAwareLogicalPosition( | ||||||
|               LogicalPosition( |               LogicalPosition( | ||||||
|                 ex1.start.line - verticalOffset, |                 ex1.start.logicalLine - verticalOffset, | ||||||
|                 ex1.start.col |                 ex1.start.col | ||||||
|               ) |               ) | ||||||
|             ) |             ) | ||||||
| @@ -253,16 +262,16 @@ class VimExchangeExtension : VimExtension { | |||||||
|  |  | ||||||
|     private fun compareExchanges(x: Exchange, y: Exchange): ExchangeCompareResult { |     private fun compareExchanges(x: Exchange, y: Exchange): ExchangeCompareResult { | ||||||
|       fun intersects(x: Exchange, y: Exchange) = |       fun intersects(x: Exchange, y: Exchange) = | ||||||
|         x.end.line < y.start.line || |         x.end.logicalLine < y.start.logicalLine || | ||||||
|           x.start.line > y.end.line || |           x.start.logicalLine > y.end.logicalLine || | ||||||
|           x.end.col < y.start.col || |           x.end.col < y.start.col || | ||||||
|           x.start.col > y.end.col |           x.start.col > y.end.col | ||||||
|  |  | ||||||
|       fun comparePos(x: Mark, y: Mark): Int = |       fun comparePos(x: Mark, y: Mark): Int = | ||||||
|         if (x.line == y.line) { |         if (x.logicalLine == y.logicalLine) { | ||||||
|           x.col - y.col |           x.col - y.col | ||||||
|         } else { |         } else { | ||||||
|           x.line - y.line |           x.logicalLine - y.logicalLine | ||||||
|         } |         } | ||||||
|  |  | ||||||
|       return if (x.type == VimStateMachine.SubMode.VISUAL_BLOCK && y.type == VimStateMachine.SubMode.VISUAL_BLOCK) { |       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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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 | 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.intellij.openapi.util.Disposer | ||||||
| import com.maddyhome.idea.vim.VimPlugin | import com.maddyhome.idea.vim.VimPlugin | ||||||
| import com.maddyhome.idea.vim.VimProjectService | 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.common.TextRange | ||||||
| import com.maddyhome.idea.vim.extension.VimExtension | import com.maddyhome.idea.vim.extension.VimExtension | ||||||
| import com.maddyhome.idea.vim.helper.MessageHelper | import com.maddyhome.idea.vim.helper.MessageHelper | ||||||
| import com.maddyhome.idea.vim.helper.VimNlsSafe | import com.maddyhome.idea.vim.helper.VimNlsSafe | ||||||
| import com.maddyhome.idea.vim.listener.VimInsertListener | import com.maddyhome.idea.vim.listener.VimInsertListener | ||||||
| import com.maddyhome.idea.vim.listener.VimYankListener | import com.maddyhome.idea.vim.listener.VimYankListener | ||||||
| import com.maddyhome.idea.vim.newapi.ij | import com.maddyhome.idea.vim.options.OptionConstants | ||||||
| import com.maddyhome.idea.vim.options.helpers.StrictMode | import com.maddyhome.idea.vim.options.OptionScope | ||||||
| import com.maddyhome.idea.vim.vimscript.model.datatypes.VimString | import com.maddyhome.idea.vim.vimscript.model.datatypes.VimString | ||||||
| import org.jetbrains.annotations.NonNls | import org.jetbrains.annotations.NonNls | ||||||
| import java.awt.Color | import java.awt.Color | ||||||
| @@ -91,8 +101,8 @@ class VimHighlightedYank : VimExtension, VimYankListener, VimInsertListener { | |||||||
|     VimPlugin.getChange().removeInsertListener(this) |     VimPlugin.getChange().removeInsertListener(this) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   override fun yankPerformed(editor: VimEditor, range: TextRange) { |   override fun yankPerformed(editor: Editor, range: TextRange) { | ||||||
|     highlightHandler.highlightYankRange(editor.ij, range) |     highlightHandler.highlightYankRange(editor, range) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   override fun insertModeStarted(editor: Editor) { |   override fun insertModeStarted(editor: Editor) { | ||||||
| @@ -129,12 +139,18 @@ class VimHighlightedYank : VimExtension, VimYankListener, VimInsertListener { | |||||||
|  |  | ||||||
|     fun clearAllYankHighlighters() { |     fun clearAllYankHighlighters() { | ||||||
|       yankHighlighters.forEach { highlighter -> |       yankHighlighters.forEach { highlighter -> | ||||||
|         editor?.markupModel?.removeHighlighter(highlighter) ?: StrictMode.fail("Highlighters without an editor") |         editor?.markupModel?.removeHighlighter(highlighter) ?: failIfStrictMode("Highlighters without an editor") | ||||||
|       } |       } | ||||||
|  |  | ||||||
|       yankHighlighters.clear() |       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>) { |     private fun highlightSingleRange(editor: Editor, range: ClosedRange<Int>) { | ||||||
|       val highlighter = editor.markupModel.addRangeHighlighter( |       val highlighter = editor.markupModel.addRangeHighlighter( | ||||||
|         range.start, |         range.start, | ||||||
| @@ -157,7 +173,7 @@ class VimHighlightedYank : VimExtension, VimYankListener, VimInsertListener { | |||||||
|         Executors.newSingleThreadScheduledExecutor().schedule( |         Executors.newSingleThreadScheduledExecutor().schedule( | ||||||
|           { |           { | ||||||
|             ApplicationManager.getApplication().invokeLater { |             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 |           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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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 | 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.intellij.psi.util.elementType | ||||||
| import com.maddyhome.idea.vim.VimPlugin | import com.maddyhome.idea.vim.VimPlugin | ||||||
| import com.maddyhome.idea.vim.api.ExecutionContext | 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.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.injector | ||||||
| import com.maddyhome.idea.vim.api.normalizeOffset |  | ||||||
| import com.maddyhome.idea.vim.command.Argument | import com.maddyhome.idea.vim.command.Argument | ||||||
| import com.maddyhome.idea.vim.command.Command | import com.maddyhome.idea.vim.command.Command | ||||||
| import com.maddyhome.idea.vim.command.CommandFlags | 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.PsiHelper | ||||||
| import com.maddyhome.idea.vim.helper.enumSetOf | import com.maddyhome.idea.vim.helper.enumSetOf | ||||||
| import com.maddyhome.idea.vim.helper.vimStateMachine | 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.ij | ||||||
| import com.maddyhome.idea.vim.newapi.vim | import com.maddyhome.idea.vim.newapi.vim | ||||||
| import java.util.* | import java.util.* | ||||||
| @@ -74,7 +79,7 @@ class Matchit : VimExtension { | |||||||
|  |  | ||||||
|     override fun getOffset( |     override fun getOffset( | ||||||
|       editor: VimEditor, |       editor: VimEditor, | ||||||
|       caret: ImmutableVimCaret, |       caret: VimCaret, | ||||||
|       context: ExecutionContext, |       context: ExecutionContext, | ||||||
|       argument: Argument?, |       argument: Argument?, | ||||||
|       operatorArguments: OperatorArguments, |       operatorArguments: OperatorArguments, | ||||||
| @@ -118,7 +123,7 @@ class Matchit : VimExtension { | |||||||
|       } else { |       } else { | ||||||
|         editor.forEachCaret { caret -> |         editor.forEachCaret { caret -> | ||||||
|           VimPlugin.getMark().saveJumpLocation(editor) |           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 |   var caretOffset = caret.offset | ||||||
|  |  | ||||||
|   // Handle the case where visual mode has brought the cursor past the end of the line. |   // 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) { |   if (caretOffset > 0 && caretOffset == lineEndOffset) { | ||||||
|     caretOffset-- |     caretOffset-- | ||||||
|   } |   } | ||||||
| @@ -354,7 +359,7 @@ private fun getMatchitOffset(editor: Editor, caret: Caret, count: Int, isInOpPen | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   if (motion >= 0) { |   if (motion >= 0) { | ||||||
|     motion = editor.vim.normalizeOffset(motion, false) |     motion = EditorHelper.normalizeOffset(editor, motion, false) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   return motion |   return motion | ||||||
| @@ -369,8 +374,8 @@ private fun findMatchingPair( | |||||||
| ): Int { | ): Int { | ||||||
|   // For better performance, we limit our search to the current line. This way we don't have to scan the entire file |   // 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. |   // to determine if we're on a pattern or not. The original plugin behaves the same way. | ||||||
|   val currentLineStart = IjVimEditor(editor).getLineStartForOffset(caretOffset) |   val currentLineStart = EditorHelper.getLineStartForOffset(editor, caretOffset) | ||||||
|   val currentLineEnd = IjVimEditor(editor).getLineEndForOffset(caretOffset) |   val currentLineEnd = EditorHelper.getLineEndForOffset(editor, caretOffset) | ||||||
|   val currentLineChars = editor.document.charsSequence.subSequence(currentLineStart, currentLineEnd) |   val currentLineChars = editor.document.charsSequence.subSequence(currentLineStart, currentLineEnd) | ||||||
|   val offset = caretOffset - currentLineStart |   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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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 | 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.VimPlugin | ||||||
| import com.maddyhome.idea.vim.api.ExecutionContext | import com.maddyhome.idea.vim.api.ExecutionContext | ||||||
| import com.maddyhome.idea.vim.api.VimEditor | 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.api.injector | ||||||
| import com.maddyhome.idea.vim.command.MappingMode | import com.maddyhome.idea.vim.command.MappingMode | ||||||
| import com.maddyhome.idea.vim.command.VimStateMachine | 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.extension.VimExtensionFacade.putKeyMappingIfMissing | ||||||
| import com.maddyhome.idea.vim.group.MotionGroup | import com.maddyhome.idea.vim.group.MotionGroup | ||||||
| import com.maddyhome.idea.vim.group.visual.vimSetSelection | 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.MessageHelper | ||||||
| import com.maddyhome.idea.vim.helper.SearchHelper | import com.maddyhome.idea.vim.helper.SearchHelper | ||||||
| import com.maddyhome.idea.vim.helper.SearchOptions | import com.maddyhome.idea.vim.helper.SearchOptions | ||||||
| @@ -157,12 +167,12 @@ class VimMultipleCursorsExtension : VimExtension { | |||||||
|             for (line in startPosition.line + 1..startPosition.line + lines) { |             for (line in startPosition.line + 1..startPosition.line + lines) { | ||||||
|               newPositions.add(VisualPosition(line, startPosition.column)) |               newPositions.add(VisualPosition(line, startPosition.column)) | ||||||
|             } |             } | ||||||
|             caret.vim.moveToOffset(selectionStart) |             MotionGroup.moveCaret(editor, caret, selectionStart) | ||||||
|           } |           } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (newPositions.size > 0) { |         if (newPositions.size > 0) { | ||||||
|           editor.vim.exitVisualMode() |           editor.exitVisualMode() | ||||||
|           newPositions.forEach { editor.caretModel.addCaret(it, true) ?: return } |           newPositions.forEach { editor.caretModel.addCaret(it, true) ?: return } | ||||||
|           editor.updateCaretsVisualAttributes() |           editor.updateCaretsVisualAttributes() | ||||||
|           return |           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 |         // 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 |         // longer selected | ||||||
|         val pattern = editor.vim.getText(lastSelection) |         val pattern = EditorHelper.getText(editor, lastSelection) | ||||||
|  |  | ||||||
|         val primaryCaret = editor.caretModel.primaryCaret |         val primaryCaret = editor.caretModel.primaryCaret | ||||||
|         val nextOffset = findNextOccurrence(editor, primaryCaret.offset, pattern, wholeWord) |         val nextOffset = findNextOccurrence(editor, primaryCaret.offset, pattern, wholeWord) | ||||||
| @@ -228,7 +238,7 @@ class VimMultipleCursorsExtension : VimExtension { | |||||||
|       } else { |       } else { | ||||||
|         val range = SearchHelper.findWordUnderCursor(editor, primaryCaret) ?: return |         val range = SearchHelper.findWordUnderCursor(editor, primaryCaret) ?: return | ||||||
|         if (range.startOffset > primaryCaret.offset) return |         if (range.startOffset > primaryCaret.offset) return | ||||||
|         IjVimEditor(editor).getText(range) |         EditorHelper.getText(editor, range) | ||||||
|       } |       } | ||||||
|  |  | ||||||
|       if (!editor.inVisualMode) { |       if (!editor.inVisualMode) { | ||||||
| @@ -240,7 +250,7 @@ class VimMultipleCursorsExtension : VimExtension { | |||||||
|       val matches = SearchHelper.findAll(editor, pattern, 0, -1, false) |       val matches = SearchHelper.findAll(editor, pattern, 0, -1, false) | ||||||
|       for (match in matches) { |       for (match in matches) { | ||||||
|         if (match.contains(primaryCaret.offset)) { |         if (match.contains(primaryCaret.offset)) { | ||||||
|           primaryCaret.vim.moveToOffset(match.startOffset) |           MotionGroup.moveCaret(editor, primaryCaret, match.startOffset) | ||||||
|           selectText(primaryCaret, text, match.startOffset) |           selectText(primaryCaret, text, match.startOffset) | ||||||
|         } else { |         } else { | ||||||
|           val caret = editor.caretModel.addCaret(editor.offsetToVisualPosition(match.startOffset), true) ?: return |           val caret = editor.caretModel.addCaret(editor.offsetToVisualPosition(match.startOffset), true) ?: return | ||||||
| @@ -277,7 +287,7 @@ class VimMultipleCursorsExtension : VimExtension { | |||||||
|       val caret = editor.caretModel.primaryCaret |       val caret = editor.caretModel.primaryCaret | ||||||
|       if (caret.selectedText == null) return |       if (caret.selectedText == null) return | ||||||
|       if (!editor.caretModel.removeCaret(caret)) { |       if (!editor.caretModel.removeCaret(caret)) { | ||||||
|         editor.vim.exitVisualMode() |         editor.exitVisualMode() | ||||||
|       } |       } | ||||||
|       MotionGroup.scrollCaretIntoView(caret.editor) |       MotionGroup.scrollCaretIntoView(caret.editor) | ||||||
|     } |     } | ||||||
| @@ -285,7 +295,7 @@ class VimMultipleCursorsExtension : VimExtension { | |||||||
|  |  | ||||||
|   private fun selectText(caret: Caret, text: String, offset: Int): TextRange? { |   private fun selectText(caret: Caret, text: String, offset: Int): TextRange? { | ||||||
|     if (text.isEmpty()) return null |     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) |     MotionGroup.scrollCaretIntoView(caret.editor) | ||||||
|     return TextRange(caret.selectionStart, caret.selectionEnd) |     return TextRange(caret.selectionStart, caret.selectionEnd) | ||||||
|   } |   } | ||||||
| @@ -297,7 +307,7 @@ class VimMultipleCursorsExtension : VimExtension { | |||||||
|     enterVisualMode(editor.vim) |     enterVisualMode(editor.vim) | ||||||
|  |  | ||||||
|     // Select the word under the caret, moving the caret to the end of the selection |     // 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) |     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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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 | 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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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 | 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.ActionUpdateThread | ||||||
| import com.intellij.openapi.actionSystem.AnActionEvent | import com.intellij.openapi.actionSystem.AnActionEvent | ||||||
| import com.intellij.openapi.actionSystem.CommonDataKeys | import com.intellij.openapi.actionSystem.CommonDataKeys | ||||||
| import com.intellij.openapi.actionSystem.PlatformDataKeys |  | ||||||
| import com.intellij.openapi.application.ApplicationManager | import com.intellij.openapi.application.ApplicationManager | ||||||
| import com.intellij.openapi.diagnostic.logger | import com.intellij.openapi.diagnostic.logger | ||||||
| import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx | import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx | ||||||
| @@ -137,7 +146,7 @@ class NerdTree : VimExtension { | |||||||
|  |  | ||||||
|   class IjCommandHandler(private val actionId: String) : CommandAliasHandler { |   class IjCommandHandler(private val actionId: String) : CommandAliasHandler { | ||||||
|     override fun execute(command: String, ranges: Ranges, editor: VimEditor, context: ExecutionContext) { |     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) { |       if (toolWindow.isVisible) { | ||||||
|         toolWindow.hide() |         toolWindow.hide() | ||||||
|       } else { |       } else { | ||||||
|         callAction(editor, "ActivateProjectToolWindow", context) |         callAction("ActivateProjectToolWindow", context) | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| @@ -210,7 +219,7 @@ class NerdTree : VimExtension { | |||||||
|  |  | ||||||
|           val action = nextNode.actionHolder |           val action = nextNode.actionHolder | ||||||
|           when (action) { |           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) } |             is NerdAction.Code -> e.project?.let { action.action(it, e.dataContext, e) } | ||||||
|           } |           } | ||||||
|         } |         } | ||||||
| @@ -231,14 +240,14 @@ class NerdTree : VimExtension { | |||||||
|         e.presentation.isEnabled = false |         e.presentation.isEnabled = false | ||||||
|         return |         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 { |     private fun speedSearchIsHere(project: Project): Boolean { | ||||||
|       val searchText = e.getData(PlatformDataKeys.SPEED_SEARCH_TEXT) |       val component = ProjectView.getInstance(project).currentProjectViewPane.tree ?: return false | ||||||
|       return !searchText.isNullOrEmpty() |       return SpeedSearchSupply.getSupply(component) != null | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     companion object { |     companion object { | ||||||
| @@ -348,7 +357,7 @@ class NerdTree : VimExtension { | |||||||
|         currentWindow?.split(SwingConstants.VERTICAL, true, file, true) |         currentWindow?.split(SwingConstants.VERTICAL, true, file, true) | ||||||
|  |  | ||||||
|         // FIXME: 22.01.2021 This solution bouncing a bit |         // FIXME: 22.01.2021 This solution bouncing a bit | ||||||
|         callAction(null, "ActivateProjectToolWindow", context.vim) |         callAction("ActivateProjectToolWindow", context.vim) | ||||||
|       } |       } | ||||||
|     ) |     ) | ||||||
|     registerCommand( |     registerCommand( | ||||||
| @@ -359,7 +368,7 @@ class NerdTree : VimExtension { | |||||||
|         val currentWindow = splitters.currentWindow |         val currentWindow = splitters.currentWindow | ||||||
|         currentWindow?.split(SwingConstants.HORIZONTAL, true, file, true) |         currentWindow?.split(SwingConstants.HORIZONTAL, true, file, true) | ||||||
|  |  | ||||||
|         callAction(null, "ActivateProjectToolWindow", context.vim) |         callAction("ActivateProjectToolWindow", context.vim) | ||||||
|       } |       } | ||||||
|     ) |     ) | ||||||
|     registerCommand( |     registerCommand( | ||||||
| @@ -497,17 +506,20 @@ class NerdTree : VimExtension { | |||||||
|  |  | ||||||
|     private val LOG = logger<NerdTree>() |     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 { |       val action = ActionManager.getInstance().getAction(name) ?: run { | ||||||
|         VimPlugin.showMessage(MessageHelper.message("action.not.found.0", name)) |         VimPlugin.showMessage(MessageHelper.message("action.not.found.0", name)) | ||||||
|         return |         return | ||||||
|       } |       } | ||||||
|       val application = ApplicationManager.getApplication() |       val application = ApplicationManager.getApplication() | ||||||
|       if (application.isUnitTestMode) { |       if (application.isUnitTestMode) { | ||||||
|         injector.actionExecutor.executeAction(editor, action.vim, context) |         injector.actionExecutor.executeAction(action.vim, context) | ||||||
|       } else { |       } else { | ||||||
|         runAfterGotFocus { |         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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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 | 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.ExecutionContext | ||||||
| import com.maddyhome.idea.vim.api.VimEditor | import com.maddyhome.idea.vim.api.VimEditor | ||||||
| import com.maddyhome.idea.vim.api.injector | 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.command.MappingMode | ||||||
| import com.maddyhome.idea.vim.extension.ExtensionHandler | import com.maddyhome.idea.vim.extension.ExtensionHandler | ||||||
| import com.maddyhome.idea.vim.extension.VimExtension | import com.maddyhome.idea.vim.extension.VimExtension | ||||||
| import com.maddyhome.idea.vim.extension.VimExtensionFacade | import com.maddyhome.idea.vim.extension.VimExtensionFacade | ||||||
| import com.maddyhome.idea.vim.extension.VimExtensionFacade.putKeyMappingIfMissing | 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.SearchHelper | ||||||
| import com.maddyhome.idea.vim.helper.vimForEachCaret | import com.maddyhome.idea.vim.helper.vimForEachCaret | ||||||
| import com.maddyhome.idea.vim.newapi.ij | import com.maddyhome.idea.vim.newapi.ij | ||||||
| import com.maddyhome.idea.vim.newapi.vim |  | ||||||
|  |  | ||||||
| class ParagraphMotion : VimExtension { | class ParagraphMotion : VimExtension { | ||||||
|   override fun getName(): String = "vim-paragraph-motion" |   override fun getName(): String = "vim-paragraph-motion" | ||||||
| @@ -40,7 +50,7 @@ class ParagraphMotion : VimExtension { | |||||||
|       editor.ij.vimForEachCaret { caret -> |       editor.ij.vimForEachCaret { caret -> | ||||||
|         val motion = moveCaretToNextParagraph(editor.ij, caret, count) |         val motion = moveCaretToNextParagraph(editor.ij, caret, count) | ||||||
|         if (motion >= 0) { |         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 { |     fun moveCaretToNextParagraph(editor: Editor, caret: Caret, count: Int): Int { | ||||||
|       var res = SearchHelper.findNextParagraph(editor, caret, count, true) |       var res = SearchHelper.findNextParagraph(editor, caret, count, true) | ||||||
|       res = if (res >= 0) { |       res = if (res >= 0) { | ||||||
|         editor.vim.normalizeOffset(res, true) |         EditorHelper.normalizeOffset(editor, res, true) | ||||||
|       } else { |       } else { | ||||||
|         -1 |         -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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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 | 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.intellij.openapi.editor.Editor | ||||||
| import com.maddyhome.idea.vim.VimPlugin | import com.maddyhome.idea.vim.VimPlugin | ||||||
| import com.maddyhome.idea.vim.api.ExecutionContext | 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.VimEditor | ||||||
| import com.maddyhome.idea.vim.api.getLineEndOffset |  | ||||||
| import com.maddyhome.idea.vim.api.injector | import com.maddyhome.idea.vim.api.injector | ||||||
| import com.maddyhome.idea.vim.command.MappingMode | import com.maddyhome.idea.vim.command.MappingMode | ||||||
| import com.maddyhome.idea.vim.command.OperatorArguments | 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.group.visual.VimSelection | ||||||
| import com.maddyhome.idea.vim.helper.EditorDataContext | import com.maddyhome.idea.vim.helper.EditorDataContext | ||||||
| import com.maddyhome.idea.vim.helper.editorMode | 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.mode | ||||||
| import com.maddyhome.idea.vim.helper.subMode | import com.maddyhome.idea.vim.helper.subMode | ||||||
| import com.maddyhome.idea.vim.helper.vimStateMachine | 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) |         val visualSelection = caret to VimSelection.create(selectionStart, selectionEnd - 1, typeInEditor, editor) | ||||||
|         doReplace(editor.ij, caret, PutData.VisualSelection(mapOf(visualSelection), typeInEditor)) |         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 val isRepeatable: Boolean = true | ||||||
|  |  | ||||||
|     override fun execute(editor: VimEditor, context: ExecutionContext) { |     override fun execute(editor: VimEditor, context: ExecutionContext) { | ||||||
|       val caretsAndSelections = mutableMapOf<ImmutableVimCaret, VimSelection>() |       val caretsAndSelections = mutableMapOf<VimCaret, VimSelection>() | ||||||
|       editor.forEachCaret { caret -> |       editor.forEachCaret { caret -> | ||||||
|         val logicalLine = caret.getBufferPosition().line |         val logicalLine = caret.getLogicalPosition().line | ||||||
|         val lineStart = editor.getLineStartOffset(logicalLine) |         val lineStart = editor.getLineStartOffset(logicalLine) | ||||||
|         val lineEnd = editor.getLineEndOffset(logicalLine, true) |         val lineEnd = editor.getLineEndOffset(logicalLine, true) | ||||||
|  |  | ||||||
| @@ -142,7 +150,7 @@ class ReplaceWithRegister : VimExtension { | |||||||
|     @NonNls |     @NonNls | ||||||
|     private const val RWR_VISUAL = "<Plug>ReplaceWithRegisterVisual" |     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 lastRegisterChar = injector.registerGroup.lastRegisterChar | ||||||
|       val savedRegister = caret.registerStorage.getRegister(caret, lastRegisterChar) ?: return |       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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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 | 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.VimCaret | ||||||
| import com.maddyhome.idea.vim.api.VimChangeGroup | import com.maddyhome.idea.vim.api.VimChangeGroup | ||||||
| import com.maddyhome.idea.vim.api.VimEditor | 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.api.injector | ||||||
| import com.maddyhome.idea.vim.command.MappingMode | import com.maddyhome.idea.vim.command.MappingMode | ||||||
| import com.maddyhome.idea.vim.command.SelectionType | import com.maddyhome.idea.vim.command.SelectionType | ||||||
| @@ -132,7 +141,7 @@ class VimSurroundExtension : VimExtension { | |||||||
|           val innerValue = if (registerValue.isNullOrEmpty()) null else registerValue |           val innerValue = if (registerValue.isNullOrEmpty()) null else registerValue | ||||||
|           it.innerText = innerValue |           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) { |           if (lineEndOffset == it.caret.offset.point) { | ||||||
|             it.isLineEnd = true |             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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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; | package com.maddyhome.idea.vim.extension.textobjentire; | ||||||
|  |  | ||||||
| import com.intellij.openapi.editor.Caret; | 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.*; | ||||||
| import com.maddyhome.idea.vim.command.MappingMode; | import com.maddyhome.idea.vim.command.MappingMode; | ||||||
| import com.maddyhome.idea.vim.common.TextRange; | 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.putExtensionHandlerMapping; | ||||||
| import static com.maddyhome.idea.vim.extension.VimExtensionFacade.putKeyMappingIfMissing; | import static com.maddyhome.idea.vim.extension.VimExtensionFacade.putKeyMappingIfMissing; | ||||||
|  | import static com.maddyhome.idea.vim.group.visual.VisualGroupKt.vimSetSelection; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Port of vim-entire: |  * Port of vim-entire: | ||||||
| @@ -92,7 +106,7 @@ public class VimTextObjEntireExtension implements VimExtension { | |||||||
|       @Nullable |       @Nullable | ||||||
|       @Override |       @Override | ||||||
|       public TextRange getRange(@NotNull VimEditor editor, |       public TextRange getRange(@NotNull VimEditor editor, | ||||||
|                                 @NotNull ImmutableVimCaret caret, |                                 @NotNull VimCaret caret, | ||||||
|                                 @NotNull ExecutionContext context, |                                 @NotNull ExecutionContext context, | ||||||
|                                 int count, |                                 int count, | ||||||
|                                 int rawCount, |                                 int rawCount, | ||||||
| @@ -141,7 +155,7 @@ public class VimTextObjEntireExtension implements VimExtension { | |||||||
|           if (range != null) { |           if (range != null) { | ||||||
|             try (VimListenerSuppressor.Locked ignored = SelectionVimListenerSuppressor.INSTANCE.lock()) { |             try (VimListenerSuppressor.Locked ignored = SelectionVimListenerSuppressor.INSTANCE.lock()) { | ||||||
|               if (vimStateMachine.getMode() == VimStateMachine.Mode.VISUAL) { |               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 { |               } else { | ||||||
|                 InlayHelperKt.moveToInlayAwareOffset(caret, range.getStartOffset()); |                 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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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; | package com.maddyhome.idea.vim.extension.textobjindent; | ||||||
|  |  | ||||||
| import com.intellij.openapi.editor.Caret; | 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.*; | ||||||
|  | import com.maddyhome.idea.vim.command.MappingMode; | ||||||
| import com.maddyhome.idea.vim.common.TextRange; | 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.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.handler.TextObjectActionHandler; | ||||||
| import com.maddyhome.idea.vim.helper.InlayHelperKt; | import com.maddyhome.idea.vim.helper.InlayHelperKt; | ||||||
| import com.maddyhome.idea.vim.listener.SelectionVimListenerSuppressor; | 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.putExtensionHandlerMapping; | ||||||
| import static com.maddyhome.idea.vim.extension.VimExtensionFacade.putKeyMapping; | import static com.maddyhome.idea.vim.extension.VimExtensionFacade.putKeyMapping; | ||||||
|  | import static com.maddyhome.idea.vim.group.visual.VisualGroupKt.vimSetSelection; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Port of vim-indent-object: |  * Port of vim-indent-object: | ||||||
| @@ -95,7 +109,7 @@ public class VimIndentObject implements VimExtension { | |||||||
|       @Nullable |       @Nullable | ||||||
|       @Override |       @Override | ||||||
|       public TextRange getRange(@NotNull VimEditor editor, |       public TextRange getRange(@NotNull VimEditor editor, | ||||||
|                                 @NotNull ImmutableVimCaret caret, |                                 @NotNull VimCaret caret, | ||||||
|                                 @NotNull ExecutionContext context, |                                 @NotNull ExecutionContext context, | ||||||
|                                 int count, |                                 int count, | ||||||
|                                 int rawCount, |                                 int rawCount, | ||||||
| @@ -269,7 +283,7 @@ public class VimIndentObject implements VimExtension { | |||||||
|           if (range != null) { |           if (range != null) { | ||||||
|             try (VimListenerSuppressor.Locked ignored = SelectionVimListenerSuppressor.INSTANCE.lock()) { |             try (VimListenerSuppressor.Locked ignored = SelectionVimListenerSuppressor.INSTANCE.lock()) { | ||||||
|               if (vimStateMachine.getMode() == VimStateMachine.Mode.VISUAL) { |               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 { |               } else { | ||||||
|                 InlayHelperKt.moveToInlayAwareOffset(caret, range.getStartOffset()); |                 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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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; | package com.maddyhome.idea.vim.group; | ||||||
|  |  | ||||||
| import com.google.common.base.Splitter; | import com.google.common.base.Splitter; | ||||||
|  | import com.google.common.collect.ImmutableSet; | ||||||
| import com.google.common.collect.Lists; | import com.google.common.collect.Lists; | ||||||
| import com.intellij.codeInsight.actions.AsyncActionExecutionService; | import com.intellij.codeInsight.actions.AsyncActionExecutionService; | ||||||
| import com.intellij.openapi.Disposable; | 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.CommandProcessor; | ||||||
| import com.intellij.openapi.command.UndoConfirmationPolicy; | import com.intellij.openapi.command.UndoConfirmationPolicy; | ||||||
| import com.intellij.openapi.diagnostic.Logger; | import com.intellij.openapi.diagnostic.Logger; | ||||||
|  | import com.intellij.openapi.editor.Caret; | ||||||
| import com.intellij.openapi.editor.Document; | import com.intellij.openapi.editor.Document; | ||||||
| import com.intellij.openapi.editor.Editor; | import com.intellij.openapi.editor.Editor; | ||||||
| import com.intellij.openapi.editor.LogicalPosition; | 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.psi.util.PsiUtilBase; | ||||||
| import com.intellij.util.containers.ContainerUtil; | import com.intellij.util.containers.ContainerUtil; | ||||||
| import com.maddyhome.idea.vim.EventFacade; | import com.maddyhome.idea.vim.EventFacade; | ||||||
|  | import com.maddyhome.idea.vim.VimPlugin; | ||||||
| import com.maddyhome.idea.vim.api.*; | import com.maddyhome.idea.vim.api.*; | ||||||
| import com.maddyhome.idea.vim.command.*; | import com.maddyhome.idea.vim.command.*; | ||||||
| import com.maddyhome.idea.vim.common.IndentConfig; | import com.maddyhome.idea.vim.common.IndentConfig; | ||||||
| @@ -55,27 +68,80 @@ import kotlin.Pair; | |||||||
| import kotlin.Unit; | import kotlin.Unit; | ||||||
| import kotlin.jvm.functions.Function0; | import kotlin.jvm.functions.Function0; | ||||||
| import kotlin.text.StringsKt; | import kotlin.text.StringsKt; | ||||||
|  | import org.jetbrains.annotations.NonNls; | ||||||
| import org.jetbrains.annotations.NotNull; | import org.jetbrains.annotations.NotNull; | ||||||
| import org.jetbrains.annotations.Nullable; | import org.jetbrains.annotations.Nullable; | ||||||
| import org.jetbrains.annotations.TestOnly; | import org.jetbrains.annotations.TestOnly; | ||||||
|  |  | ||||||
| import java.math.BigInteger; | import java.math.BigInteger; | ||||||
| import java.util.ArrayList; | import java.util.*; | ||||||
| import java.util.Collections; |  | ||||||
| import java.util.Comparator; |  | ||||||
| import java.util.List; |  | ||||||
|  |  | ||||||
| import static com.maddyhome.idea.vim.api.VimInjectorKt.injector; | 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 |  * Provides all the insert/replace related functionality | ||||||
|  */ |  */ | ||||||
| public class ChangeGroup extends VimChangeGroupBase { | 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 final List<VimInsertListener> insertListeners = ContainerUtil.createLockFreeCopyOnWriteList(); | ||||||
|  |  | ||||||
|   private long lastShownTime = 0L; |   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(); |     final Command motion = argument.getMotion(); | ||||||
|     if (!isChange && !motion.isLinewiseMotion()) { |     if (!isChange && !motion.isLinewiseMotion()) { | ||||||
|       BufferPosition start = editor.offsetToBufferPosition(range.getStartOffset()); |       VimLogicalPosition start = editor.offsetToLogicalPosition(range.getStartOffset()); | ||||||
|       BufferPosition end = editor.offsetToBufferPosition(range.getEndOffset()); |       VimLogicalPosition end = editor.offsetToLogicalPosition(range.getEndOffset()); | ||||||
|       if (start.getLine() != end.getLine()) { |       if (start.getLine() != end.getLine()) { | ||||||
|         int offset1 = range.getStartOffset(); |         if (!SearchHelper.anyNonWhitespace(((IjVimEditor) editor).getEditor(), range.getStartOffset(), -1) && | ||||||
|         if (!EngineEditorHelperKt.anyNonWhitespace(editor, offset1, -1)) { |             !SearchHelper.anyNonWhitespace(((IjVimEditor) editor).getEditor(), range.getEndOffset(), 1)) { | ||||||
|           int offset = range.getEndOffset(); |           type = SelectionType.LINE_WISE; | ||||||
|           if (!EngineEditorHelperKt.anyNonWhitespace(editor, offset, 1)) { |  | ||||||
|             type = SelectionType.LINE_WISE; |  | ||||||
|           } |  | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
| @@ -172,6 +235,93 @@ public class ChangeGroup extends VimChangeGroupBase { | |||||||
|    * @param argument The motion command |    * @param argument The motion command | ||||||
|    * @return true if able to delete the text, false if not |    * @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 |    * Toggles the case of count characters | ||||||
| @@ -183,12 +333,12 @@ public class ChangeGroup extends VimChangeGroupBase { | |||||||
|    */ |    */ | ||||||
|   @Override |   @Override | ||||||
|   public boolean changeCaseToggleCharacter(@NotNull VimEditor editor, @NotNull VimCaret caret, int count) { |   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) { |     if (offset == -1) { | ||||||
|       return false; |       return false; | ||||||
|     } |     } | ||||||
|     changeCase(editor, editor.currentCaret().getOffset().getPoint(), offset, CharacterHelper.CASE_TOGGLE); |     changeCase(editor, ((IjVimCaret) caret).getCaret().getOffset(), offset, CharacterHelper.CASE_TOGGLE); | ||||||
|     caret.moveToOffset(EngineEditorHelperKt.normalizeOffset(editor, offset, false)); |     injector.getMotion().moveCaret(editor, caret, EditorHelper.normalizeOffset(((IjVimEditor) editor).getEditor(), offset, false)); | ||||||
|     return true; |     return true; | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -199,11 +349,11 @@ public class ChangeGroup extends VimChangeGroupBase { | |||||||
|                              boolean append, |                              boolean append, | ||||||
|                              @NotNull OperatorArguments operatorArguments) { |                              @NotNull OperatorArguments operatorArguments) { | ||||||
|     final int lines = VimChangeGroupBase.Companion.getLinesCountInVisualBlock(editor, range); |     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 && |     boolean visualBlockMode = operatorArguments.getMode() == VimStateMachine.Mode.VISUAL && | ||||||
|                               operatorArguments.getSubMode() == VimStateMachine.SubMode.VISUAL_BLOCK; |                               operatorArguments.getSubMode() == VimStateMachine.SubMode.VISUAL_BLOCK; | ||||||
|     for (VimCaret caret : editor.carets()) { |     for (Caret caret : ((IjVimEditor) editor).getEditor().getCaretModel().getAllCarets()) { | ||||||
|       final int line = startPosition.getLine(); |       final int line = startPosition.getLine(); | ||||||
|       int column = startPosition.getColumn(); |       int column = startPosition.getColumn(); | ||||||
|       if (!visualBlockMode) { |       if (!visualBlockMode) { | ||||||
| @@ -211,20 +361,20 @@ public class ChangeGroup extends VimChangeGroupBase { | |||||||
|       } |       } | ||||||
|       else if (append) { |       else if (append) { | ||||||
|         column += range.getMaxLength(); |         column += range.getMaxLength(); | ||||||
|         if (caret.getVimLastColumn() == VimMotionGroupBase.LAST_COLUMN) { |         if (UserDataManager.getVimLastColumn(caret) == VimMotionGroupBase.LAST_COLUMN) { | ||||||
|           column = 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) { |       if (column < VimMotionGroupBase.LAST_COLUMN && lineLength < column) { | ||||||
|         final String pad = EditorHelper.pad(((IjVimEditor) editor).getEditor(), ((IjExecutionContext) context).getContext(), line, column); |         final String pad = EditorHelper.pad(((IjVimEditor) editor).getEditor(), ((IjExecutionContext) context).getContext(), line, column); | ||||||
|         final int offset = editor.getLineEndOffset(line); |         final int offset = ((IjVimEditor) editor).getEditor().getDocument().getLineEndOffset(line); | ||||||
|         insertText(editor, caret, offset, pad); |         insertText(editor, new IjVimCaret(caret), offset, pad); | ||||||
|       } |       } | ||||||
|  |  | ||||||
|       if (visualBlockMode || !append) { |       if (visualBlockMode || !append) { | ||||||
|         InlayHelperKt.moveToInlayAwareLogicalPosition(((IjVimCaret)caret).getCaret(), new LogicalPosition(line, column)); |         InlayHelperKt.moveToInlayAwareLogicalPosition(caret, new LogicalPosition(line, column)); | ||||||
|       } |       } | ||||||
|       if (visualBlockMode) { |       if (visualBlockMode) { | ||||||
|         setInsertRepeat(lines, column, append); |         setInsertRepeat(lines, column, append); | ||||||
| @@ -257,7 +407,7 @@ public class ChangeGroup extends VimChangeGroupBase { | |||||||
|     for (int i = ends.length - 1; i >= 0; i--) { |     for (int i = ends.length - 1; i >= 0; i--) { | ||||||
|       changeCase(editor, starts[i], ends[i], type); |       changeCase(editor, starts[i], ends[i], type); | ||||||
|     } |     } | ||||||
|     caret.moveToOffset(range.getStartOffset()); |     injector.getMotion().moveCaret(editor, caret, range.getStartOffset()); | ||||||
|     return true; |     return true; | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -275,9 +425,9 @@ public class ChangeGroup extends VimChangeGroupBase { | |||||||
|       end = start; |       end = start; | ||||||
|       start = t; |       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(); |     StringBuilder sb = new StringBuilder(); | ||||||
|     for (int i = start; i < end; i++) { |     for (int i = start; i < end; i++) { | ||||||
|       sb.append(CharacterHelper.changeCase(chars.charAt(i), type)); |       sb.append(CharacterHelper.changeCase(chars.charAt(i), type)); | ||||||
| @@ -285,10 +435,68 @@ public class ChangeGroup extends VimChangeGroupBase { | |||||||
|     replaceText(editor, start, end, sb.toString()); |     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) { |   private void restoreCursor(@NotNull VimEditor editor, @NotNull VimCaret caret, int startLine) { | ||||||
|     if (!caret.equals(editor.primaryCaret())) { |     if (!caret.equals(editor.primaryCaret())) { | ||||||
|       ((IjVimEditor) editor).getEditor().getCaretModel().addCaret( |       ((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) { |   private boolean reformatCodeRange(@NotNull VimEditor editor, @NotNull VimCaret caret, @NotNull TextRange range) { | ||||||
|     int[] starts = range.getStartOffsets(); |     int[] starts = range.getStartOffsets(); | ||||||
|     int[] ends = range.getEndOffsets(); |     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--) { |     for (int i = ends.length - 1; i >= 0; i--) { | ||||||
|       final int startOffset = EngineEditorHelperKt.getLineStartForOffset(editor, starts[i]); |       final int startOffset = EditorHelper.getLineStartForOffset(((IjVimEditor) editor).getEditor(), starts[i]); | ||||||
|       final int offset = ends[i] - (startOffset == ends[i] ? 0 : 1); |       final int endOffset = EditorHelper.getLineEndForOffset(((IjVimEditor) editor).getEditor(), ends[i] - (startOffset == ends[i] ? 0 : 1)); | ||||||
|       final int endOffset = EngineEditorHelperKt.getLineEndForOffset(editor, offset); |  | ||||||
|       reformatCode(editor, startOffset, endOffset); |       reformatCode(editor, startOffset, endOffset); | ||||||
|     } |     } | ||||||
|     final int newOffset = injector.getMotion().moveCaretToLineStartSkipLeading(editor, firstLine); |     final int newOffset = VimPlugin.getMotion().moveCaretToLineStartSkipLeading(editor, firstLine); | ||||||
|     caret.moveToOffset(newOffset); |     injector.getMotion().moveCaret(editor, caret, newOffset); | ||||||
|     return true; |     return true; | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -373,8 +580,8 @@ public class ChangeGroup extends VimChangeGroupBase { | |||||||
|                               @NotNull VimCaret caret, |                               @NotNull VimCaret caret, | ||||||
|                               @NotNull ExecutionContext context, |                               @NotNull ExecutionContext context, | ||||||
|                               @NotNull TextRange range) { |                               @NotNull TextRange range) { | ||||||
|     final int startOffset = EngineEditorHelperKt.getLineStartForOffset(editor, range.getStartOffset()); |     final int startOffset = injector.getEngineEditorHelper().getLineStartForOffset(editor, range.getStartOffset()); | ||||||
|     final int endOffset = EngineEditorHelperKt.getLineEndForOffset(editor, range.getEndOffset()); |     final int endOffset = injector.getEngineEditorHelper().getLineEndForOffset(editor, range.getEndOffset()); | ||||||
|  |  | ||||||
|     Editor ijEditor = ((IjVimEditor)editor).getEditor(); |     Editor ijEditor = ((IjVimEditor)editor).getEditor(); | ||||||
|     VisualModeHelperKt.vimSetSystemSelectionSilently(ijEditor.getSelectionModel(), startOffset, endOffset); |     VisualModeHelperKt.vimSetSystemSelectionSilently(ijEditor.getSelectionModel(), startOffset, endOffset); | ||||||
| @@ -383,14 +590,14 @@ public class ChangeGroup extends VimChangeGroupBase { | |||||||
|     Function0<Unit> actionExecution = () -> { |     Function0<Unit> actionExecution = () -> { | ||||||
|       NativeAction joinLinesAction = VimInjectorKt.getInjector().getNativeActionManager().getIndentLines(); |       NativeAction joinLinesAction = VimInjectorKt.getInjector().getNativeActionManager().getIndentLines(); | ||||||
|       if (joinLinesAction != null) { |       if (joinLinesAction != null) { | ||||||
|         VimInjectorKt.getInjector().getActionExecutor().executeAction(editor, joinLinesAction, context); |         VimInjectorKt.getInjector().getActionExecutor().executeAction(joinLinesAction, context); | ||||||
|       } |       } | ||||||
|       return null; |       return null; | ||||||
|     }; |     }; | ||||||
|     Function0<Unit> afterAction = () -> { |     Function0<Unit> afterAction = () -> { | ||||||
|       final int firstLine = editor.offsetToBufferPosition(Math.min(startOffset, endOffset)).getLine(); |       final int firstLine = editor.offsetToLogicalPosition(Math.min(startOffset, endOffset)).getLine(); | ||||||
|       final int newOffset = injector.getMotion().moveCaretToLineStartSkipLeading(editor, firstLine); |       final int newOffset = VimPlugin.getMotion().moveCaretToLineStartSkipLeading(editor, firstLine); | ||||||
|       caret.moveToOffset(newOffset); |       injector.getMotion().moveCaret(editor, caret, newOffset); | ||||||
|       restoreCursor(editor, caret, ((IjVimCaret)caret).getCaret().getLogicalPosition().line); |       restoreCursor(editor, caret, ((IjVimCaret)caret).getCaret().getLogicalPosition().line); | ||||||
|       return null; |       return null; | ||||||
|     }; |     }; | ||||||
| @@ -410,8 +617,8 @@ public class ChangeGroup extends VimChangeGroupBase { | |||||||
|                           int lines, |                           int lines, | ||||||
|                           int dir, |                           int dir, | ||||||
|                           @NotNull OperatorArguments operatorArguments) { |                           @NotNull OperatorArguments operatorArguments) { | ||||||
|     int start = caret.getOffset().getPoint(); |     int start = ((IjVimCaret) caret).getCaret().getOffset(); | ||||||
|     int end = injector.getMotion().moveCaretToRelativeLineEnd(editor, caret, lines - 1, true); |     int end = VimPlugin.getMotion().moveCaretToLineEndOffset(editor, caret, lines - 1, true); | ||||||
|     indentRange(editor, caret, context, new TextRange(start, end), 1, dir, operatorArguments); |     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 |   @Override | ||||||
|   public void indentRange(@NotNull VimEditor editor, |   public void indentRange(@NotNull VimEditor editor, | ||||||
|                           @NotNull VimCaret caret, |                           @NotNull VimCaret caret, | ||||||
| @@ -441,40 +665,40 @@ public class ChangeGroup extends VimChangeGroupBase { | |||||||
|       logger.debug("count=" + count); |       logger.debug("count=" + count); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // Remember the current caret column |     // Update the last column before we indent, or we might be retrieving the data for a line that no longer exists | ||||||
|     final int intendedColumn = caret.getVimLastColumn(); |     UserDataManager.setVimLastColumn(((IjVimCaret) caret).getCaret(), InlayHelperKt.getInlayAwareVisualColumn(((IjVimCaret) caret).getCaret())); | ||||||
|  |  | ||||||
|     IndentConfig indentConfig = IndentConfig.create(((IjVimEditor) editor).getEditor(), ((IjExecutionContext) context).getContext()); |     IndentConfig indentConfig = IndentConfig.create(((IjVimEditor) editor).getEditor(), ((IjExecutionContext) context).getContext()); | ||||||
|  |  | ||||||
|     final int sline = editor.offsetToBufferPosition(range.getStartOffset()).getLine(); |     final int sline = editor.offsetToLogicalPosition(range.getStartOffset()).getLine(); | ||||||
|     final BufferPosition endLogicalPosition = editor.offsetToBufferPosition(range.getEndOffset()); |     final VimLogicalPosition endLogicalPosition = editor.offsetToLogicalPosition(range.getEndOffset()); | ||||||
|     final int eline = |     final int eline = | ||||||
|       endLogicalPosition.getColumn() == 0 ? Math.max(endLogicalPosition.getLine() - 1, 0) : endLogicalPosition.getLine(); |       endLogicalPosition.getColumn() == 0 ? Math.max(endLogicalPosition.getLine() - 1, 0) : endLogicalPosition.getLine(); | ||||||
|  |  | ||||||
|     if (range.isMultiple()) { |     if (range.isMultiple()) { | ||||||
|       final int from = editor.offsetToBufferPosition(range.getStartOffset()).getColumn(); |       final int from = editor.offsetToLogicalPosition(range.getStartOffset()).getColumn(); | ||||||
|       if (dir == 1) { |       if (dir == 1) { | ||||||
|         // Right shift blockwise selection |         // Right shift blockwise selection | ||||||
|         final String indent = indentConfig.createIndentByCount(count); |         final String indent = indentConfig.createIndentByCount(count); | ||||||
|  |  | ||||||
|         for (int l = sline; l <= eline; l++) { |         for (int l = sline; l <= eline; l++) { | ||||||
|           int len = EngineEditorHelperKt.lineLength(editor, l); |           int len = EditorHelper.getLineLength(((IjVimEditor) editor).getEditor(), l); | ||||||
|           if (len > from) { |           if (len > from) { | ||||||
|             BufferPosition spos = new BufferPosition(l, from, false); |             VimLogicalPosition spos = new VimLogicalPosition(l, from, false); | ||||||
|             insertText(editor, caret, spos, indent); |             insertText(editor, caret, spos, indent); | ||||||
|           } |           } | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|       else { |       else { | ||||||
|         // Left shift blockwise selection |         // Left shift blockwise selection | ||||||
|         CharSequence chars = editor.text(); |         CharSequence chars = ((IjVimEditor) editor).getEditor().getDocument().getCharsSequence(); | ||||||
|         for (int l = sline; l <= eline; l++) { |         for (int l = sline; l <= eline; l++) { | ||||||
|           int len = EngineEditorHelperKt.lineLength(editor, l); |           int len = EditorHelper.getLineLength(((IjVimEditor) editor).getEditor(), l); | ||||||
|           if (len > from) { |           if (len > from) { | ||||||
|             BufferPosition spos = new BufferPosition(l, from, false); |             VimLogicalPosition spos = new VimLogicalPosition(l, from, false); | ||||||
|             BufferPosition epos = new BufferPosition(l, from + indentConfig.getTotalIndent(count) - 1, false); |             VimLogicalPosition epos = new VimLogicalPosition(l, from + indentConfig.getTotalIndent(count) - 1, false); | ||||||
|             int wsoff = editor.bufferPositionToOffset(spos); |             int wsoff = editor.logicalPositionToOffset(spos); | ||||||
|             int weoff = editor.bufferPositionToOffset(epos); |             int weoff = editor.logicalPositionToOffset(epos); | ||||||
|             int pos; |             int pos; | ||||||
|             for (pos = wsoff; pos <= weoff; pos++) { |             for (pos = wsoff; pos <= weoff; pos++) { | ||||||
|               if (CharacterHelper.charType(chars.charAt(pos), false) != CharacterHelper.CharacterType.WHITESPACE) { |               if (CharacterHelper.charType(chars.charAt(pos), false) != CharacterHelper.CharacterType.WHITESPACE) { | ||||||
| @@ -491,10 +715,10 @@ public class ChangeGroup extends VimChangeGroupBase { | |||||||
|     else { |     else { | ||||||
|       // Shift non-blockwise selection |       // Shift non-blockwise selection | ||||||
|       for (int l = sline; l <= eline; l++) { |       for (int l = sline; l <= eline; l++) { | ||||||
|         final int soff = editor.getLineStartOffset(l); |         final int soff = injector.getEngineEditorHelper().getLineStartOffset(editor, l); | ||||||
|         final int eoff = EngineEditorHelperKt.getLineEndOffset(editor, l, true); |         final int eoff = injector.getEngineEditorHelper().getLineEndOffset(editor, l, true); | ||||||
|         final int woff = injector.getMotion().moveCaretToLineStartSkipLeading(editor, l); |         final int woff = VimPlugin.getMotion().moveCaretToLineStartSkipLeading(editor, l); | ||||||
|         final int col = editor.offsetToVisualPosition(woff).getColumn(); |         final int col = ((IjVimEditor) editor).getEditor().offsetToVisualPosition(woff).getColumn(); | ||||||
|         final int limit = Math.max(0, col + dir * indentConfig.getTotalIndent(count)); |         final int limit = Math.max(0, col + dir * indentConfig.getTotalIndent(count)); | ||||||
|         if (col > 0 || soff != eoff) { |         if (col > 0 || soff != eoff) { | ||||||
|           final String indent = indentConfig.createIndentBySize(limit); |           final String indent = indentConfig.createIndentBySize(limit); | ||||||
| @@ -505,15 +729,14 @@ public class ChangeGroup extends VimChangeGroupBase { | |||||||
|  |  | ||||||
|     if (!CommandStateHelper.inInsertMode(((IjVimEditor) editor).getEditor())) { |     if (!CommandStateHelper.inInsertMode(((IjVimEditor) editor).getEditor())) { | ||||||
|       if (!range.isMultiple()) { |       if (!range.isMultiple()) { | ||||||
|         // The caret has moved, so reset the intended column before trying to get the expected offset |         injector.getMotion().moveCaret(editor, caret, VimPlugin.getMotion().moveCaretToLineWithStartOfLineOption(editor, sline, caret)); | ||||||
|         VimCaret newCaret = caret.setVimLastColumnAndGetCaret(intendedColumn); |  | ||||||
|         final int offset = injector.getMotion().moveCaretToLineWithStartOfLineOption(editor, sline, caret); |  | ||||||
|         newCaret.moveToOffset(offset); |  | ||||||
|       } |       } | ||||||
|       else { |       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; |       return false; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     final int startOffset = editor.getLineStartOffset(startLine); |     final int startOffset = ((IjVimEditor) editor).getEditor().getDocument().getLineStartOffset(startLine); | ||||||
|     final int endOffset = editor.getLineEndOffset(endLine); |     final int endOffset = ((IjVimEditor) editor).getEditor().getDocument().getLineEndOffset(endLine); | ||||||
|  |  | ||||||
|     return sortTextRange(editor, startOffset, endOffset, lineComparator); |     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 alpha = nf.contains("alpha"); | ||||||
|     boolean hex = nf.contains("hex"); |     boolean hex = nf.contains("hex"); | ||||||
|     boolean octal = nf.contains("octal"); |     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); |       SearchHelper.findNumbersInRange(((IjVimEditor) editor).getEditor(), selectedRange, alpha, hex, octal); | ||||||
|  |  | ||||||
|     List<String> newNumbers = new ArrayList<>(); |     List<String> newNumbers = new ArrayList<>(); | ||||||
|     for (int i = 0; i < numberRanges.size(); i++) { |     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; |       int iCount = avalanche ? (i + 1) * count : count; | ||||||
|       String newNumber = changeNumberInRange(editor, numberRange, iCount, alpha, hex, octal); |       String newNumber = changeNumberInRange(editor, numberRange, iCount, alpha, hex, octal); | ||||||
|       newNumbers.add(newNumber); |       newNumbers.add(newNumber); | ||||||
| @@ -611,7 +834,7 @@ public class ChangeGroup extends VimChangeGroupBase { | |||||||
|  |  | ||||||
|     for (int i = newNumbers.size() - 1; i >= 0; i--) { |     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 |       // 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); |       String newNumber = newNumbers.get(i); | ||||||
|       replaceText(editor, rangeToReplace.getFirst().getStartOffset(), rangeToReplace.getFirst().getEndOffset(), newNumber); |       replaceText(editor, rangeToReplace.getFirst().getStartOffset(), rangeToReplace.getFirst().getEndOffset(), newNumber); | ||||||
|     } |     } | ||||||
| @@ -623,12 +846,12 @@ public class ChangeGroup extends VimChangeGroupBase { | |||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public boolean changeNumber(final @NotNull VimEditor editor, @NotNull VimCaret caret, final int count) { |   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 alpha = nf.contains("alpha"); | ||||||
|     final boolean hex = nf.contains("hex"); |     final boolean hex = nf.contains("hex"); | ||||||
|     final boolean octal = nf.contains("octal"); |     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); |       SearchHelper.findNumberUnderCursor(((IjVimEditor) editor).getEditor(), ((IjVimCaret) caret).getCaret(), alpha, hex, octal); | ||||||
|     if (range == null) { |     if (range == null) { | ||||||
|       logger.debug("no number on line"); |       logger.debug("no number on line"); | ||||||
| @@ -661,14 +884,14 @@ public class ChangeGroup extends VimChangeGroupBase { | |||||||
|     strokes.add(chars); |     strokes.add(chars); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   private @Nullable String changeNumberInRange(final @NotNull VimEditor editor, |   public @Nullable String changeNumberInRange(final @NotNull VimEditor editor, | ||||||
|                                               Pair<TextRange, NumberType> range, |                                               Pair<TextRange, SearchHelper.NumberType> range, | ||||||
|                                               final int count, |                                               final int count, | ||||||
|                                               boolean alpha, |                                               boolean alpha, | ||||||
|                                               boolean hex, |                                               boolean hex, | ||||||
|                                               boolean octal) { |                                               boolean octal) { | ||||||
|     String text = EngineEditorHelperKt.getText(editor, range.getFirst()); |     String text = EditorHelper.getText(((IjVimEditor) editor).getEditor(), range.getFirst()); | ||||||
|     NumberType numberType = range.getSecond(); |     SearchHelper.NumberType numberType = range.getSecond(); | ||||||
|     if (logger.isDebugEnabled()) { |     if (logger.isDebugEnabled()) { | ||||||
|       logger.debug("found range " + range); |       logger.debug("found range " + range); | ||||||
|       logger.debug("text=" + text); |       logger.debug("text=" + text); | ||||||
| @@ -679,7 +902,7 @@ public class ChangeGroup extends VimChangeGroupBase { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     char ch = text.charAt(0); |     char ch = text.charAt(0); | ||||||
|     if (hex && NumberType.HEX.equals(numberType)) { |     if (hex && SearchHelper.NumberType.HEX.equals(numberType)) { | ||||||
|       if (!text.toLowerCase().startsWith(HEX_START)) { |       if (!text.toLowerCase().startsWith(HEX_START)) { | ||||||
|         throw new RuntimeException("Hex number should start with 0x: " + text); |         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; |       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); |       if (!text.startsWith("0")) throw new RuntimeException("Oct number should start with 0: " + text); | ||||||
|       BigInteger num = new BigInteger(text, 8).add(BigInteger.valueOf(count)); |       BigInteger num = new BigInteger(text, 8).add(BigInteger.valueOf(count)); | ||||||
|  |  | ||||||
| @@ -715,14 +938,14 @@ public class ChangeGroup extends VimChangeGroupBase { | |||||||
|       number = num.toString(8); |       number = num.toString(8); | ||||||
|       number = "0" + StringsKt.padStart(number, text.length() - 1, '0'); |       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); |       if (!Character.isLetter(ch)) throw new RuntimeException("Not alpha number : " + text); | ||||||
|       ch += count; |       ch += count; | ||||||
|       if (Character.isLetter(ch)) { |       if (Character.isLetter(ch)) { | ||||||
|         number = String.valueOf(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); |       if (ch != '-' && !Character.isDigit(ch)) throw new RuntimeException("Not dec number : " + text); | ||||||
|       boolean pad = ch == '0'; |       boolean pad = ch == '0'; | ||||||
|       int len = text.length(); |       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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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 | 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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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; | 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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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; | 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")}) | @State(name = "VimEditorSettings", storages = {@Storage(value = "$APP_CONFIG$/vim_settings.xml")}) | ||||||
| public class EditorGroup implements PersistentStateComponent<Element>, VimEditorGroup { | 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"; |   public static final @NonNls String EDITOR_STORE_ELEMENT = "editor"; | ||||||
|  |  | ||||||
|  |   private boolean isRefrainFromScrolling = false; | ||||||
|   private Boolean isKeyRepeat = null; |   private Boolean isKeyRepeat = null; | ||||||
|  |  | ||||||
|   private final CaretListener myLineNumbersCaretListener = new CaretListener() { |   private final CaretListener myLineNumbersCaretListener = new CaretListener() { | ||||||
| @@ -207,6 +219,7 @@ public class EditorGroup implements PersistentStateComponent<Element>, VimEditor | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   public void editorCreated(@NotNull Editor editor) { |   public void editorCreated(@NotNull Editor editor) { | ||||||
|  |     isRefrainFromScrolling = editor.getSettings().isRefrainFromScrolling(); | ||||||
|     DocumentManager.INSTANCE.addListeners(editor.getDocument()); |     DocumentManager.INSTANCE.addListeners(editor.getDocument()); | ||||||
|     VimPlugin.getKey().registerRequiredShortcutKeys(new IjVimEditor(editor)); |     VimPlugin.getKey().registerRequiredShortcutKeys(new IjVimEditor(editor)); | ||||||
|  |  | ||||||
| @@ -219,12 +232,14 @@ public class EditorGroup implements PersistentStateComponent<Element>, VimEditor | |||||||
|       KeyHandler.getInstance().reset(new IjVimEditor(editor)); |       KeyHandler.getInstance().reset(new IjVimEditor(editor)); | ||||||
|     } |     } | ||||||
|     updateCaretsVisualAttributes(editor); |     updateCaretsVisualAttributes(editor); | ||||||
|  |     //editor.getSettings().setRefrainFromScrolling(REFRAIN_FROM_SCROLLING_VIM_VALUE); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   public void editorDeinit(@NotNull Editor editor, boolean isReleased) { |   public void editorDeinit(@NotNull Editor editor, boolean isReleased) { | ||||||
|     deinitLineNumbers(editor, isReleased); |     deinitLineNumbers(editor, isReleased); | ||||||
|     UserDataManager.unInitializeEditor(editor); |     UserDataManager.unInitializeEditor(editor); | ||||||
|     VimPlugin.getKey().unregisterShortcutKeys(new IjVimEditor(editor)); |     VimPlugin.getKey().unregisterShortcutKeys(new IjVimEditor(editor)); | ||||||
|  |     editor.getSettings().setRefrainFromScrolling(isRefrainFromScrolling); | ||||||
|     DocumentManager.INSTANCE.removeListeners(editor.getDocument()); |     DocumentManager.INSTANCE.removeListeners(editor.getDocument()); | ||||||
|     CaretVisualAttributesHelperKt.removeCaretsVisualAttributes(editor); |     CaretVisualAttributesHelperKt.removeCaretsVisualAttributes(editor); | ||||||
|   } |   } | ||||||
| @@ -294,8 +309,8 @@ public class EditorGroup implements PersistentStateComponent<Element>, VimEditor | |||||||
|         return lineNumber; |         return lineNumber; | ||||||
|       } |       } | ||||||
|       else { |       else { | ||||||
|         final int visualLine = new IjVimEditor(editor).bufferLineToVisualLine(lineNumber - 1); |         final int visualLine = EditorHelper.logicalLineToVisualLine(editor, lineNumber - 1); | ||||||
|         final int currentVisualLine = new IjVimEditor(editor).bufferLineToVisualLine(caretLine); |         final int currentVisualLine = EditorHelper.logicalLineToVisualLine(editor, caretLine); | ||||||
|         return Math.abs(currentVisualLine - visualLine); |         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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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 | 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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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; | 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.fileTypes.FileTypeManager; | ||||||
| import com.intellij.openapi.project.Project; | import com.intellij.openapi.project.Project; | ||||||
| import com.intellij.openapi.roots.ProjectRootManager; | import com.intellij.openapi.roots.ProjectRootManager; | ||||||
|  | import com.intellij.openapi.util.Ref; | ||||||
| import com.intellij.openapi.vfs.LocalFileSystem; | import com.intellij.openapi.vfs.LocalFileSystem; | ||||||
|  | import com.intellij.openapi.vfs.VfsUtilCore; | ||||||
| import com.intellij.openapi.vfs.VirtualFile; | import com.intellij.openapi.vfs.VirtualFile; | ||||||
| import com.intellij.psi.search.FilenameIndex; | import com.intellij.openapi.vfs.VirtualFileVisitor; | ||||||
| import com.intellij.psi.search.GlobalSearchScope; |  | ||||||
| import com.intellij.psi.search.ProjectScope; |  | ||||||
| import com.maddyhome.idea.vim.VimPlugin; | import com.maddyhome.idea.vim.VimPlugin; | ||||||
| import com.maddyhome.idea.vim.api.*; | import com.maddyhome.idea.vim.api.*; | ||||||
| import com.maddyhome.idea.vim.command.VimStateMachine; | import com.maddyhome.idea.vim.command.VimStateMachine; | ||||||
| @@ -46,7 +56,6 @@ import org.jetbrains.annotations.NotNull; | |||||||
| import org.jetbrains.annotations.Nullable; | import org.jetbrains.annotations.Nullable; | ||||||
|  |  | ||||||
| import java.io.File; | import java.io.File; | ||||||
| import java.util.Collection; |  | ||||||
|  |  | ||||||
| public class FileGroup extends VimFileBase { | public class FileGroup extends VimFileBase { | ||||||
|   public boolean openFile(@NotNull String filename, @NotNull ExecutionContext context) { |   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)); |       found = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(new File(dir, homefile)); | ||||||
|     } |     } | ||||||
|     else { |     else { | ||||||
|       found = LocalFileSystem.getInstance().findFileByIoFile(new File(filename)); |       ProjectRootManager prm = ProjectRootManager.getInstance(project); | ||||||
|  |       VirtualFile[] roots = prm.getContentRoots(); | ||||||
|       if (found == null) { |       for (int i = 0; i < roots.length; i++) { | ||||||
|         found = findByNameInContentRoots(filename, project); |         if (logger.isDebugEnabled()) { | ||||||
|         if (found == null) { |           logger.debug("root[" + i + "] = " + roots[i].getPath()); | ||||||
|           found = findByNameInProject(filename, project); |         } | ||||||
|  |         found = findFile(roots[i], filename); | ||||||
|  |         if (found != null) { | ||||||
|  |           break; | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|  |  | ||||||
|  |       if (found == null) { | ||||||
|  |         found = LocalFileSystem.getInstance().findFileByIoFile(new File(filename)); | ||||||
|  |       } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     return found; |     return found; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Nullable |   private @Nullable VirtualFile findFile(@NotNull VirtualFile root, @NotNull String filename) { | ||||||
|   private VirtualFile findByNameInContentRoots(@NotNull String filename, @NotNull Project project) { |     VirtualFile res = root.findFileByRelativePath(filename); | ||||||
|     VirtualFile found = null; |     if (res != null) { | ||||||
|     ProjectRootManager prm = ProjectRootManager.getInstance(project); |       return res; | ||||||
|     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; |  | ||||||
|       } |  | ||||||
|     } |     } | ||||||
|     return found; |     final Ref<VirtualFile> result = Ref.create(); | ||||||
|   } |     final VirtualFileVisitor<Object> visitor = new VirtualFileVisitor<>() { | ||||||
|  |       @Override | ||||||
|   @Nullable |       public boolean visitFile(@NotNull VirtualFile file) { | ||||||
|   private static VirtualFile findByNameInProject(@NotNull String filename, @NotNull Project project) { |         if (file.getName().equals(filename)) { | ||||||
|     GlobalSearchScope projectScope = ProjectScope.getProjectScope(project); |           result.set(file); | ||||||
|     Collection<VirtualFile> names = FilenameIndex.getVirtualFilesByName(filename, projectScope); |           return false; | ||||||
|     if (!names.isEmpty()) { |         } | ||||||
|       return names.stream().findFirst().get(); |         return true; | ||||||
|     } |       } | ||||||
|     return null; |     }; | ||||||
|  |     VfsUtilCore.visitChildrenRecursively(root, visitor); | ||||||
|  |     return result.get(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
| @@ -310,7 +319,7 @@ public class FileGroup extends VimFileBase { | |||||||
|       } |       } | ||||||
|  |  | ||||||
|       int lline = editor.getCaretModel().getLogicalPosition().line; |       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); |       msg.append("; Line ").append(lline + 1).append(" of ").append(total); | ||||||
|  |  | ||||||
| @@ -355,7 +364,7 @@ public class FileGroup extends VimFileBase { | |||||||
|         word = cp.getCount(); |         word = cp.getCount(); | ||||||
|       } |       } | ||||||
|  |  | ||||||
|       int total = new IjVimEditor(editor).lineCount(); |       int total = EditorHelper.getLineCount(editor); | ||||||
|  |  | ||||||
|       msg.append(lines).append(" of ").append(total).append(" Lines"); |       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 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); |     int pct = (int)((float)lline / (float)total * 100f + 0.5); | ||||||
|  |  | ||||||
|     msg.append("line ").append(lline + 1).append(" of ").append(total); |     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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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; | 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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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 | 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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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 | 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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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 | 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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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; | 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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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 | 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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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; | 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.diagnostic.Logger; | ||||||
| import com.intellij.openapi.progress.ProcessCanceledException; | import com.intellij.openapi.progress.ProcessCanceledException; | ||||||
| import com.intellij.openapi.progress.ProgressManager; | import com.intellij.openapi.progress.ProgressManager; | ||||||
| import com.intellij.openapi.progress.util.PotemkinProgress; | import com.intellij.openapi.progress.util.PotemkinProgress; | ||||||
| import com.intellij.openapi.project.Project; | import com.intellij.openapi.project.Project; | ||||||
| import com.maddyhome.idea.vim.KeyHandler; | 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.ExecutionContext; | ||||||
| import com.maddyhome.idea.vim.api.VimEditor; | import com.maddyhome.idea.vim.api.VimEditor; | ||||||
| import com.maddyhome.idea.vim.helper.MessageHelper; | import com.maddyhome.idea.vim.helper.MessageHelper; | ||||||
| import com.maddyhome.idea.vim.key.KeyStack; | import com.maddyhome.idea.vim.key.KeyStack; | ||||||
| import com.maddyhome.idea.vim.macro.VimMacroBase; | import com.maddyhome.idea.vim.macro.VimMacroBase; | ||||||
| import com.maddyhome.idea.vim.newapi.IjVimEditor; | 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 org.jetbrains.annotations.NotNull; | ||||||
|  |  | ||||||
| import javax.swing.*; | import javax.swing.*; | ||||||
| @@ -46,30 +61,57 @@ public class MacroGroup extends VimMacroBase { | |||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     PotemkinProgress potemkinProgress = |     if (VimPlugin.getOptionService().isSet(OptionScope.GLOBAL.INSTANCE, OptionConstants.ideadelaymacroName, OptionConstants.ideadelaymacroName)) { | ||||||
|       new PotemkinProgress(MessageHelper.message("progress.title.macro.execution"), project, null, |       // This took a while to get just right. The original approach has a loop that made a runnable for each | ||||||
|                            MessageHelper.message("stop")); |       // character. It worked except for one case - if the macro had a complete ex command, the editor did not | ||||||
|     potemkinProgress.setIndeterminate(false); |       // end up with the focus and I couldn't find anyway to get it to have focus. This approach was the only | ||||||
|     potemkinProgress.setFraction(0); |       // solution. This makes the most sense now (of course it took hours of trial and error to come up with | ||||||
|     potemkinProgress.runInSwingThread(() -> { |       // this one). Each key gets added, one at a time, to the event queue. If a given key results in other | ||||||
|       // Handle one keystroke then queue up the next key |       // events getting queued, they get queued before the next key, just what would happen if the user was typing | ||||||
|       for (int i = 0; i < total; ++i) { |       // the keys one at a time. With the old loop approach, all the keys got queued, then any events they caused | ||||||
|         potemkinProgress.setFraction((double)(i + 1) / total); |       // were queued - after the keys. This is what caused the problem. | ||||||
|         while (keyStack.hasStroke()) { |       final Runnable run = () -> { | ||||||
|           KeyStroke key = keyStack.feedStroke(); |         // Handle one keystroke then queue up the next key | ||||||
|           try { |         if (keyStack.hasStroke()) { | ||||||
|             potemkinProgress.checkCanceled(); |           KeyHandler.getInstance().handleKey(editor, keyStack.feedStroke(), context); | ||||||
|           } |  | ||||||
|           catch (ProcessCanceledException e) { |  | ||||||
|             return; |  | ||||||
|           } |  | ||||||
|           ProgressManager.getInstance().executeNonCancelableSection(() -> { |  | ||||||
|             KeyHandler.getInstance().handleKey(editor, key, context); |  | ||||||
|           }); |  | ||||||
|         } |         } | ||||||
|         keyStack.resetFirst(); |         if (keyStack.hasStroke()) { | ||||||
|       } |           playbackKeys(editor, context, cnt, total); | ||||||
|       keyStack.removeFirst(); |         } | ||||||
|     }); |         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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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; | package com.maddyhome.idea.vim.group; | ||||||
| @@ -121,7 +131,7 @@ public class MarkGroup extends VimMarkGroupBase implements PersistentStateCompon | |||||||
|         if (!mark.isClear()) { |         if (!mark.isClear()) { | ||||||
|           Element markElem = new Element("mark"); |           Element markElem = new Element("mark"); | ||||||
|           markElem.setAttribute("key", Character.toString(mark.getKey())); |           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("column", Integer.toString(mark.getCol())); | ||||||
|           markElem.setAttribute("filename", StringUtil.notNullize(mark.getFilename())); |           markElem.setAttribute("filename", StringUtil.notNullize(mark.getFilename())); | ||||||
|           markElem.setAttribute("protocol", StringUtil.notNullize(mark.getProtocol(), "file")); |           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) { |           if (!mark.isClear() && !Character.isUpperCase(mark.getKey()) && SAVE_FILE_MARKS.indexOf(mark.getKey()) >= 0) { | ||||||
|             Element markElem = new Element("mark"); |             Element markElem = new Element("mark"); | ||||||
|             markElem.setAttribute("key", Character.toString(mark.getKey())); |             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("column", Integer.toString(mark.getCol())); | ||||||
|             fileMarkElem.addContent(markElem); |             fileMarkElem.addContent(markElem); | ||||||
|           } |           } | ||||||
| @@ -170,7 +180,7 @@ public class MarkGroup extends VimMarkGroupBase implements PersistentStateCompon | |||||||
|     Element jumpsElem = new Element("jumps"); |     Element jumpsElem = new Element("jumps"); | ||||||
|     for (Jump jump : jumps) { |     for (Jump jump : jumps) { | ||||||
|       Element jumpElem = new Element("jump"); |       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("column", Integer.toString(jump.getCol())); | ||||||
|       jumpElem.setAttribute("filename", StringUtil.notNullize(jump.getFilepath())); |       jumpElem.setAttribute("filename", StringUtil.notNullize(jump.getFilepath())); | ||||||
|       jumpsElem.addContent(jumpElem); |       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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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; | package com.maddyhome.idea.vim.group; | ||||||
|  |  | ||||||
| import com.intellij.openapi.actionSystem.DataContext; | import com.intellij.openapi.actionSystem.DataContext; | ||||||
| import com.intellij.openapi.editor.*; | import com.intellij.openapi.editor.*; | ||||||
|  | import com.intellij.openapi.editor.ex.util.EditorUtil; | ||||||
| import com.intellij.openapi.fileEditor.FileEditor; | import com.intellij.openapi.fileEditor.FileEditor; | ||||||
| import com.intellij.openapi.fileEditor.FileEditorManagerEvent; | import com.intellij.openapi.fileEditor.FileEditorManagerEvent; | ||||||
| import com.intellij.openapi.fileEditor.TextEditor; | 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.common.TextRange; | ||||||
| import com.maddyhome.idea.vim.ex.ExOutputModel; | import com.maddyhome.idea.vim.ex.ExOutputModel; | ||||||
| import com.maddyhome.idea.vim.group.visual.VimSelection; | 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.Motion; | ||||||
| import com.maddyhome.idea.vim.handler.MotionActionHandler; | import com.maddyhome.idea.vim.handler.MotionActionHandler; | ||||||
| import com.maddyhome.idea.vim.handler.TextObjectActionHandler; | import com.maddyhome.idea.vim.handler.TextObjectActionHandler; | ||||||
| @@ -64,6 +76,123 @@ import static java.lang.Math.min; | |||||||
|  */ |  */ | ||||||
| public class MotionGroup extends VimMotionGroupBase { | 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, |   public static @Nullable TextRange getMotionRange2(@NotNull Editor editor, | ||||||
|                                                     @NotNull Caret caret, |                                                     @NotNull Caret caret, | ||||||
| @@ -141,7 +270,7 @@ public class MotionGroup extends VimMotionGroupBase { | |||||||
|       String text = editor.getDocument().getCharsSequence().subSequence(start, end).toString(); |       String text = editor.getDocument().getCharsSequence().subSequence(start, end).toString(); | ||||||
|       final int lastNewLine = text.lastIndexOf('\n'); |       final int lastNewLine = text.lastIndexOf('\n'); | ||||||
|       if (lastNewLine > 0) { |       if (lastNewLine > 0) { | ||||||
|         if (!EngineEditorHelperKt.anyNonWhitespace(new IjVimEditor(editor), end, -1)) { |         if (!SearchHelper.anyNonWhitespace(editor, end, -1)) { | ||||||
|           end = start + lastNewLine; |           end = start + lastNewLine; | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
| @@ -156,16 +285,14 @@ public class MotionGroup extends VimMotionGroupBase { | |||||||
|     final int topVisualLine = getVisualLineAtTopOfScreen(editor); |     final int topVisualLine = getVisualLineAtTopOfScreen(editor); | ||||||
|     final int bottomVisualLine = getVisualLineAtBottomOfScreen(editor); |     final int bottomVisualLine = getVisualLineAtBottomOfScreen(editor); | ||||||
|     final int caretVisualLine = editor.getCaretModel().getVisualPosition().line; |     final int caretVisualLine = editor.getCaretModel().getVisualPosition().line; | ||||||
|     @NotNull final VimEditor editor1 = new IjVimEditor(editor); |     final int lastVisualLine = EditorHelper.getVisualLineCount(new IjVimEditor(editor)) - 1; | ||||||
|     final int lastVisualLine = EngineEditorHelperKt.getVisualLineCount(editor1) - 1; |  | ||||||
|  |  | ||||||
|     final int newVisualLine; |     final int newVisualLine; | ||||||
|     if (caretVisualLine < topVisualLine + scrollOffset) { |     if (caretVisualLine < topVisualLine + scrollOffset) { | ||||||
|       newVisualLine = EngineEditorHelperKt.normalizeVisualLine(new IjVimEditor(editor), topVisualLine + scrollOffset); |       newVisualLine = normalizeVisualLine(editor, topVisualLine + scrollOffset); | ||||||
|     } |     } | ||||||
|     else if (bottomVisualLine < lastVisualLine && caretVisualLine > bottomVisualLine - scrollOffset) { |     else if (bottomVisualLine < lastVisualLine && caretVisualLine > bottomVisualLine - scrollOffset) { | ||||||
|       newVisualLine = |       newVisualLine = normalizeVisualLine(editor, bottomVisualLine - scrollOffset); | ||||||
|         EngineEditorHelperKt.normalizeVisualLine(new IjVimEditor(editor), bottomVisualLine - scrollOffset); |  | ||||||
|     } |     } | ||||||
|     else { |     else { | ||||||
|       newVisualLine = caretVisualLine; |       newVisualLine = caretVisualLine; | ||||||
| @@ -175,12 +302,12 @@ public class MotionGroup extends VimMotionGroupBase { | |||||||
|  |  | ||||||
|     final int oldColumn = editor.getCaretModel().getVisualPosition().column; |     final int oldColumn = editor.getCaretModel().getVisualPosition().column; | ||||||
|     int col = oldColumn; |     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()); |       col = UserDataManager.getVimLastColumn(editor.getCaretModel().getPrimaryCaret()); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     final int leftVisualColumn = getVisualColumnAtLeftOfDisplay(editor, newVisualLine); |     final int leftVisualColumn = getVisualColumnAtLeftOfScreen(editor, newVisualLine); | ||||||
|     final int rightVisualColumn = getVisualColumnAtRightOfDisplay(editor, newVisualLine); |     final int rightVisualColumn = getVisualColumnAtRightOfScreen(editor, newVisualLine); | ||||||
|     int caretColumn = col; |     int caretColumn = col; | ||||||
|     int newColumn = caretColumn; |     int newColumn = caretColumn; | ||||||
|  |  | ||||||
| @@ -196,11 +323,11 @@ public class MotionGroup extends VimMotionGroupBase { | |||||||
|       col = newColumn; |       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) { |     if (newVisualLine != caretVisualLine || newColumn != oldColumn) { | ||||||
|       int offset = editor.visualPositionToOffset(new VisualPosition(newVisualLine, newColumn)); |       int offset = visualPositionToOffset(editor, new VisualPosition(newVisualLine, newColumn)); | ||||||
|       new IjVimCaret(editor.getCaretModel().getPrimaryCaret()).moveToOffset(offset); |       moveCaret(editor, editor.getCaretModel().getPrimaryCaret(), offset); | ||||||
|  |  | ||||||
|       UserDataManager.setVimLastColumn(editor.getCaretModel().getPrimaryCaret(), col); |       UserDataManager.setVimLastColumn(editor.getCaretModel().getPrimaryCaret(), col); | ||||||
|     } |     } | ||||||
| @@ -223,7 +350,7 @@ public class MotionGroup extends VimMotionGroupBase { | |||||||
|       targetCaretVisualLine = down ? caretVisualLine + scrollOption : caretVisualLine - scrollOption; |       targetCaretVisualLine = down ? caretVisualLine + scrollOption : caretVisualLine - scrollOption; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     return EngineEditorHelperKt.normalizeVisualLine(new IjVimEditor(editor), targetCaretVisualLine); |     return EditorHelper.normalizeVisualLine(editor, targetCaretVisualLine); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   private static int getScrollOption(int rawCount) { |   private static int getScrollOption(int rawCount) { | ||||||
| @@ -245,9 +372,43 @@ public class MotionGroup extends VimMotionGroupBase { | |||||||
|     return normalizeSideScrollOffset(editor, sideScrollOffset); |     return normalizeSideScrollOffset(editor, sideScrollOffset); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Override |   public void moveCaret(@NotNull VimEditor editor, @NotNull VimCaret caret, int offset) { | ||||||
|   public void onAppCodeMovement(@NotNull VimEditor editor, @NotNull VimCaret caret, int offset, int oldOffset) { |     moveCaret(((IjVimEditor) editor).getEditor(), ((IjVimCaret) caret).getCaret(), offset); | ||||||
|     AppCodeTemplates.onMovement(((IjVimEditor)editor).getEditor(), ((IjVimCaret)caret).getCaret(), oldOffset < 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) { |   private @Nullable Editor selectEditor(@NotNull Editor editor, @NotNull Mark mark) { | ||||||
| @@ -271,7 +432,7 @@ public class MotionGroup extends VimMotionGroupBase { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Override |   @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()); |     int pos = SearchHelper.findMatchingPairOnCurrentLine(((IjVimEditor)editor).getEditor(), ((IjVimCaret)caret).getCaret()); | ||||||
|     if (pos >= 0) { |     if (pos >= 0) { | ||||||
|       return pos; |       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 |   @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); |     scrollLineToScreenLocation(((IjVimEditor)editor).getEditor(), ScreenLocation.TOP, rawCount, start); | ||||||
|     return true; |     return true; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Override |   @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); |     scrollLineToScreenLocation(((IjVimEditor)editor).getEditor(), ScreenLocation.MIDDLE, rawCount, start); | ||||||
|     return true; |     return true; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Override |   @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); |     scrollLineToScreenLocation(((IjVimEditor)editor).getEditor(), ScreenLocation.BOTTOM, rawCount, start); | ||||||
|     return true; |     return true; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public boolean scrollCaretColumnToDisplayLeftEdge(@NotNull VimEditor vimEditor) { |   public boolean scrollCaretColumnToFirstScreenColumn(@NotNull VimEditor vimEditor) { | ||||||
|     Editor editor = ((IjVimEditor)vimEditor).getEditor(); |     Editor editor = ((IjVimEditor)vimEditor).getEditor(); | ||||||
|     final VisualPosition caretVisualPosition = editor.getCaretModel().getVisualPosition(); |     final VisualPosition caretVisualPosition = editor.getCaretModel().getVisualPosition(); | ||||||
|     final int scrollOffset = getNormalizedSideScrollOffset(editor); |     final int scrollOffset = getNormalizedSideScrollOffset(editor); | ||||||
| @@ -347,13 +552,13 @@ public class MotionGroup extends VimMotionGroupBase { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public boolean scrollCaretColumnToDisplayRightEdge(@NotNull VimEditor editor) { |   public boolean scrollCaretColumnToLastScreenColumn(@NotNull VimEditor editor) { | ||||||
|     Editor ijEditor = ((IjVimEditor)editor).getEditor(); |     Editor ijEditor = ((IjVimEditor)editor).getEditor(); | ||||||
|     final VisualPosition caretVisualPosition = ijEditor.getCaretModel().getVisualPosition(); |     final VisualPosition caretVisualPosition = ijEditor.getCaretModel().getVisualPosition(); | ||||||
|     final int scrollOffset = getNormalizedSideScrollOffset(ijEditor); |     final int scrollOffset = getNormalizedSideScrollOffset(ijEditor); | ||||||
|     // TODO: Should the offset be applied to visual columns? This includes inline inlays and folds |     // TODO: Should the offset be applied to visual columns? This includes inline inlays and folds | ||||||
|     final int column = |     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); |     scrollColumnToRightOfScreen(ijEditor, caretVisualPosition.line, column); | ||||||
|     return true; |     return true; | ||||||
|   } |   } | ||||||
| @@ -381,8 +586,7 @@ public class MotionGroup extends VimMotionGroupBase { | |||||||
|  |  | ||||||
|     final int topLine = getVisualLineAtTopOfScreen(editor); |     final int topLine = getVisualLineAtTopOfScreen(editor); | ||||||
|     final int bottomLine = getVisualLineAtBottomOfScreen(editor); |     final int bottomLine = getVisualLineAtBottomOfScreen(editor); | ||||||
|     @NotNull final VimEditor editor2 = new IjVimEditor(editor); |     final int lastLine = EditorHelper.getVisualLineCount(new IjVimEditor(editor)) - 1; | ||||||
|     final int lastLine = EngineEditorHelperKt.getVisualLineCount(editor2) - 1; |  | ||||||
|  |  | ||||||
|     // We need the non-normalised value here, so we can handle cases such as so=999 to keep the current line centred |     // 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(); |     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). |         // 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. |         // Our implementation ignores soft wrap line heights. Folds already have a line height of 1. | ||||||
|         final int usedAbove = caretLine - newTopLine; |         final int usedAbove = caretLine - newTopLine; | ||||||
|         @NotNull final VimEditor editor1 = new IjVimEditor(editor); |         final int usedBelow = min(scrollOffset, getVisualLineCount(new IjVimEditor(editor)) - caretLine); | ||||||
|         final int usedBelow = min(scrollOffset, EngineEditorHelperKt.getVisualLineCount(editor1) - caretLine); |  | ||||||
|         final int used = 1 + usedAbove + usedBelow; |         final int used = 1 + usedAbove + usedBelow; | ||||||
|         if (used > height) { |         if (used > height) { | ||||||
|           scrollVisualLineToMiddleOfScreen(editor, caretLine, false); |           scrollVisualLineToMiddleOfScreen(editor, caretLine, false); | ||||||
| @@ -493,8 +696,7 @@ public class MotionGroup extends VimMotionGroupBase { | |||||||
|         // The minus one is for the current line |         // The minus one is for the current line | ||||||
|         //noinspection UnnecessaryLocalVariable |         //noinspection UnnecessaryLocalVariable | ||||||
|         final int usedAbove = scrolledAbove; |         final int usedAbove = scrolledAbove; | ||||||
|         @NotNull final VimEditor editor1 = new IjVimEditor(editor); |         final int usedBelow = min(getVisualLineCount(new IjVimEditor(editor)) - caretLine, usedAbove - 1); | ||||||
|         final int usedBelow = min(EngineEditorHelperKt.getVisualLineCount(editor1) - caretLine, usedAbove - 1); |  | ||||||
|         final int used = min(height + 1, usedAbove + usedBelow); |         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 |         // 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) { |   private static void scrollCaretIntoViewHorizontally(@NotNull Editor editor, @NotNull VisualPosition position) { | ||||||
|     final int currentVisualLeftColumn = getVisualColumnAtLeftOfDisplay(editor, position.line); |     final int currentVisualLeftColumn = getVisualColumnAtLeftOfScreen(editor, position.line); | ||||||
|     final int currentVisualRightColumn = getVisualColumnAtRightOfDisplay(editor, position.line); |     final int currentVisualRightColumn = getVisualColumnAtRightOfScreen(editor, position.line); | ||||||
|     final int caretColumn = position.column; |     final int caretColumn = position.column; | ||||||
|  |  | ||||||
|     final int halfWidth = getApproximateScreenWidth(editor) / 2; |     final int halfWidth = getApproximateScreenWidth(editor) / 2; | ||||||
| @@ -557,7 +759,7 @@ public class MotionGroup extends VimMotionGroupBase { | |||||||
|         } |         } | ||||||
|         else { |         else { | ||||||
|           scrollColumnToRightOfScreen(editor, position.line, |           scrollColumnToRightOfScreen(editor, position.line, | ||||||
|                                       EngineEditorHelperKt.normalizeVisualColumn(new IjVimEditor(editor), position.line, currentVisualRightColumn + diff, |                                       normalizeVisualColumn(editor, position.line, currentVisualRightColumn + diff, | ||||||
|                                                             false)); |                                                             false)); | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
| @@ -565,31 +767,31 @@ public class MotionGroup extends VimMotionGroupBase { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public int moveCaretToFirstDisplayLine(@NotNull VimEditor editor, |   public int moveCaretToFirstScreenLine(@NotNull VimEditor editor, | ||||||
|                                          @NotNull ImmutableVimCaret caret, |                                         @NotNull VimCaret caret, | ||||||
|                                          int count, |                                         int count, | ||||||
|                                          boolean normalizeToScreen) { |                                         boolean normalizeToScreen) { | ||||||
|     return moveCaretToScreenLocation(((IjVimEditor)editor).getEditor(), ((IjVimCaret)caret).getCaret(), |     return moveCaretToScreenLocation(((IjVimEditor)editor).getEditor(), ((IjVimCaret)caret).getCaret(), | ||||||
|                                      ScreenLocation.TOP, count - 1, normalizeToScreen); |                                      ScreenLocation.TOP, count - 1, normalizeToScreen); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public int moveCaretToLastDisplayLine(@NotNull VimEditor editor, |   public int moveCaretToLastScreenLine(@NotNull VimEditor editor, | ||||||
|                                         @NotNull ImmutableVimCaret caret, |                                        @NotNull VimCaret caret, | ||||||
|                                         int count, |                                        int count, | ||||||
|                                         boolean normalizeToScreen) { |                                        boolean normalizeToScreen) { | ||||||
|     return moveCaretToScreenLocation(((IjVimEditor)editor).getEditor(), ((IjVimCaret)caret).getCaret(), |     return moveCaretToScreenLocation(((IjVimEditor)editor).getEditor(), ((IjVimCaret)caret).getCaret(), | ||||||
|                                      ScreenLocation.BOTTOM, count - 1, normalizeToScreen); |                                      ScreenLocation.BOTTOM, count - 1, normalizeToScreen); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Override |   @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(), |     return moveCaretToScreenLocation(((IjVimEditor)editor).getEditor(), ((IjVimCaret)caret).getCaret(), | ||||||
|                                      ScreenLocation.MIDDLE, 0, false); |                                      ScreenLocation.MIDDLE, 0, false); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public boolean scrollLines(@NotNull VimEditor editor, int lines) { |   public boolean scrollLine(@NotNull VimEditor editor, int lines) { | ||||||
|     assert lines != 0 : "lines cannot be 0"; |     assert lines != 0 : "lines cannot be 0"; | ||||||
|     Editor ijEditor = ((IjVimEditor)editor).getEditor(); |     Editor ijEditor = ((IjVimEditor)editor).getEditor(); | ||||||
|  |  | ||||||
| @@ -612,10 +814,10 @@ public class MotionGroup extends VimMotionGroupBase { | |||||||
|     final Mark mark = VimPlugin.getMark().getFileMark(editor, ch); |     final Mark mark = VimPlugin.getMark().getFileMark(editor, ch); | ||||||
|     if (mark == null) return -1; |     if (mark == null) return -1; | ||||||
|  |  | ||||||
|     final int line = mark.getLine(); |     final int line = mark.getLogicalLine(); | ||||||
|     return toLineStart |     return toLineStart | ||||||
|            ? moveCaretToLineStartSkipLeading(editor, line) |            ? moveCaretToLineStartSkipLeading(editor, line) | ||||||
|            : editor.bufferPositionToOffset(new BufferPosition(line, mark.getCol(), false)); |            : editor.logicalPositionToOffset(new VimLogicalPosition(line, mark.getCol(), false)); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
| @@ -626,20 +828,20 @@ public class MotionGroup extends VimMotionGroupBase { | |||||||
|     final VirtualFile vf = getVirtualFile(((IjVimEditor)editor).getEditor()); |     final VirtualFile vf = getVirtualFile(((IjVimEditor)editor).getEditor()); | ||||||
|     if (vf == null) return -1; |     if (vf == null) return -1; | ||||||
|  |  | ||||||
|     final int line = mark.getLine(); |     final int line = mark.getLogicalLine(); | ||||||
|     if (vf.getPath().equals(mark.getFilename())) { |     if (vf.getPath().equals(mark.getFilename())) { | ||||||
|       return toLineStart |       return toLineStart | ||||||
|              ? moveCaretToLineStartSkipLeading(editor, line) |              ? 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); |     final Editor selectedEditor = selectEditor(((IjVimEditor)editor).getEditor(), mark); | ||||||
|     if (selectedEditor != null) { |     if (selectedEditor != null) { | ||||||
|       for (Caret caret : selectedEditor.getCaretModel().getAllCarets()) { |       for (Caret caret : selectedEditor.getCaretModel().getAllCarets()) { | ||||||
|         new IjVimCaret(caret).moveToOffset(toLineStart |         moveCaret(selectedEditor, caret, toLineStart | ||||||
|                                            ? moveCaretToLineStartSkipLeading(new IjVimEditor(selectedEditor), line) |                                          ? moveCaretToLineStartSkipLeading(new IjVimEditor(selectedEditor), line) | ||||||
|                                            : selectedEditor.logicalPositionToOffset( |                                          : selectedEditor.logicalPositionToOffset( | ||||||
|                                              new LogicalPosition(line, mark.getCol()))); |                                            new LogicalPosition(line, mark.getCol()))); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|     return -2; |     return -2; | ||||||
| @@ -659,8 +861,8 @@ public class MotionGroup extends VimMotionGroupBase { | |||||||
|       return -1; |       return -1; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     final BufferPosition lp = new BufferPosition(jump.getLine(), jump.getCol(), false); |     final VimLogicalPosition lp = new VimLogicalPosition(jump.getLogicalLine(), jump.getCol(), false); | ||||||
|     final LogicalPosition lpnative = new LogicalPosition(jump.getLine(), jump.getCol(), false); |     final LogicalPosition lpnative = new LogicalPosition(jump.getLogicalLine(), jump.getCol(), false); | ||||||
|     final String fileName = jump.getFilepath(); |     final String fileName = jump.getFilepath(); | ||||||
|     if (!vf.getPath().equals(fileName)) { |     if (!vf.getPath().equals(fileName)) { | ||||||
|       final VirtualFile newFile = |       final VirtualFile newFile = | ||||||
| @@ -674,9 +876,8 @@ public class MotionGroup extends VimMotionGroupBase { | |||||||
|         if (spot == -1) { |         if (spot == -1) { | ||||||
|           VimPlugin.getMark().addJump(editor, false); |           VimPlugin.getMark().addJump(editor, false); | ||||||
|         } |         } | ||||||
|         new IjVimCaret(newEditor.getCaretModel().getCurrentCaret()).moveToOffset( |         moveCaret(newEditor, newEditor.getCaretModel().getCurrentCaret(), | ||||||
|           EngineEditorHelperKt.normalizeOffset(new IjVimEditor(newEditor), newEditor.logicalPositionToOffset(lpnative), |                   normalizeOffset(newEditor, newEditor.logicalPositionToOffset(lpnative), false)); | ||||||
|                                                false)); |  | ||||||
|       } |       } | ||||||
|  |  | ||||||
|       return -2; |       return -2; | ||||||
| @@ -686,29 +887,38 @@ public class MotionGroup extends VimMotionGroupBase { | |||||||
|         VimPlugin.getMark().addJump(editor, false); |         VimPlugin.getMark().addJump(editor, false); | ||||||
|       } |       } | ||||||
|  |  | ||||||
|       return editor.bufferPositionToOffset(lp); |       return editor.logicalPositionToOffset(lp); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Override |   @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 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); |     return moveCaretToColumn(editor, caret, max(0, min(len - 1, width)), false); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public Motion moveCaretToColumn(@NotNull VimEditor editor, @NotNull ImmutableVimCaret caret, int count, boolean allowEnd) { |   public Motion moveCaretToColumn(@NotNull VimEditor editor, @NotNull VimCaret caret, int count, boolean allowEnd) { | ||||||
|     final int line = caret.getLine().getLine(); |     int line = caret.getLine().getLine(); | ||||||
|     final int column = EngineEditorHelperKt.normalizeColumn(editor, line, count, allowEnd); |     int pos = normalizeColumn(((IjVimEditor)editor).getEditor(), line, count, allowEnd); | ||||||
|     final int offset = editor.bufferPositionToOffset(new BufferPosition(line, column, false)); |  | ||||||
|     if (column != count) { |     return new Motion.AbsoluteOffset(editor.logicalPositionToOffset(new VimLogicalPosition(line, pos, false))); | ||||||
|       return new Motion.AdjustedOffset(offset, count); |  | ||||||
|     } |  | ||||||
|     return new Motion.AbsoluteOffset(offset); |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   @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 |   @Override | ||||||
|   public boolean scrollColumns(@NotNull VimEditor editor, int columns) { |   public boolean scrollColumns(@NotNull VimEditor editor, int columns) { | ||||||
| @@ -716,8 +926,8 @@ public class MotionGroup extends VimMotionGroupBase { | |||||||
|     final VisualPosition caretVisualPosition = ijEditor.getCaretModel().getVisualPosition(); |     final VisualPosition caretVisualPosition = ijEditor.getCaretModel().getVisualPosition(); | ||||||
|     if (columns > 0) { |     if (columns > 0) { | ||||||
|       // TODO: Don't add columns to visual position. This includes inlays and folds |       // TODO: Don't add columns to visual position. This includes inlays and folds | ||||||
|       int visualColumn = EngineEditorHelperKt.normalizeVisualColumn(editor, caretVisualPosition.line, |       int visualColumn = normalizeVisualColumn(ijEditor, caretVisualPosition.line, | ||||||
|                                                getVisualColumnAtLeftOfDisplay(ijEditor, caretVisualPosition.line) + |                                                getVisualColumnAtLeftOfScreen(ijEditor, caretVisualPosition.line) + | ||||||
|                                                columns, false); |                                                columns, false); | ||||||
|  |  | ||||||
|       // If the target column has an inlay preceding it, move passed it. This inlay will have been (incorrectly) |       // 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 { |     else { | ||||||
|       // Don't normalise the rightmost column, or we break virtual space |       // 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); |       scrollColumnToRightOfScreen(ijEditor, caretVisualPosition.line, visualColumn); | ||||||
|     } |     } | ||||||
|     moveCaretToView(ijEditor); |     moveCaretToView(ijEditor); | ||||||
| @@ -742,26 +952,26 @@ public class MotionGroup extends VimMotionGroupBase { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public @NotNull Motion moveCaretToCurrentDisplayLineStart(@NotNull VimEditor editor, ImmutableVimCaret caret) { |   public @NotNull Motion moveCaretToLineScreenStart(@NotNull VimEditor editor, @NotNull VimCaret caret) { | ||||||
|     final int col = |     final int col = | ||||||
|       getVisualColumnAtLeftOfDisplay(((IjVimEditor)editor).getEditor(), caret.getVisualPosition().getLine()); |       getVisualColumnAtLeftOfScreen(((IjVimEditor)editor).getEditor(), caret.getVisualPosition().getLine()); | ||||||
|     return moveCaretToColumn(editor, caret, col, false); |     return moveCaretToColumn(editor, caret, col, false); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public @Range(from = 0, to = Integer.MAX_VALUE) int moveCaretToCurrentDisplayLineStartSkipLeading(@NotNull VimEditor editor, |   public @Range(from = 0, to = Integer.MAX_VALUE) int moveCaretToLineScreenStartSkipLeading(@NotNull VimEditor editor, | ||||||
|                                                                                                     ImmutableVimCaret caret) { |                                                                                             @NotNull VimCaret caret) { | ||||||
|     final int col = getVisualColumnAtLeftOfDisplay(((IjVimEditor)editor).getEditor(), caret.getVisualPosition().getLine()); |     final int col = getVisualColumnAtLeftOfScreen(((IjVimEditor)editor).getEditor(), caret.getVisualPosition().getLine()); | ||||||
|     final int logicalLine = caret.getLine().getLine(); |     final int logicalLine = caret.getLine().getLine(); | ||||||
|     return EngineEditorHelperKt.getLeadingCharacterOffset(editor, logicalLine, col); |     return getLeadingCharacterOffset(((IjVimEditor)editor).getEditor(), logicalLine, col); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public @NotNull Motion moveCaretToCurrentDisplayLineEnd(@NotNull VimEditor editor, |   public @NotNull Motion moveCaretToLineScreenEnd(@NotNull VimEditor editor, | ||||||
|                                                           ImmutableVimCaret caret, |                                                   @NotNull VimCaret caret, | ||||||
|                                                           boolean allowEnd) { |                                                   boolean allowEnd) { | ||||||
|     final int col = |     final int col = | ||||||
|       getVisualColumnAtRightOfDisplay(((IjVimEditor)editor).getEditor(), caret.getVisualPosition().getLine()); |       getVisualColumnAtRightOfScreen(((IjVimEditor)editor).getEditor(), caret.getVisualPosition().getLine()); | ||||||
|     return moveCaretToColumn(editor, caret, col, allowEnd); |     return moveCaretToColumn(editor, caret, col, allowEnd); | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -775,14 +985,13 @@ public class MotionGroup extends VimMotionGroupBase { | |||||||
|     final int topVisualLine = getVisualLineAtTopOfScreen(ijEditor); |     final int topVisualLine = getVisualLineAtTopOfScreen(ijEditor); | ||||||
|     int caretVisualLine = result.getSecond(); |     int caretVisualLine = result.getSecond(); | ||||||
|     if (caretVisualLine < topVisualLine + scrollOffset) { |     if (caretVisualLine < topVisualLine + scrollOffset) { | ||||||
|       caretVisualLine = |       caretVisualLine = normalizeVisualLine(ijEditor, caretVisualLine + scrollOffset); | ||||||
|         EngineEditorHelperKt.normalizeVisualLine(new IjVimEditor(ijEditor), caretVisualLine + scrollOffset); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     if (caretVisualLine != ijCaret.getVisualPosition().line) { |     if (caretVisualLine != ijCaret.getVisualPosition().line) { | ||||||
|       final int offset = |       final int offset = | ||||||
|         moveCaretToLineWithStartOfLineOption(editor, EngineEditorHelperKt.visualLineToBufferLine(editor, caretVisualLine), caret); |         moveCaretToLineWithStartOfLineOption(editor, visualLineToLogicalLine(ijEditor, caretVisualLine), caret); | ||||||
|       caret.moveToOffset(offset); |       moveCaret(ijEditor, ijCaret, offset); | ||||||
|       return result.getFirst(); |       return result.getFirst(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -799,14 +1008,13 @@ public class MotionGroup extends VimMotionGroupBase { | |||||||
|     final int bottomVisualLine = getVisualLineAtBottomOfScreen(ijEditor); |     final int bottomVisualLine = getVisualLineAtBottomOfScreen(ijEditor); | ||||||
|     int caretVisualLine = result.getSecond(); |     int caretVisualLine = result.getSecond(); | ||||||
|     if (caretVisualLine > bottomVisualLine - scrollOffset) { |     if (caretVisualLine > bottomVisualLine - scrollOffset) { | ||||||
|       caretVisualLine = |       caretVisualLine = normalizeVisualLine(ijEditor, caretVisualLine - scrollOffset); | ||||||
|         EngineEditorHelperKt.normalizeVisualLine(new IjVimEditor(ijEditor), caretVisualLine - scrollOffset); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     if (caretVisualLine != ijCaret.getVisualPosition().line && caretVisualLine != -1) { |     if (caretVisualLine != ijCaret.getVisualPosition().line && caretVisualLine != -1) { | ||||||
|       final int offset = |       final int offset = | ||||||
|         moveCaretToLineWithStartOfLineOption(editor, EngineEditorHelperKt.visualLineToBufferLine(editor, caretVisualLine), caret); |         moveCaretToLineWithStartOfLineOption(editor, visualLineToLogicalLine(ijEditor, caretVisualLine), caret); | ||||||
|       caret.moveToOffset(offset); |       moveCaret(ijEditor, ijCaret, offset); | ||||||
|       return result.getFirst(); |       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 |     // 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 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. |     // 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, |   public @Range(from = 0, to = Integer.MAX_VALUE) int moveCaretToLineWithSameColumn(@NotNull VimEditor editor, | ||||||
|                                                                                     int logicalLine, |                                                                                     int logicalLine, | ||||||
|                                                                                     @NotNull ImmutableVimCaret caret) { |                                                                                     @NotNull VimCaret caret) { | ||||||
|     int col = UserDataManager.getVimLastColumn(((IjVimCaret) caret).getCaret()); |     int col = UserDataManager.getVimLastColumn(((IjVimCaret) caret).getCaret()); | ||||||
|     int line = logicalLine; |     int line = logicalLine; | ||||||
|     if (logicalLine < 0) { |     if (logicalLine < 0) { | ||||||
| @@ -827,35 +1035,35 @@ public class MotionGroup extends VimMotionGroupBase { | |||||||
|       col = 0; |       col = 0; | ||||||
|     } |     } | ||||||
|     else if (logicalLine >= editor.lineCount()) { |     else if (logicalLine >= editor.lineCount()) { | ||||||
|       line = EngineEditorHelperKt.normalizeLine(editor, editor.lineCount() - 1); |       line = normalizeLine(((IjVimEditor) editor).getEditor(), editor.lineCount() - 1); | ||||||
|       col = EngineEditorHelperKt.lineLength(editor, line); |       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); |     return ((IjVimEditor) editor).getEditor().logicalPositionToOffset(newPos); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public @Range(from = 0, to = Integer.MAX_VALUE) int moveCaretToLineWithStartOfLineOption(@NotNull VimEditor editor, |   public @Range(from = 0, to = Integer.MAX_VALUE) int moveCaretToLineWithStartOfLineOption(@NotNull VimEditor editor, | ||||||
|                                                                                            int line, |                                                                                            int logicalLine, | ||||||
|                                                                                            @NotNull ImmutableVimCaret caret) { |                                                                                            @NotNull VimCaret caret) { | ||||||
|     if (VimPlugin.getOptionService().isSet(new OptionScope.LOCAL(editor), OptionConstants.startoflineName, OptionConstants.startoflineName)) { |     if (VimPlugin.getOptionService().isSet(new OptionScope.LOCAL(editor), OptionConstants.startoflineName, OptionConstants.startoflineName)) { | ||||||
|       return moveCaretToLineStartSkipLeading(editor, line); |       return moveCaretToLineStartSkipLeading(editor, logicalLine); | ||||||
|     } |     } | ||||||
|     else { |     else { | ||||||
|       return moveCaretToLineWithSameColumn(editor, line, caret); |       return moveCaretToLineWithSameColumn(editor, logicalLine, caret); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Override |   @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(); |     Editor ijEditor = ((IjVimEditor)editor).getEditor(); | ||||||
|     Caret ijCaret = ((IjVimCaret)caret).getCaret(); |     Caret ijCaret = ((IjVimCaret)caret).getCaret(); | ||||||
|     final CaretModel caretModel = ijEditor.getCaretModel(); |     final CaretModel caretModel = ijEditor.getCaretModel(); | ||||||
|     final int currentLogicalLine = caretModel.getLogicalPosition().line; |     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; |       return false; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -895,9 +1103,9 @@ public class MotionGroup extends VimMotionGroupBase { | |||||||
|       targetCaretVisualLine = max(visualTop, min(visualBottom, targetCaretVisualLine)); |       targetCaretVisualLine = max(visualTop, min(visualBottom, targetCaretVisualLine)); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     int logicalLine = EngineEditorHelperKt.visualLineToBufferLine(editor, targetCaretVisualLine); |     int logicalLine = visualLineToLogicalLine(ijEditor, targetCaretVisualLine); | ||||||
|     int caretOffset = moveCaretToLineWithStartOfLineOption(editor, logicalLine, caret); |     int caretOffset = moveCaretToLineWithStartOfLineOption(editor, logicalLine, caret); | ||||||
|     caret.moveToOffset(caretOffset); |     moveCaret(ijEditor, ijCaret, caretOffset); | ||||||
|  |  | ||||||
|     return true; |     return true; | ||||||
|   } |   } | ||||||
| @@ -910,14 +1118,9 @@ public class MotionGroup extends VimMotionGroupBase { | |||||||
|                                           boolean start) { |                                           boolean start) { | ||||||
|     final int scrollOffset = getNormalizedScrollOffset(editor); |     final int scrollOffset = getNormalizedScrollOffset(editor); | ||||||
|  |  | ||||||
|     int visualLine; |     int visualLine = rawCount == 0 | ||||||
|     if (rawCount == 0) { |                      ? editor.getCaretModel().getVisualPosition().line | ||||||
|       visualLine = editor.getCaretModel().getVisualPosition().line; |                      : logicalLineToVisualLine(editor, normalizeLine(editor, rawCount - 1)); | ||||||
|     } |  | ||||||
|     else { |  | ||||||
|       final int line = EngineEditorHelperKt.normalizeLine(new IjVimEditor(editor), rawCount - 1); |  | ||||||
|       visualLine = new IjVimEditor(editor).bufferLineToVisualLine(line); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     // This method moves the current (or [count]) line to the specified screen location |     // 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) |     // 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; |         break; | ||||||
|       case BOTTOM: |       case BOTTOM: | ||||||
|         // Make sure we scroll to an actual line, not virtual space |         // Make sure we scroll to an actual line, not virtual space | ||||||
|         scrollVisualLineToBottomOfScreen(editor, EngineEditorHelperKt.normalizeVisualLine(new IjVimEditor(editor), |         scrollVisualLineToBottomOfScreen(editor, normalizeVisualLine(editor, visualLine + scrollOffset)); | ||||||
|                                                                                           visualLine + scrollOffset)); |  | ||||||
|         break; |         break; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     if (visualLine != editor.getCaretModel().getVisualPosition().line || start) { |     if (visualLine != editor.getCaretModel().getVisualPosition().line || start) { | ||||||
|       int offset; |       int offset; | ||||||
|       if (start) { |       if (start) { | ||||||
|         offset = moveCaretToLineStartSkipLeading(new IjVimEditor(editor), EngineEditorHelperKt.visualLineToBufferLine( |         offset = moveCaretToLineStartSkipLeading(new IjVimEditor(editor), visualLineToLogicalLine(editor, visualLine)); | ||||||
|           new IjVimEditor(editor), visualLine)); |  | ||||||
|       } |       } | ||||||
|       else { |       else { | ||||||
|         offset = moveCaretToLineWithSameColumn(new IjVimEditor(editor), |         offset = getVerticalMotionOffset(new IjVimEditor(editor), new IjVimCaret(editor.getCaretModel().getPrimaryCaret()), | ||||||
|                                                EngineEditorHelperKt.visualLineToBufferLine(new IjVimEditor(editor), visualLine), |                                    visualLineToLogicalLine(editor, visualLine) - | ||||||
|                                                new IjVimCaret(editor.getCaretModel().getPrimaryCaret())); |                                    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 |   @Override | ||||||
|   public @Range(from = 0, to = Integer.MAX_VALUE) int moveCaretToLinePercent(@NotNull VimEditor editor, |   public @Range(from = 0, to = Integer.MAX_VALUE) int moveCaretToLinePercent(@NotNull VimEditor editor, | ||||||
|                                                                              @NotNull ImmutableVimCaret caret, |                                                                              @NotNull VimCaret caret, | ||||||
|                                                                              int count) { |                                                                              int count) { | ||||||
|     return moveCaretToLineWithStartOfLineOption(editor, |     return moveCaretToLineWithStartOfLineOption(editor, | ||||||
|                                                 EngineEditorHelperKt.normalizeLine(editor, |                                                 normalizeLine(((IjVimEditor)editor).getEditor(), | ||||||
|                                                               (editor.lineCount() * MathUtil.clamp(count, 0, 100) + |                                                               (editor.lineCount() * MathUtil.clamp(count, 0, 100) + | ||||||
|                                                                99) / 100 - 1), caret); |                                                                99) / 100 - 1), caret); | ||||||
|   } |   } | ||||||
| @@ -1012,7 +1213,7 @@ public class MotionGroup extends VimMotionGroupBase { | |||||||
|       final Editor editor = ((TextEditor)fileEditor).getEditor(); |       final Editor editor = ((TextEditor)fileEditor).getEditor(); | ||||||
|       ExOutputModel.getInstance(editor).clear(); |       ExOutputModel.getInstance(editor).clear(); | ||||||
|       if (VimStateMachine.getInstance(new IjVimEditor(editor)).getMode() == VimStateMachine.Mode.VISUAL) { |       if (VimStateMachine.getInstance(new IjVimEditor(editor)).getMode() == VimStateMachine.Mode.VISUAL) { | ||||||
|         EngineModeExtensionsKt.exitVisualMode(new IjVimEditor(editor)); |         ModeHelper.exitVisualMode(editor); | ||||||
|         KeyHandler.getInstance().reset(new IjVimEditor(editor)); |         KeyHandler.getInstance().reset(new IjVimEditor(editor)); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
| @@ -1031,8 +1232,7 @@ public class MotionGroup extends VimMotionGroupBase { | |||||||
|  |  | ||||||
|     final int scrollOffset = normalizeToScreen ? getNormalizedScrollOffset(editor) : 0; |     final int scrollOffset = normalizeToScreen ? getNormalizedScrollOffset(editor) : 0; | ||||||
|  |  | ||||||
|     @NotNull final VimEditor editor1 = new IjVimEditor(editor); |     final int maxVisualLine = getVisualLineCount(new IjVimEditor(editor)); | ||||||
|     final int maxVisualLine = EngineEditorHelperKt.getVisualLineCount(editor1); |  | ||||||
|  |  | ||||||
|     final int topVisualLine = getVisualLineAtTopOfScreen(editor); |     final int topVisualLine = getVisualLineAtTopOfScreen(editor); | ||||||
|     final int topScrollOff = topVisualLine > 0 ? scrollOffset : 0; |     final int topScrollOff = topVisualLine > 0 ? scrollOffset : 0; | ||||||
| @@ -1056,7 +1256,7 @@ public class MotionGroup extends VimMotionGroupBase { | |||||||
|         break; |         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)); |     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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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 | 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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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; | 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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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; | 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 |  * This program is free software: you can redistribute it and/or modify | ||||||
|  * license that can be found in the LICENSE.txt file or at |  * it under the terms of the GNU General Public License as published by | ||||||
|  * https://opensource.org/licenses/MIT. |  * 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; | package com.maddyhome.idea.vim.group; | ||||||
|  |  | ||||||
| @@ -62,6 +72,7 @@ import java.text.NumberFormat; | |||||||
| import java.text.ParsePosition; | import java.text.ParsePosition; | ||||||
| import java.util.*; | 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.HelperKt.localEditors; | ||||||
| import static com.maddyhome.idea.vim.helper.SearchHelperKtKt.shouldIgnoreCase; | import static com.maddyhome.idea.vim.helper.SearchHelperKtKt.shouldIgnoreCase; | ||||||
| import static com.maddyhome.idea.vim.register.RegisterConstants.LAST_SEARCH_REGISTER; | 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 (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(); |           p.inc(); | ||||||
|           patternOffset = p.toString(); |           patternOffset = p.toString(); | ||||||
|           if (logger.isDebugEnabled()) logger.debug("offset=" + patternOffset); |           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) { |       else if (command.length() == 1) { | ||||||
|         patternOffset = ""; |         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 |    * @return        The offset of the result or the start of the word under the caret if not found. Returns -1 on error | ||||||
|    */ |    */ | ||||||
|   @Override |   @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()); |     TextRange range = SearchHelper.findWordUnderCursor(((IjVimEditor)editor).getEditor(), ((IjVimCaret)caret).getCaret()); | ||||||
|     if (range == null) { |     if (range == null) { | ||||||
|       logger.warn("No range was found"); |       logger.warn("No range was found"); | ||||||
|       return -1; |       return -1; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @NotNull final Editor editor1 = ((IjVimEditor)editor).getEditor(); |     final String pattern = SearchHelper.makeSearchPattern(EditorHelper.getText(((IjVimEditor)editor).getEditor(), range.getStartOffset(), range.getEndOffset()), whole); | ||||||
|     final int start = range.getStartOffset(); |  | ||||||
|     final int end = range.getEndOffset(); |  | ||||||
|     final String pattern = SearchHelper.makeSearchPattern( |  | ||||||
|       EngineEditorHelperKt.getText(new IjVimEditor(editor1), start, end), whole); |  | ||||||
|  |  | ||||||
|     // Updates RE_LAST, ready for findItOffset |     // Updates RE_LAST, ready for findItOffset | ||||||
|     // Direction is always saved |     // 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 |    * @return        The offset of the next match, or -1 if not found | ||||||
|    */ |    */ | ||||||
|   @Override |   @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); |     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 |    * @return        The offset of the next match, or -1 if not found | ||||||
|    */ |    */ | ||||||
|   @Override |   @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, |     return searchNextWithDirection(((IjVimEditor)editor).getEditor(), ((IjVimCaret)caret).getCaret(), count, | ||||||
|                                    lastDir.reverse()); |                                    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. |     // 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<>(); |     List<ExException> exceptions = new ArrayList<>(); | ||||||
|     if (CommandStateHelper.inVisualMode(((IjVimEditor) editor).getEditor())) { |     if (CommandStateHelper.inVisualMode(((IjVimEditor) editor).getEditor())) { | ||||||
|       EngineModeExtensionsKt.exitVisualMode(editor); |       ModeHelper.exitVisualMode(((IjVimEditor) editor).getEditor()); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     CharPointer cmd = new CharPointer(new StringBuffer(exarg)); |     CharPointer cmd = new CharPointer(new StringBuffer(exarg)); | ||||||
| @@ -681,7 +688,7 @@ public class SearchGroup extends VimSearchGroupBase implements PersistentStateCo | |||||||
|         return false; |         return false; | ||||||
|       } |       } | ||||||
|       line1 = line2; |       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; |     int searchcol = 0; | ||||||
|     boolean firstMatch = true; |     boolean firstMatch = true; | ||||||
|     boolean got_quit = false; |     boolean got_quit = false; | ||||||
|     int lcount = editor.lineCount(); |     int lcount = EditorHelper.getLineCount(((IjVimEditor) editor).getEditor()); | ||||||
|     Expression expression = null; |     Expression expression = null; | ||||||
|     for (int lnum = line1; lnum <= line2 && !got_quit; ) { |     for (int lnum = line1; lnum <= line2 && !got_quit; ) { | ||||||
|       CharacterPosition newpos = null; |       CharacterPosition newpos = null; | ||||||
| @@ -810,7 +817,7 @@ public class SearchGroup extends VimSearchGroupBase implements PersistentStateCo | |||||||
|           } |           } | ||||||
|           if (doReplace) { |           if (doReplace) { | ||||||
|             SubmatchFunctionHandler.INSTANCE.setLatestMatch(((IjVimEditor) editor).getEditor().getDocument().getText(new com.intellij.openapi.util.TextRange(startoff, endoff))); |             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) { |             if (expression != null) { | ||||||
|               try { |               try { | ||||||
|               match = expression |               match = expression | ||||||
| @@ -859,8 +866,8 @@ public class SearchGroup extends VimSearchGroupBase implements PersistentStateCo | |||||||
|  |  | ||||||
|     if (!got_quit) { |     if (!got_quit) { | ||||||
|       if (lastMatch != -1) { |       if (lastMatch != -1) { | ||||||
|         caret.moveToOffset( |         injector.getMotion().moveCaret(editor, caret, | ||||||
|           VimPlugin.getMotion().moveCaretToLineStartSkipLeading(editor, editor.offsetToBufferPosition(lastMatch).getLine())); |           VimPlugin.getMotion().moveCaretToLineStartSkipLeading(editor, editor.offsetToLogicalPosition(lastMatch).getLine())); | ||||||
|       } |       } | ||||||
|       else { |       else { | ||||||
|         VimPlugin.showMessage(MessageHelper.message(Msg.e_patnotf2, pattern)); |         VimPlugin.showMessage(MessageHelper.message(Msg.e_patnotf2, pattern)); | ||||||
| @@ -979,7 +986,7 @@ public class SearchGroup extends VimSearchGroupBase implements PersistentStateCo | |||||||
|       return false; |       return false; | ||||||
|     }; |     }; | ||||||
|     if (ApplicationManager.getApplication().isUnitTestMode()) { |     if (ApplicationManager.getApplication().isUnitTestMode()) { | ||||||
|       new IjVimCaret(caret).moveToOffset(startoff); |       MotionGroup.moveCaret(editor, caret, startoff); | ||||||
|       final TestInputModel inputModel = TestInputModel.getInstance(editor); |       final TestInputModel inputModel = TestInputModel.getInstance(editor); | ||||||
|       for (KeyStroke key = inputModel.nextKeyStroke(); key != null; key = inputModel.nextKeyStroke()) { |       for (KeyStroke key = inputModel.nextKeyStroke(); key != null; key = inputModel.nextKeyStroke()) { | ||||||
|         if (!keyStrokeProcessor.invoke(key)) { |         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 |       // XXX: The Ex entry panel is used only for UI here, its logic might be inappropriate for this method | ||||||
|       final ExEntryPanel exEntryPanel = ExEntryPanel.getInstanceWithoutShortcuts(); |       final ExEntryPanel exEntryPanel = ExEntryPanel.getInstanceWithoutShortcuts(); | ||||||
|       exEntryPanel.activate(editor, EditorDataContext.init(editor, null), MessageHelper.message("replace.with.0", match), "", 1); |       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); |       ModalEntry.INSTANCE.activate(new IjVimEditor(editor), keyStrokeProcessor); | ||||||
|       exEntryPanel.deactivate(true, false); |       exEntryPanel.deactivate(true, false); | ||||||
|     } |     } | ||||||
| @@ -1126,7 +1133,7 @@ public class SearchGroup extends VimSearchGroupBase implements PersistentStateCo | |||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public Integer findDecimalNumber(@NotNull String line) { |   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) { |     if (searchResult != null) { | ||||||
|       TextRange range = searchResult.component1(); |       TextRange range = searchResult.component1(); | ||||||
|       return Integer.parseInt(line.substring(range.getStartOffset(), range.getEndOffset())); |       return Integer.parseInt(line.substring(range.getStartOffset(), range.getEndOffset())); | ||||||
| @@ -1284,7 +1291,7 @@ public class SearchGroup extends VimSearchGroupBase implements PersistentStateCo | |||||||
|  |  | ||||||
|     if (offsetIsLineOffset) { |     if (offsetIsLineOffset) { | ||||||
|       int line = editor.offsetToLogicalPosition(range.getStartOffset()).line; |       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! |       // TODO: Don't move the caret! | ||||||
|       res = VimPlugin.getMotion().moveCaretToLineStart(new IjVimEditor(editor), newLine); |       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