1
0
mirror of https://github.com/chylex/IntelliJ-IdeaVim.git synced 2025-09-15 17:32:14 +02:00

Compare commits

...

82 Commits

Author SHA1 Message Date
aleksei.plate
86bf723791 TeamCity change in 'IntelliJ IDEA plugins / IdeaVim' project: runners of 'Qodana checks' build configuration were updated 2022-07-20 11:36:12 +00:00
Alex Plate
71f2e9de4a Update changelog 2022-07-20 08:20:43 +00:00
Alex Plate
33d3f270a3 Fix(VIM-2710): Show options value on set opt 2022-07-20 09:56:23 +03:00
filipp
da94edd386 Fix(VIM-2703) 2022-07-20 02:51:45 +06:00
Alex Plate
90dfaefd11 Update formatting 2022-07-17 00:17:41 +00:00
Alex Plate
8bc616cc55 New vim behaviour: ci( searches for brackets
Change in vim:
b9115da4be
https://github.com/vim/vim/pull/8670

VIM-2699
2022-07-14 12:08:26 +03:00
aleksei.plate
a9e79d62c5 TeamCity change in 'IntelliJ IDEA plugins / IdeaVim' project: runners of 'Qodana checks' build configuration were updated 2022-07-13 11:55:31 +00:00
Alex Plate
1998221a0b Remove useless @NotNull annotations 2022-07-13 10:26:57 +03:00
Alex Plate
a9b1625749 Update deprecated action listeners 2022-07-13 10:26:16 +03:00
Alex Plate
b411836570 Hide macos notification during UI testing 2022-07-13 09:23:35 +03:00
Alex Plate
df7e0221a8 Update qodana baseline 2022-07-11 14:10:08 +03:00
aleksei.plate
8ff8f2b685 TeamCity change in 'IntelliJ IDEA plugins / IdeaVim' project: runners of 'Qodana checks' build configuration were updated 2022-07-11 10:00:37 +00:00
aleksei.plate
65dea7e3f7 TeamCity change in 'IntelliJ IDEA plugins / IdeaVim' project: runners of 'Qodana checks' build configuration were updated 2022-07-11 09:45:28 +00:00
aleksei.plate
1942f86633 TeamCity change in 'IntelliJ IDEA plugins / IdeaVim / IdeaVim releases' project: build features of 'Publish EAP Build' build configuration were updated 2022-07-11 08:29:56 +00:00
Alex Plate
ee4ce5033a Fix tests 2022-07-11 11:09:43 +03:00
Alex Plate
040fe806c8 Update release versions of IJ 2022-07-11 09:28:39 +03:00
Alex Plate
97f5c9225e Cleanup the sources 2022-07-08 11:24:10 +03:00
Alex Plate
09b86c15f9 Fix missing space 2022-07-08 10:59:02 +03:00
Alex Plate
8f34285d8c Fix issues with notations 2022-07-08 10:55:21 +03:00
Alex Plate
d3c3b71e3e Remove unnecessary libraries from the distribution 2022-07-08 10:29:51 +03:00
Alex Plate
aa6f49c9b1 Reformat code 2022-07-08 10:00:00 +03:00
Alex Plate
c011628420 Reformat code 2022-07-08 09:14:43 +03:00
Alex Plate
1c9fa9d662 Skip one test in multicaret 2022-07-07 16:32:14 +03:00
Alex Plate
7b9bc64364 Fix multicaret insert 2022-07-07 14:54:41 +03:00
Alex Plate
729062bfdd Turn on ideadelaymacro by default 2022-07-07 14:36:04 +03:00
Alex Plate
bc6c726a45 Fix macro with count execution 2022-07-07 14:35:49 +03:00
Alex Plate
dfc3df713e Update changelog 2022-07-07 12:22:46 +03:00
Alex Plate
42eca1d5f2 Apply TC patches 2022-07-07 11:20:10 +03:00
Alex Plate
66245e2730 Change secret for the merge PR action 2022-07-07 10:42:27 +03:00
aleksei.plate
d44b82c1d1 TeamCity change in 'IntelliJ IDEA plugins / IdeaVim' project: 'Plugin verification' build configuration settings were updated 2022-07-07 07:12:38 +00:00
aleksei.plate
5440e48fa3 TeamCity change in 'IntelliJ IDEA plugins / IdeaVim' project: 'Tests for IntelliJ 2021.3' build configuration was moved to 'IntelliJ IDEA plugins / IdeaVim / Old IdeaVim tests' project 2022-07-07 07:11:51 +00:00
aleksei.plate
1c513cf8aa TeamCity change in 'IntelliJ IDEA plugins / IdeaVim' project: VCS roots of 'Tests for IntelliJ 2021.3' build configuration were updated 2022-07-07 07:11:26 +00:00
aleksei.plate
a17c4b8d43 TeamCity change in 'IntelliJ IDEA plugins / IdeaVim' project: VCS roots of 'Tests for IntelliJ 2021.3' build configuration were updated 2022-07-07 07:11:07 +00:00
aleksei.plate
15eb4ac278 TeamCity change in 'IntelliJ IDEA plugins / IdeaVim' project: 'https://github.com/JetBrains/ideavim (branch 213-221)' VCS root was created 2022-07-07 07:06:47 +00:00
Alex Plate
0d9b81eab3 Update minimal version of IJ 2022-07-07 10:02:14 +03:00
Alex Plate
f02e1a20c7 Create test update job 2022-07-06 21:23:48 +03:00
Alex Plate
a11991dad7 Create test token 2022-07-06 21:21:51 +03:00
Alex Plate
1238828bfd Update token name 2022-07-06 21:18:27 +03:00
Alex Plate
ba409cb24c Add some logging to update after PR job 2022-07-06 21:06:00 +03:00
Alex Plate
d597670275 Update changelog after merging PR 2022-07-06 17:58:16 +00:00
Alex Pláte
d8540e95f8 Create gradle.properties 2022-07-06 20:56:49 +03:00
Alex Plate
d35ebf00dd Add qodana baseline to the project (I guess) 2022-07-06 20:43:40 +03:00
Alex Plate
2b32cb26b1 Set since version in config 2022-07-06 20:39:30 +03:00
aleksei.plate
ca95fcb658 TeamCity change in 'IntelliJ IDEA plugins / IdeaVim' project: runners of 'Tests with nvim' build configuration were updated 2022-07-06 17:32:40 +00:00
aleksei.plate
cc18bbd168 TeamCity change in 'IntelliJ IDEA plugins / IdeaVim' project: 'Tests with nvim' build configuration settings were updated 2022-07-06 17:09:16 +00:00
Alex Plate
8c8ea800cb Update neovim tests 2022-07-06 20:06:02 +03:00
Alex Plate
0746dcc686 Fix some neovim tests 2022-07-06 19:41:05 +03:00
Alex Plate
930650be9d Add lippfi to contributors list 2022-07-06 07:36:26 +00:00
Alex Plate
4e3a9ffa40 Add unchecked email 2022-07-06 10:34:31 +03:00
filipp
3bf68a2bb8 Update formatting 2022-07-06 13:11:11 +06:00
Alex Plate
a80f6feab0 Update changelog 2022-07-06 09:30:25 +03:00
Alex Plate
3cf8ae52ed Add link to the docs 2022-07-06 09:30:25 +03:00
Matt Ellis
62632a4514 Improve handling of fractional width fonts 2022-07-06 09:29:36 +03:00
Alex Plate
249bd3778a Add a note about refactoring 2022-07-06 09:14:52 +03:00
filipp
ab9e5d7a4a Fix selection issue with oldundo set 2022-07-06 12:12:55 +06:00
filipp
083b7dc952 Fix(VIM-2698) Undo causes confirmation dialog to reappear forever 2022-07-06 11:35:29 +06:00
Alex Plate
1791692d92 Use java boolean 2022-07-05 12:26:16 +03:00
Alex Plate
ba23c9ab5e Rename variable service 2022-07-05 11:27:53 +03:00
Alex Plate
f96ab37bcb Rename Scope 2022-07-05 11:04:08 +03:00
Alex Plate
0da34bbb34 Compatibility of toggleOption 2022-07-05 10:56:45 +03:00
Alex Plate
51e7c745ea Move number option to a different package 2022-07-05 10:26:14 +03:00
aleksei.plate
8347251572 TeamCity change in 'IntelliJ IDEA plugins / IdeaVim' project: triggers of 'IdeaVim compatibility with external plugins' build configuration were updated 2022-07-05 07:13:58 +00:00
aleksei.plate
ce8512f4e0 TeamCity change in 'IntelliJ IDEA plugins / IdeaVim' project: triggers of 'IdeaVim compatibility with external plugins' build configuration were updated 2022-07-05 07:13:22 +00:00
aleksei.plate
a724a19d00 TeamCity change in 'IntelliJ IDEA plugins / IdeaVim' project: triggers of 'IdeaVim compatibility with external plugins' build configuration were updated 2022-07-05 07:13:00 +00:00
Alex Plate
7eae7a98e8 Command state compatibility 2022-07-05 10:05:02 +03:00
Alex Plate
fe9566eebd Convert helper to kt 2022-07-04 10:59:24 +03:00
Alex Plate
b69756730f Rename .java to .kt 2022-07-04 10:59:23 +03:00
Alex Plate
6cd1a60b53 More compatibility 2022-07-04 10:33:31 +03:00
Alex Plate
9d935e47b5 Move compatibility 2022-07-04 09:49:50 +03:00
Alex Plate
a7d5372d06 Move classes to a different package 2022-07-04 09:49:50 +03:00
Alex Plate
a575942c81 Compatibility 2022-07-04 09:49:50 +03:00
aleksei.plate
3cf6c53a8e TeamCity change in 'IntelliJ IDEA plugins / IdeaVim' project: runners of 'IdeaVim compatibility with external plugins' build configuration were updated 2022-07-04 06:40:47 +00:00
aleksei.plate
91d86680de TeamCity change in 'IntelliJ IDEA plugins / IdeaVim' project: runners of 'IdeaVim compatibility with external plugins' build configuration were updated 2022-07-04 06:22:54 +00:00
aleksei.plate
d1d082fb99 TeamCity change in 'IntelliJ IDEA plugins / IdeaVim' project: runners of 'IdeaVim compatibility with external plugins' build configuration were updated 2022-07-04 06:15:19 +00:00
aleksei.plate
2c634d1bf0 TeamCity change in 'IntelliJ IDEA plugins / IdeaVim' project: runners of 'IdeaVim compatibility with external plugins' build configuration were updated 2022-07-04 06:06:43 +00:00
aleksei.plate
02a6fe4dc9 TeamCity change in 'IntelliJ IDEA plugins / IdeaVim' project: runners of 'IdeaVim compatibility with external plugins' build configuration were updated 2022-07-04 06:03:46 +00:00
aleksei.plate
223d681526 TeamCity change in 'IntelliJ IDEA plugins / IdeaVim' project: VCS roots of 'IdeaVim compatibility with external plugins' build configuration were updated 2022-07-04 06:03:33 +00:00
aleksei.plate
f42ef1c2fc TeamCity change in 'IntelliJ IDEA plugins / IdeaVim' project: VCS roots of 'IdeaVim compatibility with external plugins' build configuration were updated 2022-07-04 06:03:27 +00:00
Alex Plate
f4817b2111 Add compatibility verifier to the repo 2022-07-04 08:59:31 +03:00
Alex Plate
6f5def0abf Update formatting 2022-07-03 00:19:25 +00:00
filipp
f0fcd7f133 Better offset for multiple carets with surround 2022-07-02 18:59:21 +06:00
filipp
6115adb72e Add registers to carets 2022-07-02 18:51:10 +06:00
380 changed files with 87342 additions and 5291 deletions

View File

@@ -4,6 +4,7 @@
name: Update Changelog On PR
on:
workflow_dispatch:
pull_request:
types: [ closed ]
@@ -29,7 +30,7 @@ jobs:
id: update_authors
run: ./gradlew updateMergedPr -PprId=${{ github.event.number }}
env:
GITHUB_OAUTH: ${{ secrets.AUTOMATION_TOKEN }}
GITHUB_OAUTH: ${{ secrets.MERGE_PR }}
- name: Commit changes
uses: stefanzweifel/git-auto-commit-action@v4

40
.github/workflows/mergePrTest.yml vendored Normal file
View 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

View File

@@ -37,7 +37,7 @@ jobs:
run: ./gradlew updateAuthors --stacktrace
env:
SUCCESS_COMMIT: ${{ steps.last_successful_commit.outputs.commit_hash }}
GITHUB_OAUTH: ${{ secrets.AUTOMATION_TOKEN }}
GITHUB_OAUTH: ${{ secrets.GITHUB_TOKEN }}
- name: Commit changes
uses: stefanzweifel/git-auto-commit-action@v4

View File

@@ -13,11 +13,8 @@ object Constants {
const val PROPERTY_TESTS = "LATEST-EAP-SNAPSHOT"
const val LONG_RUNNING_TESTS = "LATEST-EAP-SNAPSHOT"
const val QODANA_TESTS = "LATEST-EAP-SNAPSHOT"
const val RELEASE = "2022.1.3"
const val RELEASE = "LATEST-EAP-SNAPSHOT"
// Use LATEST-EAP-SNAPSHOT only when we'll update the minimum version of IJ to 222+
// 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"
const val RELEASE_DEV = "LATEST-EAP-SNAPSHOT"
const val RELEASE_EAP = "LATEST-EAP-SNAPSHOT"
}

View File

@@ -1,6 +1,12 @@
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.OldTests
import _Self.subprojects.Releases
@@ -10,6 +16,7 @@ import _Self.vcsRoots.Branch_191_193
import _Self.vcsRoots.Branch_201
import _Self.vcsRoots.Branch_202
import _Self.vcsRoots.Branch_203_212
import _Self.vcsRoots.Branch_213_221
import _Self.vcsRoots.Branch_Release
import _Self.vcsRoots.GitHubPullRequest
import jetbrains.buildServer.configs.kotlin.v2019_2.Project
@@ -26,11 +33,11 @@ object Project : Project({
vcsRoot(Branch_201)
vcsRoot(Branch_202)
vcsRoot(Branch_203_212)
vcsRoot(Branch_213_221)
vcsRoot(Branch_Release)
vcsRoot(GitHubPullRequest)
// Builds
buildType(TestsForIntelliJ20213)
buildType(TestsForIntelliJEAP)
buildType(PropertyBased)
@@ -38,6 +45,7 @@ object Project : Project({
buildType(Nvim)
buildType(PluginVerifier)
buildType(Compatibility)
buildType(Qodana)
@@ -47,7 +55,7 @@ object Project : Project({
type = "CloudImage"
id = "PROJECT_EXT_768"
param("agent_pool_id", "41")
param("amazon-id", "ami-0d1a6a32faa92923e")
param("amazon-id", "ami-0fa17ce8238eb8868")
param("ebs-optimized", "false")
param("image-instances-limit", "")
param("image-name-prefix", "BuildAgentsIdeaVim")

View File

@@ -55,4 +55,4 @@ sealed class ActiveTests(buildName: String, ijVersion: String) : BuildType({
})
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")

View File

@@ -0,0 +1,49 @@
package _Self.buildTypes
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.buildSteps.script
import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.schedule
object Compatibility : BuildType({
id("IdeaVimCompatibility")
name = "IdeaVim compatibility with external plugins"
vcs {
root(DslContext.settingsRoot)
}
steps {
script {
name = "Check"
scriptContent = """
java -jar verifier/verifier-cli-dev-all.jar check-plugin '${'$'}org.jetbrains.IdeaVim-EasyMotion' [latest-IU] -team-city
java -jar verifier/verifier-cli-dev-all.jar check-plugin '${'$'}io.github.mishkun.ideavimsneak' [latest-IU] -team-city
java -jar verifier/verifier-cli-dev-all.jar check-plugin '${'$'}eu.theblob42.idea.whichkey' [latest-IU] -team-city
java -jar verifier/verifier-cli-dev-all.jar check-plugin '${'$'}IdeaVimExtension' [latest-IU] -team-city
# Outdated java -jar verifier/verifier-cli-dev-all.jar check-plugin '${'$'}github.zgqq.intellij-enhance' [latest-IU] -team-city
java -jar verifier/verifier-cli-dev-all.jar check-plugin '${'$'}com.github.copilot' [latest-IU] -team-city
java -jar verifier/verifier-cli-dev-all.jar check-plugin '${'$'}com.github.dankinsoid.multicursor' [latest-IU] -team-city
java -jar verifier/verifier-cli-dev-all.jar check-plugin '${'$'}com.joshestein.ideavim-quickscope' [latest-IU] -team-city
""".trimIndent()
}
}
triggers {
schedule {
schedulingPolicy = daily {
hour = 4
}
branchFilter = ""
triggerBuild = always()
withPendingChangesOnly = false
}
}
features {
golang {
testFormat = "json"
}
}
})

View File

@@ -31,7 +31,7 @@ object Nvim : BuildType({
script {
name = "Set up NeoVim"
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
cd nvim-linux64/bin
chmod +x nvim

View File

@@ -4,6 +4,7 @@ import _Self.Constants.QODANA_TESTS
import jetbrains.buildServer.configs.kotlin.v2019_2.BuildType
import jetbrains.buildServer.configs.kotlin.v2019_2.CheckoutMode
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.failureConditions.BuildFailureOnMetric
import jetbrains.buildServer.configs.kotlin.v2019_2.failureConditions.failOnMetricChange
@@ -46,12 +47,15 @@ object Qodana : BuildType({
param("clonefinder-enable", "true")
param("clonefinder-reference-projects", "src")
param("yaml-configuration", "")
linter = jvm {
version = Qodana.JVMVersion.LATEST
}
}
}
triggers {
vcs {
enabled = false
enabled = true
branchFilter = ""
}
schedule {

View 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")

View File

@@ -11,6 +11,7 @@ import _Self.buildTypes.TestsForIntelliJ20202
import _Self.buildTypes.TestsForIntelliJ20203
import _Self.buildTypes.TestsForIntelliJ20211
import _Self.buildTypes.TestsForIntelliJ20212
import _Self.buildTypes.TestsForIntelliJ20213
import jetbrains.buildServer.configs.kotlin.v2019_2.Project
object OldTests : Project({
@@ -28,4 +29,5 @@ object OldTests : Project({
buildType(TestsForIntelliJ20203)
buildType(TestsForIntelliJ20211)
buildType(TestsForIntelliJ20212)
buildType(TestsForIntelliJ20213)
})

View 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"
})

View File

@@ -1,40 +0,0 @@
package patches.buildTypes
import jetbrains.buildServer.configs.kotlin.v2019_2.*
import jetbrains.buildServer.configs.kotlin.v2019_2.BuildType
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.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, create a buildType with id = 'Build'
in the root project, and delete the patch script.
*/
create(DslContext.projectId, BuildType({
id("Build")
name = "IdeaVim compatibility with external plugins"
vcs {
root(RelativeId("HttpsGithubComAlexPl292IdeaVimCompatibilityRefsHeadsMaster"))
}
steps {
script {
scriptContent = "go run test.go"
}
}
triggers {
vcs {
}
}
features {
golang {
testFormat = "json"
}
}
}))

View File

@@ -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
}
}
}

View File

@@ -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
}
}
}

View File

@@ -2,9 +2,8 @@ package patches.buildTypes
import jetbrains.buildServer.configs.kotlin.v2019_2.*
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.Qodana
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.gradle
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.qodana
import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.ScheduleTrigger
import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.schedule
import jetbrains.buildServer.configs.kotlin.v2019_2.ui.*
/*
@@ -16,6 +15,9 @@ changeBuildType(RelativeId("Qodana")) {
expectSteps {
qodana {
name = "Qodana"
linter = jvm {
version = Qodana.JVMVersion.LATEST
}
param("clonefinder-enable", "true")
param("clonefinder-languages", "Java")
param("clonefinder-languages-container", "Java Kotlin")
@@ -29,27 +31,25 @@ changeBuildType(RelativeId("Qodana")) {
}
}
steps {
update<Qodana>(0) {
insert(0) {
gradle {
name = "Generate grammar"
tasks = "generateGrammarSource"
param("org.jfrog.artifactory.selectedDeployableServer.defaultModuleVersionConfiguration", "GLOBAL")
}
}
update<Qodana>(1) {
clearConditions()
linter = jvm {
version = Qodana.JVMVersion.LATEST
}
}
}
triggers {
val trigger1 = find<ScheduleTrigger> {
schedule {
schedulingPolicy = weekly {
dayOfWeek = ScheduleTrigger.DAY.Tuesday
}
branchFilter = ""
triggerBuild = always()
}
}
trigger1.apply {
enabled = false
reportAsTests = true
argumentsCommandDocker = "-e QODANA_TOKEN=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJvcmdhbml6YXRpb24iOiIzUFZrQSIsInByb2plY3QiOiIzN1FlQSIsInRva2VuIjoiM0t2bXoifQ.uohp81tM7iAfvvB6k8faarfpV-OjusAaEbWQ8iNrOgs"
argumentsEntryPointDocker = "--baseline qodana.sarif.json"
param("clonefinder-languages", "")
param("collect-anonymous-statistics", "")
param("licenseaudit-enable", "")
param("clonefinder-languages-container", "")
param("clonefinder-queried-project", "")
param("clonefinder-enable", "")
param("clonefinder-reference-projects", "")
}
}
}

View 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
}
}
}

View File

@@ -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
}
}
}

View File

@@ -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")
}))

View File

@@ -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")
}))

View File

@@ -416,6 +416,10 @@ Contributors:
[![icon][github]](https://github.com/Vvalter)
&nbsp;
Simon Rainer
* [![icon][mail]](mailto:filipp.vakhitov@jetbrains.com)
[![icon][github]](https://github.com/lippfi)
&nbsp;
lippfi
If you are a contributor and your name is not listed here, feel free to
contact the maintainers.

View File

@@ -36,6 +36,7 @@ usual beta standards.
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,
the mapping will actually be unmapped.
* New vim (and IdeaVim) behaviour: `ci(`& friends searches for the brackets in the line.
### Fixes:
* [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-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-2710](https://youtrack.jetbrains.com/issue/VIM-2710) Show options value on `set opt`
### Merged PRs:
* [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
* [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
* [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

View File

@@ -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!
: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
@@ -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.
- 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.

View File

@@ -28,7 +28,7 @@ plugins {
id("org.jetbrains.changelog") version "1.3.1"
// ktlint linter - read more: https://github.com/JLLeitschuh/ktlint-gradle
id("org.jlleitschuh.gradle.ktlint") version "10.2.1"
id("org.jlleitschuh.gradle.ktlint") version "10.3.0"
}
// Import variables from gradle.properties file
@@ -71,6 +71,8 @@ dependencies {
antlr("org.antlr:antlr4:$antlrVersion")
api(project(":vim-engine"))
testApi("com.squareup.okhttp3:okhttp:4.10.0")
}
configurations {
@@ -85,6 +87,8 @@ tasks.register<Test>("testWithNeovim") {
group = "verification"
systemProperty("ideavim.nvim.test", "true")
exclude("/ui/**")
exclude("**/longrunning/**")
exclude("**/propertybased/**")
}
tasks.register<Test>("testPropertyBased") {
@@ -115,6 +119,8 @@ tasks {
include("**/*test.class")
include("**/*Tests.class")
exclude("**/ParserTest.class")
exclude("**/longrunning/**")
exclude("**/propertybased/**")
}
val testPropertyBased by getting(Test::class) {
@@ -144,7 +150,7 @@ tasks {
compileKotlin {
kotlinOptions {
jvmTarget = javaVersion
apiVersion = "1.5"
apiVersion = "1.6"
freeCompilerArgs = listOf("-Xjvm-default=all-compatibility")
// allWarningsAsErrors = true
}
@@ -152,7 +158,7 @@ tasks {
compileTestKotlin {
kotlinOptions {
jvmTarget = javaVersion
apiVersion = "1.5"
apiVersion = "1.6"
// allWarningsAsErrors = true
}
}
@@ -200,7 +206,7 @@ tasks {
runPluginVerifier {
downloadDir.set("${project.buildDir}/pluginVerifier/ides")
teamCityOutputFormat.set(true)
ideVersions.set(listOf("IC-2021.3.4"))
// ideVersions.set(listOf("IC-2021.3.4"))
}
generateGrammarSource {
@@ -231,12 +237,18 @@ tasks {
dependsOn(createOpenApiSourceJar)
from(createOpenApiSourceJar) { into("lib/src") }
}
// Don't forget to update plugin.xml
patchPluginXml {
sinceBuild.set("222")
}
}
// --- Linting
ktlint {
disabledRules.add("no-wildcard-imports")
version.set("0.43.0")
}
// --- Tests
@@ -327,7 +339,8 @@ tasks.register("updateAuthors") {
"aleksei.plate@jetbrains.com",
"aleksei.plate@teamcity",
"aleksei.plate@TeamCity",
"alex.plate@192.168.0.109"
"alex.plate@192.168.0.109",
"nikita.koshcheev@TeamCity",
)
updateAuthors(uncheckedEmails)
}
@@ -338,6 +351,7 @@ val prId: String by project
tasks.register("updateMergedPr") {
doLast {
if (project.hasProperty("prId")) {
println("Got pr id: $prId")
updateMergedPr(prId.toInt())
} else {
error("Cannot get prId")
@@ -501,7 +515,9 @@ data class Change(val id: String, val text: String)
fun updateMergedPr(number: Int) {
val gitHub = org.kohsuke.github.GitHub.connect()
println("Connecting to the repo...")
val repository = gitHub.getRepository("JetBrains/ideavim")
println("Getting pull requests...")
val pullRequest = repository.getPullRequest(number)
if (pullRequest.user.login == "dependabot[bot]") return

View File

@@ -5,9 +5,10 @@ downloadIdeaSources=true
instrumentPluginCode=true
version=SNAPSHOT
javaVersion=11
remoteRobotVersion=0.11.10
remoteRobotVersion=0.11.15
antlrVersion=4.10.1
# Please don't forget to update kotlin version in buildscript section
kotlinVersion=1.6.21
publishToken=token

79982
qodana.sarif.json Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -101,12 +101,6 @@ public class EventFacade {
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) {
editor.addEditorMouseListener(listener);
}

View File

@@ -19,8 +19,6 @@ package com.maddyhome.idea.vim;
import com.intellij.ide.plugins.IdeaPluginDescriptor;
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.application.Application;
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.ex.KeymapManagerEx;
import com.intellij.openapi.keymap.impl.DefaultKeymap;
import com.intellij.openapi.options.ShowSettingsUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.SystemInfo;
import com.maddyhome.idea.vim.api.VimInjectorKt;
import com.maddyhome.idea.vim.api.VimKeyGroup;
@@ -48,20 +46,17 @@ import com.maddyhome.idea.vim.group.visual.VisualMotionGroup;
import com.maddyhome.idea.vim.helper.MacKeyRepeat;
import com.maddyhome.idea.vim.listener.VimListenerManager;
import com.maddyhome.idea.vim.newapi.IjVimInjector;
import com.maddyhome.idea.vim.options.OptionService;
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.vimscript.services.FunctionStorage;
import com.maddyhome.idea.vim.vimscript.services.IjVimOptionService;
import com.maddyhome.idea.vim.vimscript.services.VimVariableService;
import com.maddyhome.idea.vim.vimscript.services.OptionService;
import com.maddyhome.idea.vim.vimscript.services.VariableService;
import org.jdom.Element;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
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.KeyGroup.SHORTCUT_CONFLICTS_ELEMENT;
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();
public Disposable onOffDisposable;
VimPlugin() {
ApplicationConfigurationMigrator.getInstance().migrate();
}
@@ -226,8 +223,8 @@ public class VimPlugin implements PersistentStateComponent<Element>, Disposable
return (PutGroup)VimInjectorKt.getInjector().getPut();
}
public static @NotNull VimVariableService getVariableService() {
return ApplicationManager.getApplication().getService(VimVariableService.class);
public static @NotNull VariableService getVariableService() {
return ApplicationManager.getApplication().getService(VariableService.class);
}
public static @NotNull OptionService getOptionService() {
@@ -341,6 +338,8 @@ public class VimPlugin implements PersistentStateComponent<Element>, Disposable
* execution, what theoretically may cause bugs (e.g. VIM-2540)
*/
private void turnOnPlugin() {
onOffDisposable = Disposer.newDisposable(this, "IdeaVimOnOffDisposer");
// 1) Update state
ApplicationManager.getApplication().invokeLater(this::updateState);
@@ -376,6 +375,8 @@ public class VimPlugin implements PersistentStateComponent<Element>, Disposable
// Unregister vim actions in command mode
RegisterActions.unregisterActions();
Disposer.dispose(onOffDisposable);
}
private boolean stateUpdated = false;
@@ -389,7 +390,9 @@ public class VimPlugin implements PersistentStateComponent<Element>, Disposable
final Boolean enabled = keyRepeat.isEnabled();
final Boolean isKeyRepeat = getEditor().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);
keyRepeat.setEnabled(true);
}
@@ -408,12 +411,6 @@ public class VimPlugin implements PersistentStateComponent<Element>, Disposable
keymap = manager.getKeymap(DefaultKeymap.getInstance().getDefaultKeymapName());
}
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);
}
if (previousStateVersion > 0 && previousStateVersion < 4) {

View File

@@ -34,8 +34,8 @@ import com.maddyhome.idea.vim.group.visual.VimSelection
import com.maddyhome.idea.vim.handler.VimActionHandler
import com.maddyhome.idea.vim.handler.VisualOperatorActionHandler
import com.maddyhome.idea.vim.helper.MessageHelper
import com.maddyhome.idea.vim.helper.vimStateMachine
import com.maddyhome.idea.vim.helper.enumSetOf
import com.maddyhome.idea.vim.helper.vimStateMachine
import com.maddyhome.idea.vim.newapi.ij
import java.util.*

View File

@@ -45,7 +45,7 @@ class DeleteJoinLinesAction : ChangeEditorActionHandler.SingleExecution() {
val res = arrayOf(true)
editor.forEachNativeCaret(
{ 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
)

View File

@@ -45,7 +45,7 @@ class DeleteJoinLinesSpacesAction : ChangeEditorActionHandler.SingleExecution()
val res = arrayOf(true)
editor.forEachNativeCaret(
{ 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
)

View File

@@ -57,7 +57,14 @@ class DeleteJoinVisualLinesAction : VisualOperatorActionHandler.SingleExecution(
caret: VimCaret ->
if (!caret.isValid) 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
}
}, true

View File

@@ -56,7 +56,14 @@ class DeleteJoinVisualLinesSpacesAction : VisualOperatorActionHandler.SingleExec
{ caret: VimCaret ->
if (!caret.isValid) 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
}
},

View File

@@ -18,6 +18,7 @@
package com.maddyhome.idea.vim.action.internal
import com.intellij.ide.ui.AntialiasingType
import com.intellij.ide.ui.UISettings
import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.CommonDataKeys
@@ -124,7 +125,7 @@ class AddBlockInlaysAction : AnAction() {
val editorContext = FontInfo.getFontRenderContext(editor.contentComponent)
return FontRenderContext(
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
)
}

View File

@@ -24,12 +24,22 @@ import com.maddyhome.idea.vim.newapi.vim
/**
* COMPATIBILITY-LAYER: Additional class
* Please see: https://jb.gg/zo8n0r
*/
class CommandState(private val machine: VimStateMachine) {
val isOperatorPending: Boolean
get() = machine.isOperatorPending
val mode: CommandState.Mode
get() = machine.mode.ij
val commandBuilder: CommandBuilder
get() = machine.commandBuilder
val mappingState: MappingState
get() = machine.mappingState
enum class Mode {
// Basic modes
COMMAND, VISUAL, SELECT, INSERT, CMD_LINE, /*EX*/
@@ -50,7 +60,6 @@ class CommandState(private val machine: VimStateMachine) {
}
}
val CommandState.SubMode.engine: VimStateMachine.SubMode
get() = when (this) {
CommandState.SubMode.NONE -> VimStateMachine.SubMode.NONE
@@ -73,7 +82,6 @@ val CommandState.Mode.engine: VimStateMachine.Mode
CommandState.Mode.INSERT_SELECT -> VimStateMachine.Mode.INSERT_SELECT
}
val VimStateMachine.Mode.ij: CommandState.Mode
get() = when (this) {
VimStateMachine.Mode.COMMAND -> CommandState.Mode.COMMAND

View File

@@ -23,6 +23,7 @@ import com.intellij.openapi.editor.Editor
import com.maddyhome.idea.vim.KeyHandler
import com.maddyhome.idea.vim.VimPlugin
import com.maddyhome.idea.vim.action.change.Extension
import com.maddyhome.idea.vim.api.VimCaret
import com.maddyhome.idea.vim.command.MappingMode
import com.maddyhome.idea.vim.command.SelectionType
import com.maddyhome.idea.vim.common.CommandAlias
@@ -60,6 +61,7 @@ object VimExtensionFacade {
/**
* COMPATIBILITY-LAYER: Additional method
* Please see: https://jb.gg/zo8n0r
*/
/** The 'map' command for mapping keys to handlers defined in extensions. */
@JvmStatic
@@ -182,12 +184,24 @@ object VimExtensionFacade {
return reg.keys
}
@JvmStatic
fun getRegisterForCaret(register: Char, caret: VimCaret): List<KeyStroke>? {
val reg = caret.registerStorage.getRegister(register) ?: return null
return reg.keys
}
/** Set the current contents of the given register */
@JvmStatic
fun setRegister(register: Char, keys: List<KeyStroke?>?) {
VimPlugin.getRegister().setKeys(register, keys?.filterNotNull() ?: emptyList())
}
/** Set the current contents of the given register */
@JvmStatic
fun setRegisterForCaret(register: Char, caret: VimCaret, keys: List<KeyStroke?>?) {
caret.registerStorage.setKeys(register, keys?.filterNotNull() ?: emptyList())
}
/** Set the current contents of the given register */
@JvmStatic
fun setRegister(register: Char, keys: List<KeyStroke?>?, type: SelectionType) {

View File

@@ -26,6 +26,7 @@ import com.maddyhome.idea.vim.newapi.ij
/**
* COMPATIBILITY-LAYER: Created a class, renamed original class
* Please see: https://jb.gg/zo8n0r
*/
interface VimExtensionHandler : ExtensionHandler {
override fun execute(editor: VimEditor, context: ExecutionContext) {

View File

@@ -25,9 +25,9 @@ import com.maddyhome.idea.vim.api.VimExtensionRegistrator
import com.maddyhome.idea.vim.api.injector
import com.maddyhome.idea.vim.ex.ExException
import com.maddyhome.idea.vim.key.MappingOwner.Plugin.Companion.remove
import com.maddyhome.idea.vim.option.ToggleOption
import com.maddyhome.idea.vim.options.OptionChangeListener
import com.maddyhome.idea.vim.options.OptionScope
import com.maddyhome.idea.vim.option.ToggleOption
import com.maddyhome.idea.vim.statistic.PluginState
import com.maddyhome.idea.vim.vimscript.model.datatypes.VimDataType

View File

@@ -34,13 +34,14 @@ import com.maddyhome.idea.vim.api.injector
import com.maddyhome.idea.vim.command.Argument
import com.maddyhome.idea.vim.command.Command
import com.maddyhome.idea.vim.command.CommandFlags
import com.maddyhome.idea.vim.command.VimStateMachine
import com.maddyhome.idea.vim.command.MappingMode
import com.maddyhome.idea.vim.command.SelectionType
import com.maddyhome.idea.vim.command.TextObjectVisualType
import com.maddyhome.idea.vim.command.VimStateMachine
import com.maddyhome.idea.vim.common.CommandAliasHandler
import com.maddyhome.idea.vim.command.MappingMode
import com.maddyhome.idea.vim.common.TextRange
import com.maddyhome.idea.vim.ex.ranges.Ranges
import com.maddyhome.idea.vim.extension.ExtensionHandler
import com.maddyhome.idea.vim.extension.VimExtension
import com.maddyhome.idea.vim.extension.VimExtensionFacade.addCommand
import com.maddyhome.idea.vim.extension.VimExtensionFacade.executeNormalWithoutMapping
@@ -48,7 +49,6 @@ import com.maddyhome.idea.vim.extension.VimExtensionFacade.putExtensionHandlerMa
import com.maddyhome.idea.vim.extension.VimExtensionFacade.putKeyMapping
import com.maddyhome.idea.vim.extension.VimExtensionFacade.putKeyMappingIfMissing
import com.maddyhome.idea.vim.extension.VimExtensionFacade.setOperatorFunction
import com.maddyhome.idea.vim.extension.ExtensionHandler
import com.maddyhome.idea.vim.handler.TextObjectActionHandler
import com.maddyhome.idea.vim.helper.EditorHelper
import com.maddyhome.idea.vim.helper.PsiHelper

View File

@@ -31,10 +31,11 @@ import com.maddyhome.idea.vim.VimPlugin
import com.maddyhome.idea.vim.api.ExecutionContext
import com.maddyhome.idea.vim.api.VimEditor
import com.maddyhome.idea.vim.api.injector
import com.maddyhome.idea.vim.command.VimStateMachine
import com.maddyhome.idea.vim.command.SelectionType
import com.maddyhome.idea.vim.command.MappingMode
import com.maddyhome.idea.vim.command.SelectionType
import com.maddyhome.idea.vim.command.VimStateMachine
import com.maddyhome.idea.vim.common.TextRange
import com.maddyhome.idea.vim.extension.ExtensionHandler
import com.maddyhome.idea.vim.extension.VimExtension
import com.maddyhome.idea.vim.extension.VimExtensionFacade.executeNormalWithoutMapping
import com.maddyhome.idea.vim.extension.VimExtensionFacade.getRegister
@@ -42,7 +43,6 @@ import com.maddyhome.idea.vim.extension.VimExtensionFacade.putExtensionHandlerMa
import com.maddyhome.idea.vim.extension.VimExtensionFacade.putKeyMappingIfMissing
import com.maddyhome.idea.vim.extension.VimExtensionFacade.setOperatorFunction
import com.maddyhome.idea.vim.extension.VimExtensionFacade.setRegister
import com.maddyhome.idea.vim.extension.ExtensionHandler
import com.maddyhome.idea.vim.helper.EditorHelper
import com.maddyhome.idea.vim.helper.fileSize
import com.maddyhome.idea.vim.helper.moveToInlayAwareLogicalPosition

View File

@@ -33,21 +33,21 @@ import com.maddyhome.idea.vim.api.injector
import com.maddyhome.idea.vim.command.Argument
import com.maddyhome.idea.vim.command.Command
import com.maddyhome.idea.vim.command.CommandFlags
import com.maddyhome.idea.vim.command.MappingMode
import com.maddyhome.idea.vim.command.MotionType
import com.maddyhome.idea.vim.command.OperatorArguments
import com.maddyhome.idea.vim.common.Direction
import com.maddyhome.idea.vim.command.MappingMode
import com.maddyhome.idea.vim.extension.ExtensionHandler
import com.maddyhome.idea.vim.extension.VimExtension
import com.maddyhome.idea.vim.extension.VimExtensionFacade
import com.maddyhome.idea.vim.extension.VimExtensionFacade.putKeyMappingIfMissing
import com.maddyhome.idea.vim.extension.ExtensionHandler
import com.maddyhome.idea.vim.handler.Motion
import com.maddyhome.idea.vim.handler.MotionActionHandler
import com.maddyhome.idea.vim.handler.toMotionOrError
import com.maddyhome.idea.vim.helper.EditorHelper
import com.maddyhome.idea.vim.helper.PsiHelper
import com.maddyhome.idea.vim.helper.vimStateMachine
import com.maddyhome.idea.vim.helper.enumSetOf
import com.maddyhome.idea.vim.helper.vimStateMachine
import com.maddyhome.idea.vim.newapi.ij
import com.maddyhome.idea.vim.newapi.vim
import java.util.*

View File

@@ -29,8 +29,8 @@ import com.maddyhome.idea.vim.VimPlugin
import com.maddyhome.idea.vim.api.ExecutionContext
import com.maddyhome.idea.vim.api.VimEditor
import com.maddyhome.idea.vim.api.injector
import com.maddyhome.idea.vim.command.VimStateMachine
import com.maddyhome.idea.vim.command.MappingMode
import com.maddyhome.idea.vim.command.VimStateMachine
import com.maddyhome.idea.vim.common.TextRange
import com.maddyhome.idea.vim.extension.ExtensionHandler
import com.maddyhome.idea.vim.extension.VimExtension

View File

@@ -44,18 +44,18 @@ import com.maddyhome.idea.vim.api.VimEditor
import com.maddyhome.idea.vim.api.injector
import com.maddyhome.idea.vim.common.CommandAlias
import com.maddyhome.idea.vim.common.CommandAliasHandler
import com.maddyhome.idea.vim.common.CommandNode
import com.maddyhome.idea.vim.common.CommandPartNode
import com.maddyhome.idea.vim.common.Node
import com.maddyhome.idea.vim.common.RootNode
import com.maddyhome.idea.vim.common.addLeafs
import com.maddyhome.idea.vim.ex.ranges.Ranges
import com.maddyhome.idea.vim.extension.VimExtension
import com.maddyhome.idea.vim.group.KeyGroup
import com.maddyhome.idea.vim.helper.MessageHelper
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.Node
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.vim
import com.maddyhome.idea.vim.vimscript.model.datatypes.VimString

View File

@@ -24,10 +24,10 @@ import com.maddyhome.idea.vim.api.ExecutionContext
import com.maddyhome.idea.vim.api.VimEditor
import com.maddyhome.idea.vim.api.injector
import com.maddyhome.idea.vim.command.MappingMode
import com.maddyhome.idea.vim.extension.ExtensionHandler
import com.maddyhome.idea.vim.extension.VimExtension
import com.maddyhome.idea.vim.extension.VimExtensionFacade
import com.maddyhome.idea.vim.extension.VimExtensionFacade.putKeyMappingIfMissing
import com.maddyhome.idea.vim.extension.ExtensionHandler
import com.maddyhome.idea.vim.group.MotionGroup
import com.maddyhome.idea.vim.helper.EditorHelper
import com.maddyhome.idea.vim.helper.SearchHelper

View File

@@ -26,6 +26,7 @@ import com.maddyhome.idea.vim.api.VimCaret
import com.maddyhome.idea.vim.api.VimEditor
import com.maddyhome.idea.vim.api.injector
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.VimStateMachine
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.group.visual.VimSelection
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.subMode
import com.maddyhome.idea.vim.helper.vimStateMachine
import com.maddyhome.idea.vim.key.OperatorFunction
import com.maddyhome.idea.vim.newapi.IjExecutionContext
import com.maddyhome.idea.vim.newapi.IjVimEditor
@@ -65,15 +68,14 @@ class ReplaceWithRegister : VimExtension {
private class RwrVisual : ExtensionHandler {
override fun execute(editor: VimEditor, context: ExecutionContext) {
val caretsAndSelections = mutableMapOf<VimCaret, VimSelection>()
val typeInEditor = SelectionType.fromSubMode(editor.subMode)
editor.forEachCaret { caret ->
val selectionStart = caret.selectionStart
val selectionEnd = caret.selectionEnd
caretsAndSelections += caret to VimSelection.create(selectionStart, selectionEnd - 1, typeInEditor, editor)
val visualSelection = caret to VimSelection.create(selectionStart, selectionEnd - 1, typeInEditor, editor)
doReplace(editor.ij, caret, PutData.VisualSelection(mapOf(visualSelection), typeInEditor))
}
doReplace(editor.ij, PutData.VisualSelection(caretsAndSelections, typeInEditor))
editor.exitVisualModeNative()
}
}
@@ -97,11 +99,11 @@ class ReplaceWithRegister : VimExtension {
val lineStart = editor.getLineStartOffset(logicalLine)
val lineEnd = editor.getLineEndOffset(logicalLine, true)
caretsAndSelections += caret to VimSelection.create(lineStart, lineEnd, SelectionType.LINE_WISE, editor)
}
val visualSelection = caret to VimSelection.create(lineStart, lineEnd, SelectionType.LINE_WISE, editor)
caretsAndSelections += visualSelection
val visualSelection = PutData.VisualSelection(caretsAndSelections, SelectionType.LINE_WISE)
doReplace(editor.ij, visualSelection)
doReplace(editor.ij, caret, PutData.VisualSelection(mapOf(visualSelection), SelectionType.LINE_WISE))
}
editor.forEachCaret { caret ->
val vimStart = caretsAndSelections[caret]?.vimStart
@@ -126,7 +128,8 @@ class ReplaceWithRegister : VimExtension {
),
selectionType
)
doReplace(editor, visualSelection)
// todo multicaret
doReplace(editor, editor.vim.primaryCaret(), visualSelection)
return true
}
@@ -147,8 +150,9 @@ class ReplaceWithRegister : VimExtension {
@NonNls
private const val RWR_VISUAL = "<Plug>ReplaceWithRegisterVisual"
private fun doReplace(editor: Editor, visualSelection: PutData.VisualSelection) {
val savedRegister = VimPlugin.getRegister().lastRegister ?: return
private fun doReplace(editor: Editor, caret: VimCaret, visualSelection: PutData.VisualSelection) {
val lastRegisterChar = injector.registerGroup.lastRegisterChar
val savedRegister = caret.registerStorage.getRegister(lastRegisterChar) ?: return
var usedType = savedRegister.type
var usedText = savedRegister.text
@@ -170,11 +174,19 @@ class ReplaceWithRegister : VimExtension {
putToLine = -1
)
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
)
)
}
VimPlugin.getRegister().saveRegister(savedRegister.name, savedRegister)
VimPlugin.getRegister().saveRegister(VimPlugin.getRegister().defaultRegister, savedRegister)
caret.registerStorage.saveRegister(savedRegister.name, savedRegister)
caret.registerStorage.saveRegister(VimPlugin.getRegister().defaultRegister, savedRegister)
}
}
}

View File

@@ -22,23 +22,23 @@ import com.intellij.openapi.application.runWriteAction
import com.intellij.openapi.editor.Editor
import com.maddyhome.idea.vim.VimPlugin
import com.maddyhome.idea.vim.api.ExecutionContext
import com.maddyhome.idea.vim.api.VimCaret
import com.maddyhome.idea.vim.api.VimEditor
import com.maddyhome.idea.vim.api.injector
import com.maddyhome.idea.vim.command.VimStateMachine
import com.maddyhome.idea.vim.command.SelectionType
import com.maddyhome.idea.vim.command.MappingMode
import com.maddyhome.idea.vim.command.SelectionType
import com.maddyhome.idea.vim.command.VimStateMachine
import com.maddyhome.idea.vim.common.TextRange
import com.maddyhome.idea.vim.extension.ExtensionHandler
import com.maddyhome.idea.vim.extension.VimExtension
import com.maddyhome.idea.vim.extension.VimExtensionFacade.executeNormalWithoutMapping
import com.maddyhome.idea.vim.extension.VimExtensionFacade.getRegister
import com.maddyhome.idea.vim.extension.VimExtensionFacade.getRegisterForCaret
import com.maddyhome.idea.vim.extension.VimExtensionFacade.inputKeyStroke
import com.maddyhome.idea.vim.extension.VimExtensionFacade.inputString
import com.maddyhome.idea.vim.extension.VimExtensionFacade.putExtensionHandlerMapping
import com.maddyhome.idea.vim.extension.VimExtensionFacade.putKeyMappingIfMissing
import com.maddyhome.idea.vim.extension.VimExtensionFacade.setOperatorFunction
import com.maddyhome.idea.vim.extension.VimExtensionFacade.setRegister
import com.maddyhome.idea.vim.extension.ExtensionHandler
import com.maddyhome.idea.vim.helper.EditorHelper
import com.maddyhome.idea.vim.extension.VimExtensionFacade.setRegisterForCaret
import com.maddyhome.idea.vim.helper.editorMode
import com.maddyhome.idea.vim.key.OperatorFunction
import com.maddyhome.idea.vim.newapi.IjVimCaret
@@ -46,6 +46,7 @@ import com.maddyhome.idea.vim.newapi.IjVimEditor
import com.maddyhome.idea.vim.newapi.ij
import com.maddyhome.idea.vim.newapi.vim
import com.maddyhome.idea.vim.options.helpers.ClipboardOptionHelper
import com.maddyhome.idea.vim.put.PutData
import org.jetbrains.annotations.NonNls
import java.awt.event.KeyEvent
import javax.swing.KeyStroke
@@ -115,33 +116,70 @@ class VimSurroundExtension : VimExtension {
if (charTo.code == 0) return
val newSurround = getOrInputPair(charTo, editor.ij) ?: return
runWriteAction { change(editor.ij, charFrom, newSurround) }
runWriteAction { change(editor, context, charFrom, newSurround) }
}
companion object {
fun change(editor: Editor, charFrom: Char, newSurround: Pair<String, String>?) {
// We take over the " register, so preserve it
val oldValue: List<KeyStroke>? = getRegister(REGISTER)
// Empty the " register
setRegister(REGISTER, null)
// Extract the inner value
perform("di" + pick(charFrom), editor)
val innerValue: MutableList<KeyStroke> = getRegister(REGISTER)?.toMutableList() ?: mutableListOf()
// If the surrounding characters were not found, the register will be empty
if (innerValue.isNotEmpty()) {
// Delete the surrounding
perform("da" + pick(charFrom), editor)
// Insert the surrounding characters and paste
if (newSurround != null) {
innerValue.addAll(0, injector.parser.parseKeys(newSurround.first))
innerValue.addAll(injector.parser.parseKeys(newSurround.second))
fun change(editor: VimEditor, context: ExecutionContext, charFrom: Char, newSurround: Pair<String, String>?) {
// Save old register values for carets
val surroundings = editor.sortedCarets()
.map {
val oldValue: List<KeyStroke>? = getRegisterForCaret(REGISTER, it)
setRegisterForCaret(REGISTER, it, null)
SurroundingInfo(it, null, oldValue, null)
}
pasteSurround(innerValue, editor)
// Jump back to start
executeNormalWithoutMapping(injector.parser.parseKeys("`["), editor)
// Delete surrounding's content
perform("di" + pick(charFrom), editor.ij)
// Add info about surrounding's inner text and location
surroundings.forEach {
val registerValue = getRegisterForCaret(REGISTER, it.caret)
val innerValue = if (registerValue.isNullOrEmpty()) null else registerValue
it.innerText = innerValue
val lineEndOffset = injector.engineEditorHelper.getLineEndOffset(editor, it.caret.getLine().line, false)
if (lineEndOffset == it.caret.offset.point) {
it.isLineEnd = true
}
}
// Remove surrounding
perform("da" + pick(charFrom), editor.ij)
surroundings.forEach {
if (it.innerText == null && getRegisterForCaret(REGISTER, it.caret)?.isNotEmpty() == true) {
it.innerText = emptyList()
}
// caret should be placed at the first char of inserted text
// the best solution would be using [ mark after the paste, but marks are not supported by multicaret
// todo
if (it.innerText != null) {
it.offset = it.caret.offset.point
}
}
surroundings
.filter { it.innerText != null } // we do nothing with carets that are not inside the surrounding
.map { surrounding ->
val innerValue = injector.parser.toPrintableString(surrounding.innerText!!)
val text = newSurround?.let { it.first + innerValue + it.second } ?: innerValue
val textData = PutData.TextData(text, SelectionType.CHARACTER_WISE, emptyList())
val putData = PutData(textData, null, 1, insertTextBeforeCaret = !surrounding.isLineEnd, rawIndent = true, caretAfterInsertedText = false)
surrounding.caret to putData
}.forEach {
injector.put.putTextForCaret(editor, it.first, context, it.second)
}
surroundings.forEach {
it.restoreRegister()
}
if (surroundings.size == 1) {
surroundings.first().moveCaret()
}
// Restore the old value
setRegister(REGISTER, oldValue)
}
private fun perform(sequence: String, editor: Editor) {
@@ -149,21 +187,6 @@ class VimSurroundExtension : VimExtension {
.use { executeNormalWithoutMapping(injector.parser.parseKeys("\"" + REGISTER + sequence), editor) }
}
private fun pasteSurround(
innerValue: List<KeyStroke?>,
editor: Editor,
) { // This logic is direct from vim-surround
val offset = editor.caretModel.offset
val lineEndOffset = EditorHelper.getLineEndForOffset(editor, offset)
val motionEndMark = VimPlugin.getMark().getMark(editor.vim, ']')
val motionEndOffset = if (motionEndMark != null) {
EditorHelper.getOffset(editor, motionEndMark.logicalLine, motionEndMark.col)
} else -1
val pasteCommand = if (motionEndOffset == lineEndOffset && offset + 1 == lineEndOffset) "p" else "P"
setRegister(REGISTER, innerValue)
perform(pasteCommand, editor)
}
private fun pick(charFrom: Char) = when (charFrom) {
'a' -> '>'
'r' -> ']'
@@ -172,6 +195,18 @@ class VimSurroundExtension : VimExtension {
}
}
private data class SurroundingInfo(val caret: VimCaret, var innerText: List<KeyStroke>?, val oldRegisterContent: List<KeyStroke>?, var offset: Int?, var isLineEnd: Boolean = false) {
fun restoreRegister() {
setRegisterForCaret(REGISTER, caret, oldRegisterContent)
}
fun moveCaret() {
if (innerText != null && offset != null) {
caret.moveToOffset(offset!! + if (isLineEnd) 1 else 0)
}
}
}
private class DSurroundHandler : ExtensionHandler {
override val isRepeatable = true
@@ -180,7 +215,7 @@ class VimSurroundExtension : VimExtension {
val charFrom = getChar(editor.ij)
if (charFrom.code == 0) return
runWriteAction { CSurroundHandler.change(editor.ij, charFrom, null) }
runWriteAction { CSurroundHandler.change(editor, context, charFrom, null) }
}
}

View File

@@ -245,7 +245,7 @@ public class ChangeGroup extends VimChangeGroupBase {
final boolean lastWordChar =
offset >= fileSize - 1 || CharacterHelper.charType(chars.charAt(offset + 1), bigWord) != charType;
if (wordMotions.contains(id) && lastWordChar && motion.getCount() == 1) {
final boolean res = deleteCharacter(editor, caret, 1, true);
final boolean res = deleteCharacter(editor, caret, 1, true, operatorArguments);
if (res) {
editor.setVimChangeActionSwitchMode(VimStateMachine.Mode.INSERT);
}
@@ -306,7 +306,8 @@ public class ChangeGroup extends VimChangeGroupBase {
Pair<TextRange, SelectionType> deleteRangeAndType =
getDeleteRangeAndType(editor, caret, context, argument, true, operatorArguments.withCount0(count0));
if (deleteRangeAndType == null) return false;
return changeRange(editor, caret, deleteRangeAndType.getFirst(), deleteRangeAndType.getSecond(), context);
return changeRange(editor, caret, deleteRangeAndType.getFirst(), deleteRangeAndType.getSecond(), context,
operatorArguments);
}
}
@@ -429,6 +430,7 @@ public class ChangeGroup extends VimChangeGroupBase {
* @param caret The caret to be moved after range deletion
* @param range The range to change
* @param type The type of the range
* @param operatorArguments
* @return true if able to delete the range, false if not
*/
@Override
@@ -436,7 +438,8 @@ public class ChangeGroup extends VimChangeGroupBase {
@NotNull VimCaret caret,
@NotNull TextRange range,
@NotNull SelectionType type,
ExecutionContext context) {
@Nullable ExecutionContext context,
@NotNull OperatorArguments operatorArguments) {
int col = 0;
int lines = 0;
if (type == SelectionType.BLOCK_WISE) {
@@ -450,7 +453,7 @@ public class ChangeGroup extends VimChangeGroupBase {
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 (type == SelectionType.LINE_WISE) {
// 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 ExecutionContext context,
int lines,
int dir) {
int dir,
@NotNull OperatorArguments operatorArguments) {
int start = ((IjVimCaret) caret).getCaret().getOffset();
int end = VimPlugin.getMotion().moveCaretToLineEndOffset(editor, caret, lines - 1, true);
indentRange(editor, caret, context, new TextRange(start, end), 1, dir);
indentRange(editor, caret, context, new TextRange(start, end), 1, dir, operatorArguments);
}
@Override
@@ -602,7 +606,7 @@ public class ChangeGroup extends VimChangeGroupBase {
final TextRange range =
injector.getMotion().getMotionRange(editor, caret, context, argument, operatorArguments);
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 TextRange range,
int count,
int dir) {
int dir,
@NotNull OperatorArguments operatorArguments) {
if (logger.isDebugEnabled()) {
logger.debug("count=" + count);
}
@@ -675,7 +680,7 @@ public class ChangeGroup extends VimChangeGroupBase {
}
}
if (pos > wsoff) {
deleteText(editor, new TextRange(wsoff, pos), null);
deleteText(editor, new TextRange(wsoff, pos), null, caret, operatorArguments);
}
}
}

View File

@@ -36,6 +36,7 @@ class IjVimStorageService : VimStorageServiceBase() {
editor.ij.putUserData(getOrCreateIjKey(key), data)
}
@Suppress("UNCHECKED_CAST")
override fun <T> getDataFromBuffer(editor: VimEditor, key: com.maddyhome.idea.vim.api.Key<T>): T? {
val buffer = EditorHelper.getVirtualFile(editor.ij)?.path ?: "empty path"
return bufferToKey[buffer]?.get(key.name) as T?
@@ -60,6 +61,7 @@ class IjVimStorageService : VimStorageServiceBase() {
}
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> {
val storedIjKey = ijKeys[key.name]
if (storedIjKey != null) {

View File

@@ -38,8 +38,7 @@ import com.maddyhome.idea.vim.action.ComplicatedKeysAction;
import com.maddyhome.idea.vim.action.VimShortcutKeyAction;
import com.maddyhome.idea.vim.api.*;
import com.maddyhome.idea.vim.command.MappingMode;
import com.maddyhome.idea.vim.common.Node;
import com.maddyhome.idea.vim.common.NodesKt;
import com.maddyhome.idea.vim.key.Node;
import com.maddyhome.idea.vim.ex.ExOutputModel;
import com.maddyhome.idea.vim.handler.EditorActionHandlerBase;
import com.maddyhome.idea.vim.helper.HelperKt;

View File

@@ -108,7 +108,9 @@ public class MacroGroup extends VimMacroBase {
KeyHandler.getInstance().handleKey(editor, key, context);
});
}
keyStack.resetFirst();
}
keyStack.removeFirst();
});
}
}

View File

@@ -411,6 +411,7 @@ public class MarkGroup extends VimMarkGroupBase implements PersistentStateCompon
/**
* COMPATIBILITY-LAYER: Method added
* Please see: <a href="https://jb.gg/zo8n0r">doc</a>
*
* @deprecated Please use method with VimEditor
*/

View File

@@ -20,26 +20,23 @@ package com.maddyhome.idea.vim.group
import com.intellij.icons.AllIcons
import com.intellij.ide.BrowserUtil
import com.intellij.ide.IdeBundle
import com.intellij.ide.actions.OpenFileAction
import com.intellij.ide.actions.RevealFileAction
import com.intellij.notification.ActionCenter
import com.intellij.notification.Notification
import com.intellij.notification.NotificationGroup
import com.intellij.notification.NotificationGroupManager
import com.intellij.notification.NotificationListener
import com.intellij.notification.NotificationType
import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.KeyboardShortcut
import com.intellij.openapi.ide.CopyPasteManager
import com.intellij.openapi.keymap.Keymap
import com.intellij.openapi.keymap.KeymapUtil
import com.intellij.openapi.options.ShowSettingsUtil
import com.intellij.openapi.project.DumbAwareAction
import com.intellij.openapi.project.Project
import com.intellij.openapi.ui.Messages
import com.intellij.openapi.util.SystemInfo
import com.intellij.openapi.util.registry.Registry
import com.maddyhome.idea.vim.VimPlugin
import com.maddyhome.idea.vim.helper.MessageHelper
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.vimscript.services.IjVimOptionService
import com.maddyhome.idea.vim.vimscript.services.VimRcService
import org.jetbrains.annotations.Nls
import java.awt.datatransfer.StringSelection
import java.io.File
import javax.swing.KeyStroke
@@ -115,23 +111,6 @@ class NotificationService(private val project: Project?) {
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() {
val notification = IDEAVIM_STICKY_GROUP.createNotification(
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 = it
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())
@@ -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")) {
override fun actionPerformed(e: AnActionEvent) {
CopyPasteManager.getInstance().setContents(StringSelection(id ?: ""))

View File

@@ -21,8 +21,8 @@ package com.maddyhome.idea.vim.group;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
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.EditorWithProviderComposite;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.concurrency.annotations.RequiresReadLock;
@@ -183,7 +183,7 @@ public class WindowGroup extends WindowGroupBase {
}
private static @Nullable Rectangle getEditorWindowRectangle(@NotNull EditorWindow window) {
final EditorWithProviderComposite editor = window.getSelectedEditor();
final EditorComposite editor = window.getSelectedComposite();
if (editor != null) {
final Point point = editor.getComponent().getLocationOnScreen();
final Dimension dimension = editor.getComponent().getSize();

View File

@@ -34,8 +34,9 @@ import com.maddyhome.idea.vim.api.ExecutionContext
import com.maddyhome.idea.vim.api.VimCaret
import com.maddyhome.idea.vim.api.VimEditor
import com.maddyhome.idea.vim.api.injector
import com.maddyhome.idea.vim.command.VimStateMachine
import com.maddyhome.idea.vim.command.OperatorArguments
import com.maddyhome.idea.vim.command.SelectionType
import com.maddyhome.idea.vim.command.VimStateMachine
import com.maddyhome.idea.vim.command.isBlock
import com.maddyhome.idea.vim.command.isChar
import com.maddyhome.idea.vim.command.isLine
@@ -43,7 +44,9 @@ import com.maddyhome.idea.vim.common.TextRange
import com.maddyhome.idea.vim.helper.EditorHelper
import com.maddyhome.idea.vim.helper.TestClipboardModel
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.subMode
import com.maddyhome.idea.vim.mark.VimMarkConstants.MARK_CHANGE_POS
import com.maddyhome.idea.vim.newapi.IjVimCaret
import com.maddyhome.idea.vim.newapi.IjVimEditor
@@ -60,10 +63,20 @@ import java.awt.datatransfer.DataFlavor
import kotlin.math.min
class PutGroup : VimPutBase() {
override fun putTextForCaret(editor: VimEditor, caret: VimCaret, context: ExecutionContext, data: PutData): Boolean {
override fun putTextForCaret(editor: VimEditor, caret: VimCaret, context: ExecutionContext, data: PutData, updateVisualMarks: Boolean): Boolean {
val additionalData = collectPreModificationData(editor, data)
data.visualSelection?.let {
deleteSelectedText(
editor,
data,
OperatorArguments(false, 0, editor.mode, editor.subMode)
)
}
val processedText = processText(editor, data) ?: return false
putForCaret(editor, caret, data, additionalData, context, processedText)
if (editor.primaryCaret() == caret && updateVisualMarks) {
wrapInsertedTextWithVisualMarks(editor, data, processedText)
}
return true
}
@@ -89,7 +102,6 @@ class PutGroup : VimPutBase() {
}
}
notifyAboutIdeaPut(editor)
logger.debug("Perform put via plugin")
val myCarets = if (visualSelection != null) {
visualSelection.caretsAndSelections.keys.sortedByDescending { it.getLogicalPosition() }
@@ -109,6 +121,7 @@ class PutGroup : VimPutBase() {
context: ExecutionContext,
text: ProcessedTextData,
) {
notifyAboutIdeaPut(editor)
if (data.visualSelection?.typeInEditor?.isLine == true && editor.isOneLineMode()) return
val startOffsets = prepareDocumentAndGetStartOffsets(editor, caret, text.typeInRegister, data, additionalData)
@@ -118,7 +131,9 @@ class PutGroup : VimPutBase() {
editor, caret, context, text.text, text.typeInRegister, subMode,
startOffset, data.count, data.indent, data.caretAfterInsertedText
)
if (caret == editor.primaryCaret()) {
VimPlugin.getMark().setChangeMarks(editor, TextRange(startOffset, endOffset))
}
moveCaretToEndPosition(
editor,
caret,

View File

@@ -18,23 +18,20 @@
package com.maddyhome.idea.vim.group.copy
import com.intellij.openapi.editor.Caret
import com.intellij.openapi.editor.Editor
import com.intellij.util.containers.ContainerUtil
import com.maddyhome.idea.vim.VimPlugin
import com.maddyhome.idea.vim.action.motion.updown.MotionDownLess1FirstNonSpaceAction
import com.maddyhome.idea.vim.api.ExecutionContext
import com.maddyhome.idea.vim.api.VimCaret
import com.maddyhome.idea.vim.api.VimEditor
import com.maddyhome.idea.vim.api.injector
import com.maddyhome.idea.vim.command.Argument
import com.maddyhome.idea.vim.command.OperatorArguments
import com.maddyhome.idea.vim.command.SelectionType
import com.maddyhome.idea.vim.common.TextRange
import com.maddyhome.idea.vim.group.MotionGroup
import com.maddyhome.idea.vim.helper.EditorHelper
import com.maddyhome.idea.vim.helper.fileSize
import com.maddyhome.idea.vim.listener.VimYankListener
import com.maddyhome.idea.vim.newapi.ij
import com.maddyhome.idea.vim.newapi.vim
import com.maddyhome.idea.vim.yank.YankGroupBase
import org.jetbrains.annotations.Contract
import kotlin.math.min
@@ -46,8 +43,8 @@ class YankGroup : YankGroupBase() {
fun removeListener(listener: VimYankListener) = yankListeners.remove(listener)
private fun notifyListeners(editor: Editor, textRange: TextRange) = yankListeners.forEach {
it.yankPerformed(editor, textRange)
private fun notifyListeners(editor: VimEditor, textRange: TextRange) = yankListeners.forEach {
it.yankPerformed(editor.ij, textRange)
}
/**
@@ -67,32 +64,38 @@ class YankGroup : YankGroupBase() {
operatorArguments: OperatorArguments
): Boolean {
val motion = argument.motion
val type = if (motion.isLinewiseMotion()) SelectionType.LINE_WISE else SelectionType.CHARACTER_WISE
val caretModel = editor.ij.caretModel
if (caretModel.caretCount <= 0) return false
val nativeCaretCount = editor.nativeCarets().size
if (nativeCaretCount <= 0) return false
val ranges = ArrayList<Pair<Int, Int>>(caretModel.caretCount)
val carretToRange = HashMap<VimCaret, TextRange>(nativeCaretCount)
val ranges = ArrayList<Pair<Int, Int>>(nativeCaretCount)
// This logic is from original vim
val startOffsets =
if (argument.motion.action is MotionDownLess1FirstNonSpaceAction) null else HashMap<Caret, Int>(caretModel.caretCount)
val startOffsets = if (argument.motion.action is MotionDownLess1FirstNonSpaceAction) null else HashMap<VimCaret, Int>(nativeCaretCount)
for (caret in caretModel.allCarets) {
val motionRange = MotionGroup.getMotionRange(editor.ij, caret, context.ij, argument, operatorArguments)
for (caret in editor.nativeCarets()) {
val motionRange = injector.motion.getMotionRange(editor, caret, context, argument, operatorArguments)
?: continue
assert(motionRange.size() == 1)
ranges.add(motionRange.startOffset to motionRange.endOffset)
startOffsets?.put(caret, motionRange.normalize().startOffset)
carretToRange[caret] = TextRange(motionRange.startOffset, motionRange.endOffset)
}
val type = if (motion.isLinewiseMotion()) SelectionType.LINE_WISE else SelectionType.CHARACTER_WISE
val range = getTextRange(ranges, type) ?: return false
if (range.size() == 0) return false
val selectionType = if (type == SelectionType.CHARACTER_WISE && range.isMultiple) SelectionType.BLOCK_WISE else type
return yankRange(editor.ij, range, selectionType, startOffsets)
return yankRange(
editor,
carretToRange,
range,
type,
startOffsets
)
}
/**
@@ -103,19 +106,21 @@ class YankGroup : YankGroupBase() {
* @return true if able to yank the lines, false if not
*/
override fun yankLine(editor: VimEditor, count: Int): Boolean {
val caretModel = editor.ij.caretModel
val ranges = ArrayList<Pair<Int, Int>>(caretModel.caretCount)
for (caret in caretModel.allCarets) {
val start = VimPlugin.getMotion().moveCaretToLineStart(editor, caret.vim)
val end = min(VimPlugin.getMotion().moveCaretToLineEndOffset(editor, caret.vim, count - 1, true) + 1, editor.fileSize().toInt())
val caretCount = editor.nativeCarets().size
val ranges = ArrayList<Pair<Int, Int>>(caretCount)
val caretToRange = HashMap<VimCaret, TextRange>(caretCount)
for (caret in editor.nativeCarets()) {
val start = injector.motion.moveCaretToLineStart(editor, caret)
val end = min(injector.motion.moveCaretToLineEndOffset(editor, caret, count - 1, true) + 1, editor.fileSize().toInt())
if (end == -1) continue
ranges.add(start to end)
caretToRange[caret] = TextRange(start, end)
}
val range = getTextRange(ranges, SelectionType.LINE_WISE) ?: return false
return yankRange(editor.ij, range, SelectionType.LINE_WISE, null)
return yankRange(editor, caretToRange, range, SelectionType.LINE_WISE, null)
}
/**
@@ -129,6 +134,7 @@ class YankGroup : YankGroupBase() {
override fun yankRange(editor: VimEditor, range: TextRange?, type: SelectionType, moveCursor: Boolean): Boolean {
range ?: return false
val caretToRange = HashMap<VimCaret, TextRange>()
val selectionType = if (type == SelectionType.CHARACTER_WISE && range.isMultiple) SelectionType.BLOCK_WISE else type
if (type == SelectionType.LINE_WISE) {
@@ -143,24 +149,25 @@ class YankGroup : YankGroupBase() {
}
}
val caretModel = editor.ij.caretModel
val rangeStartOffsets = range.startOffsets
val rangeEndOffsets = range.endOffsets
return if (moveCursor) {
val startOffsets = HashMap<Caret, Int>(caretModel.caretCount)
val startOffsets = HashMap<VimCaret, Int>(editor.nativeCarets().size)
if (type == SelectionType.BLOCK_WISE) {
startOffsets[caretModel.primaryCaret] = range.normalize().startOffset
startOffsets[editor.primaryCaret()] = range.normalize().startOffset
caretToRange[editor.primaryCaret()] = range
} else {
val carets = caretModel.allCarets
for (i in carets.indices) {
startOffsets[carets[i]] = TextRange(rangeStartOffsets[i], rangeEndOffsets[i]).normalize().startOffset
for ((i, caret) in editor.nativeCarets().withIndex()) {
val textRange = TextRange(rangeStartOffsets[i], rangeEndOffsets[i])
startOffsets[caret] = textRange.normalize().startOffset
caretToRange[caret] = textRange
}
}
yankRange(editor.ij, range, selectionType, startOffsets)
return if (moveCursor) {
yankRange(editor, caretToRange, range, selectionType, startOffsets)
} else {
yankRange(editor.ij, range, selectionType, null)
yankRange(editor, caretToRange, range, selectionType, null)
}
}
@@ -192,15 +199,20 @@ class YankGroup : YankGroupBase() {
}
private fun yankRange(
editor: Editor,
editor: VimEditor,
caretToRange: Map<VimCaret, TextRange>,
range: TextRange,
type: SelectionType,
startOffsets: Map<Caret, Int>?,
startOffsets: Map<VimCaret, Int>?,
): Boolean {
startOffsets?.forEach { (caret, offset) -> MotionGroup.moveCaret(editor, caret, offset) }
startOffsets?.forEach { (caret, offset) -> injector.motion.moveCaret(editor, caret, offset) }
notifyListeners(editor, range)
return VimPlugin.getRegister().storeText(editor.vim, range, type, false)
var result = true
for ((caret, myRange) in caretToRange) {
result = caret.registerStorage.storeText(editor, myRange, type, false) && result
}
return result
}
}

View File

@@ -25,7 +25,7 @@ import com.maddyhome.idea.vim.KeyHandler
import com.maddyhome.idea.vim.VimPlugin
import com.maddyhome.idea.vim.command.VimStateMachine
import com.maddyhome.idea.vim.helper.EditorDataContext
import com.maddyhome.idea.vim.helper.vimStateMachine
import com.maddyhome.idea.vim.helper.editorMode
import com.maddyhome.idea.vim.helper.exitSelectMode
import com.maddyhome.idea.vim.helper.exitVisualMode
import com.maddyhome.idea.vim.helper.hasVisualSelection
@@ -35,8 +35,8 @@ import com.maddyhome.idea.vim.helper.inSelectMode
import com.maddyhome.idea.vim.helper.inVisualMode
import com.maddyhome.idea.vim.helper.isIdeaVimDisabledHere
import com.maddyhome.idea.vim.helper.isTemplateActive
import com.maddyhome.idea.vim.helper.editorMode
import com.maddyhome.idea.vim.helper.popAllModes
import com.maddyhome.idea.vim.helper.vimStateMachine
import com.maddyhome.idea.vim.listener.VimListenerManager
import com.maddyhome.idea.vim.newapi.IjVimEditor
import com.maddyhome.idea.vim.newapi.vim

View File

@@ -25,11 +25,11 @@ import com.maddyhome.idea.vim.VimPlugin
import com.maddyhome.idea.vim.api.VimMotionGroupBase
import com.maddyhome.idea.vim.command.VimStateMachine
import com.maddyhome.idea.vim.helper.EditorHelper
import com.maddyhome.idea.vim.helper.editorMode
import com.maddyhome.idea.vim.helper.inBlockSubMode
import com.maddyhome.idea.vim.helper.inSelectMode
import com.maddyhome.idea.vim.helper.inVisualMode
import com.maddyhome.idea.vim.helper.isEndAllowed
import com.maddyhome.idea.vim.helper.editorMode
import com.maddyhome.idea.vim.helper.moveToInlayAwareOffset
import com.maddyhome.idea.vim.helper.subMode
import com.maddyhome.idea.vim.helper.updateCaretsVisualAttributes

View File

@@ -44,6 +44,7 @@ class VisualMotionGroup : VimVisualMotionGroupBase() {
/**
* COMPATIBILITY-LAYER: Added a method
* Please see: https://jb.gg/zo8n0r
*/
fun enterVisualMode(editor: Editor, subMode: CommandState.SubMode? = null): Boolean {
return this.enterVisualMode(editor.vim, subMode?.engine)

View File

@@ -60,12 +60,14 @@ val Editor.editorMode
/**
* COMPATIBILITY-LAYER: New method
* Please see: https://jb.gg/zo8n0r
*/
val Editor.mode
get() = this.vim.vimStateMachine.mode.ij
/**
* COMPATIBILITY-LAYER: New method
* Please see: https://jb.gg/zo8n0r
*/
val CommandState.Mode.isEndAllowed: Boolean
get() = this.engine.isEndAllowed

View File

@@ -37,6 +37,7 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.Range;
import java.awt.*;
import java.awt.geom.Point2D;
import java.nio.CharBuffer;
import java.util.Collections;
import java.util.Comparator;
@@ -154,6 +155,7 @@ public class EditorHelper {
/**
* COMPATIBILITY-LAYER: Created a function
* Please see: <a href="https://jb.gg/zo8n0r">doc</a>
*/
public static int getVisualLineCount(final @NotNull Editor editor) {
return getVisualLineCount(new IjVimEditor(editor));
@@ -245,12 +247,27 @@ public class EditorHelper {
* font. It does not include inlays or folds.
* <p>
* Note that this value is only approximate and should be avoided whenever possible!
* </p>
*
* @param editor The editor
* @return The number of screen columns
*/
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);
}
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;
// 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
// still a good solution. Besides, what kind of monster uses Vim with proportional fonts?
final int standardColumnWidth = EditorUtil.getPlainSpaceWidth(editor);
final int x = max(0, point.x - (screenWidth / standardColumnWidth / 2 * standardColumnWidth));
final float standardColumnWidth = EditorHelper.getPlainSpaceWidthFloat(editor);
final int screenMidColumn = (int) (screenWidth / standardColumnWidth / 2);
final int x = max(0, (int) Math.round(point.getX() - (screenMidColumn * standardColumnWidth)));
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
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;
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
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
// editor will give us the next character if X is over half way through the character grid.
int xActualLeft = editor.visualPositionToXY(closestVisualPosition).x;
// 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 halfway through the character grid. Take into account that
// 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) {
closestVisualPosition = getPreviousNonInlayVisualPosition(editor, closestVisualPosition);
xActualLeft = editor.visualPositionToXY(closestVisualPosition).x;
xActualLeft = Math.round(editor.visualPositionToPoint2D(closestVisualPosition).getX());
}
if (xActualLeft >= leftBound) {
final int xActualRight =
editor.visualPositionToXY(new VisualPosition(closestVisualPosition.line, closestVisualPosition.column + 1)).x -
1;
final VisualPosition nextVisualPosition = new VisualPosition(closestVisualPosition.line, closestVisualPosition.column + 1);
final long xActualRight = Math.round(editor.visualPositionToPoint2D(nextVisualPosition).getX()) - 1;
if (xActualRight <= rightBound) {
return closestVisualPosition.column;
}

View File

@@ -22,6 +22,7 @@ import com.intellij.codeInsight.template.TemplateManager
import com.intellij.codeWithMe.ClientId
import com.intellij.injected.editor.EditorWindow
import com.intellij.openapi.editor.Caret
import com.intellij.openapi.editor.ClientEditorManager
import com.intellij.openapi.editor.Document
import com.intellij.openapi.editor.Editor
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.options.OptionConstants
import com.maddyhome.idea.vim.options.OptionScope
import kotlin.streams.toList
/**
* 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)
* [VERSION UPDATE] 212+ ClientEditorManager.editors()
*/
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> {

View File

@@ -24,11 +24,8 @@ import com.intellij.openapi.actionSystem.ActionPlaces
import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.AnActionResult
import com.intellij.openapi.actionSystem.DataContext
import com.intellij.openapi.actionSystem.IdeActions
import com.intellij.openapi.actionSystem.PlatformCoreDataKeys
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.ActionUtil
import com.intellij.openapi.command.CommandProcessor
@@ -86,7 +83,7 @@ class IjActionExecutor : VimActionExecutor {
// This method executes inside of lastUpdateAndCheckDumb
// Another related issue: VIM-2604
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
val popup = JBPopupFactory.getInstance()
.createActionGroupPopup(event.presentation.text, ijAction, context.ij, false, null, -1)
@@ -118,10 +115,9 @@ class IjActionExecutor : VimActionExecutor {
var indexError: IndexNotReadyException? = null
val manager = ActionManagerEx.getInstanceEx()
manager.fireBeforeActionPerformed(action, event)
val component = event.getData(PlatformCoreDataKeys.CONTEXT_COMPONENT)
var result: AnActionResult? = null
try {
SlowOperations.allowSlowOperations(SlowOperations.ACTION_PERFORM).use { ignore ->
SlowOperations.allowSlowOperations(SlowOperations.ACTION_PERFORM).use {
performRunnable.run()
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
*

View File

@@ -25,9 +25,9 @@ import com.intellij.openapi.editor.Caret
import com.intellij.openapi.editor.Editor
import com.maddyhome.idea.vim.VimPlugin
import com.maddyhome.idea.vim.api.VimEditor
import com.maddyhome.idea.vim.command.VimStateMachine
import com.maddyhome.idea.vim.command.OperatorArguments
import com.maddyhome.idea.vim.command.SelectionType
import com.maddyhome.idea.vim.command.VimStateMachine
import com.maddyhome.idea.vim.common.TextRange
import com.maddyhome.idea.vim.listener.SelectionVimListenerSuppressor
import com.maddyhome.idea.vim.newapi.IjExecutionContext

View File

@@ -529,6 +529,9 @@ public class SearchHelper {
CharSequence subSequence = chars.subSequence(startOffset, endOffset);
int inQuotePos = pos - startOffset;
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) {
startPosInStringFound = true;
int inQuoteEnd = findBlockLocation(subSequence, type, close, Direction.FORWARDS, inQuoteStart, 1, false);
@@ -542,6 +545,9 @@ public class SearchHelper {
if (!startPosInStringFound) {
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) {
bend = findBlockLocation(chars, type, close, Direction.FORWARDS, bstart, 1, false);
}

View File

@@ -0,0 +1,45 @@
/*
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
* Copyright (C) 2003-2022 The IdeaVim authors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.maddyhome.idea.vim.helper
import com.maddyhome.idea.vim.api.injector
import java.util.*
import java.util.stream.Collectors
import javax.swing.KeyStroke
/**
* COMPATIBILITY-LAYER: Created a helper class
* Please see: https://jb.gg/zo8n0r
*/
object StringHelper {
@JvmStatic
fun parseKeys(string: String): List<KeyStroke> {
return injector.parser.parseKeys(string)
}
@JvmStatic
fun parseKeys(vararg string: String): List<KeyStroke> {
return Arrays.stream(string).flatMap { o: String -> injector.parser.parseKeys(o).stream() }
.collect(Collectors.toList())
}
@JvmStatic
fun isCloseKeyStroke(stroke: KeyStroke): Boolean {
return stroke.isCloseKeyStroke()
}
}

View File

@@ -21,6 +21,8 @@ package com.maddyhome.idea.vim.helper
import com.intellij.openapi.actionSystem.CommonDataKeys
import com.intellij.openapi.actionSystem.DataContext
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.components.Service
import com.maddyhome.idea.vim.api.ExecutionContext
@@ -39,22 +41,29 @@ import com.maddyhome.idea.vim.vimscript.services.IjVimOptionService
*/
@Service
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 {
val ijContext = context.context as DataContext
val project = PlatformDataKeys.PROJECT.getData(ijContext) ?: return false
val fileEditor = PlatformDataKeys.FILE_EDITOR.getData(ijContext)
val undoManager = UndoManager.getInstance(project)
if (fileEditor != null && undoManager.isUndoAvailable(fileEditor)) {
val editor = CommonDataKeys.EDITOR.getData(context.ij)?.vim
if (injector.optionService.isSet(OptionScope.GLOBAL, IjVimOptionService.oldUndo)) {
SelectionVimListenerSuppressor.lock().use { undoManager.undo(fileEditor) }
} else {
val editor = CommonDataKeys.EDITOR.getData(context.ij)?.vim
performUntilFileChanges(editor, { undoManager.isUndoAvailable(fileEditor) }, { undoManager.undo(fileEditor) })
}
editor?.carets()?.forEach {
val ijCaret = it.ij
val hasSelection = ijCaret.hasSelection()
if (hasSelection) {
val selectionStart = ijCaret.selectionStart
CommandProcessor.getInstance().runUndoTransparentAction {
it.ij.removeSelection()
it.ij.moveToOffset(selectionStart)
}
@@ -70,12 +79,14 @@ class UndoRedoHelper : UndoRedoBase() {
val project = PlatformDataKeys.PROJECT.getData(ijContext) ?: return false
val fileEditor = PlatformDataKeys.FILE_EDITOR.getData(ijContext)
val undoManager = UndoManager.getInstance(project)
val editor = CommonDataKeys.EDITOR.getData(context.ij)?.vim
if (fileEditor != null && undoManager.isRedoAvailable(fileEditor)) {
if (injector.optionService.isSet(OptionScope.GLOBAL, IjVimOptionService.oldUndo)) {
SelectionVimListenerSuppressor.lock().use { undoManager.redo(fileEditor) }
} else {
val editor = CommonDataKeys.EDITOR.getData(context.ij)?.vim
performUntilFileChanges(editor, { undoManager.isRedoAvailable(fileEditor) }, { undoManager.redo(fileEditor) })
}
CommandProcessor.getInstance().runUndoTransparentAction {
editor?.carets()?.forEach { it.ij.removeSelection() }
}
return true
@@ -95,10 +106,15 @@ class UndoRedoHelper : UndoRedoBase() {
}
}
val oldPath = editor.getPath()
vimDocument.addChangeListener(changeListener)
while (check() && !changeListener.hasChanged) {
while (check() && !changeListener.hasChanged && !ifFilePathChanged(editor, oldPath)) {
action.run()
}
vimDocument.removeChangeListener(changeListener)
}
private fun ifFilePathChanged(editor: IjVimEditor, oldPath: String?): Boolean {
return editor.getPath() != oldPath
}
}

View File

@@ -27,8 +27,9 @@ import com.intellij.openapi.editor.RangeMarker
import com.intellij.openapi.editor.markup.RangeHighlighter
import com.intellij.openapi.util.Key
import com.intellij.openapi.util.UserDataHolder
import com.maddyhome.idea.vim.command.VimStateMachine
import com.maddyhome.idea.vim.api.CaretRegisterStorageBase
import com.maddyhome.idea.vim.command.SelectionType
import com.maddyhome.idea.vim.command.VimStateMachine
import com.maddyhome.idea.vim.ex.ExOutputModel
import com.maddyhome.idea.vim.group.visual.VisualChange
import com.maddyhome.idea.vim.group.visual.vimLeadSelectionOffset
@@ -73,6 +74,7 @@ var Caret.vimInsertStart: RangeMarker by userDataOr {
this.offset
)
}
var Caret.registerStorage: CaretRegisterStorageBase? by userDataCaretToEditor()
// ------------------ Editor
fun unInitializeEditor(editor: Editor) {

View File

@@ -19,8 +19,6 @@
package com.maddyhome.idea.vim.key
import com.maddyhome.idea.vim.api.injector
import com.maddyhome.idea.vim.common.Node
import com.maddyhome.idea.vim.common.addLeafs
fun <T> Node<T>.addLeafs(keys: String, actionHolder: T) {
addLeafs(injector.parser.parseKeys(keys), actionHolder)

View File

@@ -21,8 +21,8 @@ package com.maddyhome.idea.vim.listener
import com.intellij.openapi.actionSystem.ActionManager
import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.AnActionResult
import com.intellij.openapi.actionSystem.CommonDataKeys
import com.intellij.openapi.actionSystem.DataContext
import com.intellij.openapi.actionSystem.IdeActions
import com.intellij.openapi.actionSystem.ex.AnActionListener
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.inVisualMode
import com.maddyhome.idea.vim.newapi.vim
import org.jetbrains.annotations.NotNull
/**
* A collection of hacks to improve the interaction with fancy AppCode templates
@@ -50,16 +49,16 @@ object AppCodeTemplates {
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
val hostEditor = dataContext.getData(CommonDataKeys.HOST_EDITOR)
val hostEditor = event.dataContext.getData(CommonDataKeys.HOST_EDITOR)
if (hostEditor != null) {
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 (ActionManager.getInstance().getId(action) == IdeActions.ACTION_CHOOSE_LOOKUP_ITEM) {
@@ -77,8 +76,8 @@ object AppCodeTemplates {
@JvmStatic
fun onMovement(
editor: @NotNull Editor,
caret: @NotNull Caret,
editor: Editor,
caret: Caret,
toRight: Boolean,
) {
val offset = caret.offset

View File

@@ -29,8 +29,8 @@ import com.intellij.find.FindModelListener
import com.intellij.openapi.actionSystem.ActionManager
import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.AnActionResult
import com.intellij.openapi.actionSystem.CommonDataKeys
import com.intellij.openapi.actionSystem.DataContext
import com.intellij.openapi.actionSystem.ex.AnActionListener
import com.intellij.openapi.actionSystem.impl.ProxyShortcutSet
import com.intellij.openapi.editor.Editor
@@ -40,9 +40,9 @@ import com.maddyhome.idea.vim.VimPlugin
import com.maddyhome.idea.vim.command.VimStateMachine
import com.maddyhome.idea.vim.group.NotificationService
import com.maddyhome.idea.vim.helper.EditorDataContext
import com.maddyhome.idea.vim.helper.vimStateMachine
import com.maddyhome.idea.vim.helper.inNormalMode
import com.maddyhome.idea.vim.helper.isIdeaVimDisabledHere
import com.maddyhome.idea.vim.helper.vimStateMachine
import com.maddyhome.idea.vim.newapi.vim
import com.maddyhome.idea.vim.options.OptionConstants
import com.maddyhome.idea.vim.options.OptionScope
@@ -60,10 +60,10 @@ object IdeaSpecifics {
private val surrounderAction =
"com.intellij.codeInsight.generation.surroundWith.SurroundWithHandler\$InvokeSurrounderAction"
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
val hostEditor = dataContext.getData(CommonDataKeys.HOST_EDITOR)
val hostEditor = event.dataContext.getData(CommonDataKeys.HOST_EDITOR)
if (hostEditor != null) {
editor = hostEditor
}
@@ -72,13 +72,13 @@ object IdeaSpecifics {
if (VimPlugin.getOptionService().isSet(OptionScope.GLOBAL, OptionConstants.trackactionidsName)) {
if (action !is NotificationService.ActionIdNotifier.CopyActionId && action !is NotificationService.ActionIdNotifier.StopTracking) {
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
}
override fun afterActionPerformed(action: AnAction, dataContext: DataContext, event: AnActionEvent) {
override fun afterActionPerformed(action: AnAction, event: AnActionEvent, result: AnActionResult) {
if (!VimPlugin.isEnabled()) return
//region Enter insert mode after surround with if
@@ -93,7 +93,7 @@ object IdeaSpecifics {
while (commandState.mode != VimStateMachine.Mode.COMMAND) {
commandState.popModes()
}
VimPlugin.getChange().insertBeforeCursor(it.vim, dataContext.vim)
VimPlugin.getChange().insertBeforeCursor(it.vim, event.dataContext.vim)
KeyHandler.getInstance().reset(it.vim)
}
}

View File

@@ -21,8 +21,8 @@ package com.maddyhome.idea.vim.listener
import com.intellij.openapi.actionSystem.ActionManager
import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.AnActionResult
import com.intellij.openapi.actionSystem.CommonDataKeys
import com.intellij.openapi.actionSystem.DataContext
import com.intellij.openapi.actionSystem.IdeActions
import com.intellij.openapi.actionSystem.ex.AnActionListener
import com.intellij.openapi.editor.Editor
@@ -36,16 +36,16 @@ import com.maddyhome.idea.vim.helper.getTopLevelEditor
class RiderActionListener : AnActionListener {
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
val hostEditor = dataContext.getData(CommonDataKeys.HOST_EDITOR)
val hostEditor = event.dataContext.getData(CommonDataKeys.HOST_EDITOR)
if (hostEditor != null) {
editor = hostEditor
}
}
override fun afterActionPerformed(action: AnAction, dataContext: DataContext, event: AnActionEvent) {
override fun afterActionPerformed(action: AnAction, event: AnActionEvent, result: AnActionResult) {
if (!VimPlugin.isEnabled()) return
//region Extend Selection for Rider

View File

@@ -122,9 +122,9 @@ object VimListenerManager {
VimPlugin.getOptionService().addListener(OptionConstants.guicursorName, GuicursorChangeListener)
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() {
@@ -136,10 +136,6 @@ object VimListenerManager {
VimPlugin.getOptionService().removeListener(OptionConstants.showcmdName, ShowCmdOptionChangeListener)
VimPlugin.getOptionService().removeListener(OptionConstants.guicursorName, GuicursorChangeListener)
VimPlugin.getOptionService().removeListener(OptionConstants.iskeywordName, KeywordOptionChangeListener)
EventFacade.getInstance().removeEditorFactoryListener(VimEditorFactoryListener)
EditorFactory.getInstance().eventMulticaster.removeCaretListener(VimCaretListener)
}
}

View File

@@ -32,8 +32,8 @@ import com.maddyhome.idea.vim.api.VimChangeGroupBase
import com.maddyhome.idea.vim.api.VimEditor
import com.maddyhome.idea.vim.api.VimMotionGroupBase
import com.maddyhome.idea.vim.api.injector
import com.maddyhome.idea.vim.command.VimStateMachine
import com.maddyhome.idea.vim.command.SelectionType
import com.maddyhome.idea.vim.command.VimStateMachine
import com.maddyhome.idea.vim.common.EditorLine
import com.maddyhome.idea.vim.common.IndentConfig
import com.maddyhome.idea.vim.common.OperatedRange
@@ -99,6 +99,7 @@ fun changeRange(
vimCaret.moveToOffset(deletedInfo.leftOffset.point)
}
is OperatedRange.Block -> TODO()
else -> TODO()
}
if (type == SelectionType.BLOCK_WISE) {
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 insertedLine = editor.addLine(position) ?: continue
val insertedLine = editor.addLine(position)
VimPlugin.getChange().saveStrokes("\n")
var lineStart = editor.getLineRange(insertedLine).first

View File

@@ -49,6 +49,7 @@ class IjClipboardManager : VimClipboardManager {
return Pair(res, transferableData)
}
@Suppress("UNCHECKED_CAST")
override fun setClipboardText(text: String, rawText: String, transferableData: List<Any>): Any? {
val transferableData1 = (transferableData as List<TextBlockTransferableData>).toMutableList()
try {
@@ -97,6 +98,7 @@ class IjClipboardManager : VimClipboardManager {
return transferableData
}
@Suppress("UNCHECKED_CAST")
override fun preprocessText(
vimEditor: VimEditor,
textRange: TextRange,

View File

@@ -33,11 +33,11 @@ class IjExecutionContextManager : ExecutionContextManagerBase() {
}
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 {
return IjExecutionContext(CaretSpecificDataContext(context.ij, caret.ij))
return IjExecutionContext(CaretSpecificDataContext.create(context.ij, caret.ij))
}
override fun createEditorDataContext(editor: VimEditor, context: ExecutionContext): ExecutionContext {

View File

@@ -22,7 +22,10 @@ import com.intellij.openapi.editor.Caret
import com.intellij.openapi.editor.LogicalPosition
import com.intellij.openapi.editor.VisualPosition
import com.maddyhome.idea.vim.VimPlugin
import com.maddyhome.idea.vim.api.CaretRegisterStorage
import com.maddyhome.idea.vim.api.CaretRegisterStorageBase
import com.maddyhome.idea.vim.api.VimCaret
import com.maddyhome.idea.vim.api.VimCaretBase
import com.maddyhome.idea.vim.api.VimEditor
import com.maddyhome.idea.vim.api.VimLogicalPosition
import com.maddyhome.idea.vim.api.VimVisualPosition
@@ -38,13 +41,23 @@ import com.maddyhome.idea.vim.group.visual.vimSetSystemSelectionSilently
import com.maddyhome.idea.vim.group.visual.vimUpdateEditorSelection
import com.maddyhome.idea.vim.helper.inlayAwareVisualColumn
import com.maddyhome.idea.vim.helper.moveToInlayAwareOffset
import com.maddyhome.idea.vim.helper.registerStorage
import com.maddyhome.idea.vim.helper.vimInsertStart
import com.maddyhome.idea.vim.helper.vimLastColumn
import com.maddyhome.idea.vim.helper.vimLastVisualOperatorRange
import com.maddyhome.idea.vim.helper.vimLine
import com.maddyhome.idea.vim.helper.vimSelectionStart
class IjVimCaret(val caret: Caret) : VimCaret {
class IjVimCaret(val caret: Caret) : VimCaretBase() {
override val registerStorage: CaretRegisterStorage
get() {
var storage = this.caret.registerStorage
if (storage == null) {
storage = CaretRegisterStorageBase(editor.primaryCaret().ij == caret)
this.caret.registerStorage = storage
}
return storage
}
override val editor: VimEditor
get() = IjVimEditor(caret.editor)
override val offset: Offset

View File

@@ -38,9 +38,9 @@ import com.maddyhome.idea.vim.api.VimLogicalPosition
import com.maddyhome.idea.vim.api.VimSelectionModel
import com.maddyhome.idea.vim.api.VimVisualPosition
import com.maddyhome.idea.vim.api.VirtualFile
import com.maddyhome.idea.vim.command.VimStateMachine
import com.maddyhome.idea.vim.command.OperatorArguments
import com.maddyhome.idea.vim.command.SelectionType
import com.maddyhome.idea.vim.command.VimStateMachine
import com.maddyhome.idea.vim.common.EditorLine
import com.maddyhome.idea.vim.common.LiveRange
import com.maddyhome.idea.vim.common.Offset
@@ -62,7 +62,9 @@ import com.maddyhome.idea.vim.helper.updateCaretsVisualPosition
import com.maddyhome.idea.vim.helper.vimChangeActionSwitchMode
import com.maddyhome.idea.vim.helper.vimKeepingVisualOperatorAction
import com.maddyhome.idea.vim.helper.vimLastSelectionType
import org.jetbrains.annotations.ApiStatus
@ApiStatus.Internal
class IjVimEditor(editor: Editor) : MutableLinearEditor() {
// All the editor actions should be performed with top level editor!!!

View File

@@ -68,15 +68,15 @@ import com.maddyhome.idea.vim.helper.vimStateMachine
import com.maddyhome.idea.vim.history.VimHistory
import com.maddyhome.idea.vim.macro.VimMacro
import com.maddyhome.idea.vim.mark.VimMarkGroup
import com.maddyhome.idea.vim.options.OptionService
import com.maddyhome.idea.vim.put.VimPut
import com.maddyhome.idea.vim.register.VimRegisterGroup
import com.maddyhome.idea.vim.ui.VimRcFileState
import com.maddyhome.idea.vim.undo.VimUndoRedo
import com.maddyhome.idea.vim.vimscript.Executor
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.VimVariableService
import com.maddyhome.idea.vim.vimscript.services.VariableService
import com.maddyhome.idea.vim.yank.VimYankGroup
class IjVimInjector : VimInjectorBase() {
@@ -161,7 +161,7 @@ class IjVimInjector : VimInjectorBase() {
override val functionService: VimscriptFunctionService
get() = FunctionStorage
override val variableService: VimVariableService
override val variableService: VariableService
get() = service()
override val vimrcFileState: VimrcFileState
get() = VimRcFileState

View File

@@ -37,19 +37,19 @@ class IjVimMessages : VimMessagesBase() {
private var error = false
private var lastBeepTimeMillis = 0L
override fun showStatusBarMessage(msg: String?) {
override fun showStatusBarMessage(message: String?) {
if (ApplicationManager.getApplication().isUnitTestMode) {
message = msg
this.message = message
}
val pm = ProjectManager.getInstance()
val projects = pm.openProjects
for (project in projects) {
val bar = WindowManager.getInstance().getStatusBar(project)
if (bar != null) {
if (msg.isNullOrEmpty()) {
if (message.isNullOrEmpty()) {
bar.info = ""
} else {
bar.info = "VIM - $msg"
bar.info = "VIM - $message"
}
}
}

View File

@@ -22,18 +22,25 @@ import com.maddyhome.idea.vim.api.injector
import com.maddyhome.idea.vim.options.OptionConstants
import com.maddyhome.idea.vim.options.OptionConstants.Companion.ignorecaseName
import com.maddyhome.idea.vim.options.OptionConstants.Companion.smartcaseName
import com.maddyhome.idea.vim.options.OptionConstants.Companion.timeoutName
import com.maddyhome.idea.vim.options.OptionConstants.Companion.timeoutlenName
import com.maddyhome.idea.vim.options.OptionScope
import com.maddyhome.idea.vim.options.helpers.KeywordOptionHelper
import com.maddyhome.idea.vim.vimscript.services.IjVimOptionService
/**
* COMPATIBILITY-LAYER: Added a class and package
* Please see: https://jb.gg/zo8n0r
*/
object OptionsManager {
val ignorecase: ToggleOption
get() = (injector.optionService as IjVimOptionService).getRawOption(ignorecaseName) as ToggleOption
get() = (injector.optionService as IjVimOptionService).getOptionByNameOrAbbr(ignorecaseName) as 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
get() = (injector.optionService as IjVimOptionService).getOptionByNameOrAbbr(timeoutName) as ToggleOption
val timeoutlen: NumberOption
get() = (injector.optionService as IjVimOptionService).getOptionByNameOrAbbr(timeoutlenName) as NumberOption
val iskeyword: KeywordOption
get() = KeywordOption(KeywordOptionHelper)
}

View File

@@ -18,6 +18,7 @@
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.events.EventFields
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() {
companion object {
private val GROUP = EventLogGroup("vim.actions", 1)
private val TRACKED_ACTIONS = GROUP.registerEvent("tracked", EventFields.StringValidatedByCustomRule("action_id", "action"))
private val COPIED_ACTIONS = GROUP.registerEvent("copied", EventFields.StringValidatedByCustomRule("action_id", "action"))
private val TRACKED_ACTIONS = GROUP.registerEvent(
"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) {
TRACKED_ACTIONS.log(actionId)

View File

@@ -20,8 +20,8 @@ package com.maddyhome.idea.vim.ui
import com.maddyhome.idea.vim.KeyHandler
import com.maddyhome.idea.vim.api.VimEditor
import com.maddyhome.idea.vim.helper.vimStateMachine
import com.maddyhome.idea.vim.helper.isCloseKeyStroke
import com.maddyhome.idea.vim.helper.vimStateMachine
import java.awt.KeyEventDispatcher
import java.awt.KeyboardFocusManager
import java.awt.Toolkit

View File

@@ -48,13 +48,13 @@ class Executor : VimScriptExecutorBase() {
override var executingVimscript = false
@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
val script = VimscriptParser.parse(scriptString)
script.units.forEach { it.vimContext = vimContext ?: script }
val myScript = VimscriptParser.parse(script)
myScript.units.forEach { it.vimContext = vimContext ?: myScript }
for (unit in script.units) {
for (unit in myScript.units) {
try {
val result = unit.execute(editor, context)
if (result is ExecutionResult.Error) {
@@ -89,18 +89,18 @@ class Executor : VimScriptExecutorBase() {
}
if (!skipHistory) {
VimPlugin.getHistory().addEntry(HistoryConstants.COMMAND, scriptString)
if (script.units.size == 1 && script.units[0] is Command && script.units[0] !is RepeatCommand) {
VimPlugin.getRegister().storeTextSpecial(LAST_COMMAND_REGISTER, scriptString)
VimPlugin.getHistory().addEntry(HistoryConstants.COMMAND, script)
if (myScript.units.size == 1 && myScript.units[0] is Command && myScript.units[0] !is RepeatCommand) {
VimPlugin.getRegister().storeTextSpecial(LAST_COMMAND_REGISTER, script)
}
}
return finalResult
}
override fun execute(scriptString: String, skipHistory: Boolean) {
override fun execute(script: String, skipHistory: Boolean) {
val editor = TextComponentEditorImpl(null, JTextArea()).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) {

View File

@@ -23,6 +23,7 @@ import com.intellij.openapi.actionSystem.KeyboardShortcut
import com.maddyhome.idea.vim.api.ExecutionContext
import com.maddyhome.idea.vim.api.VimEditor
import com.maddyhome.idea.vim.api.injector
import com.maddyhome.idea.vim.command.OperatorArguments
import com.maddyhome.idea.vim.ex.ExOutputModel
import com.maddyhome.idea.vim.ex.ranges.Ranges
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) {
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 searchPattern = argument.trim().lowercase(Locale.getDefault()).split("*")
val actionManager = ActionManager.getInstance()

View File

@@ -23,6 +23,7 @@ import com.intellij.openapi.fileEditor.FileEditorManager
import com.maddyhome.idea.vim.VimPlugin
import com.maddyhome.idea.vim.api.ExecutionContext
import com.maddyhome.idea.vim.api.VimEditor
import com.maddyhome.idea.vim.command.OperatorArguments
import com.maddyhome.idea.vim.ex.ranges.Ranges
import com.maddyhome.idea.vim.helper.EditorHelper
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) {
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 overrideModified = arg.startsWith('!')
val buffer = if (overrideModified) arg.replace(Regex("^!\\s*"), "") else arg

View File

@@ -26,6 +26,7 @@ import com.intellij.openapi.vfs.VirtualFile
import com.maddyhome.idea.vim.VimPlugin
import com.maddyhome.idea.vim.api.ExecutionContext
import com.maddyhome.idea.vim.api.VimEditor
import com.maddyhome.idea.vim.command.OperatorArguments
import com.maddyhome.idea.vim.ex.ExOutputModel
import com.maddyhome.idea.vim.ex.ranges.Ranges
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', '%', '#')
}
override fun processCommand(editor: VimEditor, context: ExecutionContext): ExecutionResult {
override fun processCommand(editor: VimEditor, context: ExecutionContext, operatorArguments: OperatorArguments): ExecutionResult {
val arg = argument.trim()
val filter = pruneUnsupportedFilters(arg)
val bufferList = getBufferList(context, filter)

View File

@@ -24,6 +24,7 @@ import com.intellij.openapi.progress.ProcessCanceledException
import com.maddyhome.idea.vim.VimPlugin
import com.maddyhome.idea.vim.api.ExecutionContext
import com.maddyhome.idea.vim.api.VimEditor
import com.maddyhome.idea.vim.command.OperatorArguments
import com.maddyhome.idea.vim.ex.ExException
import com.maddyhome.idea.vim.ex.ExOutputModel
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) {
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")
val command = buildString {
var inBackslash = false

View File

@@ -23,6 +23,7 @@ import com.maddyhome.idea.vim.VimPlugin
import com.maddyhome.idea.vim.api.ExecutionContext
import com.maddyhome.idea.vim.api.VimEditor
import com.maddyhome.idea.vim.api.injector
import com.maddyhome.idea.vim.command.OperatorArguments
import com.maddyhome.idea.vim.ex.ranges.LineRange
import com.maddyhome.idea.vim.ex.ranges.Ranges
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) {
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
editor.removeSecondaryCarets()
val caret = editor.currentCaret()

View File

@@ -21,6 +21,7 @@ package com.maddyhome.idea.vim.vimscript.model.commands
import com.intellij.ide.BrowserUtil
import com.maddyhome.idea.vim.api.ExecutionContext
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.vimscript.model.ExecutionResult
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) {
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))
return ExecutionResult.Success
}

View File

@@ -25,9 +25,9 @@ import com.intellij.codeInsight.lookup.impl.LookupImpl
import com.intellij.codeInsight.template.impl.TemplateManagerImpl
import com.intellij.openapi.editor.Editor
import com.maddyhome.idea.vim.VimPlugin
import com.maddyhome.idea.vim.helper.editorMode
import com.maddyhome.idea.vim.helper.hasBlockOrUnderscoreCaret
import com.maddyhome.idea.vim.helper.hasVisualSelection
import com.maddyhome.idea.vim.helper.editorMode
import com.maddyhome.idea.vim.helper.subMode
import com.maddyhome.idea.vim.listener.SelectionVimListenerSuppressor
import com.maddyhome.idea.vim.newapi.vim

View File

@@ -33,7 +33,7 @@ import com.maddyhome.idea.vim.vimscript.model.datatypes.VimString
import com.maddyhome.idea.vim.vimscript.model.expressions.Scope
import com.maddyhome.idea.vim.vimscript.model.expressions.Variable
internal class VimVariableServiceImpl : VimVariableServiceBase() {
class IjVariableService : VimVariableServiceBase() {
override fun storeVariable(variable: Variable, value: VimDataType, editor: VimEditor, context: ExecutionContext, vimContext: VimLContext) {
super.storeVariable(variable, value, editor, context, vimContext)

View File

@@ -20,14 +20,14 @@ package com.maddyhome.idea.vim.vimscript.services
import com.intellij.openapi.application.ApplicationNamesInfo
import com.maddyhome.idea.vim.api.VimOptionServiceBase
import com.maddyhome.idea.vim.option.ToggleOption
import com.maddyhome.idea.vim.options.OptionConstants
import com.maddyhome.idea.vim.options.StringOption
import com.maddyhome.idea.vim.option.ToggleOption
internal class IjVimOptionService : VimOptionServiceBase() {
private val customOptions = setOf(
ToggleOption(oldUndo, oldUndo, false),
ToggleOption(oldUndo, oldUndo, true),
ToggleOption(ideajoinName, ideajoinAlias, false),
ToggleOption(ideamarksName, ideamarksAlias, true),
StringOption(ideName, ideAlias, ApplicationNamesInfo.getInstance().fullProductNameWithEdition),

View File

@@ -26,13 +26,13 @@
serviceInterface="com.maddyhome.idea.vim.api.VimVisualMotionGroup"/>
<applicationService serviceImplementation="com.maddyhome.idea.vim.group.copy.YankGroup"/>
<applicationService serviceImplementation="com.maddyhome.idea.vim.group.copy.PutGroup"/>
<applicationService serviceImplementation="com.maddyhome.idea.vim.vimscript.services.VimVariableServiceImpl"
serviceInterface="com.maddyhome.idea.vim.vimscript.services.VimVariableService"/>
<applicationService serviceImplementation="com.maddyhome.idea.vim.vimscript.services.IjVariableService"
serviceInterface="com.maddyhome.idea.vim.vimscript.services.VariableService"/>
<applicationService serviceImplementation="com.maddyhome.idea.vim.group.IjStatisticsService"
serviceInterface="com.maddyhome.idea.vim.api.VimStatistics"/>
<applicationService serviceImplementation="com.maddyhome.idea.vim.vimscript.services.IjVimOptionService"
serviceInterface="com.maddyhome.idea.vim.options.OptionService"/>
serviceInterface="com.maddyhome.idea.vim.vimscript.services.OptionService"/>
<applicationService serviceImplementation="com.maddyhome.idea.vim.group.IjVimStorageService"
serviceInterface="com.maddyhome.idea.vim.api.VimStorageService"/>
<applicationService serviceImplementation="com.maddyhome.idea.vim.group.IjVimSystemInfoService"

View File

@@ -2,55 +2,7 @@
<name>IdeaVim</name>
<id>IdeaVIM</id>
<change-notes><![CDATA[
<h3>Features:</h3>
<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>
<a href="https://github.com/JetBrains/ideavim/blob/master/CHANGES.md">Changes</a>
]]>
</change-notes>
<description><![CDATA[
@@ -70,8 +22,8 @@
<!-- Please search for "[VERSION UPDATE]" in project in case you update the since-build version -->
<!-- Check for [Version Update] tag in YouTrack as well -->
<!-- Also, please update the value in gradle.build file-->
<idea-version since-build="213"/>
<!-- Also, please update the value in build.gradle.kts file-->
<idea-version since-build="222"/>
<!-- Mark the plugin as compatible with RubyMine and other products based on the IntelliJ platform (including CWM) -->
<depends>com.intellij.modules.platform</depends>

View File

@@ -31,9 +31,8 @@ import com.maddyhome.idea.vim.helper.RunnableHelper;
import com.maddyhome.idea.vim.helper.TestInputModel;
import com.maddyhome.idea.vim.newapi.IjExecutionContext;
import com.maddyhome.idea.vim.newapi.IjVimEditor;
import com.maddyhome.idea.vim.ui.ex.ExEntryPanel;
import com.maddyhome.idea.vim.options.OptionScope;
import com.maddyhome.idea.vim.vimscript.services.VimVariableServiceImpl;
import com.maddyhome.idea.vim.ui.ex.ExEntryPanel;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -63,7 +62,7 @@ public abstract class JavaVimTestCase extends JavaCodeInsightFixtureTestCase {
@Override
protected void tearDown() throws Exception {
ExEntryPanel.getInstance().deactivate(false);
((VimVariableServiceImpl) VimPlugin.getVariableService()).clear();
VimPlugin.getVariableService().clear();
Timer swingTimer = VimVisualTimer.INSTANCE.getSwingTimer();
if (swingTimer != null) {
swingTimer.stop();

View File

@@ -112,7 +112,10 @@ internal object NeovimTesting {
when {
keys.equals("<esc>", ignoreCase = true) -> neovimApi.input(escapeCommand).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,
GUARDED_BLOCKS,
CTRL_CODES,
}
fun LogicalPosition.toVimCoords(): VimCoords {

View File

@@ -21,11 +21,11 @@ package org.jetbrains.plugins.ideavim
import com.maddyhome.idea.vim.RegisterActions.VIM_ACTIONS_EP
import com.maddyhome.idea.vim.VimPlugin
import com.maddyhome.idea.vim.api.injector
import com.maddyhome.idea.vim.command.VimStateMachine
import com.maddyhome.idea.vim.common.CommandNode
import com.maddyhome.idea.vim.common.CommandPartNode
import com.maddyhome.idea.vim.command.MappingMode
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.CommandPartNode
import junit.framework.TestCase
import javax.swing.KeyStroke
@@ -38,6 +38,7 @@ class RegisterActionsTest : VimTestCase() {
@TestWithoutNeovim(reason = SkipNeovimReason.EDITOR_MODIFICATION)
fun `test action in disabled plugin`() {
try {
setupChecks {
caretShape = false
}
@@ -47,6 +48,9 @@ class RegisterActionsTest : VimTestCase() {
doTest(keys, before, after, VimStateMachine.Mode.COMMAND, VimStateMachine.SubMode.NONE) {
VimPlugin.setEnabled(false)
}
} finally {
VimPlugin.setEnabled(true)
}
}
@TestWithoutNeovim(reason = SkipNeovimReason.EDITOR_MODIFICATION)

View File

@@ -34,7 +34,6 @@ import com.intellij.openapi.editor.LogicalPosition
import com.intellij.openapi.editor.VisualPosition
import com.intellij.openapi.editor.colors.EditorColors
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.fileTypes.FileType
import com.intellij.openapi.fileTypes.PlainTextFileType
@@ -50,9 +49,9 @@ import com.maddyhome.idea.vim.KeyHandler
import com.maddyhome.idea.vim.VimPlugin
import com.maddyhome.idea.vim.action.VimShortcutKeyAction
import com.maddyhome.idea.vim.api.injector
import com.maddyhome.idea.vim.command.MappingMode
import com.maddyhome.idea.vim.command.VimStateMachine
import com.maddyhome.idea.vim.command.VimStateMachine.SubMode
import com.maddyhome.idea.vim.command.MappingMode
import com.maddyhome.idea.vim.ex.ExException
import com.maddyhome.idea.vim.ex.ExOutputModel.Companion.getInstance
import com.maddyhome.idea.vim.group.visual.VimVisualTimer.swingTimer
@@ -61,9 +60,9 @@ import com.maddyhome.idea.vim.helper.EditorHelper
import com.maddyhome.idea.vim.helper.GuicursorChangeListener
import com.maddyhome.idea.vim.helper.RunnableHelper.runWriteCommand
import com.maddyhome.idea.vim.helper.TestInputModel
import com.maddyhome.idea.vim.helper.editorMode
import com.maddyhome.idea.vim.helper.getGuiCursorMode
import com.maddyhome.idea.vim.helper.inBlockSubMode
import com.maddyhome.idea.vim.helper.editorMode
import com.maddyhome.idea.vim.helper.subMode
import com.maddyhome.idea.vim.key.MappingOwner
import com.maddyhome.idea.vim.key.ToKeysMappingInfo
@@ -77,12 +76,12 @@ import com.maddyhome.idea.vim.ui.ex.ExEntryPanel
import com.maddyhome.idea.vim.vimscript.model.datatypes.VimFuncref
import com.maddyhome.idea.vim.vimscript.model.datatypes.VimInt
import com.maddyhome.idea.vim.vimscript.parser.errors.IdeavimErrorListener
import com.maddyhome.idea.vim.vimscript.services.VimVariableServiceImpl
import org.assertj.core.api.Assertions
import org.junit.Assert
import java.awt.event.KeyEvent
import java.util.*
import javax.swing.KeyStroke
import kotlin.math.roundToInt
/**
* @author vlan
@@ -137,7 +136,7 @@ abstract class VimTestCase : UsefulTestCase() {
}
SelectionVimListenerSuppressor.lock().use { myFixture.tearDown() }
ExEntryPanel.getInstance().deactivate(false)
(VimPlugin.getVariableService() as VimVariableServiceImpl).clear()
VimPlugin.getVariableService().clear()
VimFuncref.lambdaCounter = 0
VimFuncref.anonymousCounter = 0
IdeavimErrorListener.testLogger.clear()
@@ -170,7 +169,9 @@ abstract class VimTestCase : UsefulTestCase() {
get() = 35
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() {
@@ -610,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
// pixel widths
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)
}
@@ -620,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.
protected fun addBlockInlay(offset: Int, showAbove: Boolean, heightInRows: Int): Inlay<*> {
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
return EditorTestUtil.addBlockInlay(myFixture.editor, offset, false, showAbove, widthInPixels, heightInPixels)
}

View File

@@ -71,6 +71,7 @@ class ChangeActionTest : VimTestCase() {
}
// VIM-620 |i_CTRL-O|
@TestWithoutNeovim(SkipNeovimReason.SELECT_MODE)
fun testInsertSingleCommandAndNewLineInserting5() {
doTest(
listOf("i", "<C-O>", "v", "<C-G>"),
@@ -79,6 +80,7 @@ class ChangeActionTest : VimTestCase() {
}
// VIM-620 |i_CTRL-O|
@TestWithoutNeovim(SkipNeovimReason.SELECT_MODE)
fun testInsertSingleCommandAndNewLineInserting6() {
doTest(
listOf("i", "<C-O>", "gh"),
@@ -87,6 +89,7 @@ class ChangeActionTest : VimTestCase() {
}
// VIM-620 |i_CTRL-O|
@TestWithoutNeovim(SkipNeovimReason.SELECT_MODE)
fun testInsertSingleCommandAndNewLineInserting7() {
doTest(
listOf("i", "<C-O>", "gh", "<esc>"),
@@ -443,14 +446,15 @@ quux
)
}
@VimBehaviorDiffers(originalVimAfter = "foo bar")
fun testDeleteJoinLinesWithTrailingSpaceThenEmptyLine() {
doTest(
"3J",
"""
foo
foo.
bar
""".trimIndent(),
""".dotToSpace().trimIndent(),
"foo bar", VimStateMachine.Mode.COMMAND, VimStateMachine.SubMode.NONE
)
}
@@ -459,9 +463,9 @@ quux
doTest(
"J",
"""
foo
foo..
bar
""".trimIndent(),
""".dotToSpace().trimIndent(),
"foo bar", VimStateMachine.Mode.COMMAND, VimStateMachine.SubMode.NONE
)
}

Some files were not shown because too many files have changed in this diff Show More