mirror of
				https://github.com/chylex/IntelliJ-IdeaVim.git
				synced 2025-10-31 11:17:13 +01:00 
			
		
		
		
	Compare commits
	
		
			56 Commits
		
	
	
		
			1791692d92
			...
			86bf723791
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 86bf723791 | ||
|   | 71f2e9de4a | ||
|   | 33d3f270a3 | ||
|   | da94edd386 | ||
|   | 90dfaefd11 | ||
|   | 8bc616cc55 | ||
|   | a9e79d62c5 | ||
|   | 1998221a0b | ||
|   | a9b1625749 | ||
|   | b411836570 | ||
|   | df7e0221a8 | ||
|   | 8ff8f2b685 | ||
|   | 65dea7e3f7 | ||
|   | 1942f86633 | ||
|   | ee4ce5033a | ||
|   | 040fe806c8 | ||
|   | 97f5c9225e | ||
|   | 09b86c15f9 | ||
|   | 8f34285d8c | ||
|   | d3c3b71e3e | ||
|   | aa6f49c9b1 | ||
|   | c011628420 | ||
|   | 1c9fa9d662 | ||
|   | 7b9bc64364 | ||
|   | 729062bfdd | ||
|   | bc6c726a45 | ||
|   | dfc3df713e | ||
|   | 42eca1d5f2 | ||
|   | 66245e2730 | ||
|   | d44b82c1d1 | ||
|   | 5440e48fa3 | ||
|   | 1c513cf8aa | ||
|   | a17c4b8d43 | ||
|   | 15eb4ac278 | ||
|   | 0d9b81eab3 | ||
|   | f02e1a20c7 | ||
|   | a11991dad7 | ||
|   | 1238828bfd | ||
|   | ba409cb24c | ||
|   | d597670275 | ||
|   | d8540e95f8 | ||
|   | d35ebf00dd | ||
|   | 2b32cb26b1 | ||
|   | ca95fcb658 | ||
|   | cc18bbd168 | ||
|   | 8c8ea800cb | ||
|   | 0746dcc686 | ||
|   | 930650be9d | ||
|   | 4e3a9ffa40 | ||
|   | 3bf68a2bb8 | ||
|   | a80f6feab0 | ||
|   | 3cf8ae52ed | ||
|   | 62632a4514 | ||
|   | 249bd3778a | ||
|   | ab9e5d7a4a | ||
|   | 083b7dc952 | 
							
								
								
									
										3
									
								
								.github/workflows/mergePr.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.github/workflows/mergePr.yml
									
									
									
									
										vendored
									
									
								
							| @@ -4,6 +4,7 @@ | |||||||
| name: Update Changelog On PR | name: Update Changelog On PR | ||||||
|  |  | ||||||
| on: | on: | ||||||
|  |   workflow_dispatch: | ||||||
|   pull_request: |   pull_request: | ||||||
|     types: [ closed ] |     types: [ closed ] | ||||||
|  |  | ||||||
| @@ -29,7 +30,7 @@ jobs: | |||||||
|         id: update_authors |         id: update_authors | ||||||
|         run: ./gradlew updateMergedPr -PprId=${{ github.event.number }} |         run: ./gradlew updateMergedPr -PprId=${{ github.event.number }} | ||||||
|         env: |         env: | ||||||
|           GITHUB_OAUTH: ${{ secrets.AUTOMATION_TOKEN }} |           GITHUB_OAUTH: ${{ secrets.MERGE_PR }} | ||||||
|  |  | ||||||
|       - name: Commit changes |       - name: Commit changes | ||||||
|         uses: stefanzweifel/git-auto-commit-action@v4 |         uses: stefanzweifel/git-auto-commit-action@v4 | ||||||
|   | |||||||
							
								
								
									
										40
									
								
								.github/workflows/mergePrTest.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								.github/workflows/mergePrTest.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | |||||||
|  | # 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: Update Changelog On PR (Test) | ||||||
|  |  | ||||||
|  | on: | ||||||
|  |   workflow_dispatch: | ||||||
|  |  | ||||||
|  | jobs: | ||||||
|  |   build: | ||||||
|  |  | ||||||
|  |     runs-on: ubuntu-latest | ||||||
|  |  | ||||||
|  |     steps: | ||||||
|  |       - uses: actions/checkout@v2 | ||||||
|  |         with: | ||||||
|  |           fetch-depth: 50 | ||||||
|  |       - 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: Update authors | ||||||
|  |         id: update_authors | ||||||
|  |         run: ./gradlew updateMergedPr -PprId=525 | ||||||
|  |         env: | ||||||
|  |           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 | ||||||
							
								
								
									
										2
									
								
								.github/workflows/updateAuthors.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/updateAuthors.yml
									
									
									
									
										vendored
									
									
								
							| @@ -37,7 +37,7 @@ jobs: | |||||||
