mirror of
https://github.com/chylex/IntelliJ-IdeaVim.git
synced 2025-08-17 16:31:45 +02:00
Compare commits
64 Commits
0f0a73c139
...
b7c1ba4f02
Author | SHA1 | Date | |
---|---|---|---|
b7c1ba4f02
|
|||
fca7b518b3
|
|||
8aa4178449
|
|||
2e035f1260
|
|||
c5f17a68f5
|
|||
68b7788fe4
|
|||
3299059ab9
|
|||
548ed30b5b
|
|||
b171ccb96c
|
|||
93affef6d3
|
|||
0b788153cd
|
|||
70d8167e17
|
|||
67c3dec51b
|
|||
3dab706f37
|
|||
5228bca65e
|
|||
853a208eba
|
|||
fd9297edb1
|
|||
e01e4d8ecd
|
|||
b304692c4e
|
|||
05b9f44a0b
|
|||
d878b119c4
|
|||
def57128b0
|
|||
fd4422bf95
|
|||
d10a0c4ee7
|
|||
![]() |
f12b0b04f6 | ||
![]() |
ea4fc85e5b | ||
![]() |
4af8fc1868 | ||
![]() |
1482ac0335 | ||
![]() |
79168b00f3 | ||
![]() |
07990847c6 | ||
![]() |
8c40e19c44 | ||
![]() |
371769c508 | ||
![]() |
7ee34d0b27 | ||
![]() |
d1ec7d617d | ||
![]() |
898fd0537d | ||
![]() |
353603b546 | ||
![]() |
2f7f0dcacb | ||
![]() |
af9023af4b | ||
![]() |
c393c902b2 | ||
![]() |
c355cb7ed7 | ||
![]() |
0803a1c195 | ||
![]() |
5208412b46 | ||
![]() |
78c463cf7b | ||
![]() |
8f5a44bf44 | ||
![]() |
2377408028 | ||
![]() |
246425b1fb | ||
![]() |
4eadfc1fba | ||
![]() |
d3c945cd6d | ||
![]() |
2ac46129ac | ||
![]() |
c8d40be1ce | ||
![]() |
97159a33fe | ||
![]() |
861d585102 | ||
![]() |
126925b4eb | ||
![]() |
9302c0a057 | ||
![]() |
ddea72f803 | ||
![]() |
e991aa922c | ||
![]() |
5ffaa7b084 | ||
![]() |
0d4183129d | ||
![]() |
8a7fbac389 | ||
![]() |
dbab006f83 | ||
![]() |
3149de7b73 | ||
![]() |
28a71f0e09 | ||
![]() |
fc7d4e614b | ||
![]() |
5b1aade876 |
3
.idea/runConfigurations/IdeaVim_tests.xml
generated
3
.idea/runConfigurations/IdeaVim_tests.xml
generated
@@ -5,7 +5,7 @@
|
|||||||
<option name="executionName" />
|
<option name="executionName" />
|
||||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||||
<option name="externalSystemIdString" value="GRADLE" />
|
<option name="externalSystemIdString" value="GRADLE" />
|
||||||
<option name="scriptParameters" value="" />
|
<option name="scriptParameters" value="-x :tests:property-tests:test -x :tests:long-running-tests:test" />
|
||||||
<option name="taskDescriptions">
|
<option name="taskDescriptions">
|
||||||
<list />
|
<list />
|
||||||
</option>
|
</option>
|
||||||
@@ -19,6 +19,7 @@
|
|||||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||||
<DebugAllEnabled>false</DebugAllEnabled>
|
<DebugAllEnabled>false</DebugAllEnabled>
|
||||||
|
<RunAsTest>false</RunAsTest>
|
||||||
<method v="2" />
|
<method v="2" />
|
||||||
</configuration>
|
</configuration>
|
||||||
</component>
|
</component>
|
1
.teamcity/_Self/buildTypes/Compatibility.kt
vendored
1
.teamcity/_Self/buildTypes/Compatibility.kt
vendored
@@ -45,6 +45,7 @@ object Compatibility : IdeaVimBuildType({
|
|||||||
java -jar verifier1/verifier-cli-dev-all-2.jar check-plugin '${'$'}com.julienphalip.ideavim.functiontextobj' [latest-IU] -team-city
|
java -jar verifier1/verifier-cli-dev-all-2.jar check-plugin '${'$'}com.julienphalip.ideavim.functiontextobj' [latest-IU] -team-city
|
||||||
java -jar verifier1/verifier-cli-dev-all-2.jar check-plugin '${'$'}com.miksuki.HighlightCursor' [latest-IU] -team-city
|
java -jar verifier1/verifier-cli-dev-all-2.jar check-plugin '${'$'}com.miksuki.HighlightCursor' [latest-IU] -team-city
|
||||||
java -jar verifier1/verifier-cli-dev-all-2.jar check-plugin '${'$'}com.ugarosa.idea.edgemotion' [latest-IU] -team-city
|
java -jar verifier1/verifier-cli-dev-all-2.jar check-plugin '${'$'}com.ugarosa.idea.edgemotion' [latest-IU] -team-city
|
||||||
|
java -jar verifier1/verifier-cli-dev-all-2.jar check-plugin '${'$'}cn.mumukehao.plugin' [latest-IU] -team-city
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
2
.teamcity/_Self/buildTypes/LongRunning.kt
vendored
2
.teamcity/_Self/buildTypes/LongRunning.kt
vendored
@@ -25,7 +25,7 @@ object LongRunning : IdeaVimBuildType({
|
|||||||
|
|
||||||
steps {
|
steps {
|
||||||
gradle {
|
gradle {
|
||||||
tasks = "clean :tests:long-running-tests:testLongRunning"
|
tasks = "clean :tests:long-running-tests:test"
|
||||||
buildFile = ""
|
buildFile = ""
|
||||||
enableStacktrace = true
|
enableStacktrace = true
|
||||||
jdkHome = "/usr/lib/jvm/java-21-amazon-corretto"
|
jdkHome = "/usr/lib/jvm/java-21-amazon-corretto"
|
||||||
|
2
.teamcity/_Self/buildTypes/Nvim.kt
vendored
2
.teamcity/_Self/buildTypes/Nvim.kt
vendored
@@ -39,7 +39,7 @@ object Nvim : IdeaVimBuildType({
|
|||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
}
|
}
|
||||||
gradle {
|
gradle {
|
||||||
tasks = "clean test -Dnvim"
|
tasks = "clean test -x :tests:property-tests:test -x :tests:long-running-tests:test -Dnvim"
|
||||||
buildFile = ""
|
buildFile = ""
|
||||||
enableStacktrace = true
|
enableStacktrace = true
|
||||||
jdkHome = "/usr/lib/jvm/java-21-amazon-corretto"
|
jdkHome = "/usr/lib/jvm/java-21-amazon-corretto"
|
||||||
|
2
.teamcity/_Self/buildTypes/PropertyBased.kt
vendored
2
.teamcity/_Self/buildTypes/PropertyBased.kt
vendored
@@ -25,7 +25,7 @@ object PropertyBased : IdeaVimBuildType({
|
|||||||
steps {
|
steps {
|
||||||
gradle {
|
gradle {
|
||||||
clearConditions()
|
clearConditions()
|
||||||
tasks = "clean :tests:property-tests:testPropertyBased"
|
tasks = "clean :tests:property-tests:test"
|
||||||
buildFile = ""
|
buildFile = ""
|
||||||
enableStacktrace = true
|
enableStacktrace = true
|
||||||
jdkHome = "/usr/lib/jvm/java-21-amazon-corretto"
|
jdkHome = "/usr/lib/jvm/java-21-amazon-corretto"
|
||||||
|
2
.teamcity/_Self/buildTypes/ReleasePlugin.kt
vendored
2
.teamcity/_Self/buildTypes/ReleasePlugin.kt
vendored
@@ -115,7 +115,7 @@ sealed class ReleasePlugin(private val releaseType: String) : IdeaVimBuildType({
|
|||||||
}
|
}
|
||||||
script {
|
script {
|
||||||
name = "Run tests"
|
name = "Run tests"
|
||||||
scriptContent = "./gradlew test"
|
scriptContent = "./gradlew test -x :tests:property-tests:test -x :tests:long-running-tests:test"
|
||||||
}
|
}
|
||||||
gradle {
|
gradle {
|
||||||
name = "Publish release"
|
name = "Publish release"
|
||||||
|
@@ -40,7 +40,7 @@ open class TestingBuildType(
|
|||||||
steps {
|
steps {
|
||||||
gradle {
|
gradle {
|
||||||
clearConditions()
|
clearConditions()
|
||||||
tasks = "clean test"
|
tasks = "clean test -x :tests:property-tests:test -x :tests:long-running-tests:test"
|
||||||
buildFile = ""
|
buildFile = ""
|
||||||
enableStacktrace = true
|
enableStacktrace = true
|
||||||
jdkHome = "/usr/lib/jvm/java-21-amazon-corretto"
|
jdkHome = "/usr/lib/jvm/java-21-amazon-corretto"
|
||||||
|
2
.teamcity/_Self/subprojects/GitHub.kt
vendored
2
.teamcity/_Self/subprojects/GitHub.kt
vendored
@@ -15,7 +15,7 @@ object GitHub : Project({
|
|||||||
name = "Pull Requests checks"
|
name = "Pull Requests checks"
|
||||||
description = "Automatic checking of GitHub Pull Requests"
|
description = "Automatic checking of GitHub Pull Requests"
|
||||||
|
|
||||||
buildType(GithubBuildType("clean test", "Tests"))
|
buildType(GithubBuildType("clean test -x :tests:property-tests:test -x :tests:long-running-tests:test", "Tests"))
|
||||||
})
|
})
|
||||||
|
|
||||||
class GithubBuildType(command: String, desc: String) : IdeaVimBuildType({
|
class GithubBuildType(command: String, desc: String) : IdeaVimBuildType({
|
||||||
|
@@ -614,6 +614,14 @@ Contributors:
|
|||||||
[![icon][github]](https://github.com/Malandril)
|
[![icon][github]](https://github.com/Malandril)
|
||||||
|
|
||||||
Thomas Canava
|
Thomas Canava
|
||||||
|
* [![icon][mail]](mailto:xinhe.wang@jetbrains.com)
|
||||||
|
[![icon][github]](https://github.com/wxh06)
|
||||||
|
|
||||||
|
Xinhe Wang
|
||||||
|
* [![icon][mail]](mailto:zuber.kuba@gmail.com)
|
||||||
|
[![icon][github]](https://github.com/zuberol)
|
||||||
|
|
||||||
|
Jakub Zuber
|
||||||
|
|
||||||
Previous contributors:
|
Previous contributors:
|
||||||
|
|
||||||
|
@@ -65,7 +65,7 @@ We've prepared some useful configurations for you:
|
|||||||
And here are useful gradle commands:
|
And here are useful gradle commands:
|
||||||
|
|
||||||
* `./gradlew runIde` — start the dev version of IntelliJ IDEA with IdeaVim installed.
|
* `./gradlew runIde` — start the dev version of IntelliJ IDEA with IdeaVim installed.
|
||||||
* `./gradlew test` — run tests.
|
* `./gradlew test -x :tests:property-tests:test -x :tests:long-running-tests:test` — run tests.
|
||||||
* `./gradlew buildPlugin` — build the plugin. The result will be located in `build/distributions`. This file can be
|
* `./gradlew buildPlugin` — build the plugin. The result will be located in `build/distributions`. This file can be
|
||||||
installed by using `Settings | Plugin | >Gear Icon< | Install Plugin from Disk...`. You can stay with your personal build
|
installed by using `Settings | Plugin | >Gear Icon< | Install Plugin from Disk...`. You can stay with your personal build
|
||||||
for a few days or send it to a friend for testing.
|
for a few days or send it to a friend for testing.
|
||||||
|
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
kotlin("jvm")
|
kotlin("jvm")
|
||||||
kotlin("plugin.serialization") version "2.0.21"
|
kotlin("plugin.serialization") version "2.2.0"
|
||||||
}
|
}
|
||||||
|
|
||||||
val kotlinxSerializationVersion: String by project
|
val kotlinxSerializationVersion: String by project
|
||||||
@@ -21,7 +21,7 @@ repositories {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compileOnly("com.google.devtools.ksp:symbol-processing-api:2.1.21-2.0.1")
|
compileOnly("com.google.devtools.ksp:symbol-processing-api:2.1.21-2.0.2")
|
||||||
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json-jvm:$kotlinxSerializationVersion") {
|
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json-jvm:$kotlinxSerializationVersion") {
|
||||||
// kotlin stdlib is provided by IJ, so there is no need to include it into the distribution
|
// kotlin stdlib is provided by IJ, so there is no need to include it into the distribution
|
||||||
exclude("org.jetbrains.kotlin", "kotlin-stdlib")
|
exclude("org.jetbrains.kotlin", "kotlin-stdlib")
|
||||||
|
@@ -35,6 +35,8 @@ import org.intellij.markdown.ast.impl.ListCompositeNode
|
|||||||
import org.jetbrains.changelog.Changelog
|
import org.jetbrains.changelog.Changelog
|
||||||
import org.jetbrains.intellij.platform.gradle.TestFrameworkType
|
import org.jetbrains.intellij.platform.gradle.TestFrameworkType
|
||||||
import org.jetbrains.intellij.platform.gradle.tasks.aware.SplitModeAware
|
import org.jetbrains.intellij.platform.gradle.tasks.aware.SplitModeAware
|
||||||
|
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
||||||
|
import org.jetbrains.kotlin.gradle.dsl.KotlinVersion
|
||||||
import org.kohsuke.github.GHUser
|
import org.kohsuke.github.GHUser
|
||||||
import java.net.HttpURLConnection
|
import java.net.HttpURLConnection
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
@@ -46,19 +48,19 @@ buildscript {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:2.0.21")
|
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:2.2.0")
|
||||||
classpath("com.github.AlexPl292:mark-down-to-slack:1.1.2")
|
classpath("com.github.AlexPl292:mark-down-to-slack:1.1.2")
|
||||||
classpath("org.eclipse.jgit:org.eclipse.jgit:6.6.0.202305301015-r")
|
classpath("org.eclipse.jgit:org.eclipse.jgit:6.6.0.202305301015-r")
|
||||||
|
|
||||||
// This is needed for jgit to connect to ssh
|
// This is needed for jgit to connect to ssh
|
||||||
classpath("org.eclipse.jgit:org.eclipse.jgit.ssh.apache:7.2.1.202505142326-r")
|
classpath("org.eclipse.jgit:org.eclipse.jgit.ssh.apache:7.3.0.202506031305-r")
|
||||||
classpath("org.kohsuke:github-api:1.305")
|
classpath("org.kohsuke:github-api:1.305")
|
||||||
|
|
||||||
classpath("io.ktor:ktor-client-core:3.1.3")
|
classpath("io.ktor:ktor-client-core:3.2.2")
|
||||||
classpath("io.ktor:ktor-client-cio:3.1.3")
|
classpath("io.ktor:ktor-client-cio:3.2.2")
|
||||||
classpath("io.ktor:ktor-client-auth:3.1.3")
|
classpath("io.ktor:ktor-client-auth:3.2.2")
|
||||||
classpath("io.ktor:ktor-client-content-negotiation:3.1.3")
|
classpath("io.ktor:ktor-client-content-negotiation:3.2.2")
|
||||||
classpath("io.ktor:ktor-serialization-kotlinx-json:3.1.3")
|
classpath("io.ktor:ktor-serialization-kotlinx-json:3.2.2")
|
||||||
|
|
||||||
// This comes from the changelog plugin
|
// This comes from the changelog plugin
|
||||||
// classpath("org.jetbrains:markdown:0.3.1")
|
// classpath("org.jetbrains:markdown:0.3.1")
|
||||||
@@ -67,7 +69,7 @@ buildscript {
|
|||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
java
|
java
|
||||||
kotlin("jvm") version "2.0.21"
|
kotlin("jvm") version "2.2.0"
|
||||||
application
|
application
|
||||||
id("java-test-fixtures")
|
id("java-test-fixtures")
|
||||||
|
|
||||||
@@ -79,7 +81,7 @@ plugins {
|
|||||||
id("org.jetbrains.changelog") version "2.2.1"
|
id("org.jetbrains.changelog") version "2.2.1"
|
||||||
id("org.jetbrains.kotlinx.kover") version "0.6.1"
|
id("org.jetbrains.kotlinx.kover") version "0.6.1"
|
||||||
id("com.dorongold.task-tree") version "4.0.1"
|
id("com.dorongold.task-tree") version "4.0.1"
|
||||||
id("com.google.devtools.ksp") version "2.0.21-1.0.25"
|
id("com.google.devtools.ksp") version "2.2.0-2.0.2"
|
||||||
}
|
}
|
||||||
|
|
||||||
val moduleSources by configurations.registering
|
val moduleSources by configurations.registering
|
||||||
@@ -140,6 +142,11 @@ dependencies {
|
|||||||
plugin("com.intellij.classic.ui", "251.23774.318")
|
plugin("com.intellij.classic.ui", "251.23774.318")
|
||||||
|
|
||||||
bundledPlugins("org.jetbrains.plugins.terminal")
|
bundledPlugins("org.jetbrains.plugins.terminal")
|
||||||
|
|
||||||
|
// VERSION UPDATE: This module is required since 2025.2
|
||||||
|
if (ideaVersion == "LATEST-EAP-SNAPSHOT") {
|
||||||
|
bundledModule("intellij.spellchecker")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
moduleSources(project(":vim-engine", "sourcesJarArtifacts"))
|
moduleSources(project(":vim-engine", "sourcesJarArtifacts"))
|
||||||
@@ -159,19 +166,19 @@ dependencies {
|
|||||||
testFixturesImplementation("org.jetbrains.kotlin:kotlin-test:$kotlinVersion")
|
testFixturesImplementation("org.jetbrains.kotlin:kotlin-test:$kotlinVersion")
|
||||||
|
|
||||||
// https://mvnrepository.com/artifact/org.mockito.kotlin/mockito-kotlin
|
// https://mvnrepository.com/artifact/org.mockito.kotlin/mockito-kotlin
|
||||||
testImplementation("org.mockito.kotlin:mockito-kotlin:5.4.0")
|
testImplementation("org.mockito.kotlin:mockito-kotlin:6.0.0")
|
||||||
|
|
||||||
testImplementation("org.junit.jupiter:junit-jupiter-api:5.13.0")
|
testImplementation("org.junit.jupiter:junit-jupiter-api:5.13.3")
|
||||||
testImplementation("org.junit.jupiter:junit-jupiter-engine:5.13.0")
|
testImplementation("org.junit.jupiter:junit-jupiter-engine:5.13.3")
|
||||||
testImplementation("org.junit.jupiter:junit-jupiter-params:5.13.0")
|
testImplementation("org.junit.jupiter:junit-jupiter-params:5.13.3")
|
||||||
testFixturesImplementation("org.junit.jupiter:junit-jupiter-api:5.13.0")
|
testFixturesImplementation("org.junit.jupiter:junit-jupiter-api:5.13.3")
|
||||||
testFixturesImplementation("org.junit.jupiter:junit-jupiter-engine:5.13.0")
|
testFixturesImplementation("org.junit.jupiter:junit-jupiter-engine:5.13.3")
|
||||||
testFixturesImplementation("org.junit.jupiter:junit-jupiter-params:5.13.0")
|
testFixturesImplementation("org.junit.jupiter:junit-jupiter-params:5.13.3")
|
||||||
|
|
||||||
// Temp workaround suggested in https://plugins.jetbrains.com/docs/intellij/tools-intellij-platform-gradle-plugin-faq.html#junit5-test-framework-refers-to-junit4
|
// Temp workaround suggested in https://plugins.jetbrains.com/docs/intellij/tools-intellij-platform-gradle-plugin-faq.html#junit5-test-framework-refers-to-junit4
|
||||||
// Can be removed when IJPL-159134 is fixed
|
// Can be removed when IJPL-159134 is fixed
|
||||||
// testRuntimeOnly("junit:junit:4.13.2")
|
// testRuntimeOnly("junit:junit:4.13.2")
|
||||||
testImplementation("org.junit.vintage:junit-vintage-engine:5.13.0")
|
testImplementation("org.junit.vintage:junit-vintage-engine:5.13.2")
|
||||||
// testFixturesImplementation("org.junit.vintage:junit-vintage-engine:5.10.3")
|
// testFixturesImplementation("org.junit.vintage:junit-vintage-engine:5.10.3")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -221,38 +228,6 @@ tasks {
|
|||||||
options.encoding = "UTF-8"
|
options.encoding = "UTF-8"
|
||||||
}
|
}
|
||||||
|
|
||||||
compileKotlin {
|
|
||||||
kotlinOptions {
|
|
||||||
jvmTarget = javaVersion
|
|
||||||
// See https://plugins.jetbrains.com/docs/intellij/using-kotlin.html#kotlin-standard-library
|
|
||||||
// For the list of bundled versions
|
|
||||||
apiVersion = "2.0"
|
|
||||||
freeCompilerArgs = listOf(
|
|
||||||
"-Xjvm-default=all-compatibility",
|
|
||||||
|
|
||||||
// Needed to compile the AceJump which uses kotlin beta
|
|
||||||
// Without these two option compilation fails
|
|
||||||
"-Xskip-prerelease-check",
|
|
||||||
"-Xallow-unstable-dependencies",
|
|
||||||
)
|
|
||||||
// allWarningsAsErrors = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
compileTestKotlin {
|
|
||||||
enabled = false
|
|
||||||
|
|
||||||
kotlinOptions {
|
|
||||||
jvmTarget = javaVersion
|
|
||||||
apiVersion = "2.0"
|
|
||||||
|
|
||||||
// Needed to compile the AceJump which uses kotlin beta
|
|
||||||
// Without these two option compilation fails
|
|
||||||
freeCompilerArgs += listOf("-Xskip-prerelease-check", "-Xallow-unstable-dependencies")
|
|
||||||
// allWarningsAsErrors = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note that this will run the plugin installed in the IDE specified in dependencies. To run in a different IDE, use
|
// Note that this will run the plugin installed in the IDE specified in dependencies. To run in a different IDE, use
|
||||||
// a custom task (see below)
|
// a custom task (see below)
|
||||||
runIde {
|
runIde {
|
||||||
@@ -326,6 +301,23 @@ kotlin {
|
|||||||
jvmToolchain {
|
jvmToolchain {
|
||||||
languageVersion.set(JavaLanguageVersion.of(javaVersion))
|
languageVersion.set(JavaLanguageVersion.of(javaVersion))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
compilerOptions {
|
||||||
|
jvmTarget.set(JvmTarget.fromTarget(javaVersion))
|
||||||
|
|
||||||
|
// See https://plugins.jetbrains.com/docs/intellij/using-kotlin.html#kotlin-standard-library
|
||||||
|
// For the list of bundled versions
|
||||||
|
apiVersion.set(KotlinVersion.KOTLIN_2_0)
|
||||||
|
freeCompilerArgs = listOf(
|
||||||
|
"-Xjvm-default=all-compatibility",
|
||||||
|
|
||||||
|
// Needed to compile the AceJump which uses kotlin beta
|
||||||
|
// Without these two option compilation fails
|
||||||
|
"-Xskip-prerelease-check",
|
||||||
|
"-Xallow-unstable-dependencies",
|
||||||
|
)
|
||||||
|
// allWarningsAsErrors = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gradle.projectsEvaluated {
|
gradle.projectsEvaluated {
|
||||||
|
@@ -20,7 +20,7 @@ ideaVersion=2025.1
|
|||||||
# Values for type: https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#intellij-extension-type
|
# Values for type: https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#intellij-extension-type
|
||||||
ideaType=IC
|
ideaType=IC
|
||||||
instrumentPluginCode=true
|
instrumentPluginCode=true
|
||||||
version=chylex-49
|
version=chylex-50
|
||||||
javaVersion=21
|
javaVersion=21
|
||||||
remoteRobotVersion=0.11.23
|
remoteRobotVersion=0.11.23
|
||||||
antlrVersion=4.10.1
|
antlrVersion=4.10.1
|
||||||
@@ -28,7 +28,7 @@ antlrVersion=4.10.1
|
|||||||
|
|
||||||
# Please don't forget to update kotlin version in buildscript section
|
# Please don't forget to update kotlin version in buildscript section
|
||||||
# Also update kotlinxSerializationVersion version
|
# Also update kotlinxSerializationVersion version
|
||||||
kotlinVersion=2.0.21
|
kotlinVersion=2.2.0
|
||||||
publishToken=token
|
publishToken=token
|
||||||
publishChannels=eap
|
publishChannels=eap
|
||||||
|
|
||||||
|
@@ -20,27 +20,25 @@ repositories {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compileOnly("org.jetbrains.kotlin:kotlin-stdlib:2.1.21")
|
compileOnly("org.jetbrains.kotlin:kotlin-stdlib:2.2.0")
|
||||||
|
|
||||||
implementation("io.ktor:ktor-client-core:3.1.3")
|
implementation("io.ktor:ktor-client-core:3.2.2")
|
||||||
implementation("io.ktor:ktor-client-cio:3.1.3")
|
implementation("io.ktor:ktor-client-cio:3.2.2")
|
||||||
implementation("io.ktor:ktor-client-content-negotiation:3.1.3")
|
implementation("io.ktor:ktor-client-content-negotiation:3.2.2")
|
||||||
implementation("io.ktor:ktor-serialization-kotlinx-json:3.1.3")
|
implementation("io.ktor:ktor-serialization-kotlinx-json:3.2.2")
|
||||||
implementation("io.ktor:ktor-client-auth:3.1.3")
|
implementation("io.ktor:ktor-client-auth:3.2.2")
|
||||||
implementation("org.eclipse.jgit:org.eclipse.jgit:6.6.0.202305301015-r")
|
implementation("org.eclipse.jgit:org.eclipse.jgit:6.6.0.202305301015-r")
|
||||||
|
|
||||||
// This is needed for jgit to connect to ssh
|
// This is needed for jgit to connect to ssh
|
||||||
implementation("org.eclipse.jgit:org.eclipse.jgit.ssh.apache:7.2.1.202505142326-r")
|
implementation("org.eclipse.jgit:org.eclipse.jgit.ssh.apache:7.3.0.202506031305-r")
|
||||||
implementation("com.vdurmont:semver4j:3.1.0")
|
implementation("com.vdurmont:semver4j:3.1.0")
|
||||||
}
|
}
|
||||||
|
|
||||||
val releaseType: String? by project
|
val releaseType: String? by project
|
||||||
|
|
||||||
tasks {
|
kotlin {
|
||||||
compileKotlin {
|
compilerOptions {
|
||||||
kotlinOptions {
|
freeCompilerArgs = listOf("-Xjvm-default=all-compatibility")
|
||||||
freeCompilerArgs = listOf("-Xjvm-default=all-compatibility")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -45,6 +45,8 @@ val knownPlugins = setOf(
|
|||||||
"com.julienphalip.ideavim.functiontextobj", // https://plugins.jetbrains.com/plugin/25897-vim-functiontextobj
|
"com.julienphalip.ideavim.functiontextobj", // https://plugins.jetbrains.com/plugin/25897-vim-functiontextobj
|
||||||
"com.miksuki.HighlightCursor", // https://plugins.jetbrains.com/plugin/26743-highlightcursor
|
"com.miksuki.HighlightCursor", // https://plugins.jetbrains.com/plugin/26743-highlightcursor
|
||||||
"com.ugarosa.idea.edgemotion", // https://plugins.jetbrains.com/plugin/27211-edgemotion
|
"com.ugarosa.idea.edgemotion", // https://plugins.jetbrains.com/plugin/27211-edgemotion
|
||||||
|
|
||||||
|
"cn.mumukehao.plugin",
|
||||||
)
|
)
|
||||||
|
|
||||||
suspend fun main() {
|
suspend fun main() {
|
||||||
|
@@ -1,52 +0,0 @@
|
|||||||
package com.maddyhome.idea.vim.action
|
|
||||||
|
|
||||||
import com.intellij.openapi.actionSystem.ActionUpdateThread
|
|
||||||
import com.intellij.openapi.actionSystem.AnActionEvent
|
|
||||||
import com.intellij.openapi.command.UndoConfirmationPolicy
|
|
||||||
import com.intellij.openapi.command.WriteCommandAction
|
|
||||||
import com.intellij.openapi.fileEditor.TextEditor
|
|
||||||
import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx
|
|
||||||
import com.intellij.openapi.project.DumbAwareAction
|
|
||||||
import com.maddyhome.idea.vim.KeyHandler
|
|
||||||
import com.maddyhome.idea.vim.api.injector
|
|
||||||
import com.maddyhome.idea.vim.newapi.IjEditorExecutionContext
|
|
||||||
import com.maddyhome.idea.vim.newapi.vim
|
|
||||||
import com.maddyhome.idea.vim.state.mode.Mode
|
|
||||||
|
|
||||||
class VimRunLastMacroInOpenFiles : DumbAwareAction() {
|
|
||||||
override fun update(e: AnActionEvent) {
|
|
||||||
val lastRegister = injector.macro.lastRegister
|
|
||||||
val isEnabled = lastRegister != 0.toChar()
|
|
||||||
|
|
||||||
e.presentation.isEnabled = isEnabled
|
|
||||||
e.presentation.text = if (isEnabled) "Run Macro '${lastRegister}' in Open Files" else "Run Last Macro in Open Files"
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getActionUpdateThread(): ActionUpdateThread {
|
|
||||||
return ActionUpdateThread.EDT
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun actionPerformed(e: AnActionEvent) {
|
|
||||||
val project = e.project ?: return
|
|
||||||
val fileEditorManager = FileEditorManagerEx.getInstanceExIfCreated(project) ?: return
|
|
||||||
val editors = fileEditorManager.allEditors.filterIsInstance<TextEditor>()
|
|
||||||
|
|
||||||
WriteCommandAction.writeCommandAction(project)
|
|
||||||
.withName(e.presentation.text)
|
|
||||||
.withGlobalUndo()
|
|
||||||
.withUndoConfirmationPolicy(UndoConfirmationPolicy.REQUEST_CONFIRMATION)
|
|
||||||
.run<RuntimeException> {
|
|
||||||
val reg = injector.macro.lastRegister
|
|
||||||
|
|
||||||
for (editor in editors) {
|
|
||||||
fileEditorManager.openFile(editor.file, true)
|
|
||||||
|
|
||||||
val vimEditor = editor.editor.vim
|
|
||||||
vimEditor.mode = Mode.NORMAL()
|
|
||||||
KeyHandler.getInstance().reset(vimEditor)
|
|
||||||
|
|
||||||
injector.macro.playbackRegister(vimEditor, IjEditorExecutionContext(e.dataContext), reg, 1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -0,0 +1,67 @@
|
|||||||
|
package com.maddyhome.idea.vim.action.macro
|
||||||
|
|
||||||
|
import com.intellij.openapi.command.CommandProcessor
|
||||||
|
import com.intellij.openapi.command.UndoConfirmationPolicy
|
||||||
|
import com.intellij.openapi.command.impl.FinishMarkAction
|
||||||
|
import com.intellij.openapi.command.impl.StartMarkAction
|
||||||
|
import com.intellij.openapi.fileEditor.TextEditor
|
||||||
|
import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx
|
||||||
|
import com.intellij.vim.annotations.CommandOrMotion
|
||||||
|
import com.intellij.vim.annotations.Mode
|
||||||
|
import com.maddyhome.idea.vim.KeyHandler
|
||||||
|
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.Argument
|
||||||
|
import com.maddyhome.idea.vim.command.Command
|
||||||
|
import com.maddyhome.idea.vim.command.OperatorArguments
|
||||||
|
import com.maddyhome.idea.vim.handler.VimActionHandler
|
||||||
|
import com.maddyhome.idea.vim.newapi.ij
|
||||||
|
import com.maddyhome.idea.vim.newapi.vim
|
||||||
|
|
||||||
|
@CommandOrMotion(keys = ["z@"], modes = [Mode.NORMAL])
|
||||||
|
class PlaybackRegisterInOpenFilesAction : VimActionHandler.SingleExecution() {
|
||||||
|
override val type: Command.Type = Command.Type.OTHER_SELF_SYNCHRONIZED
|
||||||
|
|
||||||
|
override val argumentType: Argument.Type = Argument.Type.CHARACTER
|
||||||
|
|
||||||
|
private val playbackRegisterAction = PlaybackRegisterAction()
|
||||||
|
|
||||||
|
override fun execute(
|
||||||
|
editor: VimEditor,
|
||||||
|
context: ExecutionContext,
|
||||||
|
cmd: Command,
|
||||||
|
operatorArguments: OperatorArguments,
|
||||||
|
): Boolean {
|
||||||
|
val argument = cmd.argument as? Argument.Character ?: return false
|
||||||
|
|
||||||
|
val project = editor.ij.project ?: return false
|
||||||
|
val fileEditorManager = FileEditorManagerEx.getInstanceExIfCreated(project) ?: return false
|
||||||
|
|
||||||
|
val register = argument.character.let { if (it == '@') injector.macro.lastRegister else it }
|
||||||
|
val commandName = "Execute Macro '$register' in All Open Files"
|
||||||
|
|
||||||
|
val action = Runnable {
|
||||||
|
CommandProcessor.getInstance().markCurrentCommandAsGlobal(project)
|
||||||
|
|
||||||
|
for (textEditor in fileEditorManager.allEditors.filterIsInstance<TextEditor>()) {
|
||||||
|
fileEditorManager.openFile(textEditor.file, true)
|
||||||
|
|
||||||
|
val editor = textEditor.editor
|
||||||
|
val vimEditor = editor.vim
|
||||||
|
|
||||||
|
vimEditor.mode = com.maddyhome.idea.vim.state.mode.Mode.NORMAL()
|
||||||
|
KeyHandler.Companion.getInstance().reset(vimEditor)
|
||||||
|
|
||||||
|
val startMarkAction = StartMarkAction.start(editor, project, commandName)
|
||||||
|
playbackRegisterAction.execute(vimEditor, context, cmd, operatorArguments)
|
||||||
|
FinishMarkAction.finish(project, editor, startMarkAction)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CommandProcessor.getInstance()
|
||||||
|
.executeCommand(project, action, commandName, null, UndoConfirmationPolicy.REQUEST_CONFIRMATION)
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
@@ -455,6 +455,17 @@ internal class NerdTree : VimExtension {
|
|||||||
tree.scrollRowToVisible(expectedRow)
|
tree.scrollRowToVisible(expectedRow)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
registerCommand("gg", NerdAction.Code { project, _, _ ->
|
||||||
|
val tree = ProjectView.getInstance(project).currentProjectViewPane.tree
|
||||||
|
tree.setSelectionRow(0)
|
||||||
|
tree.scrollRowToVisible(0)
|
||||||
|
})
|
||||||
|
registerCommand("G", NerdAction.Code { project, _, _ ->
|
||||||
|
val tree = ProjectView.getInstance(project).currentProjectViewPane.tree
|
||||||
|
val lastRowIndex = tree.rowCount -1
|
||||||
|
tree.setSelectionRow(lastRowIndex)
|
||||||
|
tree.scrollRowToVisible(lastRowIndex)
|
||||||
|
})
|
||||||
registerCommand(
|
registerCommand(
|
||||||
"NERDTreeMapJumpNextSibling",
|
"NERDTreeMapJumpNextSibling",
|
||||||
"<C-J>",
|
"<C-J>",
|
||||||
|
@@ -134,7 +134,7 @@ internal object IdeaSelectionControl {
|
|||||||
is Mode.VISUAL -> VimPlugin.getVisualMotion().enterVisualMode(editor.vim, mode.selectionType)
|
is Mode.VISUAL -> VimPlugin.getVisualMotion().enterVisualMode(editor.vim, mode.selectionType)
|
||||||
is Mode.SELECT -> VimPlugin.getVisualMotion().enterSelectMode(editor.vim, mode.selectionType)
|
is Mode.SELECT -> VimPlugin.getVisualMotion().enterSelectMode(editor.vim, mode.selectionType)
|
||||||
is Mode.INSERT -> VimPlugin.getChange()
|
is Mode.INSERT -> VimPlugin.getChange()
|
||||||
.insertBeforeCursor(editor.vim, injector.executionContextManager.getEditorExecutionContext(editor.vim))
|
.insertBeforeCaret(editor.vim, injector.executionContextManager.getEditorExecutionContext(editor.vim))
|
||||||
|
|
||||||
is Mode.NORMAL -> Unit
|
is Mode.NORMAL -> Unit
|
||||||
else -> error("Unexpected mode: $mode")
|
else -> error("Unexpected mode: $mode")
|
||||||
|
@@ -61,7 +61,7 @@ class IJEditorFocusListener : EditorListener {
|
|||||||
|
|
||||||
val switchToInsertMode = Runnable {
|
val switchToInsertMode = Runnable {
|
||||||
val context: ExecutionContext = injector.executionContextManager.getEditorExecutionContext(editor)
|
val context: ExecutionContext = injector.executionContextManager.getEditorExecutionContext(editor)
|
||||||
VimPlugin.getChange().insertBeforeCursor(editor, context)
|
VimPlugin.getChange().insertBeforeCaret(editor, context)
|
||||||
KeyHandler.getInstance().lastUsedEditorInfo = LastUsedEditorInfo(currentEditorHashCode, true)
|
KeyHandler.getInstance().lastUsedEditorInfo = LastUsedEditorInfo(currentEditorHashCode, true)
|
||||||
}
|
}
|
||||||
if (isCurrentEditorTerminal) {
|
if (isCurrentEditorTerminal) {
|
||||||
|
@@ -169,7 +169,7 @@ internal object IdeaSpecifics {
|
|||||||
) {
|
) {
|
||||||
editor?.let {
|
editor?.let {
|
||||||
it.vim.mode = Mode.NORMAL()
|
it.vim.mode = Mode.NORMAL()
|
||||||
VimPlugin.getChange().insertBeforeCursor(it.vim, event.dataContext.vim)
|
VimPlugin.getChange().insertBeforeCaret(it.vim, event.dataContext.vim)
|
||||||
KeyHandler.getInstance().reset(it.vim)
|
KeyHandler.getInstance().reset(it.vim)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -223,7 +223,7 @@ internal object IdeaSpecifics {
|
|||||||
// Enable insert mode if there is no selection in template
|
// Enable insert mode if there is no selection in template
|
||||||
// Template with selection is handled by [com.maddyhome.idea.vim.group.visual.VisualMotionGroup.controlNonVimSelectionChange]
|
// Template with selection is handled by [com.maddyhome.idea.vim.group.visual.VisualMotionGroup.controlNonVimSelectionChange]
|
||||||
if (editor.vim.inNormalMode) {
|
if (editor.vim.inNormalMode) {
|
||||||
VimPlugin.getChange().insertBeforeCursor(
|
VimPlugin.getChange().insertBeforeCaret(
|
||||||
editor.vim,
|
editor.vim,
|
||||||
injector.executionContextManager.getEditorExecutionContext(editor.vim),
|
injector.executionContextManager.getEditorExecutionContext(editor.vim),
|
||||||
)
|
)
|
||||||
|
@@ -20,6 +20,7 @@ import com.intellij.openapi.editor.ex.ScrollingModelEx
|
|||||||
import com.intellij.openapi.editor.ex.util.EditorUtil
|
import com.intellij.openapi.editor.ex.util.EditorUtil
|
||||||
import com.intellij.openapi.editor.impl.CaretModelImpl
|
import com.intellij.openapi.editor.impl.CaretModelImpl
|
||||||
import com.intellij.openapi.editor.impl.EditorImpl
|
import com.intellij.openapi.editor.impl.EditorImpl
|
||||||
|
import com.intellij.openapi.util.text.StringUtil
|
||||||
import com.intellij.openapi.vfs.VirtualFileManager
|
import com.intellij.openapi.vfs.VirtualFileManager
|
||||||
import com.maddyhome.idea.vim.api.BufferPosition
|
import com.maddyhome.idea.vim.api.BufferPosition
|
||||||
import com.maddyhome.idea.vim.api.ExecutionContext
|
import com.maddyhome.idea.vim.api.ExecutionContext
|
||||||
@@ -150,7 +151,7 @@ internal class IjVimEditor(editor: Editor) : MutableLinearEditor, VimEditorBase(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
editor.document.insertString(atPosition, text)
|
editor.document.insertString(atPosition, StringUtil.convertLineSeparators(text, "\n"))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun replaceString(start: Int, end: Int, newString: String) {
|
override fun replaceString(start: Int, end: Int, newString: String) {
|
||||||
|
@@ -135,6 +135,8 @@
|
|||||||
|
|
||||||
<editorNotificationProvider
|
<editorNotificationProvider
|
||||||
implementation="com.maddyhome.idea.vim.troubleshooting.AccidentalInstallDetectorEditorNotificationProvider"/>
|
implementation="com.maddyhome.idea.vim.troubleshooting.AccidentalInstallDetectorEditorNotificationProvider"/>
|
||||||
|
|
||||||
|
<dependencySupport coordinate="configuration" kind="vim" displayName="IdeaVim"/>
|
||||||
</extensions>
|
</extensions>
|
||||||
|
|
||||||
<xi:include href="/META-INF/includes/ApplicationServices.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
<xi:include href="/META-INF/includes/ApplicationServices.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||||
@@ -142,12 +144,10 @@
|
|||||||
<xi:include href="/META-INF/includes/VimListeners.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
<xi:include href="/META-INF/includes/VimListeners.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||||
|
|
||||||
<actions resource-bundle="messages.IdeaVimBundle">
|
<actions resource-bundle="messages.IdeaVimBundle">
|
||||||
<group id="com.chylex.intellij.vim" text="Vim" popup="true">
|
<action id="VimPluginToggle" class="com.maddyhome.idea.vim.action.VimPluginToggleAction">
|
||||||
<add-to-group group-id="ToolsMenu" anchor="last"/>
|
<add-to-group group-id="ToolsMenu" anchor="last"/>
|
||||||
<action id="VimPluginToggle" class="com.maddyhome.idea.vim.action.VimPluginToggleAction"/>
|
</action>
|
||||||
<action id="VimRunLastMacroInOpenFiles" class="com.maddyhome.idea.vim.action.VimRunLastMacroInOpenFiles"/>
|
|
||||||
</group>
|
|
||||||
|
|
||||||
<!-- Internal -->
|
<!-- Internal -->
|
||||||
<!--suppress PluginXmlI18n -->
|
<!--suppress PluginXmlI18n -->
|
||||||
<action id="VimInternalAddBlockInlays" class="com.maddyhome.idea.vim.action.internal.AddBlockInlaysAction" text="Add Test Block Inlays | IdeaVim Internal" internal="true"/>
|
<action id="VimInternalAddBlockInlays" class="com.maddyhome.idea.vim.action.internal.AddBlockInlaysAction" text="Add Test Block Inlays | IdeaVim Internal" internal="true"/>
|
||||||
|
@@ -78,5 +78,10 @@
|
|||||||
"keys": "gJ",
|
"keys": "gJ",
|
||||||
"class": "com.maddyhome.idea.vim.action.change.delete.DeleteJoinVisualLinesAction",
|
"class": "com.maddyhome.idea.vim.action.change.delete.DeleteJoinVisualLinesAction",
|
||||||
"modes": "X"
|
"modes": "X"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keys": "z@",
|
||||||
|
"class": "com.maddyhome.idea.vim.action.macro.PlaybackRegisterInOpenFilesAction",
|
||||||
|
"modes": "N"
|
||||||
}
|
}
|
||||||
]
|
]
|
@@ -1144,6 +1144,12 @@ $c tw${c}o
|
|||||||
"O${c}NcE thIs ${c}TEXt wIlL n${c}Ot lOoK s${c}O rIdIcuLoUs\n",
|
"O${c}NcE thIs ${c}TEXt wIlL n${c}Ot lOoK s${c}O rIdIcuLoUs\n",
|
||||||
)
|
)
|
||||||
assertState("O${c}nce this text will n${c}ot look s${c}o ridiculous\n")
|
assertState("O${c}nce this text will n${c}ot look s${c}o ridiculous\n")
|
||||||
|
|
||||||
|
typeTextInFile(
|
||||||
|
injector.parser.parseKeys("v2wgu"),
|
||||||
|
"O${c}NcE thIs ${c}TEXt wIlL n${c}Ot lOoK s${c}O rIdIcuLoUs\n",
|
||||||
|
)
|
||||||
|
assertState("O${c}nce this text will n${c}ot look s${c}o ridiculous\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -1180,6 +1186,12 @@ $c tw${c}o
|
|||||||
"O${c}NcE thIs ${c}TEXt wIlL N${c}Ot lOoK S${c}O rIdIcuLoUs\n",
|
"O${c}NcE thIs ${c}TEXt wIlL N${c}Ot lOoK S${c}O rIdIcuLoUs\n",
|
||||||
)
|
)
|
||||||
assertState("O${c}NCE THIS TEXT WILL N${c}OT LOOK S${c}O RIDICULOUS\n")
|
assertState("O${c}NCE THIS TEXT WILL N${c}OT LOOK S${c}O RIDICULOUS\n")
|
||||||
|
|
||||||
|
typeTextInFile(
|
||||||
|
injector.parser.parseKeys("v2wgU"),
|
||||||
|
"O${c}NcE thIs ${c}TEXt wIlL N${c}Ot lOoK S${c}O rIdIcuLoUs\n",
|
||||||
|
)
|
||||||
|
assertState("O${c}NCE THIS TEXT WILL N${c}OT LOOK S${c}O RIDICULOUS\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@@ -320,4 +320,61 @@ class ChangeCaseToggleCharacterActionTest : VimTestCase() {
|
|||||||
enterCommand("set nooldundo")
|
enterCommand("set nooldundo")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `test toggle case line caret position`() {
|
||||||
|
configureByText(" Hello ${c}World")
|
||||||
|
typeText("g~~")
|
||||||
|
assertState(" ${c}hELLO wORLD")
|
||||||
|
typeText("u")
|
||||||
|
assertState(" Hello ${c}World")
|
||||||
|
|
||||||
|
typeText("^g~~")
|
||||||
|
assertState(" ${c}hELLO wORLD")
|
||||||
|
typeText("u")
|
||||||
|
assertState(" ${c}Hello World")
|
||||||
|
|
||||||
|
typeText("hg~~")
|
||||||
|
assertState(" $c hELLO wORLD")
|
||||||
|
typeText("u")
|
||||||
|
assertState(" $c Hello World")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `test uppercase line caret position`() {
|
||||||
|
configureByText(" Hello ${c}World")
|
||||||
|
typeText("gUU")
|
||||||
|
assertState(" ${c}HELLO WORLD")
|
||||||
|
typeText("u")
|
||||||
|
assertState(" Hello ${c}World")
|
||||||
|
|
||||||
|
typeText("^gUU")
|
||||||
|
assertState(" ${c}HELLO WORLD")
|
||||||
|
typeText("u")
|
||||||
|
assertState(" ${c}Hello World")
|
||||||
|
|
||||||
|
typeText("hgUU")
|
||||||
|
assertState(" $c HELLO WORLD")
|
||||||
|
typeText("u")
|
||||||
|
assertState(" $c Hello World")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `test lowercase line caret position`() {
|
||||||
|
configureByText(" Hello ${c}World")
|
||||||
|
typeText("guu")
|
||||||
|
assertState(" ${c}hello world")
|
||||||
|
typeText("u")
|
||||||
|
assertState(" Hello ${c}World")
|
||||||
|
|
||||||
|
typeText("^guu")
|
||||||
|
assertState(" ${c}hello world")
|
||||||
|
typeText("u")
|
||||||
|
assertState(" ${c}Hello World")
|
||||||
|
|
||||||
|
typeText("hguu")
|
||||||
|
assertState(" $c hello world")
|
||||||
|
typeText("u")
|
||||||
|
assertState(" $c Hello World")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -17,7 +17,7 @@ import org.jetbrains.plugins.ideavim.TestWithoutNeovim
|
|||||||
import org.jetbrains.plugins.ideavim.VimTestCase
|
import org.jetbrains.plugins.ideavim.VimTestCase
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
|
|
||||||
class VisualBlockInsertActionTest : VimTestCase() {
|
class VisualInsertActionTest : VimTestCase() {
|
||||||
// VIM-1379 |CTRL-V| |j| |v_b_I|
|
// VIM-1379 |CTRL-V| |j| |v_b_I|
|
||||||
@TestWithoutNeovim(SkipNeovimReason.VISUAL_BLOCK_MODE)
|
@TestWithoutNeovim(SkipNeovimReason.VISUAL_BLOCK_MODE)
|
||||||
@Test
|
@Test
|
||||||
@@ -101,28 +101,70 @@ class VisualBlockInsertActionTest : VimTestCase() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestWithoutNeovim(SkipNeovimReason.VISUAL_BLOCK_MODE)
|
|
||||||
@Test
|
@Test
|
||||||
fun `test insert in non block mode`() {
|
fun `test insert in non-block visual within single line`() {
|
||||||
doTest(
|
val before = """
|
||||||
listOf("vwIHello<esc>"),
|
| A ${c}Discovery
|
||||||
"""
|
|
||||||
${c}A Discovery
|
|
||||||
|
|
||||||
${c}I found it in a legendary land
|
| I ${c}found it in a legendary land
|
||||||
all rocks and ${c}lavender and tufted grass,
|
| all rocks and lavender and tufted grass,
|
||||||
where it was settled on some sodden sand
|
| where it was settled on some sodden sand
|
||||||
hard by the torrent of a mountain pass.
|
| hard by the torrent of a mountain pass.
|
||||||
""".trimIndent(),
|
""".trimMargin()
|
||||||
"""
|
val after = """
|
||||||
Hell${c}oA Discovery
|
|Hell${c}o A Discovery
|
||||||
|
|
||||||
Hell${c}oI found it in a legendary land
|
|Hell${c}o I found it in a legendary land
|
||||||
Hell${c}oall rocks and lavender and tufted grass,
|
| all rocks and lavender and tufted grass,
|
||||||
where it was settled on some sodden sand
|
| where it was settled on some sodden sand
|
||||||
hard by the torrent of a mountain pass.
|
| hard by the torrent of a mountain pass.
|
||||||
""".trimIndent(),
|
""".trimMargin()
|
||||||
)
|
doTest(listOf($$"v$IHello<esc>"), before, after)
|
||||||
|
doTest(listOf("VIHello<esc>"), before, after)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `test insert in non-block visual spanning multiple lines down`() {
|
||||||
|
val before = """
|
||||||
|
| A ${c}Discovery
|
||||||
|
|
||||||
|
| I ${c}found it in a legendary land
|
||||||
|
| all rocks and lavender and tufted grass,
|
||||||
|
| where it was settled on some sodden sand
|
||||||
|
| hard by the torrent of a mountain pass.
|
||||||
|
""".trimMargin()
|
||||||
|
val after = """
|
||||||
|
|Hell${c}o A Discovery
|
||||||
|
|
||||||
|
|Hell${c}o I found it in a legendary land
|
||||||
|
| all rocks and lavender and tufted grass,
|
||||||
|
| where it was settled on some sodden sand
|
||||||
|
| hard by the torrent of a mountain pass.
|
||||||
|
""".trimMargin()
|
||||||
|
doTest(listOf("vjIHello<esc>"), before, after)
|
||||||
|
doTest(listOf("VjIHello<esc>"), before, after)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `test insert in non-block visual spanning multiple lines up`() {
|
||||||
|
val before = """
|
||||||
|
| A Discovery
|
||||||
|
|
||||||
|
| I found it in a legendary land
|
||||||
|
| all rocks and lavender and tufted grass${c},
|
||||||
|
| where it was settled on some sodden sand
|
||||||
|
| hard ${c}by the torrent of a mountain pass.
|
||||||
|
""".trimMargin()
|
||||||
|
val after = """
|
||||||
|
| A Discovery
|
||||||
|
|
||||||
|
| I found it in a legendary landHell${c}o
|
||||||
|
| all rocks and lavender and tufted grass,
|
||||||
|
| whereHell${c}o it was settled on some sodden sand
|
||||||
|
| hard by the torrent of a mountain pass.
|
||||||
|
""".trimMargin()
|
||||||
|
doTest(listOf("vkIHello<esc>"), before, after)
|
||||||
|
doTest(listOf("VkIHello<esc>"), before, after)
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestWithoutNeovim(SkipNeovimReason.VISUAL_BLOCK_MODE)
|
@TestWithoutNeovim(SkipNeovimReason.VISUAL_BLOCK_MODE)
|
@@ -241,12 +241,7 @@ class RegistersCommandTest : VimTestCase() {
|
|||||||
|
|
||||||
val vimEditor = fixture.editor.vim
|
val vimEditor = fixture.editor.vim
|
||||||
val context = injector.executionContextManager.getEditorExecutionContext(vimEditor)
|
val context = injector.executionContextManager.getEditorExecutionContext(vimEditor)
|
||||||
injector.registerGroup.saveRegister(
|
injector.registerGroup.saveRegister(vimEditor, context, '+', Register('+', SelectionType.LINE_WISE, "Lorem ipsum dolor", mutableListOf()))
|
||||||
vimEditor,
|
|
||||||
context,
|
|
||||||
'+',
|
|
||||||
Register('+', injector.clipboardManager.dumbCopiedText("Lorem ipsum dolor"), SelectionType.LINE_WISE)
|
|
||||||
)
|
|
||||||
val clipboardContent = injector.clipboardManager.dumbCopiedText("clipboard content")
|
val clipboardContent = injector.clipboardManager.dumbCopiedText("clipboard content")
|
||||||
injector.clipboardManager.setClipboardContent(vimEditor, context, clipboardContent)
|
injector.clipboardManager.setClipboardContent(vimEditor, context, clipboardContent)
|
||||||
typeText("V<Esc>")
|
typeText("V<Esc>")
|
||||||
@@ -453,12 +448,7 @@ class RegistersCommandTest : VimTestCase() {
|
|||||||
val vimEditor = fixture.editor.vim
|
val vimEditor = fixture.editor.vim
|
||||||
val context = injector.executionContextManager.getEditorExecutionContext(vimEditor)
|
val context = injector.executionContextManager.getEditorExecutionContext(vimEditor)
|
||||||
val clipboardContent = injector.clipboardManager.dumbCopiedText("clipboard content")
|
val clipboardContent = injector.clipboardManager.dumbCopiedText("clipboard content")
|
||||||
injector.registerGroup.saveRegister(
|
injector.registerGroup.saveRegister(vimEditor, context, '+', Register('+', SelectionType.LINE_WISE, "Lorem ipsum dolor", mutableListOf()))
|
||||||
vimEditor,
|
|
||||||
context,
|
|
||||||
'+',
|
|
||||||
Register('+', injector.clipboardManager.dumbCopiedText("Lorem ipsum dolor"), SelectionType.LINE_WISE)
|
|
||||||
)
|
|
||||||
injector.clipboardManager.setClipboardContent(vimEditor, context, clipboardContent)
|
injector.clipboardManager.setClipboardContent(vimEditor, context, clipboardContent)
|
||||||
typeText("V<Esc>")
|
typeText("V<Esc>")
|
||||||
|
|
||||||
|
@@ -32,7 +32,7 @@ dependencies {
|
|||||||
compileOnly("org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion")
|
compileOnly("org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion")
|
||||||
testImplementation("org.jetbrains.kotlin:kotlin-test:$kotlinVersion")
|
testImplementation("org.jetbrains.kotlin:kotlin-test:$kotlinVersion")
|
||||||
testImplementation(testFixtures(project(":"))) // The root project
|
testImplementation(testFixtures(project(":"))) // The root project
|
||||||
testImplementation("org.junit.vintage:junit-vintage-engine:5.13.0")
|
testImplementation("org.junit.vintage:junit-vintage-engine:5.13.2")
|
||||||
|
|
||||||
intellijPlatform {
|
intellijPlatform {
|
||||||
// Snapshots don't use installers
|
// Snapshots don't use installers
|
||||||
|
@@ -17,7 +17,7 @@ import org.jetbrains.plugins.ideavim.TestWithoutNeovim
|
|||||||
import org.jetbrains.plugins.ideavim.VimJavaTestCase
|
import org.jetbrains.plugins.ideavim.VimJavaTestCase
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
|
|
||||||
class VisualBlockInsertActionJavaTest : VimJavaTestCase() {
|
class VisualInsertActionJavaTest : VimJavaTestCase() {
|
||||||
// VIM-1110 |CTRL-V| |v_b_i| |zc|
|
// VIM-1110 |CTRL-V| |v_b_i| |zc|
|
||||||
@TestWithoutNeovim(SkipNeovimReason.FOLDING)
|
@TestWithoutNeovim(SkipNeovimReason.FOLDING)
|
||||||
@Test
|
@Test
|
@@ -25,7 +25,7 @@ dependencies {
|
|||||||
compileOnly("org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion")
|
compileOnly("org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion")
|
||||||
testImplementation("org.jetbrains.kotlin:kotlin-test:$kotlinVersion")
|
testImplementation("org.jetbrains.kotlin:kotlin-test:$kotlinVersion")
|
||||||
testImplementation(testFixtures(project(":"))) // The root project
|
testImplementation(testFixtures(project(":"))) // The root project
|
||||||
testImplementation("org.junit.vintage:junit-vintage-engine:5.13.0")
|
testImplementation("org.junit.vintage:junit-vintage-engine:5.13.2")
|
||||||
|
|
||||||
intellijPlatform {
|
intellijPlatform {
|
||||||
// Snapshots don't use installers
|
// Snapshots don't use installers
|
||||||
@@ -47,17 +47,8 @@ tasks {
|
|||||||
// I didn't find a better way to exclude except disabling and defining a new task with a different name
|
// I didn't find a better way to exclude except disabling and defining a new task with a different name
|
||||||
// Note that useJUnitTestPlatform() is required to prevent red code
|
// Note that useJUnitTestPlatform() is required to prevent red code
|
||||||
test {
|
test {
|
||||||
enabled = false
|
|
||||||
useJUnitPlatform()
|
useJUnitPlatform()
|
||||||
}
|
}
|
||||||
|
|
||||||
// The `test` task is automatically set up with IntelliJ goodness. A custom test task needs to be configured for it
|
|
||||||
val testLongRunning by intellijPlatformTesting.testIde.registering {
|
|
||||||
task {
|
|
||||||
group = "verification"
|
|
||||||
useJUnitPlatform()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
java {
|
java {
|
||||||
|
@@ -25,7 +25,7 @@ dependencies {
|
|||||||
compileOnly("org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion")
|
compileOnly("org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion")
|
||||||
testImplementation("org.jetbrains.kotlin:kotlin-test:$kotlinVersion")
|
testImplementation("org.jetbrains.kotlin:kotlin-test:$kotlinVersion")
|
||||||
testImplementation(testFixtures(project(":"))) // The root project
|
testImplementation(testFixtures(project(":"))) // The root project
|
||||||
testImplementation("org.junit.vintage:junit-vintage-engine:5.13.0")
|
testImplementation("org.junit.vintage:junit-vintage-engine:5.13.2")
|
||||||
|
|
||||||
intellijPlatform {
|
intellijPlatform {
|
||||||
// Snapshots don't use installers
|
// Snapshots don't use installers
|
||||||
@@ -48,15 +48,6 @@ tasks {
|
|||||||
// I didn't find a better way to exclude except disabling and defining a new task with a different name
|
// I didn't find a better way to exclude except disabling and defining a new task with a different name
|
||||||
test {
|
test {
|
||||||
useJUnitPlatform()
|
useJUnitPlatform()
|
||||||
enabled = false
|
|
||||||
}
|
|
||||||
|
|
||||||
// The `test` task is automatically set up with IntelliJ goodness. A custom test task needs to be configured for it
|
|
||||||
val testPropertyBased by intellijPlatformTesting.testIde.registering {
|
|
||||||
task {
|
|
||||||
group = "verification"
|
|
||||||
useJUnitPlatform()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -15,7 +15,7 @@ val javaVersion: String by project
|
|||||||
val remoteRobotVersion: String by project
|
val remoteRobotVersion: String by project
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
testFixturesImplementation("org.junit.jupiter:junit-jupiter:5.13.0")
|
testFixturesImplementation("org.junit.jupiter:junit-jupiter:5.13.3")
|
||||||
compileOnly("org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion")
|
compileOnly("org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion")
|
||||||
testFixturesImplementation("org.jetbrains.kotlin:kotlin-test:$kotlinVersion")
|
testFixturesImplementation("org.jetbrains.kotlin:kotlin-test:$kotlinVersion")
|
||||||
testFixturesImplementation(testFixtures(project(":"))) // The root project
|
testFixturesImplementation(testFixtures(project(":"))) // The root project
|
||||||
|
@@ -11,6 +11,7 @@ import com.intellij.remoterobot.data.RemoteComponent
|
|||||||
import com.intellij.remoterobot.fixtures.CommonContainerFixture
|
import com.intellij.remoterobot.fixtures.CommonContainerFixture
|
||||||
import com.intellij.remoterobot.fixtures.DefaultXpath
|
import com.intellij.remoterobot.fixtures.DefaultXpath
|
||||||
import com.intellij.remoterobot.fixtures.FixtureName
|
import com.intellij.remoterobot.fixtures.FixtureName
|
||||||
|
import com.intellij.remoterobot.fixtures.JButtonFixture
|
||||||
import com.intellij.remoterobot.search.locators.byXpath
|
import com.intellij.remoterobot.search.locators.byXpath
|
||||||
import java.time.Duration
|
import java.time.Duration
|
||||||
|
|
||||||
@@ -28,6 +29,6 @@ class ManageLicensesFrame(remoteRobot: RemoteRobot, remoteComponent: RemoteCompo
|
|||||||
/// Note: The license code is obfuscated, so we use the class `W`. But a better solution is required.
|
/// Note: The license code is obfuscated, so we use the class `W`. But a better solution is required.
|
||||||
textFields(byXpath("//div[@class='W']")).first().text = System.getenv("RIDER_LICENSE")
|
textFields(byXpath("//div[@class='W']")).first().text = System.getenv("RIDER_LICENSE")
|
||||||
button("Activate").click()
|
button("Activate").click()
|
||||||
button("Close").click()
|
button(JButtonFixture.byText("Close"), timeout = Duration.ofSeconds(20)).click()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -10,8 +10,8 @@ plugins {
|
|||||||
java
|
java
|
||||||
kotlin("jvm")
|
kotlin("jvm")
|
||||||
// id("org.jlleitschuh.gradle.ktlint")
|
// id("org.jlleitschuh.gradle.ktlint")
|
||||||
id("com.google.devtools.ksp") version "2.0.21-1.0.25"
|
id("com.google.devtools.ksp") version "2.2.0-2.0.2"
|
||||||
kotlin("plugin.serialization") version "2.0.21"
|
kotlin("plugin.serialization") version "2.2.0"
|
||||||
`maven-publish`
|
`maven-publish`
|
||||||
antlr
|
antlr
|
||||||
}
|
}
|
||||||
@@ -45,13 +45,13 @@ afterEvaluate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
testImplementation("org.junit.jupiter:junit-jupiter-api:5.13.0")
|
testImplementation("org.junit.jupiter:junit-jupiter-api:5.13.3")
|
||||||
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.13.0")
|
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.13.3")
|
||||||
|
|
||||||
// Temp workaround suggested in https://plugins.jetbrains.com/docs/intellij/tools-intellij-platform-gradle-plugin-faq.html#junit5-test-framework-refers-to-junit4
|
// Temp workaround suggested in https://plugins.jetbrains.com/docs/intellij/tools-intellij-platform-gradle-plugin-faq.html#junit5-test-framework-refers-to-junit4
|
||||||
// Can be removed when IJPL-159134 is fixed
|
// Can be removed when IJPL-159134 is fixed
|
||||||
// testRuntimeOnly("junit:junit:4.13.2")
|
// testRuntimeOnly("junit:junit:4.13.2")
|
||||||
testRuntimeOnly("org.junit.vintage:junit-vintage-engine:5.13.0")
|
testRuntimeOnly("org.junit.vintage:junit-vintage-engine:5.13.2")
|
||||||
|
|
||||||
// https://mvnrepository.com/artifact/org.jetbrains.kotlin/kotlin-test
|
// https://mvnrepository.com/artifact/org.jetbrains.kotlin/kotlin-test
|
||||||
testImplementation("org.jetbrains.kotlin:kotlin-test:$kotlinVersion")
|
testImplementation("org.jetbrains.kotlin:kotlin-test:$kotlinVersion")
|
||||||
@@ -68,7 +68,7 @@ dependencies {
|
|||||||
|
|
||||||
compileOnly(kotlin("reflect"))
|
compileOnly(kotlin("reflect"))
|
||||||
|
|
||||||
testImplementation("org.mockito.kotlin:mockito-kotlin:5.4.0")
|
testImplementation("org.mockito.kotlin:mockito-kotlin:6.0.0")
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks {
|
tasks {
|
||||||
@@ -88,13 +88,13 @@ tasks {
|
|||||||
named("compileTestKotlin") {
|
named("compileTestKotlin") {
|
||||||
dependsOn("generateTestGrammarSource")
|
dependsOn("generateTestGrammarSource")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
compileKotlin {
|
kotlin {
|
||||||
kotlinOptions {
|
compilerOptions {
|
||||||
apiVersion = "2.0"
|
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_0)
|
||||||
freeCompilerArgs = listOf("-Xjvm-default=all-compatibility")
|
freeCompilerArgs = listOf("-Xjvm-default=all-compatibility")
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Linting
|
// --- Linting
|
||||||
|
@@ -18,10 +18,13 @@ import com.maddyhome.idea.vim.command.Argument
|
|||||||
import com.maddyhome.idea.vim.command.Command
|
import com.maddyhome.idea.vim.command.Command
|
||||||
import com.maddyhome.idea.vim.command.DuplicableOperatorAction
|
import com.maddyhome.idea.vim.command.DuplicableOperatorAction
|
||||||
import com.maddyhome.idea.vim.command.OperatorArguments
|
import com.maddyhome.idea.vim.command.OperatorArguments
|
||||||
|
import com.maddyhome.idea.vim.diagnostic.vimLogger
|
||||||
import com.maddyhome.idea.vim.handler.ChangeEditorActionHandler
|
import com.maddyhome.idea.vim.handler.ChangeEditorActionHandler
|
||||||
|
|
||||||
@CommandOrMotion(keys = ["gu"], modes = [Mode.NORMAL])
|
@CommandOrMotion(keys = ["gu"], modes = [Mode.NORMAL])
|
||||||
class ChangeCaseLowerMotionAction : ChangeEditorActionHandler.ForEachCaret(), DuplicableOperatorAction {
|
class ChangeCaseLowerMotionAction : ChangeEditorActionHandler.ForEachCaret(), DuplicableOperatorAction {
|
||||||
|
private val logger = vimLogger<ChangeCaseLowerMotionAction>()
|
||||||
|
|
||||||
override val type: Command.Type = Command.Type.CHANGE
|
override val type: Command.Type = Command.Type.CHANGE
|
||||||
|
|
||||||
override val argumentType: Argument.Type = Argument.Type.MOTION
|
override val argumentType: Argument.Type = Argument.Type.MOTION
|
||||||
@@ -35,15 +38,18 @@ class ChangeCaseLowerMotionAction : ChangeEditorActionHandler.ForEachCaret(), Du
|
|||||||
argument: Argument?,
|
argument: Argument?,
|
||||||
operatorArguments: OperatorArguments,
|
operatorArguments: OperatorArguments,
|
||||||
): Boolean {
|
): Boolean {
|
||||||
return argument != null &&
|
if (argument == null || argument !is Argument.Motion) {
|
||||||
injector.changeGroup
|
logger.error("Argument is null or not Argument.Motion. argument=$argument")
|
||||||
.changeCaseMotion(
|
return false
|
||||||
editor,
|
}
|
||||||
caret,
|
|
||||||
context,
|
return injector.changeGroup.changeCaseMotion(
|
||||||
VimChangeGroup.ChangeCaseType.LOWER,
|
editor,
|
||||||
argument,
|
caret,
|
||||||
operatorArguments,
|
context,
|
||||||
)
|
VimChangeGroup.ChangeCaseType.LOWER,
|
||||||
|
argument,
|
||||||
|
operatorArguments,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -18,10 +18,13 @@ import com.maddyhome.idea.vim.command.Argument
|
|||||||
import com.maddyhome.idea.vim.command.Command
|
import com.maddyhome.idea.vim.command.Command
|
||||||
import com.maddyhome.idea.vim.command.DuplicableOperatorAction
|
import com.maddyhome.idea.vim.command.DuplicableOperatorAction
|
||||||
import com.maddyhome.idea.vim.command.OperatorArguments
|
import com.maddyhome.idea.vim.command.OperatorArguments
|
||||||
|
import com.maddyhome.idea.vim.diagnostic.vimLogger
|
||||||
import com.maddyhome.idea.vim.handler.ChangeEditorActionHandler
|
import com.maddyhome.idea.vim.handler.ChangeEditorActionHandler
|
||||||
|
|
||||||
@CommandOrMotion(keys = ["g~"], modes = [Mode.NORMAL])
|
@CommandOrMotion(keys = ["g~"], modes = [Mode.NORMAL])
|
||||||
class ChangeCaseToggleMotionAction : ChangeEditorActionHandler.ForEachCaret(), DuplicableOperatorAction {
|
class ChangeCaseToggleMotionAction : ChangeEditorActionHandler.ForEachCaret(), DuplicableOperatorAction {
|
||||||
|
private val logger = vimLogger<ChangeCaseToggleMotionAction>()
|
||||||
|
|
||||||
override val type: Command.Type = Command.Type.CHANGE
|
override val type: Command.Type = Command.Type.CHANGE
|
||||||
|
|
||||||
override val argumentType: Argument.Type = Argument.Type.MOTION
|
override val argumentType: Argument.Type = Argument.Type.MOTION
|
||||||
@@ -35,15 +38,18 @@ class ChangeCaseToggleMotionAction : ChangeEditorActionHandler.ForEachCaret(), D
|
|||||||
argument: Argument?,
|
argument: Argument?,
|
||||||
operatorArguments: OperatorArguments,
|
operatorArguments: OperatorArguments,
|
||||||
): Boolean {
|
): Boolean {
|
||||||
return argument != null &&
|
if (argument == null || argument !is Argument.Motion) {
|
||||||
injector.changeGroup
|
logger.error("Argument is null or not Argument.Motion. argument=$argument")
|
||||||
.changeCaseMotion(
|
return false
|
||||||
editor,
|
}
|
||||||
caret,
|
|
||||||
context,
|
return injector.changeGroup.changeCaseMotion(
|
||||||
VimChangeGroup.ChangeCaseType.TOGGLE,
|
editor,
|
||||||
argument,
|
caret,
|
||||||
operatorArguments,
|
context,
|
||||||
)
|
VimChangeGroup.ChangeCaseType.TOGGLE,
|
||||||
|
argument,
|
||||||
|
operatorArguments,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -18,10 +18,13 @@ import com.maddyhome.idea.vim.command.Argument
|
|||||||
import com.maddyhome.idea.vim.command.Command
|
import com.maddyhome.idea.vim.command.Command
|
||||||
import com.maddyhome.idea.vim.command.DuplicableOperatorAction
|
import com.maddyhome.idea.vim.command.DuplicableOperatorAction
|
||||||
import com.maddyhome.idea.vim.command.OperatorArguments
|
import com.maddyhome.idea.vim.command.OperatorArguments
|
||||||
|
import com.maddyhome.idea.vim.diagnostic.vimLogger
|
||||||
import com.maddyhome.idea.vim.handler.ChangeEditorActionHandler
|
import com.maddyhome.idea.vim.handler.ChangeEditorActionHandler
|
||||||
|
|
||||||
@CommandOrMotion(keys = ["gU"], modes = [Mode.NORMAL])
|
@CommandOrMotion(keys = ["gU"], modes = [Mode.NORMAL])
|
||||||
class ChangeCaseUpperMotionAction : ChangeEditorActionHandler.ForEachCaret(), DuplicableOperatorAction {
|
class ChangeCaseUpperMotionAction : ChangeEditorActionHandler.ForEachCaret(), DuplicableOperatorAction {
|
||||||
|
private val logger = vimLogger<ChangeCaseUpperMotionAction>()
|
||||||
|
|
||||||
override val type: Command.Type = Command.Type.CHANGE
|
override val type: Command.Type = Command.Type.CHANGE
|
||||||
|
|
||||||
override val argumentType: Argument.Type = Argument.Type.MOTION
|
override val argumentType: Argument.Type = Argument.Type.MOTION
|
||||||
@@ -35,15 +38,18 @@ class ChangeCaseUpperMotionAction : ChangeEditorActionHandler.ForEachCaret(), Du
|
|||||||
argument: Argument?,
|
argument: Argument?,
|
||||||
operatorArguments: OperatorArguments,
|
operatorArguments: OperatorArguments,
|
||||||
): Boolean {
|
): Boolean {
|
||||||
return argument != null &&
|
if (argument == null || argument !is Argument.Motion) {
|
||||||
injector.changeGroup
|
logger.error("Argument is null or not Argument.Motion. argument=$argument")
|
||||||
.changeCaseMotion(
|
return false
|
||||||
editor,
|
}
|
||||||
caret,
|
|
||||||
context,
|
return injector.changeGroup.changeCaseMotion(
|
||||||
VimChangeGroup.ChangeCaseType.UPPER,
|
editor,
|
||||||
argument,
|
caret,
|
||||||
operatorArguments,
|
context,
|
||||||
)
|
VimChangeGroup.ChangeCaseType.UPPER,
|
||||||
|
argument,
|
||||||
|
operatorArguments,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -27,7 +27,7 @@ class InsertAfterCursorAction : ChangeEditorActionHandler.SingleExecution() {
|
|||||||
argument: Argument?,
|
argument: Argument?,
|
||||||
operatorArguments: OperatorArguments,
|
operatorArguments: OperatorArguments,
|
||||||
): Boolean {
|
): Boolean {
|
||||||
injector.changeGroup.insertAfterCursor(editor, context)
|
injector.changeGroup.insertAfterCaret(editor, context)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -47,5 +47,5 @@ private fun insertAtPreviousInsert(editor: VimEditor, context: ExecutionContext)
|
|||||||
if (motion is Motion.AbsoluteOffset) {
|
if (motion is Motion.AbsoluteOffset) {
|
||||||
caret.moveToOffset(motion.offset)
|
caret.moveToOffset(motion.offset)
|
||||||
}
|
}
|
||||||
injector.changeGroup.insertBeforeCursor(editor, context)
|
injector.changeGroup.insertBeforeCaret(editor, context)
|
||||||
}
|
}
|
||||||
|
@@ -29,7 +29,7 @@ class InsertBeforeCursorAction : ChangeEditorActionHandler.SingleExecution() {
|
|||||||
argument: Argument?,
|
argument: Argument?,
|
||||||
operatorArguments: OperatorArguments,
|
operatorArguments: OperatorArguments,
|
||||||
): Boolean {
|
): Boolean {
|
||||||
injector.changeGroup.insertBeforeCursor(editor, context)
|
injector.changeGroup.insertBeforeCaret(editor, context)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -13,6 +13,7 @@ import com.maddyhome.idea.vim.api.ExecutionContext
|
|||||||
import com.maddyhome.idea.vim.api.VimCaret
|
import com.maddyhome.idea.vim.api.VimCaret
|
||||||
import com.maddyhome.idea.vim.api.VimEditor
|
import com.maddyhome.idea.vim.api.VimEditor
|
||||||
import com.maddyhome.idea.vim.api.injector
|
import com.maddyhome.idea.vim.api.injector
|
||||||
|
import com.maddyhome.idea.vim.api.normalizeLine
|
||||||
import com.maddyhome.idea.vim.command.Command
|
import com.maddyhome.idea.vim.command.Command
|
||||||
import com.maddyhome.idea.vim.command.OperatorArguments
|
import com.maddyhome.idea.vim.command.OperatorArguments
|
||||||
import com.maddyhome.idea.vim.group.visual.VimSelection
|
import com.maddyhome.idea.vim.group.visual.VimSelection
|
||||||
@@ -20,10 +21,17 @@ import com.maddyhome.idea.vim.handler.VisualOperatorActionHandler
|
|||||||
import com.maddyhome.idea.vim.state.mode.SelectionType
|
import com.maddyhome.idea.vim.state.mode.SelectionType
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author vlan
|
* Handles the 'I' command in Visual mode.
|
||||||
|
*
|
||||||
|
* For (linewise) Visual mode, the caret positioning follows these rules (based on observation in Vim):
|
||||||
|
* - If text on multiple lines is selected AND the caret is on the first line (e.g., when selecting from bottom to top),
|
||||||
|
* the caret position remains unchanged
|
||||||
|
* - In all other cases, the caret is moved to the start of the first selected line
|
||||||
|
*
|
||||||
|
* For blockwise Visual mode, it initiates insert at the start of block on each line in the selection
|
||||||
*/
|
*/
|
||||||
@CommandOrMotion(keys = ["I"], modes = [Mode.VISUAL])
|
@CommandOrMotion(keys = ["I"], modes = [Mode.VISUAL])
|
||||||
class VisualBlockInsertAction : VisualOperatorActionHandler.SingleExecution() {
|
class VisualInsertAction : VisualOperatorActionHandler.SingleExecution() {
|
||||||
override val type: Command.Type = Command.Type.INSERT
|
override val type: Command.Type = Command.Type.INSERT
|
||||||
|
|
||||||
override fun executeForAllCarets(
|
override fun executeForAllCarets(
|
||||||
@@ -38,7 +46,17 @@ class VisualBlockInsertAction : VisualOperatorActionHandler.SingleExecution() {
|
|||||||
return if (vimSelection.type == SelectionType.BLOCK_WISE) {
|
return if (vimSelection.type == SelectionType.BLOCK_WISE) {
|
||||||
injector.changeGroup.initBlockInsert(editor, context, vimSelection.toVimTextRange(false), false)
|
injector.changeGroup.initBlockInsert(editor, context, vimSelection.toVimTextRange(false), false)
|
||||||
} else {
|
} else {
|
||||||
injector.changeGroup.insertBeforeFirstNonBlank(editor, context)
|
// For visual selections spanning multiple lines, keep caret position if it's on the first line
|
||||||
|
// Otherwise move the caret to the start of the first selected line
|
||||||
|
for ((caret, selection) in caretsAndSelections) {
|
||||||
|
val range = selection.toVimTextRange()
|
||||||
|
val posStart = editor.offsetToBufferPosition(range.startOffset)
|
||||||
|
val nextLineStart = editor.getLineStartOffset(editor.normalizeLine(posStart.line + 1))
|
||||||
|
if (caret.offset >= nextLineStart || nextLineStart >= range.endOffset) {
|
||||||
|
caret.moveToOffset(injector.motion.moveCaretToLineStart(editor, posStart.line))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
injector.changeGroup.insertBeforeCaret(editor, context)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2003-2025 The IdeaVim authors
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by an MIT-style
|
||||||
|
* license that can be found in the LICENSE.txt file or at
|
||||||
|
* https://opensource.org/licenses/MIT.
|
||||||
|
*/
|
||||||
|
package com.maddyhome.idea.vim.action.file
|
||||||
|
|
||||||
|
import com.intellij.vim.annotations.CommandOrMotion
|
||||||
|
import com.intellij.vim.annotations.Mode
|
||||||
|
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.Command
|
||||||
|
import com.maddyhome.idea.vim.command.OperatorArguments
|
||||||
|
import com.maddyhome.idea.vim.handler.VimActionHandler
|
||||||
|
|
||||||
|
@CommandOrMotion(keys = ["ZQ"], modes = [Mode.NORMAL])
|
||||||
|
class FileCloseAction : VimActionHandler.SingleExecution() {
|
||||||
|
override val type: Command.Type = Command.Type.OTHER_SELF_SYNCHRONIZED
|
||||||
|
|
||||||
|
override fun execute(
|
||||||
|
editor: VimEditor,
|
||||||
|
context: ExecutionContext,
|
||||||
|
cmd: Command,
|
||||||
|
operatorArguments: OperatorArguments,
|
||||||
|
): Boolean {
|
||||||
|
injector.file.closeFile(editor, context)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2003-2023 The IdeaVim authors
|
* Copyright 2003-2025 The IdeaVim authors
|
||||||
*
|
*
|
||||||
* Use of this source code is governed by an MIT-style
|
* Use of this source code is governed by an MIT-style
|
||||||
* license that can be found in the LICENSE.txt file or at
|
* license that can be found in the LICENSE.txt file or at
|
||||||
@@ -16,9 +16,9 @@ import com.maddyhome.idea.vim.command.Command
|
|||||||
import com.maddyhome.idea.vim.command.OperatorArguments
|
import com.maddyhome.idea.vim.command.OperatorArguments
|
||||||
import com.maddyhome.idea.vim.handler.VimActionHandler
|
import com.maddyhome.idea.vim.handler.VimActionHandler
|
||||||
|
|
||||||
@CommandOrMotion(keys = ["ZQ", "ZZ"], modes = [Mode.NORMAL])
|
@CommandOrMotion(keys = ["ZZ"], modes = [Mode.NORMAL])
|
||||||
class FileSaveCloseAction : VimActionHandler.SingleExecution() {
|
class FileSaveCloseAction : VimActionHandler.SingleExecution() {
|
||||||
override val type: Command.Type = Command.Type.OTHER_WRITABLE
|
override val type: Command.Type = Command.Type.OTHER_SELF_SYNCHRONIZED
|
||||||
|
|
||||||
override fun execute(
|
override fun execute(
|
||||||
editor: VimEditor,
|
editor: VimEditor,
|
||||||
|
@@ -48,7 +48,7 @@ class SelectMotionArrowLeftAction : MotionActionHandler.ForEachCaret() {
|
|||||||
editor.exitSelectModeNative(false)
|
editor.exitSelectModeNative(false)
|
||||||
if (editor.isTemplateActive()) {
|
if (editor.isTemplateActive()) {
|
||||||
logger.debug("Template is active. Activate insert mode")
|
logger.debug("Template is active. Activate insert mode")
|
||||||
injector.changeGroup.insertBeforeCursor(editor, context)
|
injector.changeGroup.insertBeforeCaret(editor, context)
|
||||||
if (caret.offset in startSelection..endSelection) {
|
if (caret.offset in startSelection..endSelection) {
|
||||||
return startSelection.toMotion()
|
return startSelection.toMotion()
|
||||||
}
|
}
|
||||||
|
@@ -48,7 +48,7 @@ class SelectMotionArrowRightAction : MotionActionHandler.ForEachCaret() {
|
|||||||
editor.exitSelectModeNative(false)
|
editor.exitSelectModeNative(false)
|
||||||
if (editor.isTemplateActive()) {
|
if (editor.isTemplateActive()) {
|
||||||
logger.debug("Template is active. Activate insert mode")
|
logger.debug("Template is active. Activate insert mode")
|
||||||
injector.changeGroup.insertBeforeCursor(editor, context)
|
injector.changeGroup.insertBeforeCaret(editor, context)
|
||||||
if (caret.offset in startSelection..endSelection) {
|
if (caret.offset in startSelection..endSelection) {
|
||||||
return endSelection.toMotion()
|
return endSelection.toMotion()
|
||||||
}
|
}
|
||||||
|
@@ -23,13 +23,13 @@ import javax.swing.KeyStroke
|
|||||||
interface VimChangeGroup {
|
interface VimChangeGroup {
|
||||||
fun setInsertRepeat(lines: Int, column: Int, append: Boolean)
|
fun setInsertRepeat(lines: Int, column: Int, append: Boolean)
|
||||||
|
|
||||||
fun insertBeforeCursor(editor: VimEditor, context: ExecutionContext)
|
fun insertBeforeCaret(editor: VimEditor, context: ExecutionContext)
|
||||||
|
|
||||||
fun insertBeforeFirstNonBlank(editor: VimEditor, context: ExecutionContext)
|
fun insertBeforeFirstNonBlank(editor: VimEditor, context: ExecutionContext)
|
||||||
|
|
||||||
fun insertLineStart(editor: VimEditor, context: ExecutionContext)
|
fun insertLineStart(editor: VimEditor, context: ExecutionContext)
|
||||||
|
|
||||||
fun insertAfterCursor(editor: VimEditor, context: ExecutionContext)
|
fun insertAfterCaret(editor: VimEditor, context: ExecutionContext)
|
||||||
|
|
||||||
fun insertAfterLineEnd(editor: VimEditor, context: ExecutionContext)
|
fun insertAfterLineEnd(editor: VimEditor, context: ExecutionContext)
|
||||||
|
|
||||||
@@ -198,7 +198,7 @@ interface VimChangeGroup {
|
|||||||
caret: VimCaret,
|
caret: VimCaret,
|
||||||
context: ExecutionContext?,
|
context: ExecutionContext?,
|
||||||
type: ChangeCaseType,
|
type: ChangeCaseType,
|
||||||
argument: Argument,
|
argument: Argument.Motion,
|
||||||
operatorArguments: OperatorArguments,
|
operatorArguments: OperatorArguments,
|
||||||
): Boolean
|
): Boolean
|
||||||
|
|
||||||
|
@@ -401,7 +401,7 @@ abstract class VimChangeGroupBase : VimChangeGroup {
|
|||||||
* @param editor The editor to insert into
|
* @param editor The editor to insert into
|
||||||
* @param context The data context
|
* @param context The data context
|
||||||
*/
|
*/
|
||||||
override fun insertBeforeCursor(editor: VimEditor, context: ExecutionContext) {
|
override fun insertBeforeCaret(editor: VimEditor, context: ExecutionContext) {
|
||||||
initInsert(editor, context, Mode.INSERT)
|
initInsert(editor, context, Mode.INSERT)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -417,7 +417,7 @@ abstract class VimChangeGroupBase : VimChangeGroup {
|
|||||||
* @param editor The editor to insert into
|
* @param editor The editor to insert into
|
||||||
* @param context The data context
|
* @param context The data context
|
||||||
*/
|
*/
|
||||||
override fun insertAfterCursor(editor: VimEditor, context: ExecutionContext) {
|
override fun insertAfterCaret(editor: VimEditor, context: ExecutionContext) {
|
||||||
for (caret in editor.nativeCarets()) {
|
for (caret in editor.nativeCarets()) {
|
||||||
caret.moveToMotion(injector.motion.getHorizontalMotion(editor, caret, 1, true))
|
caret.moveToMotion(injector.motion.getHorizontalMotion(editor, caret, 1, true))
|
||||||
}
|
}
|
||||||
@@ -781,7 +781,7 @@ abstract class VimChangeGroupBase : VimChangeGroup {
|
|||||||
lambdaEditor.exitSelectModeNative(false)
|
lambdaEditor.exitSelectModeNative(false)
|
||||||
KeyHandler.getInstance().reset(lambdaEditor)
|
KeyHandler.getInstance().reset(lambdaEditor)
|
||||||
if (isPrintableChar(key.keyChar) || activeTemplateWithLeftRightMotion(lambdaEditor, key)) {
|
if (isPrintableChar(key.keyChar) || activeTemplateWithLeftRightMotion(lambdaEditor, key)) {
|
||||||
injector.changeGroup.insertBeforeCursor(lambdaEditor, lambdaContext)
|
injector.changeGroup.insertBeforeCaret(lambdaEditor, lambdaContext)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1302,7 +1302,7 @@ abstract class VimChangeGroupBase : VimChangeGroup {
|
|||||||
if (type === SelectionType.LINE_WISE) {
|
if (type === SelectionType.LINE_WISE) {
|
||||||
// Please don't use `getDocument().getText().isEmpty()` because it converts CharSequence into String
|
// Please don't use `getDocument().getText().isEmpty()` because it converts CharSequence into String
|
||||||
if (editor.fileSize() == 0L) {
|
if (editor.fileSize() == 0L) {
|
||||||
insertBeforeCursor(editor, context)
|
insertBeforeCaret(editor, context)
|
||||||
} else if (after && !editor.endsWithNewLine()) {
|
} else if (after && !editor.endsWithNewLine()) {
|
||||||
insertNewLineBelow(editor, updatedCaret, lp.column)
|
insertNewLineBelow(editor, updatedCaret, lp.column)
|
||||||
} else {
|
} else {
|
||||||
@@ -1315,7 +1315,7 @@ abstract class VimChangeGroupBase : VimChangeGroup {
|
|||||||
editor.vimChangeActionSwitchMode = Mode.INSERT
|
editor.vimChangeActionSwitchMode = Mode.INSERT
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
insertBeforeCursor(editor, context)
|
insertBeforeCaret(editor, context)
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -1867,14 +1867,22 @@ abstract class VimChangeGroupBase : VimChangeGroup {
|
|||||||
caret: VimCaret,
|
caret: VimCaret,
|
||||||
context: ExecutionContext?,
|
context: ExecutionContext?,
|
||||||
type: VimChangeGroup.ChangeCaseType,
|
type: VimChangeGroup.ChangeCaseType,
|
||||||
argument: Argument,
|
argument: Argument.Motion,
|
||||||
operatorArguments: OperatorArguments,
|
operatorArguments: OperatorArguments,
|
||||||
): Boolean {
|
): Boolean {
|
||||||
val range = injector.motion.getMotionRange(
|
var range = injector.motion.getMotionRange(
|
||||||
editor, caret, context!!, argument,
|
editor, caret, context!!, argument, operatorArguments
|
||||||
operatorArguments
|
|
||||||
)
|
)
|
||||||
return range != null && changeCaseRange(editor, caret, range, type)
|
if (range == null) return false
|
||||||
|
|
||||||
|
// If the motion is linewise, we need to adjust range.startOffset to match the observed Vim behavior
|
||||||
|
if (argument.isLinewiseMotion()) {
|
||||||
|
val pos = editor.offsetToBufferPosition(range.startOffset)
|
||||||
|
// The leftmost non-whitespace character OR the current caret position, whichever is closer to the left
|
||||||
|
val start = editor.getLeadingCharacterOffset(pos.line).coerceAtMost(caret.offset)
|
||||||
|
range = TextRange(start, range.endOffset)
|
||||||
|
}
|
||||||
|
return changeCaseRange(editor, caret, range, type)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2040,7 +2048,7 @@ abstract class VimChangeGroupBase : VimChangeGroup {
|
|||||||
caret.moveToInlayAwareOffset(editor.bufferPositionToOffset(BufferPosition(line, column)))
|
caret.moveToInlayAwareOffset(editor.bufferPositionToOffset(BufferPosition(line, column)))
|
||||||
setInsertRepeat(lines, column, append)
|
setInsertRepeat(lines, column, append)
|
||||||
}
|
}
|
||||||
insertBeforeCursor(editor, context)
|
insertBeforeCaret(editor, context)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -400,12 +400,11 @@ abstract class VimMotionGroupBase : VimMotionGroup {
|
|||||||
// If we are a linewise motion we need to normalize the start and stop then move the start to the beginning
|
// If we are a linewise motion we need to normalize the start and stop then move the start to the beginning
|
||||||
// of the line and move the end to the end of the line.
|
// of the line and move the end to the end of the line.
|
||||||
if (argument.isLinewiseMotion()) {
|
if (argument.isLinewiseMotion()) {
|
||||||
if (caret.getBufferPosition().line != editor.lineCount() - 1) {
|
start = editor.getLineStartForOffset(start)
|
||||||
start = editor.getLineStartForOffset(start)
|
end = if (caret.getBufferPosition().line != editor.lineCount() - 1) {
|
||||||
end = min((editor.getLineEndForOffset(end) + 1).toLong(), editor.fileSize()).toInt()
|
min((editor.getLineEndForOffset(end) + 1).toLong(), editor.fileSize()).toInt()
|
||||||
} else {
|
} else {
|
||||||
start = editor.getLineStartForOffset(start)
|
editor.getLineEndForOffset(end)
|
||||||
end = editor.getLineEndForOffset(end)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -53,15 +53,11 @@ sealed class Argument {
|
|||||||
|
|
||||||
fun getMotionType() = if (isLinewiseMotion()) SelectionType.LINE_WISE else SelectionType.CHARACTER_WISE
|
fun getMotionType() = if (isLinewiseMotion()) SelectionType.LINE_WISE else SelectionType.CHARACTER_WISE
|
||||||
|
|
||||||
fun isLinewiseMotion(): Boolean {
|
fun isLinewiseMotion(): Boolean = when (motion) {
|
||||||
return motion.let {
|
is TextObjectActionHandler -> motion.visualType == TextObjectVisualType.LINE_WISE
|
||||||
when (it) {
|
is MotionActionHandler -> motion.motionType == MotionType.LINE_WISE
|
||||||
is TextObjectActionHandler -> it.visualType == TextObjectVisualType.LINE_WISE
|
is ExternalActionHandler -> motion.isLinewiseMotion
|
||||||
is MotionActionHandler -> it.motionType == MotionType.LINE_WISE
|
else -> error("Command is not a motion: $motion")
|
||||||
is ExternalActionHandler -> it.isLinewiseMotion
|
|
||||||
else -> error("Command is not a motion: $motion")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun withArgument(argument: Argument) = Motion(motion, argument)
|
fun withArgument(argument: Argument) = Motion(motion, argument)
|
||||||
|
@@ -1106,7 +1106,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"keys": "I",
|
"keys": "I",
|
||||||
"class": "com.maddyhome.idea.vim.action.change.insert.VisualBlockInsertAction",
|
"class": "com.maddyhome.idea.vim.action.change.insert.VisualInsertAction",
|
||||||
"modes": "X"
|
"modes": "X"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1211,7 +1211,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"keys": "ZQ",
|
"keys": "ZQ",
|
||||||
"class": "com.maddyhome.idea.vim.action.file.FileSaveCloseAction",
|
"class": "com.maddyhome.idea.vim.action.file.FileCloseAction",
|
||||||
"modes": "N"
|
"modes": "N"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user