|         run: ./gradlew updateAuthors --stacktrace |         run: ./gradlew updateAuthors --stacktrace | ||||||
|         env: |         env: | ||||||
|           SUCCESS_COMMIT: ${{ steps.last_successful_commit.outputs.commit_hash }} |           SUCCESS_COMMIT: ${{ steps.last_successful_commit.outputs.commit_hash }} | ||||||
|           GITHUB_OAUTH: ${{ secrets.AUTOMATION_TOKEN }} |           GITHUB_OAUTH: ${{ secrets.GITHUB_TOKEN }} | ||||||
|  |  | ||||||
|       - name: Commit changes |       - name: Commit changes | ||||||
|         uses: stefanzweifel/git-auto-commit-action@v4 |         uses: stefanzweifel/git-auto-commit-action@v4 | ||||||
|   | |||||||
							
								
								
									
										9
									
								
								.teamcity/_Self/Constants.kt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								.teamcity/_Self/Constants.kt
									
									
									
									
										vendored
									
									
								
							| @@ -13,11 +13,8 @@ object Constants { | |||||||
|   const val PROPERTY_TESTS = "LATEST-EAP-SNAPSHOT" |   const val PROPERTY_TESTS = "LATEST-EAP-SNAPSHOT" | ||||||
|   const val LONG_RUNNING_TESTS = "LATEST-EAP-SNAPSHOT" |   const val LONG_RUNNING_TESTS = "LATEST-EAP-SNAPSHOT" | ||||||
|   const val QODANA_TESTS = "LATEST-EAP-SNAPSHOT" |   const val QODANA_TESTS = "LATEST-EAP-SNAPSHOT" | ||||||
|   const val RELEASE = "2022.1.3" |   const val RELEASE = "LATEST-EAP-SNAPSHOT" | ||||||
|  |  | ||||||
|  |   const val RELEASE_DEV = "LATEST-EAP-SNAPSHOT" | ||||||
|   // Use LATEST-EAP-SNAPSHOT only when we'll update the minimum version of IJ to 222+ |   const val RELEASE_EAP = "LATEST-EAP-SNAPSHOT" | ||||||
|   // Because of some API inconcistincies, IdeaVim built on 2022+ won't run on older versions of IJ |  | ||||||
|   const val RELEASE_DEV = "2022.1.3" |  | ||||||
|   const val RELEASE_EAP = "2022.1.3" |  | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										14
									
								
								.teamcity/_Self/Project.kt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										14
									
								
								.teamcity/_Self/Project.kt
									
									
									
									
										vendored
									
									
								
							| @@ -1,6 +1,12 @@ | |||||||
| package _Self | package _Self | ||||||
|  |  | ||||||
| import _Self.buildTypes.* | import _Self.buildTypes.Compatibility | ||||||
|  | import _Self.buildTypes.LongRunning | ||||||
|  | import _Self.buildTypes.Nvim | ||||||
|  | import _Self.buildTypes.PluginVerifier | ||||||
|  | import _Self.buildTypes.PropertyBased | ||||||
|  | import _Self.buildTypes.Qodana | ||||||
|  | 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 | ||||||
| @@ -10,6 +16,7 @@ import _Self.vcsRoots.Branch_191_193 | |||||||
| import _Self.vcsRoots.Branch_201 | import _Self.vcsRoots.Branch_201 | ||||||
| import _Self.vcsRoots.Branch_202 | import _Self.vcsRoots.Branch_202 | ||||||
| import _Self.vcsRoots.Branch_203_212 | import _Self.vcsRoots.Branch_203_212 | ||||||
|  | import _Self.vcsRoots.Branch_213_221 | ||||||
| import _Self.vcsRoots.Branch_Release | import _Self.vcsRoots.Branch_Release | ||||||
| import _Self.vcsRoots.GitHubPullRequest | import _Self.vcsRoots.GitHubPullRequest | ||||||
| import jetbrains.buildServer.configs.kotlin.v2019_2.Project | import jetbrains.buildServer.configs.kotlin.v2019_2.Project | ||||||
| @@ -26,11 +33,11 @@ object Project : Project({ | |||||||
|   vcsRoot(Branch_201) |   vcsRoot(Branch_201) | ||||||
|   vcsRoot(Branch_202) |   vcsRoot(Branch_202) | ||||||
|   vcsRoot(Branch_203_212) |   vcsRoot(Branch_203_212) | ||||||
|  |   vcsRoot(Branch_213_221) | ||||||
|   vcsRoot(Branch_Release) |   vcsRoot(Branch_Release) | ||||||
|   vcsRoot(GitHubPullRequest) |   vcsRoot(GitHubPullRequest) | ||||||
|  |  | ||||||
|   // Builds |   // Builds | ||||||
|   buildType(TestsForIntelliJ20213) |  | ||||||
|   buildType(TestsForIntelliJEAP) |   buildType(TestsForIntelliJEAP) | ||||||
|  |  | ||||||
|   buildType(PropertyBased) |   buildType(PropertyBased) | ||||||
| @@ -38,6 +45,7 @@ object Project : Project({ | |||||||
|  |  | ||||||
|   buildType(Nvim) |   buildType(Nvim) | ||||||
|   buildType(PluginVerifier) |   buildType(PluginVerifier) | ||||||
|  |   buildType(Compatibility) | ||||||
|  |  | ||||||
|   buildType(Qodana) |   buildType(Qodana) | ||||||
|  |  | ||||||
| @@ -47,7 +55,7 @@ object Project : Project({ | |||||||
|       type = "CloudImage" |       type = "CloudImage" | ||||||
|       id = "PROJECT_EXT_768" |       id = "PROJECT_EXT_768" | ||||||
|       param("agent_pool_id", "41") |       param("agent_pool_id", "41") | ||||||
|       param("amazon-id", "ami-0d1a6a32faa92923e") |       param("amazon-id", "ami-0fa17ce8238eb8868") | ||||||
|       param("ebs-optimized", "false") |       param("ebs-optimized", "false") | ||||||
|       param("image-instances-limit", "") |       param("image-instances-limit", "") | ||||||
|       param("image-name-prefix", "BuildAgentsIdeaVim") |       param("image-name-prefix", "BuildAgentsIdeaVim") | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								.teamcity/_Self/buildTypes/ActiveTests.kt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.teamcity/_Self/buildTypes/ActiveTests.kt
									
									
									
									
										vendored
									
									
								
							| @@ -55,4 +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 TestsForIntelliJ20213 : ActiveTests("Tests for IntelliJ 2021.3", "2021.3.2") | //object TestsForIntelliJ20213 : ActiveTests("Tests for IntelliJ 2021.3", "2021.3.2") | ||||||
|   | |||||||
| @@ -1,29 +1,23 @@ | |||||||
| package patches.buildTypes | package _Self.buildTypes | ||||||
| 
 | 
 | ||||||
| import jetbrains.buildServer.configs.kotlin.v2019_2.* |  | ||||||
| import jetbrains.buildServer.configs.kotlin.v2019_2.BuildType | import jetbrains.buildServer.configs.kotlin.v2019_2.BuildType | ||||||
|  | import jetbrains.buildServer.configs.kotlin.v2019_2.DslContext | ||||||
| import jetbrains.buildServer.configs.kotlin.v2019_2.buildFeatures.golang | import jetbrains.buildServer.configs.kotlin.v2019_2.buildFeatures.golang | ||||||
| import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.script | import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.script | ||||||
| import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.schedule | import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.schedule | ||||||
| import jetbrains.buildServer.configs.kotlin.v2019_2.ui.* |  | ||||||
| 
 | 
 | ||||||
| /* | object Compatibility : BuildType({ | ||||||
| This patch script was generated by TeamCity on settings change in UI. |   id("IdeaVimCompatibility") | ||||||
| To apply the patch, create a buildType with id = 'Build' |   name = "IdeaVim compatibility with external plugins" | ||||||
| in the root project, and delete the patch script. |  | ||||||
| */ |  | ||||||
| create(DslContext.projectId, BuildType({ |  | ||||||
|     id("Build") |  | ||||||
|     name = "IdeaVim compatibility with external plugins" |  | ||||||
| 
 | 
 | ||||||
|     vcs { |   vcs { | ||||||
|         root(DslContext.settingsRoot) |     root(DslContext.settingsRoot) | ||||||
|     } |   } | ||||||
| 
 | 
 | ||||||
|     steps { |   steps { | ||||||
|         script { |     script { | ||||||
|             name = "Check" |       name = "Check" | ||||||
|             scriptContent = """ |       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 '${'$'}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 '${'$'}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 '${'$'}eu.theblob42.idea.whichkey' [latest-IU] -team-city | ||||||
| @@ -33,24 +27,23 @@ create(DslContext.projectId, BuildType({ | |||||||
|                 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.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 |                 java -jar verifier/verifier-cli-dev-all.jar check-plugin '${'$'}com.joshestein.ideavim-quickscope' [latest-IU] -team-city | ||||||
|             """.trimIndent() |             """.trimIndent() | ||||||
|         } |  | ||||||
|     } |     } | ||||||
|  |   } | ||||||
| 
 | 
 | ||||||
|     triggers { |   triggers { | ||||||
|         schedule { |     schedule { | ||||||
|             schedulingPolicy = daily { |       schedulingPolicy = daily { | ||||||
|                 hour = 4 |         hour = 4 | ||||||
|             } |       } | ||||||
|             branchFilter = "" |       branchFilter = "" | ||||||
|             triggerBuild = always() |       triggerBuild = always() | ||||||
|             withPendingChangesOnly = false |       withPendingChangesOnly = false | ||||||
|         } |  | ||||||
|     } |     } | ||||||
|  |   } | ||||||
| 
 | 
 | ||||||
|     features { |   features { | ||||||
|         golang { |     golang { | ||||||
|             testFormat = "json" |       testFormat = "json" | ||||||
|         } |  | ||||||
|     } |     } | ||||||
| })) |   } | ||||||
| 
 | }) | ||||||
							
								
								
									
										2
									
								
								.teamcity/_Self/buildTypes/Nvim.kt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.teamcity/_Self/buildTypes/Nvim.kt
									
									
									
									
										vendored
									
									
								
							| @@ -31,7 +31,7 @@ object Nvim : BuildType({ | |||||||
|     script { |     script { | ||||||
|       name = "Set up NeoVim" |       name = "Set up NeoVim" | ||||||
|       scriptContent = """ |       scriptContent = """ | ||||||
|               wget https://github.com/neovim/neovim/releases/download/v0.4.4/nvim-linux64.tar.gz |               wget https://github.com/neovim/neovim/releases/download/v0.7.2/nvim-linux64.tar.gz | ||||||
|               tar xzf nvim-linux64.tar.gz |               tar xzf nvim-linux64.tar.gz | ||||||
|               cd nvim-linux64/bin |               cd nvim-linux64/bin | ||||||
|               chmod +x nvim |               chmod +x nvim | ||||||
|   | |||||||
							
								
								
									
										6
									
								
								.teamcity/_Self/buildTypes/Qodana.kt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								.teamcity/_Self/buildTypes/Qodana.kt
									
									
									
									
										vendored
									
									
								
							| @@ -4,6 +4,7 @@ import _Self.Constants.QODANA_TESTS | |||||||
| import jetbrains.buildServer.configs.kotlin.v2019_2.BuildType | import jetbrains.buildServer.configs.kotlin.v2019_2.BuildType | ||||||
| import jetbrains.buildServer.configs.kotlin.v2019_2.CheckoutMode | import jetbrains.buildServer.configs.kotlin.v2019_2.CheckoutMode | ||||||
| import jetbrains.buildServer.configs.kotlin.v2019_2.DslContext | import jetbrains.buildServer.configs.kotlin.v2019_2.DslContext | ||||||
|  | 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.qodana | ||||||
| import jetbrains.buildServer.configs.kotlin.v2019_2.failureConditions.BuildFailureOnMetric | 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.failureConditions.failOnMetricChange | ||||||
| @@ -46,12 +47,15 @@ object Qodana : BuildType({ | |||||||
|       param("clonefinder-enable", "true") |       param("clonefinder-enable", "true") | ||||||
|       param("clonefinder-reference-projects", "src") |       param("clonefinder-reference-projects", "src") | ||||||
|       param("yaml-configuration", "") |       param("yaml-configuration", "") | ||||||
|  |       linter = jvm { | ||||||
|  |         version = Qodana.JVMVersion.LATEST | ||||||
|  |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   triggers { |   triggers { | ||||||
|     vcs { |     vcs { | ||||||
|       enabled = false |       enabled = true | ||||||
|       branchFilter = "" |       branchFilter = "" | ||||||
|     } |     } | ||||||
|     schedule { |     schedule { | ||||||
|   | |||||||
							
								
								
									
										62
									
								
								.teamcity/_Self/buildTypes/TestsForIntelliJ_213-221.kt
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								.teamcity/_Self/buildTypes/TestsForIntelliJ_213-221.kt
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,62 @@ | |||||||
|  | @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_213_221_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") | ||||||
|  |     param("env.ORG_GRADLE_PROJECT_javaVersion", "1.8") | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   vcs { | ||||||
|  |     root(_Self.vcsRoots.Branch_213_221) | ||||||
|  |  | ||||||
|  |     checkoutMode = CheckoutMode.AUTO | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   steps { | ||||||
|  |     gradle { | ||||||
|  |       tasks = "clean test" | ||||||
|  |       buildFile = "" | ||||||
|  |       enableStacktrace = true | ||||||
|  |       param("org.jfrog.artifactory.selectedDeployableServer.defaultModuleVersionConfiguration", "GLOBAL") | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   triggers { | ||||||
|  |     vcs { | ||||||
|  |       branchFilter = "" | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   requirements { | ||||||
|  |     noLessThanVer("teamcity.agent.jvm.version", "1.8") | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   failureConditions { | ||||||
|  |     failOnMetricChange { | ||||||
|  |       metric = BuildFailureOnMetric.MetricType.TEST_COUNT | ||||||
|  |       threshold = 20 | ||||||
|  |       units = BuildFailureOnMetric.MetricUnit.PERCENTS | ||||||
|  |       comparison = BuildFailureOnMetric.MetricComparison.LESS | ||||||
|  |       compareTo = build { | ||||||
|  |         buildRule = lastSuccessful() | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | object TestsForIntelliJ20213 : TestsForIntelliJ_213_221_branch("2021.3.2") | ||||||
							
								
								
									
										2
									
								
								.teamcity/_Self/subprojects/OldTests.kt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.teamcity/_Self/subprojects/OldTests.kt
									
									
									
									
										vendored
									
									
								
							| @@ -11,6 +11,7 @@ import _Self.buildTypes.TestsForIntelliJ20202 | |||||||
| import _Self.buildTypes.TestsForIntelliJ20203 | 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 jetbrains.buildServer.configs.kotlin.v2019_2.Project | import jetbrains.buildServer.configs.kotlin.v2019_2.Project | ||||||
|  |  | ||||||
| object OldTests : Project({ | object OldTests : Project({ | ||||||
| @@ -28,4 +29,5 @@ object OldTests : Project({ | |||||||
|   buildType(TestsForIntelliJ20203) |   buildType(TestsForIntelliJ20203) | ||||||
|   buildType(TestsForIntelliJ20211) |   buildType(TestsForIntelliJ20211) | ||||||
|   buildType(TestsForIntelliJ20212) |   buildType(TestsForIntelliJ20212) | ||||||
|  |   buildType(TestsForIntelliJ20213) | ||||||
| }) | }) | ||||||
|   | |||||||
							
								
								
									
										12
									
								
								.teamcity/_Self/vcsRoots/Branch_213_221.kt
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								.teamcity/_Self/vcsRoots/Branch_213_221.kt
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | |||||||
|  | @file:Suppress("ClassName") | ||||||
|  |  | ||||||
|  | package _Self.vcsRoots | ||||||
|  |  | ||||||
|  | import jetbrains.buildServer.configs.kotlin.v2019_2.vcs.GitVcsRoot | ||||||
|  |  | ||||||
|  | object Branch_213_221 : GitVcsRoot({ | ||||||
|  |   id("HttpsGithubComJetBrainsIdeavimBranch213221") | ||||||
|  |   name = "https://github.com/JetBrains/ideavim (branch 213-221)" | ||||||
|  |   url = "https://github.com/JetBrains/ideavim.git" | ||||||
|  |   branch = "213-221" | ||||||
|  | }) | ||||||
							
								
								
									
										25
									
								
								.teamcity/patches/buildTypes/Nvim.kts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										25
									
								
								.teamcity/patches/buildTypes/Nvim.kts
									
									
									
									
										vendored
									
									
								
							| @@ -1,25 +0,0 @@ | |||||||
| package patches.buildTypes |  | ||||||
|  |  | ||||||
| import jetbrains.buildServer.configs.kotlin.v2019_2.* |  | ||||||
| import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.VcsTrigger |  | ||||||
| import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.vcs |  | ||||||
| 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 = 'Nvim' |  | ||||||
| accordingly, and delete the patch script. |  | ||||||
| */ |  | ||||||
| changeBuildType(RelativeId("Nvim")) { |  | ||||||
|     triggers { |  | ||||||
|         val trigger1 = find<VcsTrigger> { |  | ||||||
|             vcs { |  | ||||||
|                 branchFilter = "" |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         trigger1.apply { |  | ||||||
|             enabled = false |  | ||||||
|  |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
							
								
								
									
										25
									
								
								.teamcity/patches/buildTypes/PluginVerifier.kts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										25
									
								
								.teamcity/patches/buildTypes/PluginVerifier.kts
									
									
									
									
										vendored
									
									
								
							| @@ -1,25 +0,0 @@ | |||||||
| package patches.buildTypes |  | ||||||
|  |  | ||||||
| import jetbrains.buildServer.configs.kotlin.v2019_2.* |  | ||||||
| import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.VcsTrigger |  | ||||||
| import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.vcs |  | ||||||
| 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 = 'PluginVerifier' |  | ||||||
| accordingly, and delete the patch script. |  | ||||||
| */ |  | ||||||
| changeBuildType(RelativeId("PluginVerifier")) { |  | ||||||
|     triggers { |  | ||||||
|         val trigger1 = find<VcsTrigger> { |  | ||||||
|             vcs { |  | ||||||
|                 branchFilter = "" |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         trigger1.apply { |  | ||||||
|             enabled = false |  | ||||||
|  |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
							
								
								
									
										44
									
								
								.teamcity/patches/buildTypes/Qodana.kts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										44
									
								
								.teamcity/patches/buildTypes/Qodana.kts
									
									
									
									
										vendored
									
									
								
							| @@ -2,9 +2,8 @@ package patches.buildTypes | |||||||
|  |  | ||||||
| import jetbrains.buildServer.configs.kotlin.v2019_2.* | 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.qodana | import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.qodana | ||||||
| import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.ScheduleTrigger |  | ||||||
| import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.schedule |  | ||||||
| import jetbrains.buildServer.configs.kotlin.v2019_2.ui.* | import jetbrains.buildServer.configs.kotlin.v2019_2.ui.* | ||||||
|  |  | ||||||
| /* | /* | ||||||
| @@ -16,6 +15,9 @@ changeBuildType(RelativeId("Qodana")) { | |||||||
|     expectSteps { |     expectSteps { | ||||||
|         qodana { |         qodana { | ||||||
|             name = "Qodana" |             name = "Qodana" | ||||||
|  |             linter = jvm { | ||||||
|  |                 version = Qodana.JVMVersion.LATEST | ||||||
|  |             } | ||||||
|             param("clonefinder-enable", "true") |             param("clonefinder-enable", "true") | ||||||
|             param("clonefinder-languages", "Java") |             param("clonefinder-languages", "Java") | ||||||
|             param("clonefinder-languages-container", "Java Kotlin") |             param("clonefinder-languages-container", "Java Kotlin") | ||||||
| @@ -29,27 +31,25 @@ changeBuildType(RelativeId("Qodana")) { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     steps { |     steps { | ||||||
|         update<Qodana>(0) { |         insert(0) { | ||||||
|  |             gradle { | ||||||
|  |                 name = "Generate grammar" | ||||||
|  |                 tasks = "generateGrammarSource" | ||||||
|  |                 param("org.jfrog.artifactory.selectedDeployableServer.defaultModuleVersionConfiguration", "GLOBAL") | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         update<Qodana>(1) { | ||||||
|             clearConditions() |             clearConditions() | ||||||
|             linter = jvm { |             reportAsTests = true | ||||||
|                 version = Qodana.JVMVersion.LATEST |             argumentsCommandDocker = "-e QODANA_TOKEN=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJvcmdhbml6YXRpb24iOiIzUFZrQSIsInByb2plY3QiOiIzN1FlQSIsInRva2VuIjoiM0t2bXoifQ.uohp81tM7iAfvvB6k8faarfpV-OjusAaEbWQ8iNrOgs" | ||||||
|             } |             argumentsEntryPointDocker = "--baseline qodana.sarif.json" | ||||||
|         } |             param("clonefinder-languages", "") | ||||||
|     } |             param("collect-anonymous-statistics", "") | ||||||
|  |             param("licenseaudit-enable", "") | ||||||
|     triggers { |             param("clonefinder-languages-container", "") | ||||||
|         val trigger1 = find<ScheduleTrigger> { |             param("clonefinder-queried-project", "") | ||||||
|             schedule { |             param("clonefinder-enable", "") | ||||||
|                 schedulingPolicy = weekly { |             param("clonefinder-reference-projects", "") | ||||||
|                     dayOfWeek = ScheduleTrigger.DAY.Tuesday |  | ||||||
|                 } |  | ||||||
|                 branchFilter = "" |  | ||||||
|                 triggerBuild = always() |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         trigger1.apply { |  | ||||||
|             enabled = false |  | ||||||
|  |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										27
									
								
								.teamcity/patches/buildTypes/ReleaseEap.kts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								.teamcity/patches/buildTypes/ReleaseEap.kts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | |||||||
|  | package patches.buildTypes | ||||||
|  |  | ||||||
|  | import jetbrains.buildServer.configs.kotlin.v2019_2.* | ||||||
|  | import jetbrains.buildServer.configs.kotlin.v2019_2.buildFeatures.VcsLabeling | ||||||
|  | import jetbrains.buildServer.configs.kotlin.v2019_2.buildFeatures.vcsLabeling | ||||||
|  | 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 = 'ReleaseEap' | ||||||
|  | accordingly, and delete the patch script. | ||||||
|  | */ | ||||||
|  | changeBuildType(RelativeId("ReleaseEap")) { | ||||||
|  |     features { | ||||||
|  |         val feature1 = find<VcsLabeling> { | ||||||
|  |             vcsLabeling { | ||||||
|  |                 vcsRootId = "${DslContext.settingsRoot.id}" | ||||||
|  |                 labelingPattern = "%system.build.number%" | ||||||
|  |                 successfulOnly = true | ||||||
|  |                 branchFilter = "" | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         feature1.apply { | ||||||
|  |             successfulOnly = false | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										74
									
								
								.teamcity/patches/projects/_Self.kts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										74
									
								
								.teamcity/patches/projects/_Self.kts
									
									
									
									
										vendored
									
									
								
							| @@ -1,74 +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.AmazonEC2CloudProfile |  | ||||||
| import jetbrains.buildServer.configs.kotlin.v2019_2.Project |  | ||||||
| import jetbrains.buildServer.configs.kotlin.v2019_2.amazonEC2CloudImage |  | ||||||
| import jetbrains.buildServer.configs.kotlin.v2019_2.amazonEC2CloudProfile |  | ||||||
| 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-0d1a6a32faa92923e") |  | ||||||
|                 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-0fa17ce8238eb8868") |  | ||||||
|         } |  | ||||||
|         val feature2 = find<AmazonEC2CloudProfile> { |  | ||||||
|             amazonEC2CloudProfile { |  | ||||||
|                 id = "amazon-48" |  | ||||||
|                 name = "Cloud Agents - Single Build" |  | ||||||
|                 terminateAfterBuild = true |  | ||||||
|                 terminateIdleMinutes = 15 |  | ||||||
|                 region = AmazonEC2CloudProfile.Regions.EU_WEST_DUBLIN |  | ||||||
|                 maxInstancesCount = 10 |  | ||||||
|                 authType = accessKey { |  | ||||||
|                     keyId = "credentialsJSON:dbcdb2a2-de5f-4bc9-9421-292b19e83947" |  | ||||||
|                     secretKey = "credentialsJSON:65a87fe7-0977-4af9-96f1-344f2b82d269" |  | ||||||
|                 } |  | ||||||
|                 param("agentPushPreset", "") |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         feature2.apply { |  | ||||||
|             name = "Cloud Agents - Single Build" |  | ||||||
|             terminateAfterBuild = true |  | ||||||
|             terminateIdleMinutes = 15 |  | ||||||
|             region = AmazonEC2CloudProfile.Regions.EU_WEST_DUBLIN |  | ||||||
|             maxInstancesCount = 10 |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,25 +0,0 @@ | |||||||
| package patches.vcsRoots |  | ||||||
|  |  | ||||||
| import jetbrains.buildServer.configs.kotlin.v2019_2.* |  | ||||||
| import jetbrains.buildServer.configs.kotlin.v2019_2.ui.* |  | ||||||
| import jetbrains.buildServer.configs.kotlin.v2019_2.vcs.GitVcsRoot |  | ||||||
|  |  | ||||||
| /* |  | ||||||
| This patch script was generated by TeamCity on settings change in UI. |  | ||||||
| To apply the patch, create a vcsRoot with id = 'HttpsGithubComAlexPl292IdeaVimCompatibilityRefsHeadsMaster' |  | ||||||
| in the root project, and delete the patch script. |  | ||||||
| */ |  | ||||||
| create(DslContext.projectId, GitVcsRoot({ |  | ||||||
|     id("HttpsGithubComAlexPl292IdeaVimCompatibilityRefsHeadsMaster") |  | ||||||
|     name = "https://github.com/AlexPl292/IdeaVimCompatibility#refs/heads/master" |  | ||||||
|     url = "https://github.com/AlexPl292/IdeaVimCompatibility" |  | ||||||
|     branch = "refs/heads/master" |  | ||||||
|     branchSpec = "refs/heads/*" |  | ||||||
|     authMethod = password { |  | ||||||
|         userName = "AlexPl292" |  | ||||||
|         password = "credentialsJSON:43afd6e5-6ad5-4d12-a218-cf1547717a7f" |  | ||||||
|     } |  | ||||||
|     param("oauthProviderId", "PROJECT_EXT_1") |  | ||||||
|     param("useAlternates", "true") |  | ||||||
| })) |  | ||||||
|  |  | ||||||
| @@ -1,23 +0,0 @@ | |||||||
| package patches.vcsRoots |  | ||||||
|  |  | ||||||
| import jetbrains.buildServer.configs.kotlin.v2019_2.* |  | ||||||
| import jetbrains.buildServer.configs.kotlin.v2019_2.ui.* |  | ||||||
| import jetbrains.buildServer.configs.kotlin.v2019_2.vcs.GitVcsRoot |  | ||||||
|  |  | ||||||
| /* |  | ||||||
| This patch script was generated by TeamCity on settings change in UI. |  | ||||||
| To apply the patch, create a vcsRoot with id = 'IdeaVimCompatibility' |  | ||||||
| in the root project, and delete the patch script. |  | ||||||
| */ |  | ||||||
| create(DslContext.projectId, GitVcsRoot({ |  | ||||||
|     id("IdeaVimCompatibility") |  | ||||||
|     name = "IdeaVimCompatibility" |  | ||||||
|     url = "git@github.com:AlexPl292/IdeaVimCompatibility.git" |  | ||||||
|     branch = "refs/heads/master" |  | ||||||
|     authMethod = uploadedKey { |  | ||||||
|         userName = "git" |  | ||||||
|         uploadedKey = "Alex Plate TeamCity key" |  | ||||||
|     } |  | ||||||
|     param("useAlternates", "true") |  | ||||||
| })) |  | ||||||
|  |  | ||||||
| @@ -416,6 +416,10 @@ Contributors: | |||||||
|   [![icon][github]](https://github.com/Vvalter) |   [![icon][github]](https://github.com/Vvalter) | ||||||
|     |     | ||||||
|   Simon Rainer |   Simon Rainer | ||||||
|  | * [![icon][mail]](mailto:filipp.vakhitov@jetbrains.com) | ||||||
|  |   [![icon][github]](https://github.com/lippfi) | ||||||
|  |     | ||||||
|  |   lippfi | ||||||
|                          |                          | ||||||
| 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. | ||||||
|   | |||||||
| @@ -36,6 +36,7 @@ usual beta standards. | |||||||
|   E.g. `<Plug>Commentary` instead of `<Plug>(CommentMotion)`. Old mappings are maintained for compatibility. |   E.g. `<Plug>Commentary` instead of `<Plug>(CommentMotion)`. Old mappings are maintained for compatibility. | ||||||
| * If you open `~/.ideavimrc` in IDE, remove a mapping, and reload the config using the reload button, | * If you open `~/.ideavimrc` in IDE, remove a mapping, and reload the config using the reload button, | ||||||
|   the mapping will actually be unmapped. |   the mapping will actually be unmapped. | ||||||
|  | * New vim (and IdeaVim) behaviour: `ci(`& friends searches for the brackets in the line. | ||||||
|  |  | ||||||
| ### Fixes: | ### Fixes: | ||||||
| * [VIM-2587](https://youtrack.jetbrains.com/issue/VIM-2587) Use ctrl-6 as ctrl-^ | * [VIM-2587](https://youtrack.jetbrains.com/issue/VIM-2587) Use ctrl-6 as ctrl-^ | ||||||
| @@ -57,6 +58,7 @@ usual beta standards. | |||||||
| * [VIM-1862](https://youtrack.jetbrains.com/issue/VIM-1862/Ex-commands-executed-in-keymaps-and-macros-are-added-to-the-command-history) Fix command history | * [VIM-1862](https://youtrack.jetbrains.com/issue/VIM-1862/Ex-commands-executed-in-keymaps-and-macros-are-added-to-the-command-history) Fix command history | ||||||
| * [VIM-2227](https://youtrack.jetbrains.com/issue/VIM-2227) Wrong behavior when deleting / changing surround with invalid character | * [VIM-2227](https://youtrack.jetbrains.com/issue/VIM-2227) Wrong behavior when deleting / changing surround with invalid character | ||||||
| * [VIM-2691](https://youtrack.jetbrains.com/issue/VIM-2691) Save file on :w | * [VIM-2691](https://youtrack.jetbrains.com/issue/VIM-2691) Save file on :w | ||||||
|  | * [VIM-2710](https://youtrack.jetbrains.com/issue/VIM-2710) Show options value on `set opt` | ||||||
|  |  | ||||||
| ### Merged PRs: | ### Merged PRs: | ||||||
| * [468](https://github.com/JetBrains/ideavim/pull/468) by [Thomas Schouten](https://github.com/PHPirates): Implement UserDataHolder for EditorDataContext | * [468](https://github.com/JetBrains/ideavim/pull/468) by [Thomas Schouten](https://github.com/PHPirates): Implement UserDataHolder for EditorDataContext | ||||||
| @@ -66,6 +68,8 @@ usual beta standards. | |||||||
| * [494](https://github.com/JetBrains/ideavim/pull/494) by [Matt Ellis](https://github.com/citizenmatt): Cleanup pre-212 CaretVisualAttributes compatibility code | * [494](https://github.com/JetBrains/ideavim/pull/494) by [Matt Ellis](https://github.com/citizenmatt): Cleanup pre-212 CaretVisualAttributes compatibility code | ||||||
| * [504](https://github.com/JetBrains/ideavim/pull/504) by [Matt Ellis](https://github.com/citizenmatt): Minor bug fixes | * [504](https://github.com/JetBrains/ideavim/pull/504) by [Matt Ellis](https://github.com/citizenmatt): Minor bug fixes | ||||||
| * [519](https://github.com/JetBrains/ideavim/pull/519) by [chylex](https://github.com/chylex): Fix(VIM-2227): Wrong behavior when deleting / changing surround with invalid character | * [519](https://github.com/JetBrains/ideavim/pull/519) by [chylex](https://github.com/chylex): Fix(VIM-2227): Wrong behavior when deleting / changing surround with invalid character | ||||||
|  | * [525](https://github.com/JetBrains/ideavim/pull/525) by [Matt Ellis](https://github.com/citizenmatt): Improve handling of fractional width fonts | ||||||
|  | * [526](https://github.com/JetBrains/ideavim/pull/526) by [Alex Pláte](https://github.com/AlexPl292): Create gradle.properties | ||||||
|  |  | ||||||
| ## 1.10.0, 2022-02-17 | ## 1.10.0, 2022-02-17 | ||||||
|  |  | ||||||
|   | |||||||
| @@ -5,7 +5,7 @@ IdeaVim is an open source project created by 80+ contributors. Would you like to | |||||||
| This page is created to help you start contributing. And who knows, maybe in a few days this project will be brighter than ever! | This page is created to help you start contributing. And who knows, maybe in a few days this project will be brighter than ever! | ||||||
|  |  | ||||||
| :warning: The plugin is currently under a huge refactoring aiming to split into vim-engine and IdeaVim in order to | :warning: The plugin is currently under a huge refactoring aiming to split into vim-engine and IdeaVim in order to | ||||||
| support the new [Fleet IDE](https://www.jetbrains.com/fleet/). | support the new [Fleet IDE](https://www.jetbrains.com/fleet/). Please see [Fleet refactoring](#Fleet-refactoring). | ||||||
|  |  | ||||||
| ## Before you begin | ## Before you begin | ||||||
|  |  | ||||||
| @@ -120,6 +120,17 @@ so you can reuse your `.vimrc` settings. | |||||||
| We also support proper command mappings (functions are mapped to `<Plug>...`), the operator function (`OperatorFunction`), and so on. | We also support proper command mappings (functions are mapped to `<Plug>...`), the operator function (`OperatorFunction`), and so on. | ||||||
| - Magic is supported as well. See `Magic`. | - Magic is supported as well. See `Magic`. | ||||||
|  |  | ||||||
|  |  | ||||||
|  | ## Fleet refactoring | ||||||
|  | At the moment, IdeaVim is under an active refactoring aiming to split IdeaVim into two modules: vim-engine and IdeaVim. | ||||||
|  |  | ||||||
|  | If you develop a plugin that depends on IdeaVim: We have an instrument to check that our changes don't affect | ||||||
|  | the plugins in the marketplace. Also, we commit to support currently used API at least till the end of 2022. | ||||||
|  | If you still encounter any issues with the newer versions of IdeaVim, please [contact maintainers](https://github.com/JetBrains/ideavim#contact-maintainers). | ||||||
|  | We kindly ask you not to use anything from the new API (like `VimEditor`, `injector`) because at the moment we don't | ||||||
|  | guarantee the compatibility of this API in the future versions. | ||||||
|  |  | ||||||
|  |  | ||||||
| ----- | ----- | ||||||
|  |  | ||||||
| ### I read the whole page but something is still unclear. | ### I read the whole page but something is still unclear. | ||||||
|   | |||||||
| @@ -28,7 +28,7 @@ plugins { | |||||||
|     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.2.1" |     id("org.jlleitschuh.gradle.ktlint") version "10.3.0" | ||||||
| } | } | ||||||
|  |  | ||||||
| // Import variables from gradle.properties file | // Import variables from gradle.properties file | ||||||
| @@ -71,6 +71,8 @@ dependencies { | |||||||
|     antlr("org.antlr:antlr4:$antlrVersion") |     antlr("org.antlr:antlr4:$antlrVersion") | ||||||
|  |  | ||||||
|     api(project(":vim-engine")) |     api(project(":vim-engine")) | ||||||
|  |  | ||||||
|  |     testApi("com.squareup.okhttp3:okhttp:4.10.0") | ||||||
| } | } | ||||||
|  |  | ||||||
| configurations { | configurations { | ||||||
| @@ -85,6 +87,8 @@ tasks.register<Test>("testWithNeovim") { | |||||||
|     group = "verification" |     group = "verification" | ||||||
|     systemProperty("ideavim.nvim.test", "true") |     systemProperty("ideavim.nvim.test", "true") | ||||||
|     exclude("/ui/**") |     exclude("/ui/**") | ||||||
|  |     exclude("**/longrunning/**") | ||||||
|  |     exclude("**/propertybased/**") | ||||||
| } | } | ||||||
|  |  | ||||||
| tasks.register<Test>("testPropertyBased") { | tasks.register<Test>("testPropertyBased") { | ||||||
| @@ -115,6 +119,8 @@ tasks { | |||||||
|         include("**/*test.class") |         include("**/*test.class") | ||||||
|         include("**/*Tests.class") |         include("**/*Tests.class") | ||||||
|         exclude("**/ParserTest.class") |         exclude("**/ParserTest.class") | ||||||
|  |         exclude("**/longrunning/**") | ||||||
|  |         exclude("**/propertybased/**") | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     val testPropertyBased by getting(Test::class) { |     val testPropertyBased by getting(Test::class) { | ||||||
| @@ -144,7 +150,7 @@ tasks { | |||||||
|     compileKotlin { |     compileKotlin { | ||||||
|         kotlinOptions { |         kotlinOptions { | ||||||
|             jvmTarget = javaVersion |             jvmTarget = javaVersion | ||||||
|             apiVersion = "1.5" |             apiVersion = "1.6" | ||||||
|             freeCompilerArgs = listOf("-Xjvm-default=all-compatibility") |             freeCompilerArgs = listOf("-Xjvm-default=all-compatibility") | ||||||
| //            allWarningsAsErrors = true | //            allWarningsAsErrors = true | ||||||
|         } |         } | ||||||
| @@ -152,7 +158,7 @@ tasks { | |||||||
|     compileTestKotlin { |     compileTestKotlin { | ||||||
|         kotlinOptions { |         kotlinOptions { | ||||||
|             jvmTarget = javaVersion |             jvmTarget = javaVersion | ||||||
|             apiVersion = "1.5" |             apiVersion = "1.6" | ||||||
| //            allWarningsAsErrors = true | //            allWarningsAsErrors = true | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| @@ -200,7 +206,7 @@ tasks { | |||||||
|     runPluginVerifier { |     runPluginVerifier { | ||||||
|         downloadDir.set("${project.buildDir}/pluginVerifier/ides") |         downloadDir.set("${project.buildDir}/pluginVerifier/ides") | ||||||
|         teamCityOutputFormat.set(true) |         teamCityOutputFormat.set(true) | ||||||
|         ideVersions.set(listOf("IC-2021.3.4")) | //        ideVersions.set(listOf("IC-2021.3.4")) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     generateGrammarSource { |     generateGrammarSource { | ||||||
| @@ -231,12 +237,18 @@ tasks { | |||||||
|         dependsOn(createOpenApiSourceJar) |         dependsOn(createOpenApiSourceJar) | ||||||
|         from(createOpenApiSourceJar) { into("lib/src") } |         from(createOpenApiSourceJar) { into("lib/src") } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     // Don't forget to update plugin.xml | ||||||
|  |     patchPluginXml { | ||||||
|  |         sinceBuild.set("222") | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| // --- Linting | // --- Linting | ||||||
|  |  | ||||||
| ktlint { | ktlint { | ||||||
|     disabledRules.add("no-wildcard-imports") |     disabledRules.add("no-wildcard-imports") | ||||||
|  |     version.set("0.43.0") | ||||||
| } | } | ||||||
|  |  | ||||||
| // --- Tests | // --- Tests | ||||||
| @@ -327,7 +339,8 @@ tasks.register("updateAuthors") { | |||||||
|             "aleksei.plate@jetbrains.com", |             "aleksei.plate@jetbrains.com", | ||||||
|             "aleksei.plate@teamcity", |             "aleksei.plate@teamcity", | ||||||
|             "aleksei.plate@TeamCity", |             "aleksei.plate@TeamCity", | ||||||
|             "alex.plate@192.168.0.109" |             "alex.plate@192.168.0.109", | ||||||
|  |             "nikita.koshcheev@TeamCity", | ||||||
|         ) |         ) | ||||||
|         updateAuthors(uncheckedEmails) |         updateAuthors(uncheckedEmails) | ||||||
|     } |     } | ||||||
| @@ -338,6 +351,7 @@ val prId: String by project | |||||||
| tasks.register("updateMergedPr") { | tasks.register("updateMergedPr") { | ||||||
|     doLast { |     doLast { | ||||||
|         if (project.hasProperty("prId")) { |         if (project.hasProperty("prId")) { | ||||||
|  |             println("Got pr id: $prId") | ||||||
|             updateMergedPr(prId.toInt()) |             updateMergedPr(prId.toInt()) | ||||||
|         } else { |         } else { | ||||||
|             error("Cannot get prId") |             error("Cannot get prId") | ||||||
| @@ -501,7 +515,9 @@ data class Change(val id: String, val text: String) | |||||||
|  |  | ||||||
| fun updateMergedPr(number: Int) { | fun updateMergedPr(number: Int) { | ||||||
|     val gitHub = org.kohsuke.github.GitHub.connect() |     val gitHub = org.kohsuke.github.GitHub.connect() | ||||||
|  |     println("Connecting to the repo...") | ||||||
|     val repository = gitHub.getRepository("JetBrains/ideavim") |     val repository = gitHub.getRepository("JetBrains/ideavim") | ||||||
|  |     println("Getting pull requests...") | ||||||
|     val pullRequest = repository.getPullRequest(number) |     val pullRequest = repository.getPullRequest(number) | ||||||
|     if (pullRequest.user.login == "dependabot[bot]") return |     if (pullRequest.user.login == "dependabot[bot]") return | ||||||
|  |  | ||||||
|   | |||||||
| @@ -5,9 +5,10 @@ downloadIdeaSources=true | |||||||
| instrumentPluginCode=true | instrumentPluginCode=true | ||||||
| version=SNAPSHOT | version=SNAPSHOT | ||||||
| javaVersion=11 | javaVersion=11 | ||||||
| remoteRobotVersion=0.11.10 | 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.6.21 | kotlinVersion=1.6.21 | ||||||
| publishToken=token | publishToken=token | ||||||
|   | |||||||
							
								
								
									
										79982
									
								
								qodana.sarif.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79982
									
								
								qodana.sarif.json
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -101,12 +101,6 @@ public class EventFacade { | |||||||
|     EditorFactory.getInstance().addEditorFactoryListener(listener, parentDisposable); |     EditorFactory.getInstance().addEditorFactoryListener(listener, parentDisposable); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @SuppressWarnings("deprecation") |  | ||||||
|   public void removeEditorFactoryListener(@NotNull EditorFactoryListener listener) { |  | ||||||
|     // Listener is removed not only if application is disposed |  | ||||||
|     EditorFactory.getInstance().removeEditorFactoryListener(listener); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   public void addEditorMouseListener(@NotNull Editor editor, @NotNull EditorMouseListener listener) { |   public void addEditorMouseListener(@NotNull Editor editor, @NotNull EditorMouseListener listener) { | ||||||
|     editor.addEditorMouseListener(listener); |     editor.addEditorMouseListener(listener); | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -19,8 +19,6 @@ package com.maddyhome.idea.vim; | |||||||
|  |  | ||||||
| import com.intellij.ide.plugins.IdeaPluginDescriptor; | import com.intellij.ide.plugins.IdeaPluginDescriptor; | ||||||
| import com.intellij.ide.plugins.PluginManagerCore; | import com.intellij.ide.plugins.PluginManagerCore; | ||||||
| import com.intellij.notification.Notification; |  | ||||||
| import com.intellij.notification.NotificationListener; |  | ||||||
| import com.intellij.openapi.Disposable; | import com.intellij.openapi.Disposable; | ||||||
| import com.intellij.openapi.application.Application; | import com.intellij.openapi.application.Application; | ||||||
| import com.intellij.openapi.application.ApplicationManager; | import com.intellij.openapi.application.ApplicationManager; | ||||||
| @@ -32,9 +30,9 @@ import com.intellij.openapi.extensions.PluginId; | |||||||
| import com.intellij.openapi.keymap.Keymap; | import com.intellij.openapi.keymap.Keymap; | ||||||
| import com.intellij.openapi.keymap.ex.KeymapManagerEx; | import com.intellij.openapi.keymap.ex.KeymapManagerEx; | ||||||
| import com.intellij.openapi.keymap.impl.DefaultKeymap; | import com.intellij.openapi.keymap.impl.DefaultKeymap; | ||||||
| import com.intellij.openapi.options.ShowSettingsUtil; |  | ||||||
| import com.intellij.openapi.project.Project; | import com.intellij.openapi.project.Project; | ||||||
| import com.intellij.openapi.ui.Messages; | import com.intellij.openapi.ui.Messages; | ||||||
|  | import com.intellij.openapi.util.Disposer; | ||||||
| import com.intellij.openapi.util.SystemInfo; | import com.intellij.openapi.util.SystemInfo; | ||||||
| import com.maddyhome.idea.vim.api.VimInjectorKt; | import com.maddyhome.idea.vim.api.VimInjectorKt; | ||||||
| import com.maddyhome.idea.vim.api.VimKeyGroup; | import com.maddyhome.idea.vim.api.VimKeyGroup; | ||||||
| @@ -49,7 +47,6 @@ import com.maddyhome.idea.vim.helper.MacKeyRepeat; | |||||||
| import com.maddyhome.idea.vim.listener.VimListenerManager; | import com.maddyhome.idea.vim.listener.VimListenerManager; | ||||||
| import com.maddyhome.idea.vim.newapi.IjVimInjector; | import com.maddyhome.idea.vim.newapi.IjVimInjector; | ||||||
| import com.maddyhome.idea.vim.ui.StatusBarIconFactory; | import com.maddyhome.idea.vim.ui.StatusBarIconFactory; | ||||||
| import com.maddyhome.idea.vim.ui.VimEmulationConfigurable; |  | ||||||
| import com.maddyhome.idea.vim.ui.ex.ExEntryPanel; | import com.maddyhome.idea.vim.ui.ex.ExEntryPanel; | ||||||
| import com.maddyhome.idea.vim.vimscript.services.FunctionStorage; | import com.maddyhome.idea.vim.vimscript.services.FunctionStorage; | ||||||
| import com.maddyhome.idea.vim.vimscript.services.IjVimOptionService; | import com.maddyhome.idea.vim.vimscript.services.IjVimOptionService; | ||||||
| @@ -60,8 +57,6 @@ 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; | ||||||
|  |  | ||||||
| import javax.swing.event.HyperlinkEvent; |  | ||||||
|  |  | ||||||
| import static com.maddyhome.idea.vim.group.EditorGroup.EDITOR_STORE_ELEMENT; | import static com.maddyhome.idea.vim.group.EditorGroup.EDITOR_STORE_ELEMENT; | ||||||
| import static com.maddyhome.idea.vim.group.KeyGroup.SHORTCUT_CONFLICTS_ELEMENT; | import static com.maddyhome.idea.vim.group.KeyGroup.SHORTCUT_CONFLICTS_ELEMENT; | ||||||
| import static com.maddyhome.idea.vim.vimscript.services.VimRcService.executeIdeaVimRc; | import static com.maddyhome.idea.vim.vimscript.services.VimRcService.executeIdeaVimRc; | ||||||
| @@ -94,6 +89,8 @@ public class VimPlugin implements PersistentStateComponent<Element>, Disposable | |||||||
|  |  | ||||||
|   private final @NotNull VimState state = new VimState(); |   private final @NotNull VimState state = new VimState(); | ||||||
|  |  | ||||||
|  |   public Disposable onOffDisposable; | ||||||
|  |  | ||||||
|   VimPlugin() { |   VimPlugin() { | ||||||
|     ApplicationConfigurationMigrator.getInstance().migrate(); |     ApplicationConfigurationMigrator.getInstance().migrate(); | ||||||
|   } |   } | ||||||
| @@ -341,6 +338,8 @@ public class VimPlugin implements PersistentStateComponent<Element>, Disposable | |||||||
|    *      execution, what theoretically may cause bugs (e.g. VIM-2540) |    *      execution, what theoretically may cause bugs (e.g. VIM-2540) | ||||||
|    */ |    */ | ||||||
|   private void turnOnPlugin() { |   private void turnOnPlugin() { | ||||||
|  |     onOffDisposable = Disposer.newDisposable(this, "IdeaVimOnOffDisposer"); | ||||||
|  |  | ||||||
|     // 1) Update state |     // 1) Update state | ||||||
|     ApplicationManager.getApplication().invokeLater(this::updateState); |     ApplicationManager.getApplication().invokeLater(this::updateState); | ||||||
|  |  | ||||||
| @@ -376,6 +375,8 @@ public class VimPlugin implements PersistentStateComponent<Element>, Disposable | |||||||
|  |  | ||||||
|     // Unregister vim actions in command mode |     // Unregister vim actions in command mode | ||||||
|     RegisterActions.unregisterActions(); |     RegisterActions.unregisterActions(); | ||||||
|  |  | ||||||
|  |     Disposer.dispose(onOffDisposable); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   private boolean stateUpdated = false; |   private boolean stateUpdated = false; | ||||||
| @@ -389,7 +390,9 @@ public class VimPlugin implements PersistentStateComponent<Element>, Disposable | |||||||
|         final Boolean enabled = keyRepeat.isEnabled(); |         final Boolean enabled = keyRepeat.isEnabled(); | ||||||
|         final Boolean isKeyRepeat = getEditor().isKeyRepeat(); |         final Boolean isKeyRepeat = getEditor().isKeyRepeat(); | ||||||
|         if ((enabled == null || !enabled) && (isKeyRepeat == null || isKeyRepeat)) { |         if ((enabled == null || !enabled) && (isKeyRepeat == null || isKeyRepeat)) { | ||||||
|           if (VimPlugin.getNotifications().enableRepeatingMode() == Messages.YES) { |           // This system property is used in IJ ui robot to hide the startup tips | ||||||
|  |           boolean showNotification = Boolean.getBoolean("ide.show.tips.on.startup.default.value"); | ||||||
|  |           if (showNotification && VimPlugin.getNotifications().enableRepeatingMode() == Messages.YES) { | ||||||
|             getEditor().setKeyRepeat(true); |             getEditor().setKeyRepeat(true); | ||||||
|             keyRepeat.setEnabled(true); |             keyRepeat.setEnabled(true); | ||||||
|           } |           } | ||||||
| @@ -408,12 +411,6 @@ public class VimPlugin implements PersistentStateComponent<Element>, Disposable | |||||||
|           keymap = manager.getKeymap(DefaultKeymap.getInstance().getDefaultKeymapName()); |           keymap = manager.getKeymap(DefaultKeymap.getInstance().getDefaultKeymapName()); | ||||||
|         } |         } | ||||||
|         assert keymap != null : "Default keymap not found"; |         assert keymap != null : "Default keymap not found"; | ||||||
|         VimPlugin.getNotifications().specialKeymap(keymap, new NotificationListener.Adapter() { |  | ||||||
|           @Override |  | ||||||
|           protected void hyperlinkActivated(@NotNull Notification notification, @NotNull HyperlinkEvent e) { |  | ||||||
|             ShowSettingsUtil.getInstance().showSettingsDialog(null, VimEmulationConfigurable.class); |  | ||||||
|           } |  | ||||||
|         }); |  | ||||||
|         manager.setActiveKeymap(keymap); |         manager.setActiveKeymap(keymap); | ||||||
|       } |       } | ||||||
|       if (previousStateVersion > 0 && previousStateVersion < 4) { |       if (previousStateVersion > 0 && previousStateVersion < 4) { | ||||||
|   | |||||||
| @@ -45,7 +45,7 @@ class DeleteJoinLinesAction : ChangeEditorActionHandler.SingleExecution() { | |||||||
|     val res = arrayOf(true) |     val res = arrayOf(true) | ||||||
|     editor.forEachNativeCaret( |     editor.forEachNativeCaret( | ||||||
|       { caret: VimCaret -> |       { caret: VimCaret -> | ||||||
|         if (!injector.changeGroup.deleteJoinLines(editor, caret, operatorArguments.count1, false)) res[0] = false |         if (!injector.changeGroup.deleteJoinLines(editor, caret, operatorArguments.count1, false, operatorArguments)) res[0] = false | ||||||
|       }, |       }, | ||||||
|       true |       true | ||||||
|     ) |     ) | ||||||
|   | |||||||
| @@ -45,7 +45,7 @@ class DeleteJoinLinesSpacesAction : ChangeEditorActionHandler.SingleExecution() | |||||||
|     val res = arrayOf(true) |     val res = arrayOf(true) | ||||||
|     editor.forEachNativeCaret( |     editor.forEachNativeCaret( | ||||||
|       { caret: VimCaret -> |       { caret: VimCaret -> | ||||||
|         if (!injector.changeGroup.deleteJoinLines(editor, caret, operatorArguments.count1, true)) res[0] = false |         if (!injector.changeGroup.deleteJoinLines(editor, caret, operatorArguments.count1, true, operatorArguments)) res[0] = false | ||||||
|       }, |       }, | ||||||
|       true |       true | ||||||
|     ) |     ) | ||||||
|   | |||||||
| @@ -57,7 +57,14 @@ class DeleteJoinVisualLinesAction : VisualOperatorActionHandler.SingleExecution( | |||||||
|         caret: VimCaret -> |         caret: VimCaret -> | ||||||
|         if (!caret.isValid) return@forEachNativeCaret |         if (!caret.isValid) return@forEachNativeCaret | ||||||
|         val range = caretsAndSelections[caret] ?: return@forEachNativeCaret |         val range = caretsAndSelections[caret] ?: return@forEachNativeCaret | ||||||
|         if (!injector.changeGroup.deleteJoinRange(editor, caret, range.toVimTextRange(true).normalize(), false)) { |         if (!injector.changeGroup.deleteJoinRange( | ||||||
|  |             editor, | ||||||
|  |             caret, | ||||||
|  |             range.toVimTextRange(true).normalize(), | ||||||
|  |             false, | ||||||
|  |             operatorArguments | ||||||
|  |           ) | ||||||
|  |         ) { | ||||||
|           res[0] = false |           res[0] = false | ||||||
|         } |         } | ||||||
|       }, true |       }, true | ||||||
|   | |||||||
| @@ -56,7 +56,14 @@ class DeleteJoinVisualLinesSpacesAction : VisualOperatorActionHandler.SingleExec | |||||||
|       { caret: VimCaret -> |       { caret: VimCaret -> | ||||||
|         if (!caret.isValid) return@forEachNativeCaret |         if (!caret.isValid) return@forEachNativeCaret | ||||||
|         val range = caretsAndSelections[caret] ?: return@forEachNativeCaret |         val range = caretsAndSelections[caret] ?: return@forEachNativeCaret | ||||||
|         if (!injector.changeGroup.deleteJoinRange(editor, caret, range.toVimTextRange(true).normalize(), true)) { |         if (!injector.changeGroup.deleteJoinRange( | ||||||
|  |             editor, | ||||||
|  |             caret, | ||||||
|  |             range.toVimTextRange(true).normalize(), | ||||||
|  |             true, | ||||||
|  |             operatorArguments | ||||||
|  |           ) | ||||||
|  |         ) { | ||||||
|           res[0] = false |           res[0] = false | ||||||
|         } |         } | ||||||
|       }, |       }, | ||||||
|   | |||||||
| @@ -18,6 +18,7 @@ | |||||||
| package com.maddyhome.idea.vim.action.internal | package com.maddyhome.idea.vim.action.internal | ||||||
|  |  | ||||||
| import com.intellij.ide.ui.AntialiasingType | import com.intellij.ide.ui.AntialiasingType | ||||||
|  | import com.intellij.ide.ui.UISettings | ||||||
| import com.intellij.openapi.actionSystem.AnAction | import com.intellij.openapi.actionSystem.AnAction | ||||||
| import com.intellij.openapi.actionSystem.AnActionEvent | import com.intellij.openapi.actionSystem.AnActionEvent | ||||||
| import com.intellij.openapi.actionSystem.CommonDataKeys | import com.intellij.openapi.actionSystem.CommonDataKeys | ||||||
| @@ -124,7 +125,7 @@ class AddBlockInlaysAction : AnAction() { | |||||||
|         val editorContext = FontInfo.getFontRenderContext(editor.contentComponent) |         val editorContext = FontInfo.getFontRenderContext(editor.contentComponent) | ||||||
|         return FontRenderContext( |         return FontRenderContext( | ||||||
|           editorContext.transform, AntialiasingType.getKeyForCurrentScope(false), |           editorContext.transform, AntialiasingType.getKeyForCurrentScope(false), | ||||||
|           if (editor is EditorImpl) editor.myFractionalMetricsHintValue else RenderingHints.VALUE_FRACTIONALMETRICS_OFF |           if (editor is EditorImpl) UISettings.editorFractionalMetricsHint else RenderingHints.VALUE_FRACTIONALMETRICS_OFF | ||||||
|         ) |         ) | ||||||
|       } |       } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -24,6 +24,7 @@ import com.maddyhome.idea.vim.newapi.vim | |||||||
|  |  | ||||||
| /** | /** | ||||||
|  * COMPATIBILITY-LAYER: Additional class |  * COMPATIBILITY-LAYER: Additional class | ||||||
|  |  * Please see: https://jb.gg/zo8n0r | ||||||
|  */ |  */ | ||||||
| class CommandState(private val machine: VimStateMachine) { | class CommandState(private val machine: VimStateMachine) { | ||||||
|  |  | ||||||
|   | |||||||
| @@ -61,6 +61,7 @@ object VimExtensionFacade { | |||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * COMPATIBILITY-LAYER: Additional method |    * COMPATIBILITY-LAYER: Additional method | ||||||
|  |    * Please see: https://jb.gg/zo8n0r | ||||||
|    */ |    */ | ||||||
|   /** The 'map' command for mapping keys to handlers defined in extensions. */ |   /** The 'map' command for mapping keys to handlers defined in extensions. */ | ||||||
|   @JvmStatic |   @JvmStatic | ||||||
|   | |||||||
| @@ -26,6 +26,7 @@ import com.maddyhome.idea.vim.newapi.ij | |||||||
|  |  | ||||||
| /** | /** | ||||||
|  * COMPATIBILITY-LAYER: Created a class, renamed original class |  * COMPATIBILITY-LAYER: Created a class, renamed original class | ||||||
|  |  * Please see: https://jb.gg/zo8n0r | ||||||
|  */ |  */ | ||||||
| interface VimExtensionHandler : ExtensionHandler { | interface VimExtensionHandler : ExtensionHandler { | ||||||
|   override fun execute(editor: VimEditor, context: ExecutionContext) { |   override fun execute(editor: VimEditor, context: ExecutionContext) { | ||||||
|   | |||||||
| @@ -44,18 +44,18 @@ 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.common.CommandAlias | import com.maddyhome.idea.vim.common.CommandAlias | ||||||
| import com.maddyhome.idea.vim.common.CommandAliasHandler | import com.maddyhome.idea.vim.common.CommandAliasHandler | ||||||
| import com.maddyhome.idea.vim.key.CommandNode |  | ||||||
| import com.maddyhome.idea.vim.key.CommandPartNode |  | ||||||
| import com.maddyhome.idea.vim.key.Node |  | ||||||
| import com.maddyhome.idea.vim.key.RootNode |  | ||||||
| import com.maddyhome.idea.vim.key.addLeafs |  | ||||||
| import com.maddyhome.idea.vim.ex.ranges.Ranges | import com.maddyhome.idea.vim.ex.ranges.Ranges | ||||||
| import com.maddyhome.idea.vim.extension.VimExtension | import com.maddyhome.idea.vim.extension.VimExtension | ||||||
| import com.maddyhome.idea.vim.group.KeyGroup | import com.maddyhome.idea.vim.group.KeyGroup | ||||||
| import com.maddyhome.idea.vim.helper.MessageHelper | import com.maddyhome.idea.vim.helper.MessageHelper | ||||||
| import com.maddyhome.idea.vim.helper.runAfterGotFocus | import com.maddyhome.idea.vim.helper.runAfterGotFocus | ||||||
|  | import com.maddyhome.idea.vim.key.CommandNode | ||||||
|  | import com.maddyhome.idea.vim.key.CommandPartNode | ||||||
| import com.maddyhome.idea.vim.key.MappingOwner | import com.maddyhome.idea.vim.key.MappingOwner | ||||||
|  | import com.maddyhome.idea.vim.key.Node | ||||||
| import com.maddyhome.idea.vim.key.RequiredShortcut | import com.maddyhome.idea.vim.key.RequiredShortcut | ||||||
|  | import com.maddyhome.idea.vim.key.RootNode | ||||||
|  | import com.maddyhome.idea.vim.key.addLeafs | ||||||
| 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 com.maddyhome.idea.vim.vimscript.model.datatypes.VimString | import com.maddyhome.idea.vim.vimscript.model.datatypes.VimString | ||||||
|   | |||||||
| @@ -26,6 +26,7 @@ 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.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.SelectionType | import com.maddyhome.idea.vim.command.SelectionType | ||||||
| import com.maddyhome.idea.vim.command.VimStateMachine | import com.maddyhome.idea.vim.command.VimStateMachine | ||||||
| import com.maddyhome.idea.vim.command.isLine | import com.maddyhome.idea.vim.command.isLine | ||||||
| @@ -38,8 +39,10 @@ import com.maddyhome.idea.vim.extension.VimExtensionFacade.putKeyMappingIfMissin | |||||||
| import com.maddyhome.idea.vim.extension.VimExtensionFacade.setOperatorFunction | 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.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.key.OperatorFunction | import com.maddyhome.idea.vim.key.OperatorFunction | ||||||
| import com.maddyhome.idea.vim.newapi.IjExecutionContext | import com.maddyhome.idea.vim.newapi.IjExecutionContext | ||||||
| import com.maddyhome.idea.vim.newapi.IjVimEditor | import com.maddyhome.idea.vim.newapi.IjVimEditor | ||||||
| @@ -171,7 +174,15 @@ class ReplaceWithRegister : VimExtension { | |||||||
|         putToLine = -1 |         putToLine = -1 | ||||||
|       ) |       ) | ||||||
|       ClipboardOptionHelper.IdeaputDisabler().use { |       ClipboardOptionHelper.IdeaputDisabler().use { | ||||||
|         VimPlugin.getPut().putText(IjVimEditor(editor), IjExecutionContext(EditorDataContext.init(editor)), putData) |         VimPlugin.getPut().putText( | ||||||
|  |           IjVimEditor(editor), | ||||||
|  |           IjExecutionContext(EditorDataContext.init(editor)), | ||||||
|  |           putData, | ||||||
|  |           operatorArguments = OperatorArguments( | ||||||
|  |             editor.vimStateMachine?.isOperatorPending ?: false, | ||||||
|  |             0, editor.editorMode, editor.subMode | ||||||
|  |           ) | ||||||
|  |         ) | ||||||
|       } |       } | ||||||
|  |  | ||||||
|       caret.registerStorage.saveRegister(savedRegister.name, savedRegister) |       caret.registerStorage.saveRegister(savedRegister.name, savedRegister) | ||||||
|   | |||||||
| @@ -245,7 +245,7 @@ public class ChangeGroup extends VimChangeGroupBase { | |||||||
|         final boolean lastWordChar = |         final boolean lastWordChar = | ||||||
|           offset >= fileSize - 1 || CharacterHelper.charType(chars.charAt(offset + 1), bigWord) != charType; |           offset >= fileSize - 1 || CharacterHelper.charType(chars.charAt(offset + 1), bigWord) != charType; | ||||||
|         if (wordMotions.contains(id) && lastWordChar && motion.getCount() == 1) { |         if (wordMotions.contains(id) && lastWordChar && motion.getCount() == 1) { | ||||||
|           final boolean res = deleteCharacter(editor, caret, 1, true); |           final boolean res = deleteCharacter(editor, caret, 1, true, operatorArguments); | ||||||
|           if (res) { |           if (res) { | ||||||
|             editor.setVimChangeActionSwitchMode(VimStateMachine.Mode.INSERT); |             editor.setVimChangeActionSwitchMode(VimStateMachine.Mode.INSERT); | ||||||
|           } |           } | ||||||
| @@ -306,7 +306,8 @@ public class ChangeGroup extends VimChangeGroupBase { | |||||||
|       Pair<TextRange, SelectionType> deleteRangeAndType = |       Pair<TextRange, SelectionType> deleteRangeAndType = | ||||||
|         getDeleteRangeAndType(editor, caret, context, argument, true, operatorArguments.withCount0(count0)); |         getDeleteRangeAndType(editor, caret, context, argument, true, operatorArguments.withCount0(count0)); | ||||||
|       if (deleteRangeAndType == null) return false; |       if (deleteRangeAndType == null) return false; | ||||||
|       return changeRange(editor, caret, deleteRangeAndType.getFirst(), deleteRangeAndType.getSecond(), context); |       return changeRange(editor, caret, deleteRangeAndType.getFirst(), deleteRangeAndType.getSecond(), context, | ||||||
|  |                          operatorArguments); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -425,10 +426,11 @@ public class ChangeGroup extends VimChangeGroupBase { | |||||||
|   /** |   /** | ||||||
|    * Deletes the range of text and enters insert mode |    * Deletes the range of text and enters insert mode | ||||||
|    * |    * | ||||||
|    * @param editor The editor to change |    * @param editor            The editor to change | ||||||
|    * @param caret  The caret to be moved after range deletion |    * @param caret             The caret to be moved after range deletion | ||||||
|    * @param range  The range to change |    * @param range             The range to change | ||||||
|    * @param type   The type of the range |    * @param type              The type of the range | ||||||
|  |    * @param operatorArguments | ||||||
|    * @return true if able to delete the range, false if not |    * @return true if able to delete the range, false if not | ||||||
|    */ |    */ | ||||||
|   @Override |   @Override | ||||||
| @@ -436,7 +438,8 @@ public class ChangeGroup extends VimChangeGroupBase { | |||||||
|                              @NotNull VimCaret caret, |                              @NotNull VimCaret caret, | ||||||
|                              @NotNull TextRange range, |                              @NotNull TextRange range, | ||||||
|                              @NotNull SelectionType type, |                              @NotNull SelectionType type, | ||||||
|                              ExecutionContext context) { |                              @Nullable ExecutionContext context, | ||||||
|  |                              @NotNull OperatorArguments operatorArguments) { | ||||||
|     int col = 0; |     int col = 0; | ||||||
|     int lines = 0; |     int lines = 0; | ||||||
|     if (type == SelectionType.BLOCK_WISE) { |     if (type == SelectionType.BLOCK_WISE) { | ||||||
| @@ -450,7 +453,7 @@ public class ChangeGroup extends VimChangeGroupBase { | |||||||
|  |  | ||||||
|     final VimLogicalPosition lp = editor.offsetToLogicalPosition(injector.getMotion().moveCaretToLineStartSkipLeading(editor, caret)); |     final VimLogicalPosition lp = editor.offsetToLogicalPosition(injector.getMotion().moveCaretToLineStartSkipLeading(editor, caret)); | ||||||
|  |  | ||||||
|     boolean res = deleteRange(editor, caret, range, type, true); |     boolean res = deleteRange(editor, caret, range, type, true, operatorArguments); | ||||||
|     if (res) { |     if (res) { | ||||||
|       if (type == SelectionType.LINE_WISE) { |       if (type == SelectionType.LINE_WISE) { | ||||||
|         // Please don't use `getDocument().getText().isEmpty()` because it converts CharSequence into String |         // Please don't use `getDocument().getText().isEmpty()` because it converts CharSequence into String | ||||||
| @@ -586,10 +589,11 @@ public class ChangeGroup extends VimChangeGroupBase { | |||||||
|                           @NotNull VimCaret caret, |                           @NotNull VimCaret caret, | ||||||
|                           @NotNull ExecutionContext context, |                           @NotNull ExecutionContext context, | ||||||
|                           int lines, |                           int lines, | ||||||
|                           int dir) { |                           int dir, | ||||||
|  |                           @NotNull OperatorArguments operatorArguments) { | ||||||
|     int start = ((IjVimCaret) caret).getCaret().getOffset(); |     int start = ((IjVimCaret) caret).getCaret().getOffset(); | ||||||
|     int end = VimPlugin.getMotion().moveCaretToLineEndOffset(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); |     indentRange(editor, caret, context, new TextRange(start, end), 1, dir, operatorArguments); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
| @@ -602,7 +606,7 @@ public class ChangeGroup extends VimChangeGroupBase { | |||||||
|     final TextRange range = |     final TextRange range = | ||||||
|       injector.getMotion().getMotionRange(editor, caret, context, argument, operatorArguments); |       injector.getMotion().getMotionRange(editor, caret, context, argument, operatorArguments); | ||||||
|     if (range != null) { |     if (range != null) { | ||||||
|       indentRange(editor, caret, context, range, 1, dir); |       indentRange(editor, caret, context, range, 1, dir, operatorArguments); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -629,7 +633,8 @@ public class ChangeGroup extends VimChangeGroupBase { | |||||||
|                           @NotNull ExecutionContext context, |                           @NotNull ExecutionContext context, | ||||||
|                           @NotNull TextRange range, |                           @NotNull TextRange range, | ||||||
|                           int count, |                           int count, | ||||||
|                           int dir) { |                           int dir, | ||||||
|  |                           @NotNull OperatorArguments operatorArguments) { | ||||||
|     if (logger.isDebugEnabled()) { |     if (logger.isDebugEnabled()) { | ||||||
|       logger.debug("count=" + count); |       logger.debug("count=" + count); | ||||||
|     } |     } | ||||||
| @@ -675,7 +680,7 @@ public class ChangeGroup extends VimChangeGroupBase { | |||||||
|               } |               } | ||||||
|             } |             } | ||||||
|             if (pos > wsoff) { |             if (pos > wsoff) { | ||||||
|               deleteText(editor, new TextRange(wsoff, pos), null, caret); |               deleteText(editor, new TextRange(wsoff, pos), null, caret, operatorArguments); | ||||||
|             } |             } | ||||||
|           } |           } | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -36,6 +36,7 @@ class IjVimStorageService : VimStorageServiceBase() { | |||||||
|     editor.ij.putUserData(getOrCreateIjKey(key), data) |     editor.ij.putUserData(getOrCreateIjKey(key), data) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   @Suppress("UNCHECKED_CAST") | ||||||
|   override fun <T> getDataFromBuffer(editor: VimEditor, key: com.maddyhome.idea.vim.api.Key<T>): T? { |   override fun <T> getDataFromBuffer(editor: VimEditor, key: com.maddyhome.idea.vim.api.Key<T>): T? { | ||||||
|     val buffer = EditorHelper.getVirtualFile(editor.ij)?.path ?: "empty path" |     val buffer = EditorHelper.getVirtualFile(editor.ij)?.path ?: "empty path" | ||||||
|     return bufferToKey[buffer]?.get(key.name) as T? |     return bufferToKey[buffer]?.get(key.name) as T? | ||||||
| @@ -60,6 +61,7 @@ class IjVimStorageService : VimStorageServiceBase() { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   private val ijKeys = mutableMapOf<String, Key<out Any?>>() |   private val ijKeys = mutableMapOf<String, Key<out Any?>>() | ||||||
|  |   @Suppress("UNCHECKED_CAST") | ||||||
|   private fun <T> getOrCreateIjKey(key: com.maddyhome.idea.vim.api.Key<T>): Key<T> { |   private fun <T> getOrCreateIjKey(key: com.maddyhome.idea.vim.api.Key<T>): Key<T> { | ||||||
|     val storedIjKey = ijKeys[key.name] |     val storedIjKey = ijKeys[key.name] | ||||||
|     if (storedIjKey != null) { |     if (storedIjKey != null) { | ||||||
|   | |||||||
| @@ -108,7 +108,9 @@ public class MacroGroup extends VimMacroBase { | |||||||
|               KeyHandler.getInstance().handleKey(editor, key, context); |               KeyHandler.getInstance().handleKey(editor, key, context); | ||||||
|             }); |             }); | ||||||
|           } |           } | ||||||
|  |           keyStack.resetFirst(); | ||||||
|         } |         } | ||||||
|  |         keyStack.removeFirst(); | ||||||
|       }); |       }); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -411,6 +411,7 @@ public class MarkGroup extends VimMarkGroupBase implements PersistentStateCompon | |||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * COMPATIBILITY-LAYER: Method added |    * COMPATIBILITY-LAYER: Method added | ||||||
|  |    * Please see: <a href="https://jb.gg/zo8n0r">doc</a> | ||||||
|    * |    * | ||||||
|    * @deprecated Please use method with VimEditor |    * @deprecated Please use method with VimEditor | ||||||
|    */ |    */ | ||||||
|   | |||||||
| @@ -20,26 +20,23 @@ package com.maddyhome.idea.vim.group | |||||||
|  |  | ||||||
| import com.intellij.icons.AllIcons | import com.intellij.icons.AllIcons | ||||||
| import com.intellij.ide.BrowserUtil | import com.intellij.ide.BrowserUtil | ||||||
| import com.intellij.ide.IdeBundle |  | ||||||
| import com.intellij.ide.actions.OpenFileAction | import com.intellij.ide.actions.OpenFileAction | ||||||
| import com.intellij.ide.actions.RevealFileAction | import com.intellij.ide.actions.RevealFileAction | ||||||
|  | import com.intellij.notification.ActionCenter | ||||||
| import com.intellij.notification.Notification | import com.intellij.notification.Notification | ||||||
| import com.intellij.notification.NotificationGroup | import com.intellij.notification.NotificationGroup | ||||||
| import com.intellij.notification.NotificationGroupManager | import com.intellij.notification.NotificationGroupManager | ||||||
| import com.intellij.notification.NotificationListener |  | ||||||
| import com.intellij.notification.NotificationType | import com.intellij.notification.NotificationType | ||||||
| import com.intellij.openapi.actionSystem.AnAction | import com.intellij.openapi.actionSystem.AnAction | ||||||
| import com.intellij.openapi.actionSystem.AnActionEvent | import com.intellij.openapi.actionSystem.AnActionEvent | ||||||
| import com.intellij.openapi.actionSystem.KeyboardShortcut | import com.intellij.openapi.actionSystem.KeyboardShortcut | ||||||
| import com.intellij.openapi.ide.CopyPasteManager | import com.intellij.openapi.ide.CopyPasteManager | ||||||
| import com.intellij.openapi.keymap.Keymap |  | ||||||
| import com.intellij.openapi.keymap.KeymapUtil | import com.intellij.openapi.keymap.KeymapUtil | ||||||
| import com.intellij.openapi.options.ShowSettingsUtil | import com.intellij.openapi.options.ShowSettingsUtil | ||||||
| import com.intellij.openapi.project.DumbAwareAction | import com.intellij.openapi.project.DumbAwareAction | ||||||
| import com.intellij.openapi.project.Project | import com.intellij.openapi.project.Project | ||||||
| import com.intellij.openapi.ui.Messages | import com.intellij.openapi.ui.Messages | ||||||
| import com.intellij.openapi.util.SystemInfo | import com.intellij.openapi.util.SystemInfo | ||||||
| import com.intellij.openapi.util.registry.Registry |  | ||||||
| import com.maddyhome.idea.vim.VimPlugin | import com.maddyhome.idea.vim.VimPlugin | ||||||
| import com.maddyhome.idea.vim.helper.MessageHelper | import com.maddyhome.idea.vim.helper.MessageHelper | ||||||
| import com.maddyhome.idea.vim.key.ShortcutOwner | import com.maddyhome.idea.vim.key.ShortcutOwner | ||||||
| @@ -50,7 +47,6 @@ import com.maddyhome.idea.vim.statistic.ActionTracker | |||||||
| import com.maddyhome.idea.vim.ui.VimEmulationConfigurable | import com.maddyhome.idea.vim.ui.VimEmulationConfigurable | ||||||
| import com.maddyhome.idea.vim.vimscript.services.IjVimOptionService | import com.maddyhome.idea.vim.vimscript.services.IjVimOptionService | ||||||
| import com.maddyhome.idea.vim.vimscript.services.VimRcService | import com.maddyhome.idea.vim.vimscript.services.VimRcService | ||||||
| import org.jetbrains.annotations.Nls |  | ||||||
| import java.awt.datatransfer.StringSelection | import java.awt.datatransfer.StringSelection | ||||||
| import java.io.File | import java.io.File | ||||||
| import javax.swing.KeyStroke | import javax.swing.KeyStroke | ||||||
| @@ -115,23 +111,6 @@ class NotificationService(private val project: Project?) { | |||||||
|     Messages.getQuestionIcon() |     Messages.getQuestionIcon() | ||||||
|   ) |   ) | ||||||
|  |  | ||||||
|   fun specialKeymap(keymap: Keymap, listener: NotificationListener.Adapter) { |  | ||||||
|     val notification = IDEAVIM_STICKY_GROUP.createNotification( |  | ||||||
|       IDEAVIM_NOTIFICATION_TITLE, |  | ||||||
|       "IdeaVim plugin doesn't use the special \"Vim\" keymap any longer. " + |  | ||||||
|         "Switching to \"${keymap.presentableName}\" keymap.<br/><br/>" + |  | ||||||
|         "Now it is possible to set up:<br/>" + |  | ||||||
|         "<ul>" + |  | ||||||
|         "<li>Vim keys in your ~/.ideavimrc file using key mapping commands</li>" + |  | ||||||
|         "<li>IDE action shortcuts in \"File | Settings | Keymap\"</li>" + |  | ||||||
|         "<li>Vim or IDE handlers for conflicting shortcuts in <a href='#settings'>Vim Emulation</a> settings</li>" + |  | ||||||
|         "</ul>", |  | ||||||
|       NotificationType.INFORMATION |  | ||||||
|     ) |  | ||||||
|     notification.setListener(listener) |  | ||||||
|     notification.notify(project) |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   fun noVimrcAsDefault() { |   fun noVimrcAsDefault() { | ||||||
|     val notification = IDEAVIM_STICKY_GROUP.createNotification( |     val notification = IDEAVIM_STICKY_GROUP.createNotification( | ||||||
|       IDEAVIM_NOTIFICATION_TITLE, |       IDEAVIM_NOTIFICATION_TITLE, | ||||||
| @@ -208,7 +187,7 @@ class NotificationService(private val project: Project?) { | |||||||
|       Notification(IDEAVIM_NOTIFICATION_ID, IDEAVIM_NOTIFICATION_TITLE, content, NotificationType.INFORMATION).let { |       Notification(IDEAVIM_NOTIFICATION_ID, IDEAVIM_NOTIFICATION_TITLE, content, NotificationType.INFORMATION).let { | ||||||
|         notification = it |         notification = it | ||||||
|         it.whenExpired { notification = null } |         it.whenExpired { notification = null } | ||||||
|         it.setContent(it.content + "<br><br><small>Use ${getToolwindowName()} to see previous ids</small>") |         it.setContent(it.content + "<br><br><small>Use ${ActionCenter.getToolwindowName()} to see previous ids</small>") | ||||||
|  |  | ||||||
|         it.addAction(StopTracking()) |         it.addAction(StopTracking()) | ||||||
|  |  | ||||||
| @@ -222,15 +201,6 @@ class NotificationService(private val project: Project?) { | |||||||
|       } |       } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // [VERSION UPDATE] 221+ Use ActionCenter.getToolWindowName |  | ||||||
|     private fun getToolwindowName(): @Nls String { |  | ||||||
|       return IdeBundle.message(if (isEnabled()) "toolwindow.stripe.Notifications" else "toolwindow.stripe.Event_Log") |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     private fun isEnabled(): Boolean { |  | ||||||
|       return Registry.`is`("ide.notification.action.center", true) |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     class CopyActionId(val id: String?, val project: Project?) : DumbAwareAction(MessageHelper.message("action.copy.action.id.text")) { |     class CopyActionId(val id: String?, val project: Project?) : DumbAwareAction(MessageHelper.message("action.copy.action.id.text")) { | ||||||
|       override fun actionPerformed(e: AnActionEvent) { |       override fun actionPerformed(e: AnActionEvent) { | ||||||
|         CopyPasteManager.getInstance().setContents(StringSelection(id ?: "")) |         CopyPasteManager.getInstance().setContents(StringSelection(id ?: "")) | ||||||
|   | |||||||
| @@ -21,8 +21,8 @@ package com.maddyhome.idea.vim.group; | |||||||
| import com.intellij.openapi.actionSystem.DataContext; | import com.intellij.openapi.actionSystem.DataContext; | ||||||
| import com.intellij.openapi.actionSystem.PlatformDataKeys; | import com.intellij.openapi.actionSystem.PlatformDataKeys; | ||||||
| import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx; | import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx; | ||||||
|  | import com.intellij.openapi.fileEditor.impl.EditorComposite; | ||||||
| import com.intellij.openapi.fileEditor.impl.EditorWindow; | import com.intellij.openapi.fileEditor.impl.EditorWindow; | ||||||
| import com.intellij.openapi.fileEditor.impl.EditorWithProviderComposite; |  | ||||||
| import com.intellij.openapi.project.Project; | import com.intellij.openapi.project.Project; | ||||||
| import com.intellij.openapi.vfs.VirtualFile; | import com.intellij.openapi.vfs.VirtualFile; | ||||||
| import com.intellij.util.concurrency.annotations.RequiresReadLock; | import com.intellij.util.concurrency.annotations.RequiresReadLock; | ||||||
| @@ -183,7 +183,7 @@ public class WindowGroup extends WindowGroupBase { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   private static @Nullable Rectangle getEditorWindowRectangle(@NotNull EditorWindow window) { |   private static @Nullable Rectangle getEditorWindowRectangle(@NotNull EditorWindow window) { | ||||||
|     final EditorWithProviderComposite editor = window.getSelectedEditor(); |     final EditorComposite editor = window.getSelectedComposite(); | ||||||
|     if (editor != null) { |     if (editor != null) { | ||||||
|       final Point point = editor.getComponent().getLocationOnScreen(); |       final Point point = editor.getComponent().getLocationOnScreen(); | ||||||
|       final Dimension dimension = editor.getComponent().getSize(); |       final Dimension dimension = editor.getComponent().getSize(); | ||||||
|   | |||||||
| @@ -34,6 +34,7 @@ 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.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.command.OperatorArguments | ||||||
| import com.maddyhome.idea.vim.command.SelectionType | import com.maddyhome.idea.vim.command.SelectionType | ||||||
| import com.maddyhome.idea.vim.command.VimStateMachine | import com.maddyhome.idea.vim.command.VimStateMachine | ||||||
| import com.maddyhome.idea.vim.command.isBlock | import com.maddyhome.idea.vim.command.isBlock | ||||||
| @@ -43,7 +44,9 @@ import com.maddyhome.idea.vim.common.TextRange | |||||||
| import com.maddyhome.idea.vim.helper.EditorHelper | import com.maddyhome.idea.vim.helper.EditorHelper | ||||||
| import com.maddyhome.idea.vim.helper.TestClipboardModel | import com.maddyhome.idea.vim.helper.TestClipboardModel | ||||||
| import com.maddyhome.idea.vim.helper.fileSize | import com.maddyhome.idea.vim.helper.fileSize | ||||||
|  | import com.maddyhome.idea.vim.helper.mode | ||||||
| import com.maddyhome.idea.vim.helper.moveToInlayAwareOffset | import com.maddyhome.idea.vim.helper.moveToInlayAwareOffset | ||||||
|  | import com.maddyhome.idea.vim.helper.subMode | ||||||
| import com.maddyhome.idea.vim.mark.VimMarkConstants.MARK_CHANGE_POS | import com.maddyhome.idea.vim.mark.VimMarkConstants.MARK_CHANGE_POS | ||||||
| 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 | ||||||
| @@ -62,7 +65,13 @@ import kotlin.math.min | |||||||
| class PutGroup : VimPutBase() { | class PutGroup : VimPutBase() { | ||||||
|   override fun putTextForCaret(editor: VimEditor, caret: VimCaret, context: ExecutionContext, data: PutData, updateVisualMarks: Boolean): Boolean { |   override fun putTextForCaret(editor: VimEditor, caret: VimCaret, context: ExecutionContext, data: PutData, updateVisualMarks: Boolean): Boolean { | ||||||
|     val additionalData = collectPreModificationData(editor, data) |     val additionalData = collectPreModificationData(editor, data) | ||||||
|     data.visualSelection?.let { deleteSelectedText(editor, data) } |     data.visualSelection?.let { | ||||||
|  |       deleteSelectedText( | ||||||
|  |         editor, | ||||||
|  |         data, | ||||||
|  |         OperatorArguments(false, 0, editor.mode, editor.subMode) | ||||||
|  |       ) | ||||||
|  |     } | ||||||
|     val processedText = processText(editor, data) ?: return false |     val processedText = processText(editor, data) ?: return false | ||||||
|     putForCaret(editor, caret, data, additionalData, context, processedText) |     putForCaret(editor, caret, data, additionalData, context, processedText) | ||||||
|     if (editor.primaryCaret() == caret && updateVisualMarks) { |     if (editor.primaryCaret() == caret && updateVisualMarks) { | ||||||
| @@ -93,7 +102,6 @@ class PutGroup : VimPutBase() { | |||||||
|       } |       } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     notifyAboutIdeaPut(editor) |  | ||||||
|     logger.debug("Perform put via plugin") |     logger.debug("Perform put via plugin") | ||||||
|     val myCarets = if (visualSelection != null) { |     val myCarets = if (visualSelection != null) { | ||||||
|       visualSelection.caretsAndSelections.keys.sortedByDescending { it.getLogicalPosition() } |       visualSelection.caretsAndSelections.keys.sortedByDescending { it.getLogicalPosition() } | ||||||
| @@ -113,6 +121,7 @@ class PutGroup : VimPutBase() { | |||||||
|     context: ExecutionContext, |     context: ExecutionContext, | ||||||
|     text: ProcessedTextData, |     text: ProcessedTextData, | ||||||
|   ) { |   ) { | ||||||
|  |     notifyAboutIdeaPut(editor) | ||||||
|     if (data.visualSelection?.typeInEditor?.isLine == true && editor.isOneLineMode()) return |     if (data.visualSelection?.typeInEditor?.isLine == true && editor.isOneLineMode()) return | ||||||
|     val startOffsets = prepareDocumentAndGetStartOffsets(editor, caret, text.typeInRegister, data, additionalData) |     val startOffsets = prepareDocumentAndGetStartOffsets(editor, caret, text.typeInRegister, data, additionalData) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -32,7 +32,6 @@ 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.listener.VimYankListener | import com.maddyhome.idea.vim.listener.VimYankListener | ||||||
| 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.yank.YankGroupBase | import com.maddyhome.idea.vim.yank.YankGroupBase | ||||||
| import org.jetbrains.annotations.Contract | import org.jetbrains.annotations.Contract | ||||||
| import kotlin.math.min | import kotlin.math.min | ||||||
| @@ -211,8 +210,8 @@ class YankGroup : YankGroupBase() { | |||||||
|     notifyListeners(editor, range) |     notifyListeners(editor, range) | ||||||
|  |  | ||||||
|     var result = true |     var result = true | ||||||
|     for ((caret, range) in caretToRange) { |     for ((caret, myRange) in caretToRange) { | ||||||
|       result = caret.registerStorage.storeText(editor, range, type, false) && result |       result = caret.registerStorage.storeText(editor, myRange, type, false) && result | ||||||
|     } |     } | ||||||
|     return result |     return result | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -44,6 +44,7 @@ class VisualMotionGroup : VimVisualMotionGroupBase() { | |||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * COMPATIBILITY-LAYER: Added a method |    * COMPATIBILITY-LAYER: Added a method | ||||||
|  |    * Please see: https://jb.gg/zo8n0r | ||||||
|    */ |    */ | ||||||
|   fun enterVisualMode(editor: Editor, subMode: CommandState.SubMode? = null): Boolean { |   fun enterVisualMode(editor: Editor, subMode: CommandState.SubMode? = null): Boolean { | ||||||
|     return this.enterVisualMode(editor.vim, subMode?.engine) |     return this.enterVisualMode(editor.vim, subMode?.engine) | ||||||
|   | |||||||
| @@ -60,12 +60,14 @@ val Editor.editorMode | |||||||
|  |  | ||||||
| /** | /** | ||||||
|  * COMPATIBILITY-LAYER: New method |  * COMPATIBILITY-LAYER: New method | ||||||
|  |  * Please see: https://jb.gg/zo8n0r | ||||||
|  */ |  */ | ||||||
| val Editor.mode | val Editor.mode | ||||||
|   get() = this.vim.vimStateMachine.mode.ij |   get() = this.vim.vimStateMachine.mode.ij | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * COMPATIBILITY-LAYER: New method |  * COMPATIBILITY-LAYER: New method | ||||||
|  |  * Please see: https://jb.gg/zo8n0r | ||||||
|  */ |  */ | ||||||
| val CommandState.Mode.isEndAllowed: Boolean | val CommandState.Mode.isEndAllowed: Boolean | ||||||
|   get() = this.engine.isEndAllowed |   get() = this.engine.isEndAllowed | ||||||
|   | |||||||
| @@ -37,6 +37,7 @@ import org.jetbrains.annotations.Nullable; | |||||||
| import org.jetbrains.annotations.Range; | import org.jetbrains.annotations.Range; | ||||||
|  |  | ||||||
| import java.awt.*; | import java.awt.*; | ||||||
|  | import java.awt.geom.Point2D; | ||||||
| import java.nio.CharBuffer; | import java.nio.CharBuffer; | ||||||
| import java.util.Collections; | import java.util.Collections; | ||||||
| import java.util.Comparator; | import java.util.Comparator; | ||||||
| @@ -154,6 +155,7 @@ public class EditorHelper { | |||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * COMPATIBILITY-LAYER: Created a function |    * COMPATIBILITY-LAYER: Created a function | ||||||
|  |    * Please see: <a href="https://jb.gg/zo8n0r">doc</a> | ||||||
|    */ |    */ | ||||||
|   public static int getVisualLineCount(final @NotNull Editor editor) { |   public static int getVisualLineCount(final @NotNull Editor editor) { | ||||||
|     return getVisualLineCount(new IjVimEditor(editor)); |     return getVisualLineCount(new IjVimEditor(editor)); | ||||||
| @@ -245,12 +247,27 @@ public class EditorHelper { | |||||||
|    * font. It does not include inlays or folds. |    * font. It does not include inlays or folds. | ||||||
|    * <p> |    * <p> | ||||||
|    * Note that this value is only approximate and should be avoided whenever possible! |    * Note that this value is only approximate and should be avoided whenever possible! | ||||||
|  |    * </p> | ||||||
|    * |    * | ||||||
|    * @param editor The editor |    * @param editor The editor | ||||||
|    * @return The number of screen columns |    * @return The number of screen columns | ||||||
|    */ |    */ | ||||||
|   public static int getApproximateScreenWidth(final @NotNull Editor editor) { |   public static int getApproximateScreenWidth(final @NotNull Editor editor) { | ||||||
|     return getVisibleArea(editor).width / EditorUtil.getPlainSpaceWidth(editor); |     return (int)(getVisibleArea(editor).width / getPlainSpaceWidthFloat(editor)); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * Gets the width of the space character in the editor's plain font as a float. | ||||||
|  |    * <p> | ||||||
|  |    * Font width can be fractional, but {@link EditorUtil#getPlainSpaceWidth(Editor)} returns it as an int, which can | ||||||
|  |    * lead to rounding errors. | ||||||
|  |    * </p> | ||||||
|  |    * | ||||||
|  |    * @param editor The editor | ||||||
|  |    * @return The width of the space character in the editor's plain font in pixels. It might be a fractional value. | ||||||
|  |    */ | ||||||
|  |   public static float getPlainSpaceWidthFloat(final @NotNull Editor editor) { | ||||||
|  |     return EditorUtil.fontForChar(' ', Font.PLAIN, editor).charWidth2D(' '); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
| @@ -802,19 +819,20 @@ public class EditorHelper { | |||||||
|       } |       } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     final int columnLeftX = editor.visualPositionToXY(new VisualPosition(visualLine, targetVisualColumn)).x; |     final int columnLeftX = (int) Math.round(editor.visualPositionToPoint2D(new VisualPosition(visualLine, targetVisualColumn)).getX()); | ||||||
|     scrollHorizontally(editor, columnLeftX); |     scrollHorizontally(editor, columnLeftX); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   public static void scrollColumnToMiddleOfScreen(@NotNull Editor editor, int visualLine, int visualColumn) { |   public static void scrollColumnToMiddleOfScreen(@NotNull Editor editor, int visualLine, int visualColumn) { | ||||||
|     final Point point = editor.visualPositionToXY(new VisualPosition(visualLine, visualColumn)); |     final Point2D point = editor.visualPositionToPoint2D(new VisualPosition(visualLine, visualColumn)); | ||||||
|     final int screenWidth = getVisibleArea(editor).width; |     final int screenWidth = getVisibleArea(editor).width; | ||||||
|  |  | ||||||
|     // Snap the column to the nearest standard column grid. This positions us nicely if there are an odd or even number |     // Snap the column to the nearest standard column grid. This positions us nicely if there are an odd or even number | ||||||
|     // of columns. It also works with inline inlays and folds. It is slightly inaccurate for proportional fonts, but is |     // of columns. It also works with inline inlays and folds. It is slightly inaccurate for proportional fonts, but is | ||||||
|     // still a good solution. Besides, what kind of monster uses Vim with proportional fonts? |     // still a good solution. Besides, what kind of monster uses Vim with proportional fonts? | ||||||
|     final int standardColumnWidth = EditorUtil.getPlainSpaceWidth(editor); |     final float standardColumnWidth = EditorHelper.getPlainSpaceWidthFloat(editor); | ||||||
|     final int x = max(0, point.x - (screenWidth / standardColumnWidth / 2 * standardColumnWidth)); |     final int screenMidColumn = (int) (screenWidth / standardColumnWidth / 2); | ||||||
|  |     final int x = max(0, (int) Math.round(point.getX() - (screenMidColumn * standardColumnWidth))); | ||||||
|     scrollHorizontally(editor, x); |     scrollHorizontally(editor, x); | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -839,7 +857,7 @@ public class EditorHelper { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     // Scroll to the left edge of the target column, minus a screenwidth, and adjusted for inlays |     // Scroll to the left edge of the target column, minus a screenwidth, and adjusted for inlays | ||||||
|     final int targetColumnRightX = editor.visualPositionToXY(new VisualPosition(visualLine, targetVisualColumn + 1)).x; |     final int targetColumnRightX = (int) Math.round(editor.visualPositionToPoint2D(new VisualPosition(visualLine, targetVisualColumn + 1)).getX()); | ||||||
|     final int screenWidth = getVisibleArea(editor).width; |     final int screenWidth = getVisibleArea(editor).width; | ||||||
|     scrollHorizontally(editor, targetColumnRightX - screenWidth); |     scrollHorizontally(editor, targetColumnRightX - screenWidth); | ||||||
|   } |   } | ||||||
| @@ -1001,18 +1019,18 @@ public class EditorHelper { | |||||||
|     // Note that visualPos.leansRight will be true for the right half side of the character grid |     // Note that visualPos.leansRight will be true for the right half side of the character grid | ||||||
|     VisualPosition closestVisualPosition = editor.xyToVisualPosition(new Point(x, y)); |     VisualPosition closestVisualPosition = editor.xyToVisualPosition(new Point(x, y)); | ||||||
|  |  | ||||||
|     // Make sure we get the character that contains this XY, not the editor's decision about closest character. The |     // Make sure we get the character that contains this XY, not the editor's decision about the closest character. The | ||||||
|     // editor will give us the next character if X is over half way through the character grid. |     // editor will give us the next character if X is over halfway through the character grid. Take into account that | ||||||
|     int xActualLeft = editor.visualPositionToXY(closestVisualPosition).x; |     // the font size might be fractional, but the editor's area is integer. Use floating point values and round. | ||||||
|  |     long xActualLeft = Math.round(editor.visualPositionToPoint2D(closestVisualPosition).getX()); | ||||||
|     if (xActualLeft > x) { |     if (xActualLeft > x) { | ||||||
|       closestVisualPosition = getPreviousNonInlayVisualPosition(editor, closestVisualPosition); |       closestVisualPosition = getPreviousNonInlayVisualPosition(editor, closestVisualPosition); | ||||||
|       xActualLeft = editor.visualPositionToXY(closestVisualPosition).x; |       xActualLeft = Math.round(editor.visualPositionToPoint2D(closestVisualPosition).getX()); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     if (xActualLeft >= leftBound) { |     if (xActualLeft >= leftBound) { | ||||||
|       final int xActualRight = |       final VisualPosition nextVisualPosition = new VisualPosition(closestVisualPosition.line, closestVisualPosition.column + 1); | ||||||
|         editor.visualPositionToXY(new VisualPosition(closestVisualPosition.line, closestVisualPosition.column + 1)).x - |       final long xActualRight = Math.round(editor.visualPositionToPoint2D(nextVisualPosition).getX()) - 1; | ||||||
|         1; |  | ||||||
|       if (xActualRight <= rightBound) { |       if (xActualRight <= rightBound) { | ||||||
|         return closestVisualPosition.column; |         return closestVisualPosition.column; | ||||||
|       } |       } | ||||||
|   | |||||||
| @@ -22,6 +22,7 @@ import com.intellij.codeInsight.template.TemplateManager | |||||||
| import com.intellij.codeWithMe.ClientId | import com.intellij.codeWithMe.ClientId | ||||||
| import com.intellij.injected.editor.EditorWindow | import com.intellij.injected.editor.EditorWindow | ||||||
| import com.intellij.openapi.editor.Caret | import com.intellij.openapi.editor.Caret | ||||||
|  | import com.intellij.openapi.editor.ClientEditorManager | ||||||
| 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.EditorFactory | import com.intellij.openapi.editor.EditorFactory | ||||||
| @@ -30,6 +31,7 @@ import com.intellij.openapi.util.Key | |||||||
| import com.maddyhome.idea.vim.VimPlugin | import com.maddyhome.idea.vim.VimPlugin | ||||||
| import com.maddyhome.idea.vim.options.OptionConstants | import com.maddyhome.idea.vim.options.OptionConstants | ||||||
| import com.maddyhome.idea.vim.options.OptionScope | import com.maddyhome.idea.vim.options.OptionScope | ||||||
|  | import kotlin.streams.toList | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * This annotation is created for test functions (methods). |  * This annotation is created for test functions (methods). | ||||||
| @@ -83,10 +85,9 @@ fun Editor.getTopLevelEditor() = if (this is EditorWindow) this.delegate else th | |||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Return list of editors for local host (for code with me plugin) |  * Return list of editors for local host (for code with me plugin) | ||||||
|  * [VERSION UPDATE] 212+ ClientEditorManager.editors() |  | ||||||
|  */ |  */ | ||||||
| fun localEditors(): List<Editor> { | fun localEditors(): List<Editor> { | ||||||
|   return EditorFactory.getInstance().allEditors.filter { editor -> editor.editorClientId.let { it == null || it == ClientId.currentOrNull } } |   return ClientEditorManager.getCurrentInstance().editors().toList() | ||||||
| } | } | ||||||
|  |  | ||||||
| fun localEditors(doc: Document): List<Editor> { | fun localEditors(doc: Document): List<Editor> { | ||||||
|   | |||||||
| @@ -24,11 +24,8 @@ import com.intellij.openapi.actionSystem.ActionPlaces | |||||||
| import com.intellij.openapi.actionSystem.AnAction | import com.intellij.openapi.actionSystem.AnAction | ||||||
| import com.intellij.openapi.actionSystem.AnActionEvent | import com.intellij.openapi.actionSystem.AnActionEvent | ||||||
| import com.intellij.openapi.actionSystem.AnActionResult | import com.intellij.openapi.actionSystem.AnActionResult | ||||||
| import com.intellij.openapi.actionSystem.DataContext |  | ||||||
| import com.intellij.openapi.actionSystem.IdeActions | import com.intellij.openapi.actionSystem.IdeActions | ||||||
| import com.intellij.openapi.actionSystem.PlatformCoreDataKeys |  | ||||||
| import com.intellij.openapi.actionSystem.PlatformDataKeys | import com.intellij.openapi.actionSystem.PlatformDataKeys | ||||||
| import com.intellij.openapi.actionSystem.Presentation |  | ||||||
| import com.intellij.openapi.actionSystem.ex.ActionManagerEx | import com.intellij.openapi.actionSystem.ex.ActionManagerEx | ||||||
| import com.intellij.openapi.actionSystem.ex.ActionUtil | import com.intellij.openapi.actionSystem.ex.ActionUtil | ||||||
| import com.intellij.openapi.command.CommandProcessor | import com.intellij.openapi.command.CommandProcessor | ||||||
| @@ -86,7 +83,7 @@ class IjActionExecutor : VimActionExecutor { | |||||||
|     // This method executes inside of lastUpdateAndCheckDumb |     // This method executes inside of lastUpdateAndCheckDumb | ||||||
|     // Another related issue: VIM-2604 |     // Another related issue: VIM-2604 | ||||||
|     if (!ActionUtil.lastUpdateAndCheckDumb(ijAction, event, false)) return false |     if (!ActionUtil.lastUpdateAndCheckDumb(ijAction, event, false)) return false | ||||||
|     if (ijAction is ActionGroup && !canBePerformed(event, ijAction, context.ij)) { |     if (ijAction is ActionGroup && !event.presentation.isPerformGroup) { | ||||||
|       // Some ActionGroups should not be performed, but shown as a popup |       // Some ActionGroups should not be performed, but shown as a popup | ||||||
|       val popup = JBPopupFactory.getInstance() |       val popup = JBPopupFactory.getInstance() | ||||||
|         .createActionGroupPopup(event.presentation.text, ijAction, context.ij, false, null, -1) |         .createActionGroupPopup(event.presentation.text, ijAction, context.ij, false, null, -1) | ||||||
| @@ -118,10 +115,9 @@ class IjActionExecutor : VimActionExecutor { | |||||||
|     var indexError: IndexNotReadyException? = null |     var indexError: IndexNotReadyException? = null | ||||||
|     val manager = ActionManagerEx.getInstanceEx() |     val manager = ActionManagerEx.getInstanceEx() | ||||||
|     manager.fireBeforeActionPerformed(action, event) |     manager.fireBeforeActionPerformed(action, event) | ||||||
|     val component = event.getData(PlatformCoreDataKeys.CONTEXT_COMPONENT) |  | ||||||
|     var result: AnActionResult? = null |     var result: AnActionResult? = null | ||||||
|     try { |     try { | ||||||
|       SlowOperations.allowSlowOperations(SlowOperations.ACTION_PERFORM).use { ignore -> |       SlowOperations.allowSlowOperations(SlowOperations.ACTION_PERFORM).use { | ||||||
|         performRunnable.run() |         performRunnable.run() | ||||||
|         result = AnActionResult.PERFORMED |         result = AnActionResult.PERFORMED | ||||||
|       } |       } | ||||||
| @@ -143,17 +139,6 @@ class IjActionExecutor : VimActionExecutor { | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   private fun canBePerformed(event: AnActionEvent, action: ActionGroup, context: DataContext): Boolean { |  | ||||||
|     val presentation = event.presentation |  | ||||||
|     return try { |  | ||||||
|       // [VERSION UPDATE] 221+ Just use Presentation.isPerformGroup |  | ||||||
|       val method = Presentation::class.java.getMethod("isPerformGroup") |  | ||||||
|       method.invoke(presentation) as Boolean |  | ||||||
|     } catch (e: Exception) { |  | ||||||
|       action.canBePerformed(context) |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * Execute an action by name |    * Execute an action by name | ||||||
|    * |    * | ||||||
|   | |||||||
| @@ -529,6 +529,9 @@ public class SearchHelper { | |||||||
|         CharSequence subSequence = chars.subSequence(startOffset, endOffset); |         CharSequence subSequence = chars.subSequence(startOffset, endOffset); | ||||||
|         int inQuotePos = pos - startOffset; |         int inQuotePos = pos - startOffset; | ||||||
|         int inQuoteStart = findBlockLocation(subSequence, close, type, Direction.BACKWARDS, inQuotePos, count, false); |         int inQuoteStart = findBlockLocation(subSequence, close, type, Direction.BACKWARDS, inQuotePos, count, false); | ||||||
|  |         if (inQuoteStart == -1) { | ||||||
|  |           inQuoteStart = findBlockLocation(subSequence, close, type, Direction.FORWARDS, inQuotePos, count, false); | ||||||
|  |         } | ||||||
|         if (inQuoteStart != -1) { |         if (inQuoteStart != -1) { | ||||||
|           startPosInStringFound = true; |           startPosInStringFound = true; | ||||||
|           int inQuoteEnd = findBlockLocation(subSequence, type, close, Direction.FORWARDS, inQuoteStart, 1, false); |           int inQuoteEnd = findBlockLocation(subSequence, type, close, Direction.FORWARDS, inQuoteStart, 1, false); | ||||||
| @@ -542,6 +545,9 @@ public class SearchHelper { | |||||||
|  |  | ||||||
|     if (!startPosInStringFound) { |     if (!startPosInStringFound) { | ||||||
|       bstart = findBlockLocation(chars, close, type, Direction.BACKWARDS, pos, count, false); |       bstart = findBlockLocation(chars, close, type, Direction.BACKWARDS, pos, count, false); | ||||||
|  |       if (bstart == -1) { | ||||||
|  |         bstart = findBlockLocation(chars, close, type, Direction.FORWARDS, pos, count, false); | ||||||
|  |       } | ||||||
|       if (bstart != -1) { |       if (bstart != -1) { | ||||||
|         bend = findBlockLocation(chars, type, close, Direction.FORWARDS, bstart, 1, false); |         bend = findBlockLocation(chars, type, close, Direction.FORWARDS, bstart, 1, false); | ||||||
|       } |       } | ||||||
|   | |||||||
| @@ -24,6 +24,7 @@ import javax.swing.KeyStroke | |||||||
|  |  | ||||||
| /** | /** | ||||||
|  * COMPATIBILITY-LAYER: Created a helper class |  * COMPATIBILITY-LAYER: Created a helper class | ||||||
|  |  * Please see: https://jb.gg/zo8n0r | ||||||
|  */ |  */ | ||||||
| object StringHelper { | object StringHelper { | ||||||
|   @JvmStatic |   @JvmStatic | ||||||
| @@ -41,4 +42,4 @@ object StringHelper { | |||||||
|   fun isCloseKeyStroke(stroke: KeyStroke): Boolean { |   fun isCloseKeyStroke(stroke: KeyStroke): Boolean { | ||||||
|     return stroke.isCloseKeyStroke() |     return stroke.isCloseKeyStroke() | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -21,6 +21,8 @@ package com.maddyhome.idea.vim.helper | |||||||
| import com.intellij.openapi.actionSystem.CommonDataKeys | import com.intellij.openapi.actionSystem.CommonDataKeys | ||||||
| import com.intellij.openapi.actionSystem.DataContext | import com.intellij.openapi.actionSystem.DataContext | ||||||
| import com.intellij.openapi.actionSystem.PlatformDataKeys | import com.intellij.openapi.actionSystem.PlatformDataKeys | ||||||
|  | import com.intellij.openapi.command.CommandProcessor | ||||||
|  | import com.intellij.openapi.command.impl.UndoManagerImpl | ||||||
| import com.intellij.openapi.command.undo.UndoManager | import com.intellij.openapi.command.undo.UndoManager | ||||||
| import com.intellij.openapi.components.Service | import com.intellij.openapi.components.Service | ||||||
| import com.maddyhome.idea.vim.api.ExecutionContext | import com.maddyhome.idea.vim.api.ExecutionContext | ||||||
| @@ -39,22 +41,29 @@ import com.maddyhome.idea.vim.vimscript.services.IjVimOptionService | |||||||
|  */ |  */ | ||||||
| @Service | @Service | ||||||
| class UndoRedoHelper : UndoRedoBase() { | class UndoRedoHelper : UndoRedoBase() { | ||||||
|  |   init { | ||||||
|  |     injector.optionService.addListener(IjVimOptionService.oldUndo, { UndoManagerImpl.ourNeverAskUser = !injector.optionService.isSet(OptionScope.GLOBAL, IjVimOptionService.oldUndo) }, true) | ||||||
|  |   } | ||||||
|  |  | ||||||
|   override fun undo(context: ExecutionContext): Boolean { |   override fun undo(context: ExecutionContext): Boolean { | ||||||
|     val ijContext = context.context as DataContext |     val ijContext = context.context as DataContext | ||||||
|     val project = PlatformDataKeys.PROJECT.getData(ijContext) ?: return false |     val project = PlatformDataKeys.PROJECT.getData(ijContext) ?: return false | ||||||
|     val fileEditor = PlatformDataKeys.FILE_EDITOR.getData(ijContext) |     val fileEditor = PlatformDataKeys.FILE_EDITOR.getData(ijContext) | ||||||
|     val undoManager = UndoManager.getInstance(project) |     val undoManager = UndoManager.getInstance(project) | ||||||
|     if (fileEditor != null && undoManager.isUndoAvailable(fileEditor)) { |     if (fileEditor != null && undoManager.isUndoAvailable(fileEditor)) { | ||||||
|  |       val editor = CommonDataKeys.EDITOR.getData(context.ij)?.vim | ||||||
|       if (injector.optionService.isSet(OptionScope.GLOBAL, IjVimOptionService.oldUndo)) { |       if (injector.optionService.isSet(OptionScope.GLOBAL, IjVimOptionService.oldUndo)) { | ||||||
|         SelectionVimListenerSuppressor.lock().use { undoManager.undo(fileEditor) } |         SelectionVimListenerSuppressor.lock().use { undoManager.undo(fileEditor) } | ||||||
|       } else { |       } else { | ||||||
|         val editor = CommonDataKeys.EDITOR.getData(context.ij)?.vim |  | ||||||
|         performUntilFileChanges(editor, { undoManager.isUndoAvailable(fileEditor) }, { undoManager.undo(fileEditor) }) |         performUntilFileChanges(editor, { undoManager.isUndoAvailable(fileEditor) }, { undoManager.undo(fileEditor) }) | ||||||
|         editor?.carets()?.forEach { |       } | ||||||
|           val ijCaret = it.ij |  | ||||||
|           val hasSelection = ijCaret.hasSelection() |       editor?.carets()?.forEach { | ||||||
|           if (hasSelection) { |         val ijCaret = it.ij | ||||||
|             val selectionStart = ijCaret.selectionStart |         val hasSelection = ijCaret.hasSelection() | ||||||
|  |         if (hasSelection) { | ||||||
|  |           val selectionStart = ijCaret.selectionStart | ||||||
|  |           CommandProcessor.getInstance().runUndoTransparentAction { | ||||||
|             it.ij.removeSelection() |             it.ij.removeSelection() | ||||||
|             it.ij.moveToOffset(selectionStart) |             it.ij.moveToOffset(selectionStart) | ||||||
|           } |           } | ||||||
| @@ -70,12 +79,14 @@ class UndoRedoHelper : UndoRedoBase() { | |||||||
|     val project = PlatformDataKeys.PROJECT.getData(ijContext) ?: return false |     val project = PlatformDataKeys.PROJECT.getData(ijContext) ?: return false | ||||||
|     val fileEditor = PlatformDataKeys.FILE_EDITOR.getData(ijContext) |     val fileEditor = PlatformDataKeys.FILE_EDITOR.getData(ijContext) | ||||||
|     val undoManager = UndoManager.getInstance(project) |     val undoManager = UndoManager.getInstance(project) | ||||||
|  |     val editor = CommonDataKeys.EDITOR.getData(context.ij)?.vim | ||||||
|     if (fileEditor != null && undoManager.isRedoAvailable(fileEditor)) { |     if (fileEditor != null && undoManager.isRedoAvailable(fileEditor)) { | ||||||
|       if (injector.optionService.isSet(OptionScope.GLOBAL, IjVimOptionService.oldUndo)) { |       if (injector.optionService.isSet(OptionScope.GLOBAL, IjVimOptionService.oldUndo)) { | ||||||
|         SelectionVimListenerSuppressor.lock().use { undoManager.redo(fileEditor) } |         SelectionVimListenerSuppressor.lock().use { undoManager.redo(fileEditor) } | ||||||
|       } else { |       } else { | ||||||
|         val editor = CommonDataKeys.EDITOR.getData(context.ij)?.vim |  | ||||||
|         performUntilFileChanges(editor, { undoManager.isRedoAvailable(fileEditor) }, { undoManager.redo(fileEditor) }) |         performUntilFileChanges(editor, { undoManager.isRedoAvailable(fileEditor) }, { undoManager.redo(fileEditor) }) | ||||||
|  |       } | ||||||
|  |       CommandProcessor.getInstance().runUndoTransparentAction { | ||||||
|         editor?.carets()?.forEach { it.ij.removeSelection() } |         editor?.carets()?.forEach { it.ij.removeSelection() } | ||||||
|       } |       } | ||||||
|       return true |       return true | ||||||
| @@ -95,10 +106,15 @@ class UndoRedoHelper : UndoRedoBase() { | |||||||
|       } |       } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     val oldPath = editor.getPath() | ||||||
|     vimDocument.addChangeListener(changeListener) |     vimDocument.addChangeListener(changeListener) | ||||||
|     while (check() && !changeListener.hasChanged) { |     while (check() && !changeListener.hasChanged && !ifFilePathChanged(editor, oldPath)) { | ||||||
|       action.run() |       action.run() | ||||||
|     } |     } | ||||||
|     vimDocument.removeChangeListener(changeListener) |     vimDocument.removeChangeListener(changeListener) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   private fun ifFilePathChanged(editor: IjVimEditor, oldPath: String?): Boolean { | ||||||
|  |     return editor.getPath() != oldPath | ||||||
|  |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -21,8 +21,8 @@ package com.maddyhome.idea.vim.listener | |||||||
| import com.intellij.openapi.actionSystem.ActionManager | import com.intellij.openapi.actionSystem.ActionManager | ||||||
| import com.intellij.openapi.actionSystem.AnAction | import com.intellij.openapi.actionSystem.AnAction | ||||||
| import com.intellij.openapi.actionSystem.AnActionEvent | import com.intellij.openapi.actionSystem.AnActionEvent | ||||||
|  | import com.intellij.openapi.actionSystem.AnActionResult | ||||||
| import com.intellij.openapi.actionSystem.CommonDataKeys | import com.intellij.openapi.actionSystem.CommonDataKeys | ||||||
| import com.intellij.openapi.actionSystem.DataContext |  | ||||||
| import com.intellij.openapi.actionSystem.IdeActions | import com.intellij.openapi.actionSystem.IdeActions | ||||||
| import com.intellij.openapi.actionSystem.ex.AnActionListener | import com.intellij.openapi.actionSystem.ex.AnActionListener | ||||||
| import com.intellij.openapi.editor.Caret | import com.intellij.openapi.editor.Caret | ||||||
| @@ -35,7 +35,6 @@ import com.maddyhome.idea.vim.group.visual.VimVisualTimer | |||||||
| import com.maddyhome.idea.vim.helper.fileSize | import com.maddyhome.idea.vim.helper.fileSize | ||||||
| import com.maddyhome.idea.vim.helper.inVisualMode | import com.maddyhome.idea.vim.helper.inVisualMode | ||||||
| import com.maddyhome.idea.vim.newapi.vim | import com.maddyhome.idea.vim.newapi.vim | ||||||
| import org.jetbrains.annotations.NotNull |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * A collection of hacks to improve the interaction with fancy AppCode templates |  * A collection of hacks to improve the interaction with fancy AppCode templates | ||||||
| @@ -50,16 +49,16 @@ object AppCodeTemplates { | |||||||
|  |  | ||||||
|     private var editor: Editor? = null |     private var editor: Editor? = null | ||||||
|  |  | ||||||
|     override fun beforeActionPerformed(action: AnAction, dataContext: DataContext, event: AnActionEvent) { |     override fun beforeActionPerformed(action: AnAction, event: AnActionEvent) { | ||||||
|       if (!VimPlugin.isEnabled()) return |       if (!VimPlugin.isEnabled()) return | ||||||
|  |  | ||||||
|       val hostEditor = dataContext.getData(CommonDataKeys.HOST_EDITOR) |       val hostEditor = event.dataContext.getData(CommonDataKeys.HOST_EDITOR) | ||||||
|       if (hostEditor != null) { |       if (hostEditor != null) { | ||||||
|         editor = hostEditor |         editor = hostEditor | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     override fun afterActionPerformed(action: AnAction, dataContext: DataContext, event: AnActionEvent) { |     override fun afterActionPerformed(action: AnAction, event: AnActionEvent, result: AnActionResult) { | ||||||
|       if (!VimPlugin.isEnabled()) return |       if (!VimPlugin.isEnabled()) return | ||||||
|  |  | ||||||
|       if (ActionManager.getInstance().getId(action) == IdeActions.ACTION_CHOOSE_LOOKUP_ITEM) { |       if (ActionManager.getInstance().getId(action) == IdeActions.ACTION_CHOOSE_LOOKUP_ITEM) { | ||||||
| @@ -77,8 +76,8 @@ object AppCodeTemplates { | |||||||
|  |  | ||||||
|   @JvmStatic |   @JvmStatic | ||||||
|   fun onMovement( |   fun onMovement( | ||||||
|     editor: @NotNull Editor, |     editor: Editor, | ||||||
|     caret: @NotNull Caret, |     caret: Caret, | ||||||
|     toRight: Boolean, |     toRight: Boolean, | ||||||
|   ) { |   ) { | ||||||
|     val offset = caret.offset |     val offset = caret.offset | ||||||
|   | |||||||
| @@ -29,8 +29,8 @@ import com.intellij.find.FindModelListener | |||||||
| import com.intellij.openapi.actionSystem.ActionManager | import com.intellij.openapi.actionSystem.ActionManager | ||||||
| import com.intellij.openapi.actionSystem.AnAction | import com.intellij.openapi.actionSystem.AnAction | ||||||
| import com.intellij.openapi.actionSystem.AnActionEvent | import com.intellij.openapi.actionSystem.AnActionEvent | ||||||
|  | import com.intellij.openapi.actionSystem.AnActionResult | ||||||
| import com.intellij.openapi.actionSystem.CommonDataKeys | import com.intellij.openapi.actionSystem.CommonDataKeys | ||||||
| import com.intellij.openapi.actionSystem.DataContext |  | ||||||
| import com.intellij.openapi.actionSystem.ex.AnActionListener | import com.intellij.openapi.actionSystem.ex.AnActionListener | ||||||
| import com.intellij.openapi.actionSystem.impl.ProxyShortcutSet | import com.intellij.openapi.actionSystem.impl.ProxyShortcutSet | ||||||
| import com.intellij.openapi.editor.Editor | import com.intellij.openapi.editor.Editor | ||||||
| @@ -60,10 +60,10 @@ object IdeaSpecifics { | |||||||
|     private val surrounderAction = |     private val surrounderAction = | ||||||
|       "com.intellij.codeInsight.generation.surroundWith.SurroundWithHandler\$InvokeSurrounderAction" |       "com.intellij.codeInsight.generation.surroundWith.SurroundWithHandler\$InvokeSurrounderAction" | ||||||
|     private var editor: Editor? = null |     private var editor: Editor? = null | ||||||
|     override fun beforeActionPerformed(action: AnAction, dataContext: DataContext, event: AnActionEvent) { |     override fun beforeActionPerformed(action: AnAction, event: AnActionEvent) { | ||||||
|       if (!VimPlugin.isEnabled()) return |       if (!VimPlugin.isEnabled()) return | ||||||
|  |  | ||||||
|       val hostEditor = dataContext.getData(CommonDataKeys.HOST_EDITOR) |       val hostEditor = event.dataContext.getData(CommonDataKeys.HOST_EDITOR) | ||||||
|       if (hostEditor != null) { |       if (hostEditor != null) { | ||||||
|         editor = hostEditor |         editor = hostEditor | ||||||
|       } |       } | ||||||
| @@ -72,13 +72,13 @@ object IdeaSpecifics { | |||||||
|       if (VimPlugin.getOptionService().isSet(OptionScope.GLOBAL, OptionConstants.trackactionidsName)) { |       if (VimPlugin.getOptionService().isSet(OptionScope.GLOBAL, OptionConstants.trackactionidsName)) { | ||||||
|         if (action !is NotificationService.ActionIdNotifier.CopyActionId && action !is NotificationService.ActionIdNotifier.StopTracking) { |         if (action !is NotificationService.ActionIdNotifier.CopyActionId && action !is NotificationService.ActionIdNotifier.StopTracking) { | ||||||
|           val id: String? = ActionManager.getInstance().getId(action) ?: (action.shortcutSet as? ProxyShortcutSet)?.actionId |           val id: String? = ActionManager.getInstance().getId(action) ?: (action.shortcutSet as? ProxyShortcutSet)?.actionId | ||||||
|           VimPlugin.getNotifications(dataContext.getData(CommonDataKeys.PROJECT)).notifyActionId(id) |           VimPlugin.getNotifications(event.dataContext.getData(CommonDataKeys.PROJECT)).notifyActionId(id) | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|       //endregion |       //endregion | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     override fun afterActionPerformed(action: AnAction, dataContext: DataContext, event: AnActionEvent) { |     override fun afterActionPerformed(action: AnAction, event: AnActionEvent, result: AnActionResult) { | ||||||
|       if (!VimPlugin.isEnabled()) return |       if (!VimPlugin.isEnabled()) return | ||||||
|  |  | ||||||
|       //region Enter insert mode after surround with if |       //region Enter insert mode after surround with if | ||||||
| @@ -93,7 +93,7 @@ object IdeaSpecifics { | |||||||
|           while (commandState.mode != VimStateMachine.Mode.COMMAND) { |           while (commandState.mode != VimStateMachine.Mode.COMMAND) { | ||||||
|             commandState.popModes() |             commandState.popModes() | ||||||
|           } |           } | ||||||
|           VimPlugin.getChange().insertBeforeCursor(it.vim, dataContext.vim) |           VimPlugin.getChange().insertBeforeCursor(it.vim, event.dataContext.vim) | ||||||
|           KeyHandler.getInstance().reset(it.vim) |           KeyHandler.getInstance().reset(it.vim) | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|   | |||||||
| @@ -21,8 +21,8 @@ package com.maddyhome.idea.vim.listener | |||||||
| import com.intellij.openapi.actionSystem.ActionManager | import com.intellij.openapi.actionSystem.ActionManager | ||||||
| import com.intellij.openapi.actionSystem.AnAction | import com.intellij.openapi.actionSystem.AnAction | ||||||
| import com.intellij.openapi.actionSystem.AnActionEvent | import com.intellij.openapi.actionSystem.AnActionEvent | ||||||
|  | import com.intellij.openapi.actionSystem.AnActionResult | ||||||
| import com.intellij.openapi.actionSystem.CommonDataKeys | import com.intellij.openapi.actionSystem.CommonDataKeys | ||||||
| import com.intellij.openapi.actionSystem.DataContext |  | ||||||
| import com.intellij.openapi.actionSystem.IdeActions | import com.intellij.openapi.actionSystem.IdeActions | ||||||
| import com.intellij.openapi.actionSystem.ex.AnActionListener | import com.intellij.openapi.actionSystem.ex.AnActionListener | ||||||
| import com.intellij.openapi.editor.Editor | import com.intellij.openapi.editor.Editor | ||||||
| @@ -36,16 +36,16 @@ import com.maddyhome.idea.vim.helper.getTopLevelEditor | |||||||
| class RiderActionListener : AnActionListener { | class RiderActionListener : AnActionListener { | ||||||
|  |  | ||||||
|   private var editor: Editor? = null |   private var editor: Editor? = null | ||||||
|   override fun beforeActionPerformed(action: AnAction, dataContext: DataContext, event: AnActionEvent) { |   override fun beforeActionPerformed(action: AnAction, event: AnActionEvent) { | ||||||
|     if (!VimPlugin.isEnabled()) return |     if (!VimPlugin.isEnabled()) return | ||||||
|  |  | ||||||
|     val hostEditor = dataContext.getData(CommonDataKeys.HOST_EDITOR) |     val hostEditor = event.dataContext.getData(CommonDataKeys.HOST_EDITOR) | ||||||
|     if (hostEditor != null) { |     if (hostEditor != null) { | ||||||
|       editor = hostEditor |       editor = hostEditor | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   override fun afterActionPerformed(action: AnAction, dataContext: DataContext, event: AnActionEvent) { |   override fun afterActionPerformed(action: AnAction, event: AnActionEvent, result: AnActionResult) { | ||||||
|     if (!VimPlugin.isEnabled()) return |     if (!VimPlugin.isEnabled()) return | ||||||
|  |  | ||||||
|     //region Extend Selection for Rider |     //region Extend Selection for Rider | ||||||
|   | |||||||
| @@ -122,9 +122,9 @@ object VimListenerManager { | |||||||
|       VimPlugin.getOptionService().addListener(OptionConstants.guicursorName, GuicursorChangeListener) |       VimPlugin.getOptionService().addListener(OptionConstants.guicursorName, GuicursorChangeListener) | ||||||
|       VimPlugin.getOptionService().addListener(OptionConstants.iskeywordName, KeywordOptionChangeListener, true) |       VimPlugin.getOptionService().addListener(OptionConstants.iskeywordName, KeywordOptionChangeListener, true) | ||||||
|  |  | ||||||
|       EventFacade.getInstance().addEditorFactoryListener(VimEditorFactoryListener, VimPlugin.getInstance()) |       EventFacade.getInstance().addEditorFactoryListener(VimEditorFactoryListener, VimPlugin.getInstance().onOffDisposable) | ||||||
|  |  | ||||||
|       EditorFactory.getInstance().eventMulticaster.addCaretListener(VimCaretListener, VimPlugin.getInstance()) |       EditorFactory.getInstance().eventMulticaster.addCaretListener(VimCaretListener, VimPlugin.getInstance().onOffDisposable) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     fun disable() { |     fun disable() { | ||||||
| @@ -136,10 +136,6 @@ object VimListenerManager { | |||||||
|       VimPlugin.getOptionService().removeListener(OptionConstants.showcmdName, ShowCmdOptionChangeListener) |       VimPlugin.getOptionService().removeListener(OptionConstants.showcmdName, ShowCmdOptionChangeListener) | ||||||
|       VimPlugin.getOptionService().removeListener(OptionConstants.guicursorName, GuicursorChangeListener) |       VimPlugin.getOptionService().removeListener(OptionConstants.guicursorName, GuicursorChangeListener) | ||||||
|       VimPlugin.getOptionService().removeListener(OptionConstants.iskeywordName, KeywordOptionChangeListener) |       VimPlugin.getOptionService().removeListener(OptionConstants.iskeywordName, KeywordOptionChangeListener) | ||||||
|  |  | ||||||
|       EventFacade.getInstance().removeEditorFactoryListener(VimEditorFactoryListener) |  | ||||||
|  |  | ||||||
|       EditorFactory.getInstance().eventMulticaster.removeCaretListener(VimCaretListener) |  | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -99,6 +99,7 @@ fun changeRange( | |||||||
|           vimCaret.moveToOffset(deletedInfo.leftOffset.point) |           vimCaret.moveToOffset(deletedInfo.leftOffset.point) | ||||||
|         } |         } | ||||||
|         is OperatedRange.Block -> TODO() |         is OperatedRange.Block -> TODO() | ||||||
|  |         else -> TODO() | ||||||
|       } |       } | ||||||
|       if (type == SelectionType.BLOCK_WISE) { |       if (type == SelectionType.BLOCK_WISE) { | ||||||
|         VimPlugin.getChange().setInsertRepeat(lines, col, false) |         VimPlugin.getChange().setInsertRepeat(lines, col, false) | ||||||
| @@ -179,7 +180,7 @@ fun insertLineAround(editor: VimEditor, context: ExecutionContext, shift: Int) { | |||||||
|       } |       } | ||||||
|       val position = EditorLine.Offset.init(editor.offsetToLogicalPosition(lineEndOffset).line + shift, editor) |       val position = EditorLine.Offset.init(editor.offsetToLogicalPosition(lineEndOffset).line + shift, editor) | ||||||
|  |  | ||||||
|       val insertedLine = editor.addLine(position) ?: continue |       val insertedLine = editor.addLine(position) | ||||||
|       VimPlugin.getChange().saveStrokes("\n") |       VimPlugin.getChange().saveStrokes("\n") | ||||||
|  |  | ||||||
|       var lineStart = editor.getLineRange(insertedLine).first |       var lineStart = editor.getLineRange(insertedLine).first | ||||||
|   | |||||||
| @@ -49,6 +49,7 @@ class IjClipboardManager : VimClipboardManager { | |||||||
|     return Pair(res, transferableData) |     return Pair(res, transferableData) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   @Suppress("UNCHECKED_CAST") | ||||||
|   override fun setClipboardText(text: String, rawText: String, transferableData: List<Any>): Any? { |   override fun setClipboardText(text: String, rawText: String, transferableData: List<Any>): Any? { | ||||||
|     val transferableData1 = (transferableData as List<TextBlockTransferableData>).toMutableList() |     val transferableData1 = (transferableData as List<TextBlockTransferableData>).toMutableList() | ||||||
|     try { |     try { | ||||||
| @@ -97,6 +98,7 @@ class IjClipboardManager : VimClipboardManager { | |||||||
|     return transferableData |     return transferableData | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   @Suppress("UNCHECKED_CAST") | ||||||
|   override fun preprocessText( |   override fun preprocessText( | ||||||
|     vimEditor: VimEditor, |     vimEditor: VimEditor, | ||||||
|     textRange: TextRange, |     textRange: TextRange, | ||||||
|   | |||||||
| @@ -33,11 +33,11 @@ class IjExecutionContextManager : ExecutionContextManagerBase() { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   override fun onCaret(caret: VimCaret, prevContext: ExecutionContext): ExecutionContext { |   override fun onCaret(caret: VimCaret, prevContext: ExecutionContext): ExecutionContext { | ||||||
|     return IjExecutionContext(CaretSpecificDataContext(prevContext.ij, caret.ij)) |     return IjExecutionContext(CaretSpecificDataContext.create(prevContext.ij, caret.ij)) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   override fun createCaretSpecificDataContext(context: ExecutionContext, caret: VimCaret): ExecutionContext { |   override fun createCaretSpecificDataContext(context: ExecutionContext, caret: VimCaret): ExecutionContext { | ||||||
|     return IjExecutionContext(CaretSpecificDataContext(context.ij, caret.ij)) |     return IjExecutionContext(CaretSpecificDataContext.create(context.ij, caret.ij)) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   override fun createEditorDataContext(editor: VimEditor, context: ExecutionContext): ExecutionContext { |   override fun createEditorDataContext(editor: VimEditor, context: ExecutionContext): ExecutionContext { | ||||||
|   | |||||||
| @@ -62,7 +62,9 @@ import com.maddyhome.idea.vim.helper.updateCaretsVisualPosition | |||||||
| import com.maddyhome.idea.vim.helper.vimChangeActionSwitchMode | import com.maddyhome.idea.vim.helper.vimChangeActionSwitchMode | ||||||
| import com.maddyhome.idea.vim.helper.vimKeepingVisualOperatorAction | import com.maddyhome.idea.vim.helper.vimKeepingVisualOperatorAction | ||||||
| import com.maddyhome.idea.vim.helper.vimLastSelectionType | import com.maddyhome.idea.vim.helper.vimLastSelectionType | ||||||
|  | import org.jetbrains.annotations.ApiStatus | ||||||
|  |  | ||||||
|  | @ApiStatus.Internal | ||||||
| class IjVimEditor(editor: Editor) : MutableLinearEditor() { | class IjVimEditor(editor: Editor) : MutableLinearEditor() { | ||||||
|  |  | ||||||
|   // All the editor actions should be performed with top level editor!!! |   // All the editor actions should be performed with top level editor!!! | ||||||
|   | |||||||
| @@ -68,13 +68,13 @@ import com.maddyhome.idea.vim.helper.vimStateMachine | |||||||
| import com.maddyhome.idea.vim.history.VimHistory | import com.maddyhome.idea.vim.history.VimHistory | ||||||
| import com.maddyhome.idea.vim.macro.VimMacro | import com.maddyhome.idea.vim.macro.VimMacro | ||||||
| import com.maddyhome.idea.vim.mark.VimMarkGroup | import com.maddyhome.idea.vim.mark.VimMarkGroup | ||||||
| import com.maddyhome.idea.vim.vimscript.services.OptionService |  | ||||||
| import com.maddyhome.idea.vim.put.VimPut | import com.maddyhome.idea.vim.put.VimPut | ||||||
| import com.maddyhome.idea.vim.register.VimRegisterGroup | import com.maddyhome.idea.vim.register.VimRegisterGroup | ||||||
| import com.maddyhome.idea.vim.ui.VimRcFileState | import com.maddyhome.idea.vim.ui.VimRcFileState | ||||||
| import com.maddyhome.idea.vim.undo.VimUndoRedo | import com.maddyhome.idea.vim.undo.VimUndoRedo | ||||||
| import com.maddyhome.idea.vim.vimscript.Executor | import com.maddyhome.idea.vim.vimscript.Executor | ||||||
| import com.maddyhome.idea.vim.vimscript.services.FunctionStorage | import com.maddyhome.idea.vim.vimscript.services.FunctionStorage | ||||||
|  | import com.maddyhome.idea.vim.vimscript.services.OptionService | ||||||
| import com.maddyhome.idea.vim.vimscript.services.PatternService | import com.maddyhome.idea.vim.vimscript.services.PatternService | ||||||
| import com.maddyhome.idea.vim.vimscript.services.VariableService | import com.maddyhome.idea.vim.vimscript.services.VariableService | ||||||
| import com.maddyhome.idea.vim.yank.VimYankGroup | import com.maddyhome.idea.vim.yank.VimYankGroup | ||||||
|   | |||||||
| @@ -37,19 +37,19 @@ class IjVimMessages : VimMessagesBase() { | |||||||
|   private var error = false |   private var error = false | ||||||
|   private var lastBeepTimeMillis = 0L |   private var lastBeepTimeMillis = 0L | ||||||
|  |  | ||||||
|   override fun showStatusBarMessage(msg: String?) { |   override fun showStatusBarMessage(message: String?) { | ||||||
|     if (ApplicationManager.getApplication().isUnitTestMode) { |     if (ApplicationManager.getApplication().isUnitTestMode) { | ||||||
|       message = msg |       this.message = message | ||||||
|     } |     } | ||||||
|     val pm = ProjectManager.getInstance() |     val pm = ProjectManager.getInstance() | ||||||
|     val projects = pm.openProjects |     val projects = pm.openProjects | ||||||
|     for (project in projects) { |     for (project in projects) { | ||||||
|       val bar = WindowManager.getInstance().getStatusBar(project) |       val bar = WindowManager.getInstance().getStatusBar(project) | ||||||
|       if (bar != null) { |       if (bar != null) { | ||||||
|         if (msg.isNullOrEmpty()) { |         if (message.isNullOrEmpty()) { | ||||||
|           bar.info = "" |           bar.info = "" | ||||||
|         } else { |         } else { | ||||||
|           bar.info = "VIM - $msg" |           bar.info = "VIM - $message" | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -30,16 +30,17 @@ import com.maddyhome.idea.vim.vimscript.services.IjVimOptionService | |||||||
|  |  | ||||||
| /** | /** | ||||||
|  * COMPATIBILITY-LAYER: Added a class and package |  * COMPATIBILITY-LAYER: Added a class and package | ||||||
|  |  * Please see: https://jb.gg/zo8n0r | ||||||
|  */ |  */ | ||||||
| object OptionsManager { | object OptionsManager { | ||||||
|   val ignorecase: ToggleOption |   val ignorecase: ToggleOption | ||||||
|     get() = (injector.optionService as IjVimOptionService).getRawOption(ignorecaseName) as ToggleOption |     get() = (injector.optionService as IjVimOptionService).getOptionByNameOrAbbr(ignorecaseName) as ToggleOption | ||||||
|   val smartcase: ToggleOption |   val smartcase: ToggleOption | ||||||
|     get() = (injector.optionService as IjVimOptionService).getRawOption(smartcaseName) as ToggleOption |     get() = (injector.optionService as IjVimOptionService).getOptionByNameOrAbbr(smartcaseName) as ToggleOption | ||||||
|   val timeout: ToggleOption |   val timeout: ToggleOption | ||||||
|     get() = (injector.optionService as IjVimOptionService).getRawOption(timeoutName) as ToggleOption |     get() = (injector.optionService as IjVimOptionService).getOptionByNameOrAbbr(timeoutName) as ToggleOption | ||||||
|   val timeoutlen: NumberOption |   val timeoutlen: NumberOption | ||||||
|     get() = (injector.optionService as IjVimOptionService).getRawOption(timeoutlenName) as NumberOption |     get() = (injector.optionService as IjVimOptionService).getOptionByNameOrAbbr(timeoutlenName) as NumberOption | ||||||
|   val iskeyword: KeywordOption |   val iskeyword: KeywordOption | ||||||
|     get() = KeywordOption(KeywordOptionHelper) |     get() = KeywordOption(KeywordOptionHelper) | ||||||
| } | } | ||||||
|   | |||||||
| @@ -18,6 +18,7 @@ | |||||||
|  |  | ||||||
| package com.maddyhome.idea.vim.statistic | package com.maddyhome.idea.vim.statistic | ||||||
|  |  | ||||||
|  | import com.intellij.internal.statistic.collectors.fus.actions.persistence.ActionRuleValidator | ||||||
| import com.intellij.internal.statistic.eventLog.EventLogGroup | import com.intellij.internal.statistic.eventLog.EventLogGroup | ||||||
| import com.intellij.internal.statistic.eventLog.events.EventFields | import com.intellij.internal.statistic.eventLog.events.EventFields | ||||||
| import com.intellij.internal.statistic.service.fus.collectors.CounterUsagesCollector | import com.intellij.internal.statistic.service.fus.collectors.CounterUsagesCollector | ||||||
| @@ -25,8 +26,14 @@ import com.intellij.internal.statistic.service.fus.collectors.CounterUsagesColle | |||||||
| internal class ActionTracker : CounterUsagesCollector() { | internal class ActionTracker : CounterUsagesCollector() { | ||||||
|   companion object { |   companion object { | ||||||
|     private val GROUP = EventLogGroup("vim.actions", 1) |     private val GROUP = EventLogGroup("vim.actions", 1) | ||||||
|     private val TRACKED_ACTIONS = GROUP.registerEvent("tracked", EventFields.StringValidatedByCustomRule("action_id", "action")) |     private val TRACKED_ACTIONS = GROUP.registerEvent( | ||||||
|     private val COPIED_ACTIONS = GROUP.registerEvent("copied", EventFields.StringValidatedByCustomRule("action_id", "action")) |       "tracked", | ||||||
|  |       EventFields.StringValidatedByCustomRule("action_id", ActionRuleValidator::class.java) | ||||||
|  |     ) | ||||||
|  |     private val COPIED_ACTIONS = GROUP.registerEvent( | ||||||
|  |       "copied", | ||||||
|  |       EventFields.StringValidatedByCustomRule("action_id", ActionRuleValidator::class.java) | ||||||
|  |     ) | ||||||
|  |  | ||||||
|     fun logTrackedAction(actionId: String) { |     fun logTrackedAction(actionId: String) { | ||||||
|       TRACKED_ACTIONS.log(actionId) |       TRACKED_ACTIONS.log(actionId) | ||||||
|   | |||||||
| @@ -48,13 +48,13 @@ class Executor : VimScriptExecutorBase() { | |||||||
|   override var executingVimscript = false |   override var executingVimscript = false | ||||||
|  |  | ||||||
|   @Throws(ExException::class) |   @Throws(ExException::class) | ||||||
|   override fun execute(scriptString: String, editor: VimEditor, context: ExecutionContext, skipHistory: Boolean, indicateErrors: Boolean, vimContext: VimLContext?): ExecutionResult { |   override fun execute(script: String, editor: VimEditor, context: ExecutionContext, skipHistory: Boolean, indicateErrors: Boolean, vimContext: VimLContext?): ExecutionResult { | ||||||
|     var finalResult: ExecutionResult = ExecutionResult.Success |     var finalResult: ExecutionResult = ExecutionResult.Success | ||||||
|  |  | ||||||
|     val script = VimscriptParser.parse(scriptString) |     val myScript = VimscriptParser.parse(script) | ||||||
|     script.units.forEach { it.vimContext = vimContext ?: script } |     myScript.units.forEach { it.vimContext = vimContext ?: myScript } | ||||||
|  |  | ||||||
|     for (unit in script.units) { |     for (unit in myScript.units) { | ||||||
|       try { |       try { | ||||||
|         val result = unit.execute(editor, context) |         val result = unit.execute(editor, context) | ||||||
|         if (result is ExecutionResult.Error) { |         if (result is ExecutionResult.Error) { | ||||||
| @@ -89,18 +89,18 @@ class Executor : VimScriptExecutorBase() { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     if (!skipHistory) { |     if (!skipHistory) { | ||||||
|       VimPlugin.getHistory().addEntry(HistoryConstants.COMMAND, scriptString) |       VimPlugin.getHistory().addEntry(HistoryConstants.COMMAND, script) | ||||||
|       if (script.units.size == 1 && script.units[0] is Command && script.units[0] !is RepeatCommand) { |       if (myScript.units.size == 1 && myScript.units[0] is Command && myScript.units[0] !is RepeatCommand) { | ||||||
|         VimPlugin.getRegister().storeTextSpecial(LAST_COMMAND_REGISTER, scriptString) |         VimPlugin.getRegister().storeTextSpecial(LAST_COMMAND_REGISTER, script) | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|     return finalResult |     return finalResult | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   override fun execute(scriptString: String, skipHistory: Boolean) { |   override fun execute(script: String, skipHistory: Boolean) { | ||||||
|     val editor = TextComponentEditorImpl(null, JTextArea()).vim |     val editor = TextComponentEditorImpl(null, JTextArea()).vim | ||||||
|     val context = DataContext.EMPTY_CONTEXT.vim |     val context = DataContext.EMPTY_CONTEXT.vim | ||||||
|     execute(scriptString, editor, context, skipHistory, indicateErrors = true, CommandLineVimLContext) |     execute(script, editor, context, skipHistory, indicateErrors = true, CommandLineVimLContext) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   override fun executeFile(file: File, indicateErrors: Boolean) { |   override fun executeFile(file: File, indicateErrors: Boolean) { | ||||||
|   | |||||||
| @@ -23,6 +23,7 @@ import com.intellij.openapi.actionSystem.KeyboardShortcut | |||||||
| 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.command.OperatorArguments | ||||||
| import com.maddyhome.idea.vim.ex.ExOutputModel | import com.maddyhome.idea.vim.ex.ExOutputModel | ||||||
| import com.maddyhome.idea.vim.ex.ranges.Ranges | import com.maddyhome.idea.vim.ex.ranges.Ranges | ||||||
| import com.maddyhome.idea.vim.helper.MessageHelper | import com.maddyhome.idea.vim.helper.MessageHelper | ||||||
| @@ -36,7 +37,7 @@ import java.util.* | |||||||
| data class ActionListCommand(val ranges: Ranges, val argument: String) : Command.SingleExecution(ranges) { | data class ActionListCommand(val ranges: Ranges, val argument: String) : Command.SingleExecution(ranges) { | ||||||
|   override val argFlags = flags(RangeFlag.RANGE_FORBIDDEN, ArgumentFlag.ARGUMENT_OPTIONAL, Access.READ_ONLY) |   override val argFlags = flags(RangeFlag.RANGE_FORBIDDEN, ArgumentFlag.ARGUMENT_OPTIONAL, Access.READ_ONLY) | ||||||
|  |  | ||||||
|   override fun processCommand(editor: VimEditor, context: ExecutionContext): ExecutionResult { |   override fun processCommand(editor: VimEditor, context: ExecutionContext, operatorArguments: OperatorArguments): ExecutionResult { | ||||||
|     val lineSeparator = "\n" |     val lineSeparator = "\n" | ||||||
|     val searchPattern = argument.trim().lowercase(Locale.getDefault()).split("*") |     val searchPattern = argument.trim().lowercase(Locale.getDefault()).split("*") | ||||||
|     val actionManager = ActionManager.getInstance() |     val actionManager = ActionManager.getInstance() | ||||||
|   | |||||||
| @@ -23,6 +23,7 @@ import com.intellij.openapi.fileEditor.FileEditorManager | |||||||
| 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.command.OperatorArguments | ||||||
| import com.maddyhome.idea.vim.ex.ranges.Ranges | import com.maddyhome.idea.vim.ex.ranges.Ranges | ||||||
| import com.maddyhome.idea.vim.helper.EditorHelper | import com.maddyhome.idea.vim.helper.EditorHelper | ||||||
| import com.maddyhome.idea.vim.helper.MessageHelper | import com.maddyhome.idea.vim.helper.MessageHelper | ||||||
| @@ -38,7 +39,7 @@ import com.maddyhome.idea.vim.vimscript.model.ExecutionResult | |||||||
| data class BufferCommand(val ranges: Ranges, val argument: String) : Command.SingleExecution(ranges) { | data class BufferCommand(val ranges: Ranges, val argument: String) : Command.SingleExecution(ranges) { | ||||||
|   override val argFlags = flags(RangeFlag.RANGE_FORBIDDEN, ArgumentFlag.ARGUMENT_OPTIONAL, Access.READ_ONLY) |   override val argFlags = flags(RangeFlag.RANGE_FORBIDDEN, ArgumentFlag.ARGUMENT_OPTIONAL, Access.READ_ONLY) | ||||||
|  |  | ||||||
|   override fun processCommand(editor: VimEditor, context: ExecutionContext): ExecutionResult { |   override fun processCommand(editor: VimEditor, context: ExecutionContext, operatorArguments: OperatorArguments): ExecutionResult { | ||||||
|     val arg = argument.trim() |     val arg = argument.trim() | ||||||
|     val overrideModified = arg.startsWith('!') |     val overrideModified = arg.startsWith('!') | ||||||
|     val buffer = if (overrideModified) arg.replace(Regex("^!\\s*"), "") else arg |     val buffer = if (overrideModified) arg.replace(Regex("^!\\s*"), "") else arg | ||||||
|   | |||||||
| @@ -26,6 +26,7 @@ import com.intellij.openapi.vfs.VirtualFile | |||||||
| 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.command.OperatorArguments | ||||||
| import com.maddyhome.idea.vim.ex.ExOutputModel | import com.maddyhome.idea.vim.ex.ExOutputModel | ||||||
| import com.maddyhome.idea.vim.ex.ranges.Ranges | import com.maddyhome.idea.vim.ex.ranges.Ranges | ||||||
| import com.maddyhome.idea.vim.helper.EditorHelper | import com.maddyhome.idea.vim.helper.EditorHelper | ||||||
| @@ -48,7 +49,7 @@ data class BufferListCommand(val ranges: Ranges, val argument: String) : Command | |||||||
|     val SUPPORTED_FILTERS = setOf('+', '=', 'a', '%', '#') |     val SUPPORTED_FILTERS = setOf('+', '=', 'a', '%', '#') | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   override fun processCommand(editor: VimEditor, context: ExecutionContext): ExecutionResult { |   override fun processCommand(editor: VimEditor, context: ExecutionContext, operatorArguments: OperatorArguments): ExecutionResult { | ||||||
|     val arg = argument.trim() |     val arg = argument.trim() | ||||||
|     val filter = pruneUnsupportedFilters(arg) |     val filter = pruneUnsupportedFilters(arg) | ||||||
|     val bufferList = getBufferList(context, filter) |     val bufferList = getBufferList(context, filter) | ||||||
|   | |||||||
| @@ -24,6 +24,7 @@ import com.intellij.openapi.progress.ProcessCanceledException | |||||||
| 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.command.OperatorArguments | ||||||
| import com.maddyhome.idea.vim.ex.ExException | import com.maddyhome.idea.vim.ex.ExException | ||||||
| import com.maddyhome.idea.vim.ex.ExOutputModel | import com.maddyhome.idea.vim.ex.ExOutputModel | ||||||
| import com.maddyhome.idea.vim.ex.ranges.Ranges | import com.maddyhome.idea.vim.ex.ranges.Ranges | ||||||
| @@ -38,7 +39,7 @@ import com.maddyhome.idea.vim.vimscript.model.ExecutionResult | |||||||
| data class CmdFilterCommand(val ranges: Ranges, val argument: String) : Command.SingleExecution(ranges) { | data class CmdFilterCommand(val ranges: Ranges, val argument: String) : Command.SingleExecution(ranges) { | ||||||
|   override val argFlags = flags(RangeFlag.RANGE_OPTIONAL, ArgumentFlag.ARGUMENT_OPTIONAL, Access.SELF_SYNCHRONIZED) |   override val argFlags = flags(RangeFlag.RANGE_OPTIONAL, ArgumentFlag.ARGUMENT_OPTIONAL, Access.SELF_SYNCHRONIZED) | ||||||
|  |  | ||||||
|   override fun processCommand(editor: VimEditor, context: ExecutionContext): ExecutionResult { |   override fun processCommand(editor: VimEditor, context: ExecutionContext, operatorArguments: OperatorArguments): ExecutionResult { | ||||||
|     logger.debug("execute") |     logger.debug("execute") | ||||||
|     val command = buildString { |     val command = buildString { | ||||||
|       var inBackslash = false |       var inBackslash = false | ||||||
|   | |||||||
| @@ -23,6 +23,7 @@ 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.injector | import com.maddyhome.idea.vim.api.injector | ||||||
|  | import com.maddyhome.idea.vim.command.OperatorArguments | ||||||
| import com.maddyhome.idea.vim.ex.ranges.LineRange | import com.maddyhome.idea.vim.ex.ranges.LineRange | ||||||
| import com.maddyhome.idea.vim.ex.ranges.Ranges | import com.maddyhome.idea.vim.ex.ranges.Ranges | ||||||
| import com.maddyhome.idea.vim.group.SearchGroup.RE_BOTH | import com.maddyhome.idea.vim.group.SearchGroup.RE_BOTH | ||||||
| @@ -42,7 +43,7 @@ import com.maddyhome.idea.vim.vimscript.model.ExecutionResult | |||||||
| data class GlobalCommand(val ranges: Ranges, val argument: String, val invert: Boolean) : Command.SingleExecution(ranges, argument) { | data class GlobalCommand(val ranges: Ranges, val argument: String, val invert: Boolean) : Command.SingleExecution(ranges, argument) { | ||||||
|   override val argFlags = flags(RangeFlag.RANGE_OPTIONAL, ArgumentFlag.ARGUMENT_OPTIONAL, Access.SELF_SYNCHRONIZED) |   override val argFlags = flags(RangeFlag.RANGE_OPTIONAL, ArgumentFlag.ARGUMENT_OPTIONAL, Access.SELF_SYNCHRONIZED) | ||||||
|  |  | ||||||
|   override fun processCommand(editor: VimEditor, context: ExecutionContext): ExecutionResult { |   override fun processCommand(editor: VimEditor, context: ExecutionContext, operatorArguments: OperatorArguments): ExecutionResult { | ||||||
|     var result: ExecutionResult = ExecutionResult.Success |     var result: ExecutionResult = ExecutionResult.Success | ||||||
|     editor.removeSecondaryCarets() |     editor.removeSecondaryCarets() | ||||||
|     val caret = editor.currentCaret() |     val caret = editor.currentCaret() | ||||||
|   | |||||||
| @@ -21,6 +21,7 @@ package com.maddyhome.idea.vim.vimscript.model.commands | |||||||
| import com.intellij.ide.BrowserUtil | import com.intellij.ide.BrowserUtil | ||||||
| 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.command.OperatorArguments | ||||||
| import com.maddyhome.idea.vim.ex.ranges.Ranges | import com.maddyhome.idea.vim.ex.ranges.Ranges | ||||||
| import com.maddyhome.idea.vim.vimscript.model.ExecutionResult | import com.maddyhome.idea.vim.vimscript.model.ExecutionResult | ||||||
| import org.jetbrains.annotations.NonNls | import org.jetbrains.annotations.NonNls | ||||||
| @@ -33,7 +34,7 @@ import java.net.URLEncoder | |||||||
|  */ |  */ | ||||||
| data class HelpCommand(val ranges: Ranges, val argument: String) : Command.SingleExecution(ranges, argument) { | data class HelpCommand(val ranges: Ranges, val argument: String) : Command.SingleExecution(ranges, argument) { | ||||||
|   override val argFlags = flags(RangeFlag.RANGE_OPTIONAL, ArgumentFlag.ARGUMENT_OPTIONAL, Access.READ_ONLY) |   override val argFlags = flags(RangeFlag.RANGE_OPTIONAL, ArgumentFlag.ARGUMENT_OPTIONAL, Access.READ_ONLY) | ||||||
|   override fun processCommand(editor: VimEditor, context: ExecutionContext): ExecutionResult { |   override fun processCommand(editor: VimEditor, context: ExecutionContext, operatorArguments: OperatorArguments): ExecutionResult { | ||||||
|     BrowserUtil.browse(helpTopicUrl(argument)) |     BrowserUtil.browse(helpTopicUrl(argument)) | ||||||
|     return ExecutionResult.Success |     return ExecutionResult.Success | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -27,7 +27,7 @@ import com.maddyhome.idea.vim.options.StringOption | |||||||
| internal class IjVimOptionService : VimOptionServiceBase() { | internal class IjVimOptionService : VimOptionServiceBase() { | ||||||
|  |  | ||||||
|   private val customOptions = setOf( |   private val customOptions = setOf( | ||||||
|     ToggleOption(oldUndo, oldUndo, false), |     ToggleOption(oldUndo, oldUndo, true), | ||||||
|     ToggleOption(ideajoinName, ideajoinAlias, false), |     ToggleOption(ideajoinName, ideajoinAlias, false), | ||||||
|     ToggleOption(ideamarksName, ideamarksAlias, true), |     ToggleOption(ideamarksName, ideamarksAlias, true), | ||||||
|     StringOption(ideName, ideAlias, ApplicationNamesInfo.getInstance().fullProductNameWithEdition), |     StringOption(ideName, ideAlias, ApplicationNamesInfo.getInstance().fullProductNameWithEdition), | ||||||
|   | |||||||
| @@ -2,55 +2,7 @@ | |||||||
|   <name>IdeaVim</name> |   <name>IdeaVim</name> | ||||||
|   <id>IdeaVIM</id> |   <id>IdeaVIM</id> | ||||||
|   <change-notes><![CDATA[ |   <change-notes><![CDATA[ | ||||||
|       <h3>Features:</h3> |       <a href="https://github.com/JetBrains/ideavim/blob/master/CHANGES.md">Changes</a> | ||||||
|       <ul> |  | ||||||
|         <li>Add register support to let command | <a href="https://youtrack.jetbrains.com/issue/VIM-749">VIM-749</a>, <a |  | ||||||
|             href="https://youtrack.jetbrains.com/issue/VIM-1783">VIM-1783</a></li> |  | ||||||
|         <li>Add tabmove command | <a href="https://youtrack.jetbrains.com/issue/VIM-1164">VIM-1164</a></li> |  | ||||||
|       </ul> |  | ||||||
|  |  | ||||||
|       <h3>Fixes:</h3> |  | ||||||
|       <ul> |  | ||||||
|         <li><a href="https://youtrack.jetbrains.com/issue/VIM-2502">VIM-2502</a> Fix the shape of new carets</li> |  | ||||||
|         <li><a href="https://youtrack.jetbrains.com/issue/VIM-2499">VIM-2499</a> Fix mapping to esc</li> |  | ||||||
|         <li><a href="https://youtrack.jetbrains.com/issue/VIM-2500">VIM-2500</a> Fix esc for normal mode</li> |  | ||||||
|         <li><a href="https://youtrack.jetbrains.com/issue/VIM-2523">VIM-2523</a> <code>i</code> command for the folder in the |  | ||||||
|           project tree |  | ||||||
|         </li> |  | ||||||
|         <li><a href="https://youtrack.jetbrains.com/issue/VIM-2471">VIM-2471</a> Multiple [{ and ]} actions</li> |  | ||||||
|         <li><a href="https://youtrack.jetbrains.com/issue/VIM-2504">VIM-2504</a> Fix esc with using python notebooks</li> |  | ||||||
|         <li><a href="https://youtrack.jetbrains.com/issue/VIM-2540">VIM-2540</a> Fix option listeners</li> |  | ||||||
|         <li><a href="https://youtrack.jetbrains.com/issue/VIM-2548">VIM-2548</a> Fix paste</li> |  | ||||||
|         <li><a href="https://youtrack.jetbrains.com/issue/VIM-2470">VIM-2470</a> Fix incorrect reset of cursor shape</li> |  | ||||||
|         <li><a href="https://youtrack.jetbrains.com/issue/VIM-2223">VIM-2223</a>, <a |  | ||||||
|             href="https://youtrack.jetbrains.com/issue/VIM-1684">VIM-1684</a>, <a |  | ||||||
|             href="https://youtrack.jetbrains.com/issue/VIM-2491">VIM-2491</a> Fix <code>gv</code></li> |  | ||||||
|       </ul> |  | ||||||
|  |  | ||||||
|       <h3>Merged PRs:</h3> |  | ||||||
|       <ul> |  | ||||||
|         <li><a href="https://github.com/JetBrains/ideavim/pull/441">441</a> by <a href="https://github.com/DanEEStar">DanEEStar</a>: |  | ||||||
|           Add Matchit support for Vue.js files |  | ||||||
|         </li> |  | ||||||
|         <li><a href="https://github.com/JetBrains/ideavim/pull/440">440</a> by <a href="https://github.com/ksrb">Kevin |  | ||||||
|           Suen</a>: Add matchit support for handlebars |  | ||||||
|         </li> |  | ||||||
|         <li><a href="https://github.com/JetBrains/ideavim/pull/448">448</a> by <a href="https://github.com/cravay">Michael |  | ||||||
|           Schertenleib</a>: Support custom element names in vim-surround |  | ||||||
|         </li> |  | ||||||
|         <li><a href="https://github.com/JetBrains/ideavim/pull/435">435</a> by <a href="https://github.com/pmnoxx">Piotr |  | ||||||
|           Mikulski</a>: Print stderr when running a command just like vim does |  | ||||||
|         </li> |  | ||||||
|         <li><a href="https://github.com/JetBrains/ideavim/pull/449">449</a> by <a href="https://github.com/lonre">Lonre |  | ||||||
|           Wang</a>: Typo fix |  | ||||||
|         </li> |  | ||||||
|         <li><a href="https://github.com/JetBrains/ideavim/pull/453">453</a> by <a href="https://github.com/citizenmatt">Matt |  | ||||||
|           Ellis</a>: fix(VIM-2470): Fix incorrect reset of cursor shape |  | ||||||
|         </li> |  | ||||||
|         <li><a href="https://github.com/JetBrains/ideavim/pull/461">461</a> by <a href="https://github.com/ddadon10">David |  | ||||||
|           Dadon</a>: Add shortcut to ideajoin example |  | ||||||
|         </li> |  | ||||||
|       </ul> |  | ||||||
|     ]]> |     ]]> | ||||||
|   </change-notes> |   </change-notes> | ||||||
|   <description><![CDATA[ |   <description><![CDATA[ | ||||||
| @@ -70,8 +22,8 @@ | |||||||
|  |  | ||||||
|   <!-- Please search for "[VERSION UPDATE]" in project in case you update the since-build version --> |   <!-- Please search for "[VERSION UPDATE]" in project in case you update the since-build version --> | ||||||
|   <!-- Check for [Version Update] tag in YouTrack as well --> |   <!-- Check for [Version Update] tag in YouTrack as well --> | ||||||
|   <!-- Also, please update the value in gradle.build file--> |   <!-- Also, please update the value in build.gradle.kts file--> | ||||||
|   <idea-version since-build="213"/> |   <idea-version since-build="222"/> | ||||||
|  |  | ||||||
|   <!-- Mark the plugin as compatible with RubyMine and other products based on the IntelliJ platform (including CWM) --> |   <!-- Mark the plugin as compatible with RubyMine and other products based on the IntelliJ platform (including CWM) --> | ||||||
|   <depends>com.intellij.modules.platform</depends> |   <depends>com.intellij.modules.platform</depends> | ||||||
|   | |||||||
| @@ -112,7 +112,10 @@ internal object NeovimTesting { | |||||||
|     when { |     when { | ||||||
|       keys.equals("<esc>", ignoreCase = true) -> neovimApi.input(escapeCommand).get() |       keys.equals("<esc>", ignoreCase = true) -> neovimApi.input(escapeCommand).get() | ||||||
|       keys.equals("<C-C>", ignoreCase = true) -> neovimApi.input(ctrlcCommand).get() |       keys.equals("<C-C>", ignoreCase = true) -> neovimApi.input(ctrlcCommand).get() | ||||||
|       else -> neovimApi.input(neovimApi.replaceTermcodes(keys, true, false, true).get()).get() |       else -> { | ||||||
|  |         val replacedCodes = neovimApi.replaceTermcodes(keys, true, false, true).get() | ||||||
|  |         neovimApi.input(replacedCodes).get() | ||||||
|  |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -228,6 +231,7 @@ enum class SkipNeovimReason { | |||||||
|   VIM_SCRIPT, |   VIM_SCRIPT, | ||||||
|  |  | ||||||
|   GUARDED_BLOCKS, |   GUARDED_BLOCKS, | ||||||
|  |   CTRL_CODES, | ||||||
| } | } | ||||||
|  |  | ||||||
| fun LogicalPosition.toVimCoords(): VimCoords { | fun LogicalPosition.toVimCoords(): VimCoords { | ||||||
|   | |||||||
| @@ -23,9 +23,9 @@ import com.maddyhome.idea.vim.VimPlugin | |||||||
| 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 | ||||||
|  | import com.maddyhome.idea.vim.handler.ActionBeanClass | ||||||
| import com.maddyhome.idea.vim.key.CommandNode | import com.maddyhome.idea.vim.key.CommandNode | ||||||
| import com.maddyhome.idea.vim.key.CommandPartNode | import com.maddyhome.idea.vim.key.CommandPartNode | ||||||
| import com.maddyhome.idea.vim.handler.ActionBeanClass |  | ||||||
| import junit.framework.TestCase | import junit.framework.TestCase | ||||||
| import javax.swing.KeyStroke | import javax.swing.KeyStroke | ||||||
|  |  | ||||||
| @@ -38,14 +38,18 @@ class RegisterActionsTest : VimTestCase() { | |||||||
|  |  | ||||||
|   @TestWithoutNeovim(reason = SkipNeovimReason.EDITOR_MODIFICATION) |   @TestWithoutNeovim(reason = SkipNeovimReason.EDITOR_MODIFICATION) | ||||||
|   fun `test action in disabled plugin`() { |   fun `test action in disabled plugin`() { | ||||||
|     setupChecks { |     try { | ||||||
|       caretShape = false |       setupChecks { | ||||||
|     } |         caretShape = false | ||||||
|     val keys = injector.parser.parseKeys("jklwB") // just random keys |       } | ||||||
|     val before = "I ${c}found it in a legendary land" |       val keys = injector.parser.parseKeys("jklwB") // just random keys | ||||||
|     val after = "I jklwB${c}found it in a legendary land" |       val before = "I ${c}found it in a legendary land" | ||||||
|     doTest(keys, before, after, VimStateMachine.Mode.COMMAND, VimStateMachine.SubMode.NONE) { |       val after = "I jklwB${c}found it in a legendary land" | ||||||
|       VimPlugin.setEnabled(false) |       doTest(keys, before, after, VimStateMachine.Mode.COMMAND, VimStateMachine.SubMode.NONE) { | ||||||
|  |         VimPlugin.setEnabled(false) | ||||||
|  |       } | ||||||
|  |     } finally { | ||||||
|  |       VimPlugin.setEnabled(true) | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -34,7 +34,6 @@ import com.intellij.openapi.editor.LogicalPosition | |||||||
| import com.intellij.openapi.editor.VisualPosition | import com.intellij.openapi.editor.VisualPosition | ||||||
| import com.intellij.openapi.editor.colors.EditorColors | import com.intellij.openapi.editor.colors.EditorColors | ||||||
| import com.intellij.openapi.editor.ex.EditorEx | import com.intellij.openapi.editor.ex.EditorEx | ||||||
| import com.intellij.openapi.editor.ex.util.EditorUtil |  | ||||||
| import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx | import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx | ||||||
| import com.intellij.openapi.fileTypes.FileType | import com.intellij.openapi.fileTypes.FileType | ||||||
| import com.intellij.openapi.fileTypes.PlainTextFileType | import com.intellij.openapi.fileTypes.PlainTextFileType | ||||||
| @@ -82,6 +81,7 @@ import org.junit.Assert | |||||||
| import java.awt.event.KeyEvent | import java.awt.event.KeyEvent | ||||||
| import java.util.* | import java.util.* | ||||||
| import javax.swing.KeyStroke | import javax.swing.KeyStroke | ||||||
|  | import kotlin.math.roundToInt | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * @author vlan |  * @author vlan | ||||||
| @@ -169,7 +169,9 @@ abstract class VimTestCase : UsefulTestCase() { | |||||||
|     get() = 35 |     get() = 35 | ||||||
|  |  | ||||||
|   protected fun setEditorVisibleSize(width: Int, height: Int) { |   protected fun setEditorVisibleSize(width: Int, height: Int) { | ||||||
|     EditorTestUtil.setEditorVisibleSize(myFixture.editor, width, height) |     val w = (width * EditorHelper.getPlainSpaceWidthFloat(myFixture.editor)).roundToInt() | ||||||
|  |     val h = height * myFixture.editor.lineHeight | ||||||
|  |     EditorTestUtil.setEditorVisibleSizeInPixels(myFixture.editor, w, h) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   protected fun setEditorVirtualSpace() { |   protected fun setEditorVirtualSpace() { | ||||||
| @@ -609,7 +611,7 @@ abstract class VimTestCase : UsefulTestCase() { | |||||||
|   // per platform (e.g. Windows is 7, Mac is 8) so we can't guarantee correct positioning for tests if we use hard coded |   // per platform (e.g. Windows is 7, Mac is 8) so we can't guarantee correct positioning for tests if we use hard coded | ||||||
|   // pixel widths |   // pixel widths | ||||||
|   protected fun addInlay(offset: Int, relatesToPrecedingText: Boolean, widthInColumns: Int): Inlay<*> { |   protected fun addInlay(offset: Int, relatesToPrecedingText: Boolean, widthInColumns: Int): Inlay<*> { | ||||||
|     val widthInPixels = EditorUtil.getPlainSpaceWidth(myFixture.editor) * widthInColumns |     val widthInPixels = (EditorHelper.getPlainSpaceWidthFloat(myFixture.editor) * widthInColumns).roundToInt() | ||||||
|     return EditorTestUtil.addInlay(myFixture.editor, offset, relatesToPrecedingText, widthInPixels) |     return EditorTestUtil.addInlay(myFixture.editor, offset, relatesToPrecedingText, widthInPixels) | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -619,7 +621,7 @@ abstract class VimTestCase : UsefulTestCase() { | |||||||
|   // float if necessary. We'd still be working scaled to the line height, so fractional values should still work. |   // float if necessary. We'd still be working scaled to the line height, so fractional values should still work. | ||||||
|   protected fun addBlockInlay(offset: Int, showAbove: Boolean, heightInRows: Int): Inlay<*> { |   protected fun addBlockInlay(offset: Int, showAbove: Boolean, heightInRows: Int): Inlay<*> { | ||||||
|     val widthInColumns = 10 // Arbitrary width. We don't care. |     val widthInColumns = 10 // Arbitrary width. We don't care. | ||||||
|     val widthInPixels = EditorUtil.getPlainSpaceWidth(myFixture.editor) * widthInColumns |     val widthInPixels = (EditorHelper.getPlainSpaceWidthFloat(myFixture.editor) * widthInColumns).roundToInt() | ||||||
|     val heightInPixels = myFixture.editor.lineHeight * heightInRows |     val heightInPixels = myFixture.editor.lineHeight * heightInRows | ||||||
|     return EditorTestUtil.addBlockInlay(myFixture.editor, offset, false, showAbove, widthInPixels, heightInPixels) |     return EditorTestUtil.addBlockInlay(myFixture.editor, offset, false, showAbove, widthInPixels, heightInPixels) | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -71,6 +71,7 @@ class ChangeActionTest : VimTestCase() { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   // VIM-620 |i_CTRL-O| |   // VIM-620 |i_CTRL-O| | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.SELECT_MODE) | ||||||
|   fun testInsertSingleCommandAndNewLineInserting5() { |   fun testInsertSingleCommandAndNewLineInserting5() { | ||||||
|     doTest( |     doTest( | ||||||
|       listOf("i", "<C-O>", "v", "<C-G>"), |       listOf("i", "<C-O>", "v", "<C-G>"), | ||||||
| @@ -79,6 +80,7 @@ class ChangeActionTest : VimTestCase() { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   // VIM-620 |i_CTRL-O| |   // VIM-620 |i_CTRL-O| | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.SELECT_MODE) | ||||||
|   fun testInsertSingleCommandAndNewLineInserting6() { |   fun testInsertSingleCommandAndNewLineInserting6() { | ||||||
|     doTest( |     doTest( | ||||||
|       listOf("i", "<C-O>", "gh"), |       listOf("i", "<C-O>", "gh"), | ||||||
| @@ -87,6 +89,7 @@ class ChangeActionTest : VimTestCase() { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   // VIM-620 |i_CTRL-O| |   // VIM-620 |i_CTRL-O| | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.SELECT_MODE) | ||||||
|   fun testInsertSingleCommandAndNewLineInserting7() { |   fun testInsertSingleCommandAndNewLineInserting7() { | ||||||
|     doTest( |     doTest( | ||||||
|       listOf("i", "<C-O>", "gh", "<esc>"), |       listOf("i", "<C-O>", "gh", "<esc>"), | ||||||
| @@ -443,14 +446,15 @@ quux | |||||||
|     ) |     ) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   @VimBehaviorDiffers(originalVimAfter = "foo  bar") | ||||||
|   fun testDeleteJoinLinesWithTrailingSpaceThenEmptyLine() { |   fun testDeleteJoinLinesWithTrailingSpaceThenEmptyLine() { | ||||||
|     doTest( |     doTest( | ||||||
|       "3J", |       "3J", | ||||||
|       """ |       """ | ||||||
|         foo  |         foo. | ||||||
|          |          | ||||||
|         bar |         bar | ||||||
|       """.trimIndent(), |       """.dotToSpace().trimIndent(), | ||||||
|       "foo bar", VimStateMachine.Mode.COMMAND, VimStateMachine.SubMode.NONE |       "foo bar", VimStateMachine.Mode.COMMAND, VimStateMachine.SubMode.NONE | ||||||
|     ) |     ) | ||||||
|   } |   } | ||||||
| @@ -459,9 +463,9 @@ quux | |||||||
|     doTest( |     doTest( | ||||||
|       "J", |       "J", | ||||||
|       """ |       """ | ||||||
|         foo   |         foo.. | ||||||
|         bar |         bar | ||||||
|       """.trimIndent(), |       """.dotToSpace().trimIndent(), | ||||||
|       "foo  bar", VimStateMachine.Mode.COMMAND, VimStateMachine.SubMode.NONE |       "foo  bar", VimStateMachine.Mode.COMMAND, VimStateMachine.SubMode.NONE | ||||||
|     ) |     ) | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -2846,4 +2846,30 @@ rtyfg${c}hzxc""" | |||||||
|     """.trimIndent() |     """.trimIndent() | ||||||
|     assertState(after) |     assertState(after) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   // VIM-2703 | ||||||
|  |   @TestWithoutNeovim(reason = SkipNeovimReason.MULTICARET) | ||||||
|  |   fun `test multicaret with unnamed clipboard`() { | ||||||
|  |     injector.optionService.appendValue(OptionScope.GLOBAL, OptionConstants.clipboardName, OptionConstants.clipboard_unnamed) | ||||||
|  |     val before = """ | ||||||
|  |             attach${c}Download(null) | ||||||
|  |             attach${c}Download(null) | ||||||
|  |             attach${c}Download(null) | ||||||
|  |             attach${c}Download(null) | ||||||
|  |             attach${c}Download(null) | ||||||
|  |              | ||||||
|  |     """.trimIndent() | ||||||
|  |     configureByText(before) | ||||||
|  |     typeText(injector.parser.parseKeys("diw")) | ||||||
|  |     val after = """ | ||||||
|  |             ${c}(null) | ||||||
|  |             ${c}(null) | ||||||
|  |             ${c}(null) | ||||||
|  |             ${c}(null) | ||||||
|  |             ${c}(null) | ||||||
|  |              | ||||||
|  |     """.trimIndent() | ||||||
|  |     assertState(after) | ||||||
|  |     injector.optionService.resetDefault(OptionScope.GLOBAL, OptionConstants.clipboardName) | ||||||
|  |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -111,6 +111,7 @@ class ResetModeActionTest : VimTestCase() { | |||||||
|     TestCase.assertFalse(myFixture.editor.selectionModel.hasSelection()) |     TestCase.assertFalse(myFixture.editor.selectionModel.hasSelection()) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.CTRL_CODES) | ||||||
|   fun `test delete command after resetting operator-pending mode with ctrl open bracket`() { |   fun `test delete command after resetting operator-pending mode with ctrl open bracket`() { | ||||||
|     val keys = listOf("d", "<C-[>", "dw") |     val keys = listOf("d", "<C-[>", "dw") | ||||||
|     val before = "A Discovery" |     val before = "A Discovery" | ||||||
|   | |||||||
| @@ -140,7 +140,7 @@ public class SpecialRegistersTest extends VimTestCase { | |||||||
|  |  | ||||||
|     // Small deletes (less than a line) with register specified go to that register and to numbered registers |     // Small deletes (less than a line) with register specified go to that register and to numbered registers | ||||||
|     assertRegisterChanged('a'); |     assertRegisterChanged('a'); | ||||||
|     assertRegisterChanged('1'); |     assertRegisterNotChanged('1'); | ||||||
|     assertRegisterNotChanged(SMALL_DELETION_REGISTER); |     assertRegisterNotChanged(SMALL_DELETION_REGISTER); | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -155,7 +155,7 @@ public class SpecialRegistersTest extends VimTestCase { | |||||||
|     typeTextInFile(VimInjectorKt.getInjector().getParser().parseKeys("\"add"), "one <caret>two three\n"); |     typeTextInFile(VimInjectorKt.getInjector().getParser().parseKeys("\"add"), "one <caret>two three\n"); | ||||||
|  |  | ||||||
|     assertRegisterChanged('a'); |     assertRegisterChanged('a'); | ||||||
|     assertRegisterChanged('1'); |     assertRegisterNotChanged('1'); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   public void testNumberedRegistersShifting() { |   public void testNumberedRegistersShifting() { | ||||||
|   | |||||||
| @@ -317,6 +317,14 @@ class RepeatChangeActionTest : VimTestCase() { | |||||||
|     doTest(keys, before, after, VimStateMachine.Mode.COMMAND, VimStateMachine.SubMode.NONE) |     doTest(keys, before, after, VimStateMachine.Mode.COMMAND, VimStateMachine.SubMode.NONE) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   @VimBehaviorDiffers( | ||||||
|  |     originalVimAfter = """ | ||||||
|  |      | ||||||
|  |         Three | ||||||
|  |         Two | ||||||
|  |         One | ||||||
|  |   """ | ||||||
|  |   ) | ||||||
|   fun `test redo register feature`() { |   fun `test redo register feature`() { | ||||||
|     doTest( |     doTest( | ||||||
|       listOf("dd", "dd", "dd", "\"1p", ".", "."), |       listOf("dd", "dd", "dd", "\"1p", ".", "."), | ||||||
|   | |||||||
| @@ -18,7 +18,10 @@ | |||||||
|  |  | ||||||
| package org.jetbrains.plugins.ideavim.action.change | package org.jetbrains.plugins.ideavim.action.change | ||||||
|  |  | ||||||
|  | import com.maddyhome.idea.vim.api.injector | ||||||
| import com.maddyhome.idea.vim.command.VimStateMachine | import com.maddyhome.idea.vim.command.VimStateMachine | ||||||
|  | import com.maddyhome.idea.vim.options.OptionScope | ||||||
|  | import com.maddyhome.idea.vim.vimscript.services.IjVimOptionService | ||||||
| import org.jetbrains.plugins.ideavim.VimTestCase | import org.jetbrains.plugins.ideavim.VimTestCase | ||||||
|  |  | ||||||
| class UndoActionTest : VimTestCase() { | class UndoActionTest : VimTestCase() { | ||||||
| @@ -76,25 +79,27 @@ class UndoActionTest : VimTestCase() { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   fun `test cursor movements do not require additional undo`() { |   fun `test cursor movements do not require additional undo`() { | ||||||
|     val keys = listOf("a1<Esc>ea2<Esc>ea3<Esc>", "uu") |     if (!injector.optionService.isSet(OptionScope.GLOBAL, IjVimOptionService.oldUndo)) { | ||||||
|     val before = """ |       val keys = listOf("a1<Esc>ea2<Esc>ea3<Esc>", "uu") | ||||||
|  |       val before = """ | ||||||
|                 A Discovery |                 A Discovery | ||||||
|  |  | ||||||
|                 ${c}I found it in a legendary land |                 ${c}I found it in a legendary land | ||||||
|                 all rocks and lavender and tufted grass, |                 all rocks and lavender and tufted grass, | ||||||
|                 where it was settled on some sodden sand |                 where it was settled on some sodden sand | ||||||
|                 hard by the torrent of a mountain pass. |                 hard by the torrent of a mountain pass. | ||||||
|     """.trimIndent() |       """.trimIndent() | ||||||
|     val after = """ |       val after = """ | ||||||
|                 A Discovery |                 A Discovery | ||||||
|  |  | ||||||
|                 I1 found$c it in a legendary land |                 I1 found$c it in a legendary land | ||||||
|                 all rocks and lavender and tufted grass, |                 all rocks and lavender and tufted grass, | ||||||
|                 where it was settled on some sodden sand |                 where it was settled on some sodden sand | ||||||
|                 hard by the torrent of a mountain pass. |                 hard by the torrent of a mountain pass. | ||||||
|     """.trimIndent() |       """.trimIndent() | ||||||
|     doTest(keys, before, after, VimStateMachine.Mode.COMMAND, VimStateMachine.SubMode.NONE) |       doTest(keys, before, after, VimStateMachine.Mode.COMMAND, VimStateMachine.SubMode.NONE) | ||||||
|     assertFalse(hasSelection()) |       assertFalse(hasSelection()) | ||||||
|  |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   private fun hasSelection(): Boolean { |   private fun hasSelection(): Boolean { | ||||||
|   | |||||||
| @@ -20,9 +20,11 @@ | |||||||
|  |  | ||||||
| package org.jetbrains.plugins.ideavim.action.change.delete | package org.jetbrains.plugins.ideavim.action.change.delete | ||||||
|  |  | ||||||
|  | import com.intellij.notification.ActionCenter | ||||||
| import com.intellij.notification.EventLog | import com.intellij.notification.EventLog | ||||||
| import com.maddyhome.idea.vim.VimPlugin | import com.maddyhome.idea.vim.VimPlugin | ||||||
| import com.maddyhome.idea.vim.api.injector | import com.maddyhome.idea.vim.api.injector | ||||||
|  | import com.maddyhome.idea.vim.group.NotificationService | ||||||
| import com.maddyhome.idea.vim.vimscript.services.IjVimOptionService | import com.maddyhome.idea.vim.vimscript.services.IjVimOptionService | ||||||
| import org.jetbrains.plugins.ideavim.OptionValueType | import org.jetbrains.plugins.ideavim.OptionValueType | ||||||
| import org.jetbrains.plugins.ideavim.VimOptionTestCase | import org.jetbrains.plugins.ideavim.VimOptionTestCase | ||||||
| @@ -33,8 +35,6 @@ import org.jetbrains.plugins.ideavim.VimTestOption | |||||||
|  * @author Alex Plate |  * @author Alex Plate | ||||||
|  */ |  */ | ||||||
| class JoinNotificationTest : VimOptionTestCase(IjVimOptionService.ideajoinName) { | class JoinNotificationTest : VimOptionTestCase(IjVimOptionService.ideajoinName) { | ||||||
|   // [VERSION UPDATE] 221+: Uncomment |  | ||||||
| /* |  | ||||||
|   @VimOptionTestConfiguration(VimTestOption(IjVimOptionService.ideajoinName, OptionValueType.NUMBER, "0")) |   @VimOptionTestConfiguration(VimTestOption(IjVimOptionService.ideajoinName, OptionValueType.NUMBER, "0")) | ||||||
|   fun `test notification shown for no ideajoin`() { |   fun `test notification shown for no ideajoin`() { | ||||||
|     val before = "I found${c} it\n in a legendary land" |     val before = "I found${c} it\n in a legendary land" | ||||||
| @@ -45,17 +45,14 @@ class JoinNotificationTest : VimOptionTestCase(IjVimOptionService.ideajoinName) | |||||||
|     val notification = ActionCenter.getNotifications(myFixture.project, true).last() |     val notification = ActionCenter.getNotifications(myFixture.project, true).last() | ||||||
|     try { |     try { | ||||||
|       assertEquals(NotificationService.IDEAVIM_NOTIFICATION_TITLE, notification.title) |       assertEquals(NotificationService.IDEAVIM_NOTIFICATION_TITLE, notification.title) | ||||||
|       assertTrue(OptionConstants.ideajoinName in notification.content) |       assertTrue(IjVimOptionService.ideajoinName in notification.content) | ||||||
|       assertEquals(3, notification.actions.size) |       assertEquals(3, notification.actions.size) | ||||||
|     } finally { |     } finally { | ||||||
|       notification.expire() |       notification.expire() | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| */ |  | ||||||
|  |  | ||||||
|   // [VERSION UPDATE] 221+: Uncomment |   @VimOptionTestConfiguration(VimTestOption(IjVimOptionService.ideajoinName, OptionValueType.NUMBER, "1")) | ||||||
| /* |  | ||||||
|   @VimOptionTestConfiguration(VimTestOption(OptionConstants.ideajoinName, OptionValueType.NUMBER, "1")) |  | ||||||
|   fun `test notification not shown for ideajoin`() { |   fun `test notification not shown for ideajoin`() { | ||||||
|     val before = "I found${c} it\n in a legendary land" |     val before = "I found${c} it\n in a legendary land" | ||||||
|     configureByText(before) |     configureByText(before) | ||||||
| @@ -63,9 +60,8 @@ class JoinNotificationTest : VimOptionTestCase(IjVimOptionService.ideajoinName) | |||||||
|     typeText(injector.parser.parseKeys("J")) |     typeText(injector.parser.parseKeys("J")) | ||||||
|  |  | ||||||
|     val notifications = ActionCenter.getNotifications(myFixture.project, true) |     val notifications = ActionCenter.getNotifications(myFixture.project, true) | ||||||
|     assertTrue(notifications.isEmpty() || notifications.last().isExpired || OptionConstants.ideajoinName !in notifications.last().content) |     assertTrue(notifications.isEmpty() || notifications.last().isExpired || IjVimOptionService.ideajoinName !in notifications.last().content) | ||||||
|   } |   } | ||||||
| */ |  | ||||||
|  |  | ||||||
|   @VimOptionTestConfiguration(VimTestOption(IjVimOptionService.ideajoinName, OptionValueType.NUMBER, "0")) |   @VimOptionTestConfiguration(VimTestOption(IjVimOptionService.ideajoinName, OptionValueType.NUMBER, "0")) | ||||||
|   fun `test notification not shown if was shown already`() { |   fun `test notification not shown if was shown already`() { | ||||||
|   | |||||||
| @@ -42,6 +42,7 @@ class InsertEnterActionTest : VimTestCase() { | |||||||
|     doTest(listOf("i", "<Enter>"), before, after, VimStateMachine.Mode.INSERT, VimStateMachine.SubMode.NONE) |     doTest(listOf("i", "<Enter>"), before, after, VimStateMachine.Mode.INSERT, VimStateMachine.SubMode.NONE) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.CTRL_CODES) | ||||||
|   fun `test insert enter with C-M`() { |   fun `test insert enter with C-M`() { | ||||||
|     val before = """I found it in a legendary land |     val before = """I found it in a legendary land | ||||||
|         |${c}all rocks and lavender and tufted grass, |         |${c}all rocks and lavender and tufted grass, | ||||||
|   | |||||||
| @@ -18,10 +18,12 @@ | |||||||
|  |  | ||||||
| package org.jetbrains.plugins.ideavim.action.copy | package org.jetbrains.plugins.ideavim.action.copy | ||||||
|  |  | ||||||
|  | import com.intellij.notification.ActionCenter | ||||||
| import com.intellij.notification.EventLog | import com.intellij.notification.EventLog | ||||||
| import com.maddyhome.idea.vim.VimPlugin | import com.maddyhome.idea.vim.VimPlugin | ||||||
| import com.maddyhome.idea.vim.api.injector | import com.maddyhome.idea.vim.api.injector | ||||||
| import com.maddyhome.idea.vim.command.SelectionType | import com.maddyhome.idea.vim.command.SelectionType | ||||||
|  | import com.maddyhome.idea.vim.group.NotificationService | ||||||
| import com.maddyhome.idea.vim.newapi.vim | import com.maddyhome.idea.vim.newapi.vim | ||||||
| import com.maddyhome.idea.vim.options.OptionConstants | import com.maddyhome.idea.vim.options.OptionConstants | ||||||
| import org.jetbrains.plugins.ideavim.OptionValueType | import org.jetbrains.plugins.ideavim.OptionValueType | ||||||
| @@ -34,14 +36,12 @@ import org.jetbrains.plugins.ideavim.rangeOf | |||||||
|  * @author Alex Plate |  * @author Alex Plate | ||||||
|  */ |  */ | ||||||
| class IdeaPutNotificationsTest : VimOptionTestCase(OptionConstants.clipboardName) { | class IdeaPutNotificationsTest : VimOptionTestCase(OptionConstants.clipboardName) { | ||||||
|   // [VERSION UPDATE] 221+: Uncomment |  | ||||||
| /* |  | ||||||
|   @VimOptionTestConfiguration(VimTestOption(OptionConstants.clipboardName, OptionValueType.STRING, "")) |   @VimOptionTestConfiguration(VimTestOption(OptionConstants.clipboardName, OptionValueType.STRING, "")) | ||||||
|   fun `test notification exists if no ideaput`() { |   fun `test notification exists if no ideaput`() { | ||||||
|     val before = "${c}I found it in a legendary land" |     val before = "${c}I found it in a legendary land" | ||||||
|     configureByText(before) |     configureByText(before) | ||||||
|     appReadySetup(false) |     appReadySetup(false) | ||||||
|     VimPlugin.getRegister().storeText(myFixture.editor, before rangeOf "legendary", SelectionType.CHARACTER_WISE, false) |     VimPlugin.getRegister().storeText(myFixture.editor.vim, before rangeOf "legendary", SelectionType.CHARACTER_WISE, false) | ||||||
|     typeText(injector.parser.parseKeys("p")) |     typeText(injector.parser.parseKeys("p")) | ||||||
|  |  | ||||||
|     val notification = ActionCenter.getNotifications(myFixture.project, true).last() |     val notification = ActionCenter.getNotifications(myFixture.project, true).last() | ||||||
| @@ -53,10 +53,7 @@ class IdeaPutNotificationsTest : VimOptionTestCase(OptionConstants.clipboardName | |||||||
|       notification.expire() |       notification.expire() | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| */ |  | ||||||
|  |  | ||||||
|   // [VERSION UPDATE] 221+: Uncomment |  | ||||||
| /* |  | ||||||
|   @VimOptionTestConfiguration( |   @VimOptionTestConfiguration( | ||||||
|     VimTestOption( |     VimTestOption( | ||||||
|       OptionConstants.clipboardName, |       OptionConstants.clipboardName, | ||||||
| @@ -68,13 +65,12 @@ class IdeaPutNotificationsTest : VimOptionTestCase(OptionConstants.clipboardName | |||||||
|     val before = "${c}I found it in a legendary land" |     val before = "${c}I found it in a legendary land" | ||||||
|     configureByText(before) |     configureByText(before) | ||||||
|     appReadySetup(false) |     appReadySetup(false) | ||||||
|     VimPlugin.getRegister().storeText(myFixture.editor, before rangeOf "legendary", SelectionType.CHARACTER_WISE, false) |     VimPlugin.getRegister().storeText(myFixture.editor.vim, before rangeOf "legendary", SelectionType.CHARACTER_WISE, false) | ||||||
|     typeText(injector.parser.parseKeys("p")) |     typeText(injector.parser.parseKeys("p")) | ||||||
|  |  | ||||||
|     val notifications = ActionCenter.getNotifications(myFixture.project, true) |     val notifications = ActionCenter.getNotifications(myFixture.project, true) | ||||||
|     assertTrue(notifications.isEmpty() || notifications.last().isExpired || OptionConstants.clipboard_ideaput !in notifications.last().content) |     assertTrue(notifications.isEmpty() || notifications.last().isExpired || OptionConstants.clipboard_ideaput !in notifications.last().content) | ||||||
|   } |   } | ||||||
| */ |  | ||||||
|  |  | ||||||
|   @VimOptionTestConfiguration(VimTestOption(OptionConstants.clipboardName, OptionValueType.STRING, "")) |   @VimOptionTestConfiguration(VimTestOption(OptionConstants.clipboardName, OptionValueType.STRING, "")) | ||||||
|   fun `test no notification if already was`() { |   fun `test no notification if already was`() { | ||||||
|   | |||||||
| @@ -24,6 +24,8 @@ import com.maddyhome.idea.vim.command.SelectionType | |||||||
| import com.maddyhome.idea.vim.command.VimStateMachine | import com.maddyhome.idea.vim.command.VimStateMachine | ||||||
| import com.maddyhome.idea.vim.helper.VimBehaviorDiffers | import com.maddyhome.idea.vim.helper.VimBehaviorDiffers | ||||||
| import com.maddyhome.idea.vim.newapi.vim | import com.maddyhome.idea.vim.newapi.vim | ||||||
|  | import org.jetbrains.plugins.ideavim.SkipNeovimReason | ||||||
|  | import org.jetbrains.plugins.ideavim.TestWithoutNeovim | ||||||
| import org.jetbrains.plugins.ideavim.VimTestCase | import org.jetbrains.plugins.ideavim.VimTestCase | ||||||
| import org.jetbrains.plugins.ideavim.rangeOf | import org.jetbrains.plugins.ideavim.rangeOf | ||||||
| import org.junit.Test | import org.junit.Test | ||||||
| @@ -31,7 +33,13 @@ import org.junit.Test | |||||||
| class PutTestAfterCursorActionTest : VimTestCase() { | class PutTestAfterCursorActionTest : VimTestCase() { | ||||||
|   fun `test put from number register`() { |   fun `test put from number register`() { | ||||||
|     setRegister('4', "XXX ") |     setRegister('4', "XXX ") | ||||||
|     doTest("\"4p", "This is my$c text", "This is my XXX$c text", VimStateMachine.Mode.COMMAND, VimStateMachine.SubMode.NONE) |     doTest( | ||||||
|  |       "\"4p", | ||||||
|  |       "This is my$c text", | ||||||
|  |       "This is my XXX$c text", | ||||||
|  |       VimStateMachine.Mode.COMMAND, | ||||||
|  |       VimStateMachine.SubMode.NONE | ||||||
|  |     ) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @VimBehaviorDiffers( |   @VimBehaviorDiffers( | ||||||
| @@ -69,4 +77,29 @@ class PutTestAfterCursorActionTest : VimTestCase() { | |||||||
|     """.trimIndent() |     """.trimIndent() | ||||||
|     assertState(after) |     assertState(after) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.MULTICARET) | ||||||
|  |   @Test | ||||||
|  |   fun `test inserting same content to multiple carets`() { | ||||||
|  |     val before = """ | ||||||
|  |             A Discovery | ||||||
|  |  | ||||||
|  |             ${c}I found it in a legendary land | ||||||
|  |             ${c}all rocks and lavender and tufted grass, | ||||||
|  |             ${c}where it was settled on some sodden sand | ||||||
|  |             ${c}hard by the torrent of a mountain pass. | ||||||
|  |     """.trimIndent() | ||||||
|  |     val editor = configureByText(before) | ||||||
|  |     VimPlugin.getRegister().storeText(editor.vim, before rangeOf "Discovery", SelectionType.CHARACTER_WISE, false) | ||||||
|  |     typeText(injector.parser.parseKeys("vep")) | ||||||
|  |     val after = """ | ||||||
|  |             A Discovery | ||||||
|  |  | ||||||
|  |             Discovery it in a legendary land | ||||||
|  |             Discovery rocks and lavender and tufted grass, | ||||||
|  |             Discovery it was settled on some sodden sand | ||||||
|  |             Discovery by the torrent of a mountain pass. | ||||||
|  |     """.trimIndent() | ||||||
|  |     assertState(after) | ||||||
|  |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -171,6 +171,7 @@ class PutVisualTextMoveCursorActionTest : VimTestCase() { | |||||||
|     assertState(after) |     assertState(after) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.CTRL_CODES) | ||||||
|   fun `test Put line in block selection`() { |   fun `test Put line in block selection`() { | ||||||
|     val file = """ |     val file = """ | ||||||
|             ${c}A Discovery |             ${c}A Discovery | ||||||
|   | |||||||
| @@ -22,6 +22,8 @@ package org.jetbrains.plugins.ideavim.action.motion.leftright | |||||||
|  |  | ||||||
| import com.maddyhome.idea.vim.command.VimStateMachine | import com.maddyhome.idea.vim.command.VimStateMachine | ||||||
| import com.maddyhome.idea.vim.helper.VimBehaviorDiffers | import com.maddyhome.idea.vim.helper.VimBehaviorDiffers | ||||||
|  | import org.jetbrains.plugins.ideavim.SkipNeovimReason | ||||||
|  | import org.jetbrains.plugins.ideavim.TestWithoutNeovim | ||||||
| import org.jetbrains.plugins.ideavim.VimTestCase | import org.jetbrains.plugins.ideavim.VimTestCase | ||||||
|  |  | ||||||
| class MotionLastColumnActionTest : VimTestCase() { | class MotionLastColumnActionTest : VimTestCase() { | ||||||
| @@ -140,6 +142,7 @@ class MotionLastColumnActionTest : VimTestCase() { | |||||||
|     doTest(keys, before, after, VimStateMachine.Mode.INSERT, VimStateMachine.SubMode.NONE) |     doTest(keys, before, after, VimStateMachine.Mode.INSERT, VimStateMachine.SubMode.NONE) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.CTRL_CODES) | ||||||
|   fun `test dollar motion from insert mode with deletion`() { |   fun `test dollar motion from insert mode with deletion`() { | ||||||
|     val keys = "i<C-O>d$" |     val keys = "i<C-O>d$" | ||||||
|     val before = """ |     val before = """ | ||||||
|   | |||||||
| @@ -0,0 +1,28 @@ | |||||||
|  | /* | ||||||
|  |  * 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 org.jetbrains.plugins.ideavim.action.motion.`object` | ||||||
|  |  | ||||||
|  | import com.maddyhome.idea.vim.command.VimStateMachine | ||||||
|  | import org.jetbrains.plugins.ideavim.VimTestCase | ||||||
|  |  | ||||||
|  | class MotionInnerBlockDoubleQuoteActionTest : VimTestCase() { | ||||||
|  |   fun `test change outside quotes`() { | ||||||
|  |     doTest("di\"", "${c}print(\"hello\")", "print(\"$c\")", VimStateMachine.Mode.COMMAND, VimStateMachine.SubMode.NONE) | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -198,4 +198,28 @@ class MotionInnerBlockParenActionTest : VimTestCase() { | |||||||
|     ) |     ) | ||||||
|     assertState("foo()\n") |     assertState("foo()\n") | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   fun testOutside() { | ||||||
|  |     typeTextInFile( | ||||||
|  |       injector.parser.parseKeys("di)"), | ||||||
|  |       "${c}foo(bar)\n" | ||||||
|  |     ) | ||||||
|  |     assertState("foo()\n") | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   fun testOutsideInString() { | ||||||
|  |     typeTextInFile( | ||||||
|  |       injector.parser.parseKeys("di)"), | ||||||
|  |       "\"1${c}23\"foo(bar)\n" | ||||||
|  |     ) | ||||||
|  |     assertState("\"123\"foo()\n") | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   fun testOutsideInString2() { | ||||||
|  |     typeTextInFile( | ||||||
|  |       injector.parser.parseKeys("di)"), | ||||||
|  |       "\"1${c}23(dsa)d\"foo(bar)\n" | ||||||
|  |     ) | ||||||
|  |     assertState("\"123()d\"foo(bar)\n") | ||||||
|  |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -0,0 +1,48 @@ | |||||||
|  | /* | ||||||
|  |  * 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 org.jetbrains.plugins.ideavim.action.motion.`object` | ||||||
|  |  | ||||||
|  | import com.maddyhome.idea.vim.api.injector | ||||||
|  | import org.jetbrains.plugins.ideavim.VimTestCase | ||||||
|  |  | ||||||
|  | class MotionOuterBlockBraceActionTest : VimTestCase() { | ||||||
|  |   fun testOutside() { | ||||||
|  |     typeTextInFile( | ||||||
|  |       injector.parser.parseKeys("di}"), | ||||||
|  |       "${c}foo{bar}\n" | ||||||
|  |     ) | ||||||
|  |     assertState("foo{}\n") | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   fun testOutsideInString() { | ||||||
|  |     typeTextInFile( | ||||||
|  |       injector.parser.parseKeys("di}"), | ||||||
|  |       "\"1${c}23\"foo{bar}\n" | ||||||
|  |     ) | ||||||
|  |     assertState("\"123\"foo{}\n") | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   fun testOutsideInString2() { | ||||||
|  |     typeTextInFile( | ||||||
|  |       injector.parser.parseKeys("di}"), | ||||||
|  |       "\"1${c}23{dsa}d\"foo{bar}\n" | ||||||
|  |     ) | ||||||
|  |     assertState("\"123{}d\"foo{bar}\n") | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -84,6 +84,7 @@ class MotionPercentOrMatchActionTest : VimTestCase() { | |||||||
|     assertOffset(7) |     assertOffset(7) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.PLUGIN, description = "Matchit plugin affects neovim") | ||||||
|   fun `test percent match parens in string`() { |   fun `test percent match parens in string`() { | ||||||
|     typeTextInFile( |     typeTextInFile( | ||||||
|       injector.parser.parseKeys("%"), |       injector.parser.parseKeys("%"), | ||||||
| @@ -113,6 +114,7 @@ class MotionPercentOrMatchActionTest : VimTestCase() { | |||||||
|     assertState("$c<!-- foo -->") |     assertState("$c<!-- foo -->") | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.PLUGIN, description = "Matchit plugin affects neovim") | ||||||
|   fun `test percent match java comment start`() { |   fun `test percent match java comment start`() { | ||||||
|     configureByJavaText("/$c* foo */") |     configureByJavaText("/$c* foo */") | ||||||
|     typeText(injector.parser.parseKeys("%")) |     typeText(injector.parser.parseKeys("%")) | ||||||
| @@ -144,12 +146,14 @@ class MotionPercentOrMatchActionTest : VimTestCase() { | |||||||
|     assertState("$c/** foo */") |     assertState("$c/** foo */") | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.PLUGIN, description = "Matchit plugin affects neovim") | ||||||
|   fun `test percent doesnt match after comment start`() { |   fun `test percent doesnt match after comment start`() { | ||||||
|     configureByJavaText("/*$c foo */") |     configureByJavaText("/*$c foo */") | ||||||
|     typeText(injector.parser.parseKeys("%")) |     typeText(injector.parser.parseKeys("%")) | ||||||
|     assertState("/*$c foo */") |     assertState("/*$c foo */") | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.UNCLEAR) | ||||||
|   fun `test percent doesnt match before comment end`() { |   fun `test percent doesnt match before comment end`() { | ||||||
|     configureByJavaText("/* foo $c */") |     configureByJavaText("/* foo $c */") | ||||||
|     typeText(injector.parser.parseKeys("%")) |     typeText(injector.parser.parseKeys("%")) | ||||||
| @@ -232,10 +236,12 @@ class MotionPercentOrMatchActionTest : VimTestCase() { | |||||||
|     ) |     ) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.PLUGIN, description = "Matchit plugin affects neovim") | ||||||
|   fun `test deleting with percent motion backward`() { |   fun `test deleting with percent motion backward`() { | ||||||
|     doTest("d%", "(foo bar$c)", c, VimStateMachine.Mode.COMMAND, VimStateMachine.SubMode.NONE) |     doTest("d%", "(foo bar$c)", c, VimStateMachine.Mode.COMMAND, VimStateMachine.SubMode.NONE) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.PLUGIN, description = "Matchit plugin affects neovim") | ||||||
|   fun `test deleting with percent motion`() { |   fun `test deleting with percent motion`() { | ||||||
|     doTest("d%", "$c(foo bar)", c, VimStateMachine.Mode.COMMAND, VimStateMachine.SubMode.NONE) |     doTest("d%", "$c(foo bar)", c, VimStateMachine.Mode.COMMAND, VimStateMachine.SubMode.NONE) | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -19,15 +19,16 @@ | |||||||
| package org.jetbrains.plugins.ideavim.action.scroll | package org.jetbrains.plugins.ideavim.action.scroll | ||||||
|  |  | ||||||
| import com.intellij.openapi.editor.Inlay | import com.intellij.openapi.editor.Inlay | ||||||
| import com.intellij.openapi.editor.ex.util.EditorUtil |  | ||||||
| import com.maddyhome.idea.vim.VimPlugin | import com.maddyhome.idea.vim.VimPlugin | ||||||
| import com.maddyhome.idea.vim.api.injector | import com.maddyhome.idea.vim.api.injector | ||||||
|  | import com.maddyhome.idea.vim.helper.EditorHelper | ||||||
| import com.maddyhome.idea.vim.helper.VimBehaviorDiffers | import com.maddyhome.idea.vim.helper.VimBehaviorDiffers | ||||||
| import com.maddyhome.idea.vim.options.OptionConstants | import com.maddyhome.idea.vim.options.OptionConstants | ||||||
| import com.maddyhome.idea.vim.options.OptionScope | import com.maddyhome.idea.vim.options.OptionScope | ||||||
| import com.maddyhome.idea.vim.vimscript.model.datatypes.VimInt | import com.maddyhome.idea.vim.vimscript.model.datatypes.VimInt | ||||||
| import org.jetbrains.plugins.ideavim.VimTestCase | import org.jetbrains.plugins.ideavim.VimTestCase | ||||||
| import org.junit.Assert | import org.junit.Assert | ||||||
|  | import kotlin.math.roundToInt | ||||||
|  |  | ||||||
| /* | /* | ||||||
|                                                        *zs* |                                                        *zs* | ||||||
| @@ -77,7 +78,7 @@ class ScrollFirstScreenColumnActionTest : VimTestCase() { | |||||||
|     typeText(injector.parser.parseKeys("100|" + "zs")) |     typeText(injector.parser.parseKeys("100|" + "zs")) | ||||||
|     val visibleArea = myFixture.editor.scrollingModel.visibleArea |     val visibleArea = myFixture.editor.scrollingModel.visibleArea | ||||||
|     val textWidth = visibleArea.width - inlay.widthInPixels |     val textWidth = visibleArea.width - inlay.widthInPixels | ||||||
|     val availableColumns = textWidth / EditorUtil.getPlainSpaceWidth(myFixture.editor) |     val availableColumns = (textWidth / EditorHelper.getPlainSpaceWidthFloat(myFixture.editor)).roundToInt() | ||||||
|  |  | ||||||
|     // The first visible text column will be 99, with the inlay positioned to the left of it |     // The first visible text column will be 99, with the inlay positioned to the left of it | ||||||
|     assertVisibleLineBounds(0, 99, 99 + availableColumns - 1) |     assertVisibleLineBounds(0, 99, 99 + availableColumns - 1) | ||||||
| @@ -112,6 +113,6 @@ class ScrollFirstScreenColumnActionTest : VimTestCase() { | |||||||
|  |  | ||||||
|   private fun getAvailableColumns(inlay: Inlay<*>): Int { |   private fun getAvailableColumns(inlay: Inlay<*>): Int { | ||||||
|     val textWidth = myFixture.editor.scrollingModel.visibleArea.width - inlay.widthInPixels |     val textWidth = myFixture.editor.scrollingModel.visibleArea.width - inlay.widthInPixels | ||||||
|     return textWidth / EditorUtil.getPlainSpaceWidth(myFixture.editor) |     return (textWidth / EditorHelper.getPlainSpaceWidthFloat(myFixture.editor)).roundToInt() | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -19,14 +19,15 @@ | |||||||
| package org.jetbrains.plugins.ideavim.action.scroll | package org.jetbrains.plugins.ideavim.action.scroll | ||||||
|  |  | ||||||
| import com.intellij.openapi.editor.Inlay | import com.intellij.openapi.editor.Inlay | ||||||
| import com.intellij.openapi.editor.ex.util.EditorUtil |  | ||||||
| import com.maddyhome.idea.vim.VimPlugin | import com.maddyhome.idea.vim.VimPlugin | ||||||
| import com.maddyhome.idea.vim.api.injector | import com.maddyhome.idea.vim.api.injector | ||||||
|  | import com.maddyhome.idea.vim.helper.EditorHelper | ||||||
| import com.maddyhome.idea.vim.options.OptionConstants | import com.maddyhome.idea.vim.options.OptionConstants | ||||||
| import com.maddyhome.idea.vim.options.OptionScope | import com.maddyhome.idea.vim.options.OptionScope | ||||||
| import com.maddyhome.idea.vim.vimscript.model.datatypes.VimInt | import com.maddyhome.idea.vim.vimscript.model.datatypes.VimInt | ||||||
| import org.jetbrains.plugins.ideavim.VimTestCase | import org.jetbrains.plugins.ideavim.VimTestCase | ||||||
| import org.junit.Assert | import org.junit.Assert | ||||||
|  | import kotlin.math.roundToInt | ||||||
|  |  | ||||||
| /* | /* | ||||||
|                                                        *ze* |                                                        *ze* | ||||||
| @@ -109,14 +110,15 @@ class ScrollLastScreenColumnActionTest : VimTestCase() { | |||||||
|     typeText(injector.parser.parseKeys("100|" + "ze")) |     typeText(injector.parser.parseKeys("100|" + "ze")) | ||||||
|     val visibleArea = myFixture.editor.scrollingModel.visibleArea |     val visibleArea = myFixture.editor.scrollingModel.visibleArea | ||||||
|     val textWidth = visibleArea.width - inlay.widthInPixels |     val textWidth = visibleArea.width - inlay.widthInPixels | ||||||
|     val availableColumns = textWidth / EditorUtil.getPlainSpaceWidth(myFixture.editor) |     val availableColumns = (textWidth / EditorHelper.getPlainSpaceWidthFloat(myFixture.editor)).roundToInt() | ||||||
|  |  | ||||||
|     // The last visible text column will be 99, but it will be positioned before the inlay |     // The last visible text column will be 99, but it will be positioned before the inlay | ||||||
|     assertVisibleLineBounds(0, 99 - availableColumns + 1, 99) |     assertVisibleLineBounds(0, 99 - availableColumns + 1, 99) | ||||||
|  |  | ||||||
|     // We have to assert the location of the inlay |     // We have to assert the location of the inlay | ||||||
|     Assert.assertEquals(visibleArea.x + textWidth, inlay.bounds!!.x) |     val inlayX = myFixture.editor.visualPositionToPoint2D(inlay.visualPosition).x.roundToInt() | ||||||
|     Assert.assertEquals(visibleArea.x + visibleArea.width, inlay.bounds!!.x + inlay.bounds!!.width) |     Assert.assertEquals(visibleArea.x + textWidth, inlayX) | ||||||
|  |     Assert.assertEquals(visibleArea.x + visibleArea.width, inlayX + inlay.widthInPixels) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   fun `test last screen column does not include subsequent inline inlay associated with following text`() { |   fun `test last screen column does not include subsequent inline inlay associated with following text`() { | ||||||
| @@ -130,6 +132,6 @@ class ScrollLastScreenColumnActionTest : VimTestCase() { | |||||||
|  |  | ||||||
|   private fun getAvailableColumns(inlay: Inlay<*>): Int { |   private fun getAvailableColumns(inlay: Inlay<*>): Int { | ||||||
|     val textWidth = myFixture.editor.scrollingModel.visibleArea.width - inlay.widthInPixels |     val textWidth = myFixture.editor.scrollingModel.visibleArea.width - inlay.widthInPixels | ||||||
|     return textWidth / EditorUtil.getPlainSpaceWidth(myFixture.editor) |     return (textWidth / EditorHelper.getPlainSpaceWidthFloat(myFixture.editor)).roundToInt() | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -134,4 +134,18 @@ class SetCommandTest : VimTestCase() { | |||||||
|     typeText(commandToKeys("set selection?")) |     typeText(commandToKeys("set selection?")) | ||||||
|     assertExOutput("selection=exclusive \n") |     assertExOutput("selection=exclusive \n") | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   @TestWithoutNeovim(reason = SkipNeovimReason.OPTION) | ||||||
|  |   fun `test show numbered value`() { | ||||||
|  |     configureByText("\n") | ||||||
|  |     typeText(commandToKeys("set so")) | ||||||
|  |     assertExOutput("scrolloff=0         \n") | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   @TestWithoutNeovim(reason = SkipNeovimReason.OPTION) | ||||||
|  |   fun `test show numbered value with questionmark`() { | ||||||
|  |     configureByText("\n") | ||||||
|  |     typeText(commandToKeys("set so?")) | ||||||
|  |     assertExOutput("scrolloff=0         \n") | ||||||
|  |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -22,17 +22,21 @@ import com.intellij.ide.highlighter.HtmlFileType | |||||||
| import com.intellij.ide.highlighter.JavaFileType | import com.intellij.ide.highlighter.JavaFileType | ||||||
| import com.maddyhome.idea.vim.command.VimStateMachine | import com.maddyhome.idea.vim.command.VimStateMachine | ||||||
| import com.maddyhome.idea.vim.helper.VimBehaviorDiffers | import com.maddyhome.idea.vim.helper.VimBehaviorDiffers | ||||||
|  | import org.jetbrains.plugins.ideavim.SkipNeovimReason | ||||||
|  | import org.jetbrains.plugins.ideavim.TestWithoutNeovim | ||||||
| import org.jetbrains.plugins.ideavim.VimTestCase | import org.jetbrains.plugins.ideavim.VimTestCase | ||||||
| import org.jetbrains.yaml.YAMLFileType | import org.jetbrains.yaml.YAMLFileType | ||||||
|  |  | ||||||
| @Suppress("SpellCheckingInspection") | @Suppress("SpellCheckingInspection") | ||||||
| class CommentaryExtensionTest : VimTestCase() { | class CommentaryExtensionTest : VimTestCase() { | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.PLUGIN) | ||||||
|   override fun setUp() { |   override fun setUp() { | ||||||
|     super.setUp() |     super.setUp() | ||||||
|     enableExtensions("commentary") |     enableExtensions("commentary") | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   // |gc| |l| + move caret |   // |gc| |l| + move caret | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.PLUGIN) | ||||||
|   fun testBlockCommentSingle() { |   fun testBlockCommentSingle() { | ||||||
|     doTest( |     doTest( | ||||||
|       "gcll", |       "gcll", | ||||||
| @@ -44,6 +48,7 @@ class CommentaryExtensionTest : VimTestCase() { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   // |gc| |iw| |   // |gc| |iw| | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.PLUGIN) | ||||||
|   fun testBlockCommentInnerWord() { |   fun testBlockCommentInnerWord() { | ||||||
|     doTest( |     doTest( | ||||||
|       "gciw", |       "gciw", | ||||||
| @@ -55,6 +60,7 @@ class CommentaryExtensionTest : VimTestCase() { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   // |gc| |iw| |   // |gc| |iw| | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.PLUGIN) | ||||||
|   fun testBlockCommentTillForward() { |   fun testBlockCommentTillForward() { | ||||||
|     doTest( |     doTest( | ||||||
|       "gct{", |       "gct{", | ||||||
| @@ -65,6 +71,7 @@ class CommentaryExtensionTest : VimTestCase() { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   // |gc| |ab| |   // |gc| |ab| | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.PLUGIN) | ||||||
|   fun testBlockCommentOuterParens() { |   fun testBlockCommentOuterParens() { | ||||||
|     doTest( |     doTest( | ||||||
|       "gcab", |       "gcab", | ||||||
| @@ -79,6 +86,7 @@ class CommentaryExtensionTest : VimTestCase() { | |||||||
|    *  otherwise, they are incredibly difficult to undo |    *  otherwise, they are incredibly difficult to undo | ||||||
|    */ |    */ | ||||||
| // |gc| |j| | // |gc| |j| | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.PLUGIN) | ||||||
|   fun testLineCommentDown() { |   fun testLineCommentDown() { | ||||||
|     doTest( |     doTest( | ||||||
|       "gcj", |       "gcj", | ||||||
| @@ -89,6 +97,7 @@ class CommentaryExtensionTest : VimTestCase() { | |||||||
|     ) |     ) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.PLUGIN) | ||||||
|   fun testLineCommentDownPreservesAbsoluteCaretLocation() { |   fun testLineCommentDownPreservesAbsoluteCaretLocation() { | ||||||
|     doTest( |     doTest( | ||||||
|       "gcj", |       "gcj", | ||||||
| @@ -100,6 +109,7 @@ class CommentaryExtensionTest : VimTestCase() { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   // |gc| |ip| |   // |gc| |ip| | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.PLUGIN) | ||||||
|   fun testLineCommentInnerParagraph() { |   fun testLineCommentInnerParagraph() { | ||||||
|     doTest( |     doTest( | ||||||
|       "gcip", |       "gcip", | ||||||
| @@ -111,6 +121,7 @@ class CommentaryExtensionTest : VimTestCase() { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   // |gc| |ip| |   // |gc| |ip| | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.PLUGIN) | ||||||
|   fun testLineCommentSingleLineInnerParagraph() { |   fun testLineCommentSingleLineInnerParagraph() { | ||||||
|     doTest( |     doTest( | ||||||
|       "gcip", |       "gcip", | ||||||
| @@ -121,6 +132,7 @@ class CommentaryExtensionTest : VimTestCase() { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* Ensure uncommenting works as well */ // |gc| |ip| |   /* Ensure uncommenting works as well */ // |gc| |ip| | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.PLUGIN) | ||||||
|   fun testLineUncommentInnerParagraph() { |   fun testLineUncommentInnerParagraph() { | ||||||
|     doTest( |     doTest( | ||||||
|       "gcip", |       "gcip", | ||||||
| @@ -133,6 +145,7 @@ class CommentaryExtensionTest : VimTestCase() { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   // |gc| |ip| |   // |gc| |ip| | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.PLUGIN) | ||||||
|   fun testLineUncommentSingleLineInnerParagraph() { |   fun testLineUncommentSingleLineInnerParagraph() { | ||||||
|     doTest( |     doTest( | ||||||
|       "gcip", |       "gcip", | ||||||
| @@ -143,6 +156,7 @@ class CommentaryExtensionTest : VimTestCase() { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* Visual mode */ // |gc| |ip| |   /* Visual mode */ // |gc| |ip| | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.PLUGIN) | ||||||
|   fun testLineCommentVisualInnerParagraph() { |   fun testLineCommentVisualInnerParagraph() { | ||||||
|     doTest( |     doTest( | ||||||
|       "vipgc", |       "vipgc", | ||||||
| @@ -154,6 +168,7 @@ class CommentaryExtensionTest : VimTestCase() { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   // |gc| |ip| |   // |gc| |ip| | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.PLUGIN) | ||||||
|   fun testLineUncommentVisualInnerParagraph() { |   fun testLineUncommentVisualInnerParagraph() { | ||||||
|     doTest( |     doTest( | ||||||
|       "vipgc", |       "vipgc", | ||||||
| @@ -165,6 +180,7 @@ class CommentaryExtensionTest : VimTestCase() { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* Special shortcut gcc is always linewise */ // |gcc| |   /* Special shortcut gcc is always linewise */ // |gcc| | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.PLUGIN) | ||||||
|   fun testLineCommentShortcut() { |   fun testLineCommentShortcut() { | ||||||
|     doTest( |     doTest( | ||||||
|       "gccj", |       "gccj", | ||||||
| @@ -177,6 +193,7 @@ class CommentaryExtensionTest : VimTestCase() { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   // |gcc| |   // |gcc| | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.PLUGIN) | ||||||
|   fun testLineCommentShortcutSetsCaretToMotionLocation() { |   fun testLineCommentShortcutSetsCaretToMotionLocation() { | ||||||
|     doTest( |     doTest( | ||||||
|       "gcc", |       "gcc", | ||||||
| @@ -188,6 +205,7 @@ class CommentaryExtensionTest : VimTestCase() { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   // |gcc| |   // |gcc| | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.PLUGIN) | ||||||
|   fun testLineUncommentShortcut() { |   fun testLineUncommentShortcut() { | ||||||
|     doTest( |     doTest( | ||||||
|       "gcc", |       "gcc", | ||||||
| @@ -200,6 +218,7 @@ class CommentaryExtensionTest : VimTestCase() { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   // |gcc| |   // |gcc| | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.PLUGIN) | ||||||
|   fun testHTMLCommentShortcut() { |   fun testHTMLCommentShortcut() { | ||||||
|     doTest( |     doTest( | ||||||
|       "gcc", |       "gcc", | ||||||
| @@ -212,6 +231,7 @@ class CommentaryExtensionTest : VimTestCase() { | |||||||
|     assertSelection(null) |     assertSelection(null) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.PLUGIN) | ||||||
|   fun `test comment motion repeat`() { |   fun `test comment motion repeat`() { | ||||||
|     doTest( |     doTest( | ||||||
|       "gcj" + "jj.", |       "gcj" + "jj.", | ||||||
| @@ -231,6 +251,7 @@ class CommentaryExtensionTest : VimTestCase() { | |||||||
|     ) |     ) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.PLUGIN) | ||||||
|   fun `test comment motion right repeat`() { |   fun `test comment motion right repeat`() { | ||||||
|     doTest( |     doTest( | ||||||
|       "gciw" + "jj.", |       "gciw" + "jj.", | ||||||
| @@ -250,6 +271,7 @@ class CommentaryExtensionTest : VimTestCase() { | |||||||
|     ) |     ) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.PLUGIN) | ||||||
|   fun `test comment line repeat`() { |   fun `test comment line repeat`() { | ||||||
|     doTest( |     doTest( | ||||||
|       "gcc" + "j.", |       "gcc" + "j.", | ||||||
| @@ -266,6 +288,7 @@ class CommentaryExtensionTest : VimTestCase() { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   @VimBehaviorDiffers(description = "IntelliJ's uncomment leaves the leading whitespace") |   @VimBehaviorDiffers(description = "IntelliJ's uncomment leaves the leading whitespace") | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.PLUGIN) | ||||||
|   fun `test uncomment with gcgc`() { |   fun `test uncomment with gcgc`() { | ||||||
|     doTest( |     doTest( | ||||||
|       "gcgc", |       "gcgc", | ||||||
| @@ -286,6 +309,7 @@ class CommentaryExtensionTest : VimTestCase() { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   @VimBehaviorDiffers(description = "IntelliJ's uncomment leaves the leading whitespace") |   @VimBehaviorDiffers(description = "IntelliJ's uncomment leaves the leading whitespace") | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.PLUGIN) | ||||||
|   fun `test uncomment with gcu`() { |   fun `test uncomment with gcu`() { | ||||||
|     doTest( |     doTest( | ||||||
|       "gcu", |       "gcu", | ||||||
| @@ -305,6 +329,7 @@ class CommentaryExtensionTest : VimTestCase() { | |||||||
|     ) |     ) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.PLUGIN) | ||||||
|   fun `test comment line with count`() { |   fun `test comment line with count`() { | ||||||
|     // Caret position is kept as the position *before* the commenting. This is how Vim works |     // Caret position is kept as the position *before* the commenting. This is how Vim works | ||||||
|     doTest( |     doTest( | ||||||
| @@ -329,6 +354,7 @@ class CommentaryExtensionTest : VimTestCase() { | |||||||
|     ) |     ) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.PLUGIN) | ||||||
|   fun `test text object deletes single line comment`() { |   fun `test text object deletes single line comment`() { | ||||||
|     doTest( |     doTest( | ||||||
|       "dgc", |       "dgc", | ||||||
| @@ -343,6 +369,7 @@ class CommentaryExtensionTest : VimTestCase() { | |||||||
|     ) |     ) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.PLUGIN) | ||||||
|   fun `test text object deletes multiple line comments`() { |   fun `test text object deletes multiple line comments`() { | ||||||
|     doTest( |     doTest( | ||||||
|       "dgc", |       "dgc", | ||||||
| @@ -361,6 +388,7 @@ class CommentaryExtensionTest : VimTestCase() { | |||||||
|     ) |     ) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.PLUGIN) | ||||||
|   fun `test text object deletes multiple line comments 2`() { |   fun `test text object deletes multiple line comments 2`() { | ||||||
|     doTest( |     doTest( | ||||||
|       "dgc", |       "dgc", | ||||||
| @@ -379,6 +407,7 @@ class CommentaryExtensionTest : VimTestCase() { | |||||||
|     ) |     ) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.PLUGIN) | ||||||
|   fun `test text object deletes single line comment from leading whitespace`() { |   fun `test text object deletes single line comment from leading whitespace`() { | ||||||
|     doTest( |     doTest( | ||||||
|       "dgc", |       "dgc", | ||||||
| @@ -393,6 +422,7 @@ class CommentaryExtensionTest : VimTestCase() { | |||||||
|     ) |     ) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.PLUGIN) | ||||||
|   fun `test text object deletes single line comment from leading whitespace 2`() { |   fun `test text object deletes single line comment from leading whitespace 2`() { | ||||||
|     doTest( |     doTest( | ||||||
|       "dgc", |       "dgc", | ||||||
| @@ -409,6 +439,7 @@ class CommentaryExtensionTest : VimTestCase() { | |||||||
|     ) |     ) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.PLUGIN) | ||||||
|   fun `test text object deletes single line comment from leading whitespace 3`() { |   fun `test text object deletes single line comment from leading whitespace 3`() { | ||||||
|     doTest( |     doTest( | ||||||
|       "dgc", |       "dgc", | ||||||
| @@ -427,6 +458,7 @@ class CommentaryExtensionTest : VimTestCase() { | |||||||
|     ) |     ) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.PLUGIN) | ||||||
|   fun `test text object deletes single line comment from trailing whitespace`() { |   fun `test text object deletes single line comment from trailing whitespace`() { | ||||||
|     doTest( |     doTest( | ||||||
|       "dgc", |       "dgc", | ||||||
| @@ -444,6 +476,7 @@ class CommentaryExtensionTest : VimTestCase() { | |||||||
|     ) |     ) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.PLUGIN) | ||||||
|   fun `test text object deletes single line comments separated by whitespace`() { |   fun `test text object deletes single line comments separated by whitespace`() { | ||||||
|     doTest( |     doTest( | ||||||
|       "dgc", |       "dgc", | ||||||
| @@ -460,6 +493,7 @@ class CommentaryExtensionTest : VimTestCase() { | |||||||
|     ) |     ) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.PLUGIN) | ||||||
|   fun `test text object deletes disjointed single line comments from whitespace`() { |   fun `test text object deletes disjointed single line comments from whitespace`() { | ||||||
|     doTest( |     doTest( | ||||||
|       "dgc", |       "dgc", | ||||||
| @@ -481,6 +515,7 @@ class CommentaryExtensionTest : VimTestCase() { | |||||||
|         final Int value = 42; |         final Int value = 42; | ||||||
|   """ |   """ | ||||||
|   ) |   ) | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.PLUGIN) | ||||||
|   fun `test text object deletes single line comment from current line`() { |   fun `test text object deletes single line comment from current line`() { | ||||||
|     doTest( |     doTest( | ||||||
|       "dgc", |       "dgc", | ||||||
| @@ -496,6 +531,7 @@ class CommentaryExtensionTest : VimTestCase() { | |||||||
|     ) |     ) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.PLUGIN) | ||||||
|   fun `test text object deletes single line comment from current line 2`() { |   fun `test text object deletes single line comment from current line 2`() { | ||||||
|     doTest( |     doTest( | ||||||
|       "dgc", |       "dgc", | ||||||
| @@ -512,6 +548,7 @@ class CommentaryExtensionTest : VimTestCase() { | |||||||
|     ) |     ) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.PLUGIN) | ||||||
|   fun `test text object does not delete line with comment and text`() { |   fun `test text object does not delete line with comment and text`() { | ||||||
|     doTest( |     doTest( | ||||||
|       "dgc", |       "dgc", | ||||||
| @@ -525,6 +562,7 @@ class CommentaryExtensionTest : VimTestCase() { | |||||||
|     ) |     ) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.PLUGIN) | ||||||
|   fun `test text object deletes block comment`() { |   fun `test text object deletes block comment`() { | ||||||
|     doTest( |     doTest( | ||||||
|       "dgc", |       "dgc", | ||||||
| @@ -539,6 +577,7 @@ class CommentaryExtensionTest : VimTestCase() { | |||||||
|     ) |     ) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.PLUGIN) | ||||||
|   fun `test text object deletes multi-line block comment`() { |   fun `test text object deletes multi-line block comment`() { | ||||||
|     doTest( |     doTest( | ||||||
|       "dgc", |       "dgc", | ||||||
| @@ -555,6 +594,7 @@ class CommentaryExtensionTest : VimTestCase() { | |||||||
|     ) |     ) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.PLUGIN) | ||||||
|   fun `test text object deletes adjoining multi-line block comments`() { |   fun `test text object deletes adjoining multi-line block comments`() { | ||||||
|     doTest( |     doTest( | ||||||
|       "dgc", |       "dgc", | ||||||
| @@ -574,6 +614,7 @@ class CommentaryExtensionTest : VimTestCase() { | |||||||
|     ) |     ) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.PLUGIN) | ||||||
|   fun `test text object deletes adjoining multi-line block comments 2`() { |   fun `test text object deletes adjoining multi-line block comments 2`() { | ||||||
|     doTest( |     doTest( | ||||||
|       "dgc", |       "dgc", | ||||||
| @@ -594,6 +635,7 @@ class CommentaryExtensionTest : VimTestCase() { | |||||||
|     ) |     ) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.PLUGIN) | ||||||
|   fun `test text object does not delete line with text and block comment`() { |   fun `test text object does not delete line with text and block comment`() { | ||||||
|     doTest( |     doTest( | ||||||
|       "dgc", |       "dgc", | ||||||
| @@ -607,6 +649,7 @@ class CommentaryExtensionTest : VimTestCase() { | |||||||
|     ) |     ) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.PLUGIN) | ||||||
|   fun `test text object deletes JavaDoc comment`() { |   fun `test text object deletes JavaDoc comment`() { | ||||||
|     doTest( |     doTest( | ||||||
|       "dgc", |       "dgc", | ||||||
| @@ -627,6 +670,7 @@ class CommentaryExtensionTest : VimTestCase() { | |||||||
|     ) |     ) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.PLUGIN) | ||||||
|   fun `test text object deletes JavaDoc comment from leading whitespace`() { |   fun `test text object deletes JavaDoc comment from leading whitespace`() { | ||||||
|     doTest( |     doTest( | ||||||
|       "dgc", |       "dgc", | ||||||
| @@ -648,6 +692,7 @@ class CommentaryExtensionTest : VimTestCase() { | |||||||
|     ) |     ) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.PLUGIN) | ||||||
|   fun `test text object deletes JavaDoc comment and adjoining comments`() { |   fun `test text object deletes JavaDoc comment and adjoining comments`() { | ||||||
|     doTest( |     doTest( | ||||||
|       "dgc", |       "dgc", | ||||||
| @@ -669,6 +714,7 @@ class CommentaryExtensionTest : VimTestCase() { | |||||||
|     ) |     ) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.PLUGIN) | ||||||
|   fun `test text object deletes JavaDoc comment and adjoining comments separated by whitespace`() { |   fun `test text object deletes JavaDoc comment and adjoining comments separated by whitespace`() { | ||||||
|     doTest( |     doTest( | ||||||
|       "dgc", |       "dgc", | ||||||
| @@ -693,6 +739,7 @@ class CommentaryExtensionTest : VimTestCase() { | |||||||
|     ) |     ) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.PLUGIN) | ||||||
|   fun `test Commentary command comments current line`() { |   fun `test Commentary command comments current line`() { | ||||||
|     doTest( |     doTest( | ||||||
|       ":Commentary<CR>", |       ":Commentary<CR>", | ||||||
| @@ -710,6 +757,7 @@ class CommentaryExtensionTest : VimTestCase() { | |||||||
|     ) |     ) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.PLUGIN) | ||||||
|   fun `test Commentary command comments simple line range`() { |   fun `test Commentary command comments simple line range`() { | ||||||
|     doTest( |     doTest( | ||||||
|       ":2Commentary<CR>", |       ":2Commentary<CR>", | ||||||
| @@ -727,6 +775,7 @@ class CommentaryExtensionTest : VimTestCase() { | |||||||
|     ) |     ) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.PLUGIN) | ||||||
|   fun `test Commentary command comments line range`() { |   fun `test Commentary command comments line range`() { | ||||||
|     doTest( |     doTest( | ||||||
|       ":1,3Commentary<CR>", |       ":1,3Commentary<CR>", | ||||||
| @@ -755,6 +804,7 @@ class CommentaryExtensionTest : VimTestCase() { | |||||||
|       "Note that Escape exits Visual mode, but leaves the caret where it is", |       "Note that Escape exits Visual mode, but leaves the caret where it is", | ||||||
|     shouldBeFixed = true |     shouldBeFixed = true | ||||||
|   ) |   ) | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.PLUGIN) | ||||||
|   fun `test Commentary command comments visual range`() { |   fun `test Commentary command comments visual range`() { | ||||||
|     doTest( |     doTest( | ||||||
|       "Vjj" + ":Commentary<CR>", |       "Vjj" + ":Commentary<CR>", | ||||||
| @@ -772,6 +822,7 @@ class CommentaryExtensionTest : VimTestCase() { | |||||||
|     ) |     ) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.PLUGIN) | ||||||
|   fun `test Commentary command comments search range`() { |   fun `test Commentary command comments search range`() { | ||||||
|     doTest( |     doTest( | ||||||
|       ":g/value2/Commentary<CR>", |       ":g/value2/Commentary<CR>", | ||||||
| @@ -793,6 +844,7 @@ class CommentaryExtensionTest : VimTestCase() { | |||||||
|     ) |     ) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   @TestWithoutNeovim(SkipNeovimReason.PLUGIN) | ||||||
|   fun `test block comment falls back to line comment when not available`() { |   fun `test block comment falls back to line comment when not available`() { | ||||||
|     doTest( |     doTest( | ||||||
|       "gcw", |       "gcw", | ||||||
|   | |||||||
| @@ -18,15 +18,16 @@ | |||||||
|  |  | ||||||
| package org.jetbrains.plugins.ideavim.group.motion | package org.jetbrains.plugins.ideavim.group.motion | ||||||
|  |  | ||||||
| import com.intellij.openapi.editor.ex.util.EditorUtil |  | ||||||
| import com.maddyhome.idea.vim.VimPlugin | import com.maddyhome.idea.vim.VimPlugin | ||||||
| import com.maddyhome.idea.vim.api.injector | import com.maddyhome.idea.vim.api.injector | ||||||
|  | import com.maddyhome.idea.vim.helper.EditorHelper | ||||||
| import com.maddyhome.idea.vim.options.OptionConstants | import com.maddyhome.idea.vim.options.OptionConstants | ||||||
| import com.maddyhome.idea.vim.options.OptionScope | import com.maddyhome.idea.vim.options.OptionScope | ||||||
| import com.maddyhome.idea.vim.vimscript.model.datatypes.VimInt | import com.maddyhome.idea.vim.vimscript.model.datatypes.VimInt | ||||||
| import org.jetbrains.plugins.ideavim.SkipNeovimReason | import org.jetbrains.plugins.ideavim.SkipNeovimReason | ||||||
| import org.jetbrains.plugins.ideavim.TestWithoutNeovim | import org.jetbrains.plugins.ideavim.TestWithoutNeovim | ||||||
| import org.jetbrains.plugins.ideavim.VimTestCase | import org.jetbrains.plugins.ideavim.VimTestCase | ||||||
|  | import kotlin.math.roundToInt | ||||||
|  |  | ||||||
| @Suppress("ClassName") | @Suppress("ClassName") | ||||||
| class MotionGroup_ScrollCaretIntoViewHorizontally_Test : VimTestCase() { | class MotionGroup_ScrollCaretIntoViewHorizontally_Test : VimTestCase() { | ||||||
| @@ -110,7 +111,7 @@ class MotionGroup_ScrollCaretIntoViewHorizontally_Test : VimTestCase() { | |||||||
|     // These columns are hard to calculate, because the visible offset depends on the rendered width of the inlay |     // These columns are hard to calculate, because the visible offset depends on the rendered width of the inlay | ||||||
|     // Also, because we're scrolling right (adding columns to the right) we make the right most column line up |     // Also, because we're scrolling right (adding columns to the right) we make the right most column line up | ||||||
|     val textWidth = myFixture.editor.scrollingModel.visibleArea.width - inlay.widthInPixels |     val textWidth = myFixture.editor.scrollingModel.visibleArea.width - inlay.widthInPixels | ||||||
|     val availableColumns = textWidth / EditorUtil.getPlainSpaceWidth(myFixture.editor) |     val availableColumns = (textWidth / EditorHelper.getPlainSpaceWidthFloat(myFixture.editor)).roundToInt() | ||||||
|     assertVisibleLineBounds(0, 119 - availableColumns + 1, 119) |     assertVisibleLineBounds(0, 119 - availableColumns + 1, 119) | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -185,7 +186,7 @@ class MotionGroup_ScrollCaretIntoViewHorizontally_Test : VimTestCase() { | |||||||
|     typeText(injector.parser.parseKeys("120|zs" + "20h")) |     typeText(injector.parser.parseKeys("120|zs" + "20h")) | ||||||
|     // These columns are hard to calculate, because the visible offset depends on the rendered width of the inlay |     // These columns are hard to calculate, because the visible offset depends on the rendered width of the inlay | ||||||
|     val textWidth = myFixture.editor.scrollingModel.visibleArea.width - inlay.widthInPixels |     val textWidth = myFixture.editor.scrollingModel.visibleArea.width - inlay.widthInPixels | ||||||
|     val availableColumns = textWidth / EditorUtil.getPlainSpaceWidth(myFixture.editor) |     val availableColumns = (textWidth / EditorHelper.getPlainSpaceWidthFloat(myFixture.editor)).roundToInt() | ||||||
|     assertVisibleLineBounds(0, 99, 99 + availableColumns - 1) |     assertVisibleLineBounds(0, 99, 99 + availableColumns - 1) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -23,6 +23,7 @@ import org.jetbrains.plugins.ideavim.SkipNeovimReason | |||||||
| import org.jetbrains.plugins.ideavim.TestWithoutNeovim | import org.jetbrains.plugins.ideavim.TestWithoutNeovim | ||||||
| import org.jetbrains.plugins.ideavim.VimTestCase | import org.jetbrains.plugins.ideavim.VimTestCase | ||||||
| import org.junit.Assert | import org.junit.Assert | ||||||
|  | import kotlin.math.roundToInt | ||||||
|  |  | ||||||
| class EditorHelperTest : VimTestCase() { | class EditorHelperTest : VimTestCase() { | ||||||
|   @TestWithoutNeovim(SkipNeovimReason.NOT_VIM_TESTING) |   @TestWithoutNeovim(SkipNeovimReason.NOT_VIM_TESTING) | ||||||
| @@ -30,8 +31,8 @@ class EditorHelperTest : VimTestCase() { | |||||||
|     configureByColumns(100) |     configureByColumns(100) | ||||||
|     EditorHelper.scrollColumnToLeftOfScreen(myFixture.editor, 0, 2) |     EditorHelper.scrollColumnToLeftOfScreen(myFixture.editor, 0, 2) | ||||||
|     val visibleArea = myFixture.editor.scrollingModel.visibleArea |     val visibleArea = myFixture.editor.scrollingModel.visibleArea | ||||||
|     val columnWidth = visibleArea.width / screenWidth |     val columnWidth = EditorHelper.getPlainSpaceWidthFloat(myFixture.editor) | ||||||
|     Assert.assertEquals(2 * columnWidth, visibleArea.x) |     Assert.assertEquals((2 * columnWidth).roundToInt(), visibleArea.x) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @TestWithoutNeovim(SkipNeovimReason.NOT_VIM_TESTING) |   @TestWithoutNeovim(SkipNeovimReason.NOT_VIM_TESTING) | ||||||
| @@ -40,8 +41,8 @@ class EditorHelperTest : VimTestCase() { | |||||||
|     val column = screenWidth + 2 |     val column = screenWidth + 2 | ||||||
|     EditorHelper.scrollColumnToRightOfScreen(myFixture.editor, 0, column) |     EditorHelper.scrollColumnToRightOfScreen(myFixture.editor, 0, column) | ||||||
|     val visibleArea = myFixture.editor.scrollingModel.visibleArea |     val visibleArea = myFixture.editor.scrollingModel.visibleArea | ||||||
|     val columnWidth = visibleArea.width / screenWidth |     val columnWidth = EditorHelper.getPlainSpaceWidthFloat(myFixture.editor) | ||||||
|     Assert.assertEquals((column - screenWidth + 1) * columnWidth, visibleArea.x) |     Assert.assertEquals(((column - screenWidth + 1) * columnWidth).roundToInt(), visibleArea.x) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @TestWithoutNeovim(SkipNeovimReason.NOT_VIM_TESTING) |   @TestWithoutNeovim(SkipNeovimReason.NOT_VIM_TESTING) | ||||||
| @@ -52,8 +53,8 @@ class EditorHelperTest : VimTestCase() { | |||||||
|     // Put column 100 into position 41 -> offset is 59 columns |     // Put column 100 into position 41 -> offset is 59 columns | ||||||
|     EditorHelper.scrollColumnToMiddleOfScreen(myFixture.editor, 0, 99) |     EditorHelper.scrollColumnToMiddleOfScreen(myFixture.editor, 0, 99) | ||||||
|     val visibleArea = myFixture.editor.scrollingModel.visibleArea |     val visibleArea = myFixture.editor.scrollingModel.visibleArea | ||||||
|     val columnWidth = visibleArea.width / screenWidth |     val columnWidth = EditorHelper.getPlainSpaceWidthFloat(myFixture.editor) | ||||||
|     Assert.assertEquals(59 * columnWidth, visibleArea.x) |     Assert.assertEquals((59 * columnWidth).roundToInt(), visibleArea.x) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @TestWithoutNeovim(SkipNeovimReason.NOT_VIM_TESTING) |   @TestWithoutNeovim(SkipNeovimReason.NOT_VIM_TESTING) | ||||||
| @@ -65,7 +66,7 @@ class EditorHelperTest : VimTestCase() { | |||||||
|     // Put column 100 into position 41 -> offset is 59 columns |     // Put column 100 into position 41 -> offset is 59 columns | ||||||
|     EditorHelper.scrollColumnToMiddleOfScreen(myFixture.editor, 0, 99) |     EditorHelper.scrollColumnToMiddleOfScreen(myFixture.editor, 0, 99) | ||||||
|     val visibleArea = myFixture.editor.scrollingModel.visibleArea |     val visibleArea = myFixture.editor.scrollingModel.visibleArea | ||||||
|     val columnWidth = visibleArea.width / screenWidth |     val columnWidth = EditorHelper.getPlainSpaceWidthFloat(myFixture.editor) | ||||||
|     Assert.assertEquals(59 * columnWidth, visibleArea.x) |     Assert.assertEquals((59 * columnWidth).roundToInt(), visibleArea.x) | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -20,11 +20,14 @@ package org.jetbrains.plugins.ideavim.longrunning | |||||||
|  |  | ||||||
| import com.intellij.testFramework.PlatformTestUtil | import com.intellij.testFramework.PlatformTestUtil | ||||||
| import com.maddyhome.idea.vim.api.injector | import com.maddyhome.idea.vim.api.injector | ||||||
|  | import org.jetbrains.plugins.ideavim.SkipNeovimReason | ||||||
|  | import org.jetbrains.plugins.ideavim.TestWithoutNeovim | ||||||
| import org.jetbrains.plugins.ideavim.VimTestCase | import org.jetbrains.plugins.ideavim.VimTestCase | ||||||
|  |  | ||||||
| class MacroTest : VimTestCase() { | class MacroTest : VimTestCase() { | ||||||
|  |  | ||||||
|   // was a problem on revision affec9bb61ea5e1e635673a0041d61f7af3722b2 |   // was a problem on revision affec9bb61ea5e1e635673a0041d61f7af3722b2 | ||||||
|  |   @TestWithoutNeovim(reason = SkipNeovimReason.NOT_VIM_TESTING) | ||||||
|   fun `test no StackOverflowException`() { |   fun `test no StackOverflowException`() { | ||||||
|     configureByText("abc de${c}fg") |     configureByText("abc de${c}fg") | ||||||
|     typeText(injector.parser.parseKeys("qahlq")) |     typeText(injector.parser.parseKeys("qahlq")) | ||||||
|   | |||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user