mirror of
https://github.com/chylex/IntelliJ-IdeaVim.git
synced 2025-07-05 05:38:52 +02:00
Compare commits
24 Commits
3cc9ce73b9
...
295f0b6c53
Author | SHA1 | Date | |
---|---|---|---|
295f0b6c53 | |||
2643301ea9 | |||
51f15782af | |||
de930ed57c | |||
590d5bd22d | |||
69c748d881 | |||
144cc5c3fc | |||
fb270cdbc5 | |||
ce6a296233 | |||
949f359b98 | |||
c922426e02 | |||
9240e82f2d | |||
a1639d80b0 | |||
7860b98107 | |||
7157f9c5a5 | |||
1522618cd6 | |||
09862c8356 | |||
c6ef3f286f | |||
b358e63444 | |||
7ac743c604 | |||
db3d3fc608 | |||
14d313907b | |||
fe37a69544 | |||
54de3dac25 |
4
.github/workflows/runUiRdTests.yml
vendored
4
.github/workflows/runUiRdTests.yml
vendored
@ -28,12 +28,10 @@ jobs:
|
|||||||
uses: jtalk/url-health-check-action@v3
|
uses: jtalk/url-health-check-action@v3
|
||||||
with:
|
with:
|
||||||
url: http://127.0.0.1:8082
|
url: http://127.0.0.1:8082
|
||||||
max-attempts: 100
|
max-attempts: 20
|
||||||
retry-delay: 10s
|
retry-delay: 10s
|
||||||
- name: Tests
|
- name: Tests
|
||||||
run: gradle :tests:ui-rd-tests:testUi
|
run: gradle :tests:ui-rd-tests:testUi
|
||||||
env:
|
|
||||||
RIDER_LICENSE: ${{ secrets.RIDER_LICENSE }}
|
|
||||||
- name: Move video
|
- name: Move video
|
||||||
if: always()
|
if: always()
|
||||||
run: mv tests/ui-rd-tests/video build/reports
|
run: mv tests/ui-rd-tests/video build/reports
|
||||||
|
12
.teamcity/_Self/Constants.kt
vendored
12
.teamcity/_Self/Constants.kt
vendored
@ -5,11 +5,11 @@ object Constants {
|
|||||||
const val EAP_CHANNEL = "eap"
|
const val EAP_CHANNEL = "eap"
|
||||||
const val DEV_CHANNEL = "Dev"
|
const val DEV_CHANNEL = "Dev"
|
||||||
|
|
||||||
const val NVIM_TESTS = "2025.1"
|
const val NVIM_TESTS = "2024.3.3"
|
||||||
const val PROPERTY_TESTS = "2025.1"
|
const val PROPERTY_TESTS = "2024.3.3"
|
||||||
const val LONG_RUNNING_TESTS = "2025.1"
|
const val LONG_RUNNING_TESTS = "2024.3.3"
|
||||||
const val RELEASE = "2025.1"
|
const val RELEASE = "2024.3.3"
|
||||||
|
|
||||||
const val RELEASE_DEV = "2025.1"
|
const val RELEASE_DEV = "2024.3.3"
|
||||||
const val RELEASE_EAP = "2025.1"
|
const val RELEASE_EAP = "2024.3.3"
|
||||||
}
|
}
|
||||||
|
4
.teamcity/_Self/Project.kt
vendored
4
.teamcity/_Self/Project.kt
vendored
@ -23,8 +23,8 @@ object Project : Project({
|
|||||||
vcsRoot(ReleasesVcsRoot)
|
vcsRoot(ReleasesVcsRoot)
|
||||||
|
|
||||||
// Active tests
|
// Active tests
|
||||||
buildType(TestingBuildType("Latest EAP", version = "LATEST-EAP-SNAPSHOT"))
|
buildType(TestingBuildType("Latest EAP", "<default>", version = "LATEST-EAP-SNAPSHOT"))
|
||||||
buildType(TestingBuildType("2025.1"))
|
buildType(TestingBuildType("2024.3.3", "<default>"))
|
||||||
buildType(TestingBuildType("Latest EAP With Xorg", "<default>", version = "LATEST-EAP-SNAPSHOT"))
|
buildType(TestingBuildType("Latest EAP With Xorg", "<default>", version = "LATEST-EAP-SNAPSHOT"))
|
||||||
|
|
||||||
buildType(PropertyBased)
|
buildType(PropertyBased)
|
||||||
|
2
.teamcity/_Self/buildTypes/Compatibility.kt
vendored
2
.teamcity/_Self/buildTypes/Compatibility.kt
vendored
@ -43,8 +43,6 @@ object Compatibility : IdeaVimBuildType({
|
|||||||
java -jar verifier1/verifier-cli-dev-all-2.jar check-plugin '${'$'}com.julienphalip.ideavim.peekaboo' [latest-IU] -team-city
|
java -jar verifier1/verifier-cli-dev-all-2.jar check-plugin '${'$'}com.julienphalip.ideavim.peekaboo' [latest-IU] -team-city
|
||||||
java -jar verifier1/verifier-cli-dev-all-2.jar check-plugin '${'$'}com.julienphalip.ideavim.switch' [latest-IU] -team-city
|
java -jar verifier1/verifier-cli-dev-all-2.jar check-plugin '${'$'}com.julienphalip.ideavim.switch' [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.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.ugarosa.idea.edgemotion' [latest-IU] -team-city
|
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
1
.teamcity/_Self/buildTypes/PropertyBased.kt
vendored
1
.teamcity/_Self/buildTypes/PropertyBased.kt
vendored
@ -24,7 +24,6 @@ object PropertyBased : IdeaVimBuildType({
|
|||||||
|
|
||||||
steps {
|
steps {
|
||||||
gradle {
|
gradle {
|
||||||
clearConditions()
|
|
||||||
tasks = "clean :tests:property-tests:testPropertyBased"
|
tasks = "clean :tests:property-tests:testPropertyBased"
|
||||||
buildFile = ""
|
buildFile = ""
|
||||||
enableStacktrace = true
|
enableStacktrace = true
|
||||||
|
@ -12,7 +12,7 @@ import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.vcs
|
|||||||
|
|
||||||
open class TestingBuildType(
|
open class TestingBuildType(
|
||||||
private val testName: String,
|
private val testName: String,
|
||||||
private val branch: String = "<default>",
|
private val branch: String,
|
||||||
private val version: String = testName,
|
private val version: String = testName,
|
||||||
private val javaVersion: String? = null,
|
private val javaVersion: String? = null,
|
||||||
private val javaPlugin: Boolean = true,
|
private val javaPlugin: Boolean = true,
|
||||||
|
23
AUTHORS.md
23
AUTHORS.md
@ -26,13 +26,6 @@ Previous maintainers:
|
|||||||
|
|
||||||
Andrey Vlasovskikh
|
Andrey Vlasovskikh
|
||||||
|
|
||||||
Previous support members:
|
|
||||||
|
|
||||||
* [![icon][mail]](mailto:lejia.chen@jetbrains.com)
|
|
||||||
[![icon][github-off]](#)
|
|
||||||
|
|
||||||
Lejia Chen
|
|
||||||
|
|
||||||
Contributors:
|
Contributors:
|
||||||
|
|
||||||
* [![icon][mail]](mailto:yole@jetbrains.com)
|
* [![icon][mail]](mailto:yole@jetbrains.com)
|
||||||
@ -594,22 +587,6 @@ Contributors:
|
|||||||
[![icon][github]](https://github.com/Iliya-usov)
|
[![icon][github]](https://github.com/Iliya-usov)
|
||||||
|
|
||||||
Ilya Usov
|
Ilya Usov
|
||||||
* [![icon][mail]](mailto:peterHoburg@users.noreply.github.com)
|
|
||||||
[![icon][github]](https://github.com/peterHoburg)
|
|
||||||
|
|
||||||
Peter Hoburg
|
|
||||||
* [![icon][mail]](mailto:erotourtes@gmail.com)
|
|
||||||
[![icon][github]](https://github.com/erotourtes)
|
|
||||||
|
|
||||||
Max Siryk
|
|
||||||
* [![icon][mail]](mailto:ivan.yarkov@jetbrains.com)
|
|
||||||
[![icon][github]](https://github.com/MToolMakerJB)
|
|
||||||
|
|
||||||
Ivan Yarkov
|
|
||||||
* [![icon][mail]](mailto:mia.vucinic@jetbrains.com)
|
|
||||||
[![icon][github]](https://github.com/vumi19)
|
|
||||||
|
|
||||||
Mia Vucinic
|
|
||||||
|
|
||||||
Previous contributors:
|
Previous contributors:
|
||||||
|
|
||||||
|
30
README.md
30
README.md
@ -92,26 +92,20 @@ Here are some examples of supported vim features and commands:
|
|||||||
|
|
||||||
[IdeaVim plugins](https://github.com/JetBrains/ideavim/wiki/IdeaVim-Plugins):
|
[IdeaVim plugins](https://github.com/JetBrains/ideavim/wiki/IdeaVim-Plugins):
|
||||||
|
|
||||||
* argtextobj
|
* vim-easymotion
|
||||||
* commentary
|
|
||||||
* easymotion
|
|
||||||
* exchange
|
|
||||||
* FunctionTextObj
|
|
||||||
* highlightedyank
|
|
||||||
* indent-object
|
|
||||||
* matchit.vim
|
|
||||||
* Mini.ai
|
|
||||||
* multiple-cursors
|
|
||||||
* NERDTree
|
* NERDTree
|
||||||
* paragraph-motion
|
* vim-surround
|
||||||
* Peekaboo
|
* vim-multiple-cursors
|
||||||
* quick-scope
|
* vim-commentary
|
||||||
|
* argtextobj.vim
|
||||||
|
* vim-textobj-entire
|
||||||
* ReplaceWithRegister
|
* ReplaceWithRegister
|
||||||
* sneak
|
* vim-exchange
|
||||||
* surround
|
* vim-highlightedyank
|
||||||
* Switch
|
* vim-paragraph-motion
|
||||||
* textobj-entire
|
* vim-indent-object
|
||||||
* Which-Key
|
* match.it
|
||||||
|
etc
|
||||||
|
|
||||||
See also:
|
See also:
|
||||||
|
|
||||||
|
@ -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.10-1.0.29")
|
||||||
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")
|
||||||
|
@ -31,7 +31,6 @@ import kotlinx.serialization.json.putJsonObject
|
|||||||
import org.eclipse.jgit.api.Git
|
import org.eclipse.jgit.api.Git
|
||||||
import org.eclipse.jgit.lib.RepositoryBuilder
|
import org.eclipse.jgit.lib.RepositoryBuilder
|
||||||
import org.intellij.markdown.ast.getTextInNode
|
import org.intellij.markdown.ast.getTextInNode
|
||||||
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
|
||||||
@ -51,14 +50,14 @@ buildscript {
|
|||||||
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.0.202503040940-r")
|
classpath("org.eclipse.jgit:org.eclipse.jgit.ssh.apache:7.1.0.202411261347-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.1.1")
|
||||||
classpath("io.ktor:ktor-client-cio:3.1.3")
|
classpath("io.ktor:ktor-client-cio:3.1.1")
|
||||||
classpath("io.ktor:ktor-client-auth:3.1.3")
|
classpath("io.ktor:ktor-client-auth:3.1.1")
|
||||||
classpath("io.ktor:ktor-client-content-negotiation:3.1.3")
|
classpath("io.ktor:ktor-client-content-negotiation:3.1.1")
|
||||||
classpath("io.ktor:ktor-serialization-kotlinx-json:3.1.3")
|
classpath("io.ktor:ktor-serialization-kotlinx-json:3.1.1")
|
||||||
|
|
||||||
// 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")
|
||||||
@ -70,12 +69,7 @@ plugins {
|
|||||||
kotlin("jvm") version "2.0.21"
|
kotlin("jvm") version "2.0.21"
|
||||||
application
|
application
|
||||||
id("java-test-fixtures")
|
id("java-test-fixtures")
|
||||||
|
id("org.jetbrains.intellij.platform") version "2.3.0"
|
||||||
// NOTE: Unignore "test block comment falls back to line comment when not available" test
|
|
||||||
// After changing this version. It supposed to work on the next version of the gradle plugin
|
|
||||||
// Or go report to the devs that this test still fails.
|
|
||||||
id("org.jetbrains.intellij.platform") version "2.5.0"
|
|
||||||
|
|
||||||
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"
|
||||||
@ -118,11 +112,7 @@ dependencies {
|
|||||||
intellijPlatform {
|
intellijPlatform {
|
||||||
// Snapshots don't use installers
|
// Snapshots don't use installers
|
||||||
// https://plugins.jetbrains.com/docs/intellij/tools-intellij-platform-gradle-plugin-dependencies-extension.html#target-versions-installers
|
// https://plugins.jetbrains.com/docs/intellij/tools-intellij-platform-gradle-plugin-dependencies-extension.html#target-versions-installers
|
||||||
var useInstaller = "EAP-SNAPSHOT" !in ideaVersion
|
val useInstaller = "EAP-SNAPSHOT" !in ideaVersion
|
||||||
if (ideaType == "RD") {
|
|
||||||
// Using Rider as a target IntelliJ Platform with `useInstaller = true` is currently not supported, please set `useInstaller = false` instead. See: https://github.com/JetBrains/intellij-platform-gradle-plugin/issues/1852
|
|
||||||
useInstaller = false
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note that it is also possible to use local("...") to compile against a locally installed IDE
|
// Note that it is also possible to use local("...") to compile against a locally installed IDE
|
||||||
// E.g. local("/Users/{user}/Applications/IntelliJ IDEA Ultimate.app")
|
// E.g. local("/Users/{user}/Applications/IntelliJ IDEA Ultimate.app")
|
||||||
@ -137,7 +127,7 @@ dependencies {
|
|||||||
|
|
||||||
// AceJump is an optional dependency. We use their SessionManager class to check if it's active
|
// AceJump is an optional dependency. We use their SessionManager class to check if it's active
|
||||||
plugin("AceJump", "3.8.19")
|
plugin("AceJump", "3.8.19")
|
||||||
plugin("com.intellij.classic.ui", "251.23774.318")
|
plugin("com.intellij.classic.ui", "243.21565.122")
|
||||||
|
|
||||||
bundledPlugins("org.jetbrains.plugins.terminal", "com.intellij.modules.json")
|
bundledPlugins("org.jetbrains.plugins.terminal", "com.intellij.modules.json")
|
||||||
}
|
}
|
||||||
@ -161,17 +151,17 @@ dependencies {
|
|||||||
// 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:5.4.0")
|
||||||
|
|
||||||
testImplementation("org.junit.jupiter:junit-jupiter-api:5.12.2")
|
testImplementation("org.junit.jupiter:junit-jupiter-api:5.12.0")
|
||||||
testImplementation("org.junit.jupiter:junit-jupiter-engine:5.12.2")
|
testImplementation("org.junit.jupiter:junit-jupiter-engine:5.12.0")
|
||||||
testImplementation("org.junit.jupiter:junit-jupiter-params:5.12.2")
|
testImplementation("org.junit.jupiter:junit-jupiter-params:5.12.0")
|
||||||
testFixturesImplementation("org.junit.jupiter:junit-jupiter-api:5.12.2")
|
testFixturesImplementation("org.junit.jupiter:junit-jupiter-api:5.12.0")
|
||||||
testFixturesImplementation("org.junit.jupiter:junit-jupiter-engine:5.12.2")
|
testFixturesImplementation("org.junit.jupiter:junit-jupiter-engine:5.12.0")
|
||||||
testFixturesImplementation("org.junit.jupiter:junit-jupiter-params:5.12.2")
|
testFixturesImplementation("org.junit.jupiter:junit-jupiter-params:5.12.0")
|
||||||
|
|
||||||
// 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.12.2")
|
testImplementation("org.junit.vintage:junit-vintage-engine:5.12.0")
|
||||||
// testFixturesImplementation("org.junit.vintage:junit-vintage-engine:5.10.3")
|
// testFixturesImplementation("org.junit.vintage:junit-vintage-engine:5.10.3")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -260,7 +250,6 @@ tasks {
|
|||||||
// a custom task (see below)
|
// a custom task (see below)
|
||||||
runIde {
|
runIde {
|
||||||
systemProperty("octopus.handler", System.getProperty("octopus.handler") ?: true)
|
systemProperty("octopus.handler", System.getProperty("octopus.handler") ?: true)
|
||||||
systemProperty("idea.trust.all.projects", "true")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Uncomment to run the plugin in a custom IDE, rather than the IDE specified as a compile target in dependencies
|
// Uncomment to run the plugin in a custom IDE, rather than the IDE specified as a compile target in dependencies
|
||||||
@ -833,9 +822,7 @@ fun updateAuthors(uncheckedEmails: Set<String>) {
|
|||||||
org.intellij.markdown.parser.MarkdownParser(org.intellij.markdown.flavours.gfm.GFMFlavourDescriptor())
|
org.intellij.markdown.parser.MarkdownParser(org.intellij.markdown.flavours.gfm.GFMFlavourDescriptor())
|
||||||
val tree = parser.buildMarkdownTreeFromString(authors)
|
val tree = parser.buildMarkdownTreeFromString(authors)
|
||||||
|
|
||||||
val contributorsSection = tree.children
|
val contributorsSection = tree.children[24]
|
||||||
.filter { it is ListCompositeNode }
|
|
||||||
.single { it.getTextInNode(authors).contains("yole") }
|
|
||||||
val existingEmails = mutableSetOf<String>()
|
val existingEmails = mutableSetOf<String>()
|
||||||
for (child in contributorsSection.children) {
|
for (child in contributorsSection.children) {
|
||||||
if (child.children.size > 1) {
|
if (child.children.size > 1) {
|
||||||
|
@ -16,95 +16,10 @@ in `~/.ideavimrc`. E.g. `set nosurround`.
|
|||||||
Available plugins:
|
Available plugins:
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary><h2>argtextobj: Provides a text-object 'a' argument</h2></summary>
|
<summary><h2>easymotion</h2></summary>
|
||||||
|
|
||||||
Original plugin: [argtextobj.vim](https://www.vim.org/scripts/script.php?script_id=2699).
|
|
||||||
|
|
||||||
### Summary:
|
|
||||||
This plugin provides a text-object 'a' (argument).
|
|
||||||
You can d(elete), c(hange), v(select)... an argument or inner argument in familiar ways.
|
|
||||||
|
|
||||||
That is, such as 'daa'(delete-an-argument) 'cia'(change-inner-argument) 'via'(select-inner-argument).
|
|
||||||
What this script does is more than just typing
|
|
||||||
|
|
||||||
F,dt,
|
|
||||||
|
|
||||||
because it recognizes inclusion relationship of parentheses.
|
|
||||||
|
|
||||||
### Setup:
|
|
||||||
- Add the following command to `~/.ideavimrc`: `Plug 'vim-scripts/argtextobj.vim'`
|
|
||||||
<details>
|
|
||||||
<summary>Alternative syntax</summary>
|
|
||||||
<code>Plugin 'vim-scripts/argtextobj.vim'</code>
|
|
||||||
<br/>
|
|
||||||
<code>Plug 'https://github.com/vim-scripts/argtextobj.vim'</code>
|
|
||||||
<br/>
|
|
||||||
<code>Plug 'argtextobj.vim'</code>
|
|
||||||
<br/>
|
|
||||||
<code>Plug 'https://www.vim.org/scripts/script.php?script_id=2699'</code>
|
|
||||||
<br/>
|
|
||||||
<code>set argtextobj</code>
|
|
||||||
</details>
|
|
||||||
|
|
||||||
### Instructions
|
|
||||||
|
|
||||||
By default, only the arguments inside parenthesis are considered. To extend the functionality
|
|
||||||
to other types of brackets, set `g:argtextobj_pairs` variable to a comma-separated
|
|
||||||
list of colon-separated pairs (same as VIM's `matchpairs` option), like
|
|
||||||
`let g:argtextobj_pairs="(:),{:},<:>"`. The order of pairs matters when
|
|
||||||
handling symbols that can also be operators: `func(x << 5, 20) >> 17`. To handle
|
|
||||||
this syntax parenthesis, must come before angle brackets in the list.
|
|
||||||
|
|
||||||
https://www.vim.org/scripts/script.php?script_id=2699
|
|
||||||
|
|
||||||
</details>
|
|
||||||
|
|
||||||
<details>
|
|
||||||
<summary><h2>commentary: Adds mapping for quickly commenting stuff out</h2></summary>
|
|
||||||
|
|
||||||
By [Daniel Leong](https://github.com/dhleong)
|
|
||||||
Original plugin: [commentary.vim](https://github.com/tpope/vim-commentary).
|
|
||||||
|
|
||||||
### Summary:
|
|
||||||
Comment stuff out.
|
|
||||||
Use gcc to comment out a line (takes a count), gc to comment out the target of a motion
|
|
||||||
(for example, gcap to comment out a paragraph), gc in visual mode to comment out the selection,
|
|
||||||
and gc in operator pending mode to target a comment.
|
|
||||||
You can also use it as a command, either with a range like :7,17Commentary,
|
|
||||||
or as part of a :global invocation like with :g/TODO/Commentary.
|
|
||||||
That's it.
|
|
||||||
|
|
||||||
### Setup:
|
|
||||||
- Add the following command to `~/.ideavimrc`: `Plug 'tpope/vim-commentary'`
|
|
||||||
<details>
|
|
||||||
<summary>Alternative syntax</summary>
|
|
||||||
<code>Plugin 'tpope/vim-commentary'</code>
|
|
||||||
<br/>
|
|
||||||
<code>Plug 'https://github.com/tpope/vim-commentary'</code>
|
|
||||||
<br/>
|
|
||||||
<code>Plug 'vim-commentary'</code>
|
|
||||||
<br/>
|
|
||||||
<code>Plug 'tcomment_vim'</code>
|
|
||||||
<br/>
|
|
||||||
<code>set commentary</code>
|
|
||||||
</details>
|
|
||||||
|
|
||||||
### Instructions
|
|
||||||
|
|
||||||
https://github.com/tpope/vim-commentary/blob/master/doc/commentary.txt
|
|
||||||
|
|
||||||
</details>
|
|
||||||
|
|
||||||
<details>
|
|
||||||
<summary><h2>easymotion: Simplifies some motions</h2></summary>
|
|
||||||
|
|
||||||
Original plugin: [vim-easymotion](https://github.com/easymotion/vim-easymotion).
|
Original plugin: [vim-easymotion](https://github.com/easymotion/vim-easymotion).
|
||||||
|
|
||||||
### Summary:
|
|
||||||
EasyMotion provides a much simpler way to use some motions in vim.
|
|
||||||
It takes the \<number> out of \<number>w or \<number>f{char} by highlighting all possible choices
|
|
||||||
and allowing you to press one key to jump directly to the target.
|
|
||||||
|
|
||||||
### Setup:
|
### Setup:
|
||||||
- Install [IdeaVim-EasyMotion](https://plugins.jetbrains.com/plugin/13360-ideavim-easymotion/)
|
- Install [IdeaVim-EasyMotion](https://plugins.jetbrains.com/plugin/13360-ideavim-easymotion/)
|
||||||
and [AceJump](https://plugins.jetbrains.com/plugin/7086-acejump/) plugins.
|
and [AceJump](https://plugins.jetbrains.com/plugin/7086-acejump/) plugins.
|
||||||
@ -126,176 +41,80 @@ All commands with the mappings are supported. See the [full list of supported co
|
|||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary><h2>exchange: Easy text exchange operator</h2></summary>
|
<summary><h2>sneak</h2></summary>
|
||||||
|
|
||||||
By [fan-tom](https://github.com/fan-tom)
|
<img src="images/sneakIcon.svg" width="80" height="80" alt="icon"/>
|
||||||
Original plugin: [vim-exchange](https://github.com/tommcdo/vim-exchange).
|
|
||||||
|
|
||||||
### Summary:
|
|
||||||
Easy text exchange operator for Vim.
|
|
||||||
|
|
||||||
|
By [Mikhail Levchenko](https://github.com/Mishkun)
|
||||||
|
Original repository with the plugin: https://github.com/Mishkun/ideavim-sneak
|
||||||
|
Original plugin: [vim-sneak](https://github.com/justinmk/vim-sneak).
|
||||||
|
|
||||||
### Setup:
|
### Setup:
|
||||||
- Add the following command to `~/.ideavimrc`: `Plug 'tommcdo/vim-exchange'`
|
- Add the following command to `~/.ideavimrc`: `Plug 'justinmk/vim-sneak'`
|
||||||
|
|
||||||
|
### Instructions
|
||||||
|
|
||||||
|
* Type `s` and two chars to start sneaking in forward direction
|
||||||
|
* Type `S` and two chars to start sneaking in backward direction
|
||||||
|
* Type `;` or `,` to proceed with sneaking just as if you were using `f` or `t` commands
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><h2>NERDTree</h2></summary>
|
||||||
|
|
||||||
|
Original plugin: [NERDTree](https://github.com/preservim/nerdtree).
|
||||||
|
|
||||||
|
### Setup:
|
||||||
|
- Add the following command to `~/.ideavimrc`: `Plug 'preservim/nerdtree'`
|
||||||
<details>
|
<details>
|
||||||
<summary>Alternative syntax</summary>
|
<summary>Alternative syntax</summary>
|
||||||
<code>Plugin 'tommcdo/vim-exchange'</code>
|
<code>Plugin 'preservim/nerdtree'</code>
|
||||||
<br/>
|
<br/>
|
||||||
<code>Plug 'https://github.com/tommcdo/vim-exchange'</code>
|
<code>Plug 'https://github.com/preservim/nerdtree'</code>
|
||||||
<br/>
|
<br/>
|
||||||
<code>Plug 'vim-exchange'</code>
|
<code>Plug 'nerdtree'</code>
|
||||||
<br/>
|
<br/>
|
||||||
<code>set exchange</code>
|
<code>set NERDTree</code>
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
### Instructions
|
### Instructions
|
||||||
|
|
||||||
https://github.com/tommcdo/vim-exchange/blob/master/doc/exchange.txt
|
[See here](NERDTree-support.md).
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary><h2>FunctionTextObj: Adds text objects for manipulating functions/methods</h2></summary>
|
<summary><h2>surround</h2></summary>
|
||||||
|
|
||||||
By Julien Phalip
|
Original plugin: [vim-surround](https://github.com/tpope/vim-surround).
|
||||||
|
|
||||||
### Summary:
|
|
||||||
An extension for IdeaVim that adds text objects for manipulating functions/methods in your code.
|
|
||||||
Similar to how iw operates on words or i" operates on quoted strings,
|
|
||||||
this plugin provides if and af to operate on functions
|
|
||||||
|
|
||||||
### Setup
|
|
||||||
|
|
||||||
Add `set functiontextobj` to your `~/.ideavimrc` file, then run `:source ~/.ideavimrc`
|
|
||||||
or restart the IDE.
|
|
||||||
|
|
||||||
### Instructions
|
|
||||||
|
|
||||||
https://plugins.jetbrains.com/plugin/25897-vim-functiontextobj
|
|
||||||
</details>
|
|
||||||
|
|
||||||
<details>
|
|
||||||
<summary><h2>highlightedyank: Highlights the yanked region</h2></summary>
|
|
||||||
|
|
||||||
By [KostkaBrukowa](https://github.com/KostkaBrukowa)
|
|
||||||
Original plugin: [vim-highlightedyank](https://github.com/machakann/vim-highlightedyank).
|
|
||||||
|
|
||||||
### Summary:
|
|
||||||
Make the yanked region apparent!
|
|
||||||
|
|
||||||
### Setup:
|
### Setup:
|
||||||
- Add the following command to `~/.ideavimrc`: `Plug 'machakann/vim-highlightedyank'`
|
- Add the following command to `~/.ideavimrc`: `Plug 'tpope/vim-surround'`
|
||||||
<details>
|
<details>
|
||||||
<summary>Alternative syntax</summary>
|
<summary>Alternative syntax</summary>
|
||||||
<code>Plugin 'machakann/vim-highlightedyank'</code>
|
<code>Plugin 'tpope/vim-surround'</code>
|
||||||
<br/>
|
<br/>
|
||||||
<code>Plug 'https://github.com/machakann/vim-highlightedyank'</code>
|
<code>Plug 'https://www.vim.org/scripts/script.php?script_id=1697'</code>
|
||||||
<br/>
|
<br/>
|
||||||
<code>Plug 'vim-highlightedyank'</code>
|
<code>Plug 'vim-surround'</code>
|
||||||
<br/>
|
<br/>
|
||||||
<code>set highlightedyank</code>
|
<code>set surround</code>
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
### Instructions
|
### Instructions
|
||||||
|
|
||||||
If you want to optimize highlight duration, assign a time in milliseconds:
|
https://github.com/tpope/vim-surround/blob/master/doc/surround.txt
|
||||||
`let g:highlightedyank_highlight_duration = "1000"`
|
|
||||||
A negative number makes the highlight persistent.
|
|
||||||
|
|
||||||
If you want to change background color of highlight you can provide the rgba of the color you want e.g.
|
|
||||||
`let g:highlightedyank_highlight_color = "rgba(160, 160, 160, 155)"`
|
|
||||||
|
|
||||||
If you want to change text color of highlight you can provide the rgba of the color you want e.g.
|
|
||||||
`let g:highlightedyank_highlight_foreground_color = "rgba(0, 0, 0, 255)"`
|
|
||||||
|
|
||||||
https://github.com/machakann/vim-highlightedyank/blob/master/doc/highlightedyank.txt
|
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary><h2>indent-object: Adds text objects for manipulating sentences/paragraphs/etc...</h2></summary>
|
<summary><h2>multiple-cursors</h2></summary>
|
||||||
|
|
||||||
By [Shrikant Sharat Kandula](https://github.com/sharat87)
|
|
||||||
Original plugin: [vim-indent-object](https://github.com/michaeljsmith/vim-indent-object).
|
|
||||||
|
|
||||||
### Summary:
|
|
||||||
Vim text objects provide a convenient way to select and operate on various types of objects.
|
|
||||||
These objects include regions surrounded by various types of brackets and various parts of language
|
|
||||||
(ie sentences, paragraphs, etc).
|
|
||||||
|
|
||||||
### Setup:
|
|
||||||
- Add the following command to `~/.ideavimrc`: `Plug 'michaeljsmith/vim-indent-object'`
|
|
||||||
<details>
|
|
||||||
<summary>Alternative syntax</summary>
|
|
||||||
<code>Plugin 'michaeljsmith/vim-indent-object'</code>
|
|
||||||
<br/>
|
|
||||||
<code>Plug 'https://github.com/michaeljsmith/vim-indent-object'</code>
|
|
||||||
<br/>
|
|
||||||
<code>Plug 'vim-indent-object'</code>
|
|
||||||
<br/>
|
|
||||||
<code>set textobj-indent</code>
|
|
||||||
</details>
|
|
||||||
|
|
||||||
### Instructions
|
|
||||||
|
|
||||||
https://github.com/michaeljsmith/vim-indent-object/blob/master/doc/indent-object.txt
|
|
||||||
|
|
||||||
</details>
|
|
||||||
|
|
||||||
<details>
|
|
||||||
<summary><h2>matchit.vim: Extends the % key functionality</h2></summary>
|
|
||||||
|
|
||||||
By [Martin Yzeiri](https://github.com/myzeiri)
|
|
||||||
Original plugin: [matchit.vim](https://github.com/chrisbra/matchit).
|
|
||||||
|
|
||||||
### Summary:
|
|
||||||
In Vim, as in plain vi, the percent key, |%|, jumps the cursor from a brace, bracket, or paren to its match.
|
|
||||||
This can be configured with the 'matchpairs' option.
|
|
||||||
The matchit plugin extends this in several ways...
|
|
||||||
|
|
||||||
### Setup:
|
|
||||||
- Add the following command to `~/.ideavimrc`: `packadd matchit`
|
|
||||||
<details>
|
|
||||||
<summary>Alternative syntax</summary>
|
|
||||||
<code>Plug 'vim-matchit'</code>
|
|
||||||
<br/>
|
|
||||||
<code>Plug 'chrisbra/matchit'</code>
|
|
||||||
<br/>
|
|
||||||
<code>set matchit</code>
|
|
||||||
</details>
|
|
||||||
|
|
||||||
### Instructions
|
|
||||||
|
|
||||||
https://github.com/adelarsq/vim-matchit/blob/master/doc/matchit.txt
|
|
||||||
|
|
||||||
</details>
|
|
||||||
|
|
||||||
<details>
|
|
||||||
<summary><h2>Mini.ai: Extend and create a/i textobjects (IMPORTANT: The plugin is not related with artificial intelligence)</h2></summary>
|
|
||||||
|
|
||||||
### Summary:
|
|
||||||
Extend and create a/i textobjects
|
|
||||||
|
|
||||||
### Features:
|
|
||||||
Provides additional text object motions for handling quotes and brackets. The following motions are included:
|
|
||||||
|
|
||||||
- aq: Around any quotes.
|
|
||||||
- iq: Inside any quotes.
|
|
||||||
- ab: Around any parentheses, curly braces, and square brackets.
|
|
||||||
- ib: Inside any parentheses, curly braces, and square brackets.
|
|
||||||
|
|
||||||
Original plugin: [mini.ai](https://github.com/echasnovski/mini.ai).
|
|
||||||
|
|
||||||
### Setup:
|
|
||||||
- Add the following command to `~/.ideavimrc`: `set mini-ai`
|
|
||||||
|
|
||||||
</details>
|
|
||||||
|
|
||||||
<details>
|
|
||||||
<summary><h2>multiple-cursors: Extends multicursor support</h2></summary>
|
|
||||||
|
|
||||||
Original plugin: [vim-multiple-cursors](https://github.com/terryma/vim-multiple-cursors).
|
Original plugin: [vim-multiple-cursors](https://github.com/terryma/vim-multiple-cursors).
|
||||||
|
|
||||||
### Setup:
|
### Setup:
|
||||||
- Add the following command to `~/.ideavimrc`: `Plug 'terryma/vim-multiple-cursors'`
|
- Add the following command to `~/.ideavimrc`: `Plug 'terryma/vim-multiple-cursors'`
|
||||||
<details>
|
<details>
|
||||||
@ -308,7 +127,7 @@ Original plugin: [vim-multiple-cursors](https://github.com/terryma/vim-multiple-
|
|||||||
<br/>
|
<br/>
|
||||||
<code>set multiple-cursors</code>
|
<code>set multiple-cursors</code>
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
### Instructions
|
### Instructions
|
||||||
|
|
||||||
At the moment, the default key binds for this plugin do not get mapped correctly in IdeaVim (see [VIM-2178](https://youtrack.jetbrains.com/issue/VIM-2178)). To enable the default key binds, add the following to your `.ideavimrc` file...
|
At the moment, the default key binds for this plugin do not get mapped correctly in IdeaVim (see [VIM-2178](https://youtrack.jetbrains.com/issue/VIM-2178)). To enable the default key binds, add the following to your `.ideavimrc` file...
|
||||||
@ -334,118 +153,38 @@ xmap <leader>g<C-n> <Plug>AllOccurrences
|
|||||||
</details>
|
</details>
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary><h2>NERDTree: Adds NERDTree navigation to the project panel</h2></summary>
|
<summary><h2>commentary</h2></summary>
|
||||||
|
|
||||||
Original plugin: [NERDTree](https://github.com/preservim/nerdtree).
|
|
||||||
|
|
||||||
### Summary:
|
By [Daniel Leong](https://github.com/dhleong)
|
||||||
Adds NERDTree navigation to the project panel.
|
Original plugin: [commentary.vim](https://github.com/tpope/vim-commentary).
|
||||||
|
|
||||||
### Setup:
|
### Setup:
|
||||||
- Add the following command to `~/.ideavimrc`: `Plug 'preservim/nerdtree'`
|
- Add the following command to `~/.ideavimrc`: `Plug 'tpope/vim-commentary'`
|
||||||
<details>
|
<details>
|
||||||
<summary>Alternative syntax</summary>
|
<summary>Alternative syntax</summary>
|
||||||
<code>Plugin 'preservim/nerdtree'</code>
|
<code>Plugin 'tpope/vim-commentary'</code>
|
||||||
<br/>
|
<br/>
|
||||||
<code>Plug 'https://github.com/preservim/nerdtree'</code>
|
<code>Plug 'https://github.com/tpope/vim-commentary'</code>
|
||||||
<br/>
|
<br/>
|
||||||
<code>Plug 'nerdtree'</code>
|
<code>Plug 'vim-commentary'</code>
|
||||||
<br/>
|
<br/>
|
||||||
<code>set NERDTree</code>
|
<code>Plug 'tcomment_vim'</code>
|
||||||
|
<br/>
|
||||||
|
<code>set commentary</code>
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
### Instructions
|
### Instructions
|
||||||
|
|
||||||
[See here](NERDTree-support.md).
|
https://github.com/tpope/vim-commentary/blob/master/doc/commentary.txt
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary><h2>paragraph-motion: Extends the { and } motions to ignore whitespace on otherwise empty lines</h2></summary>
|
<summary><h2>ReplaceWithRegister</h2></summary>
|
||||||
|
|
||||||
Original plugin: [vim-paragraph-motion](https://github.com/dbakker/vim-paragraph-motion).
|
|
||||||
|
|
||||||
### Summary:
|
|
||||||
Normally the { and } motions only match completely empty lines.
|
|
||||||
With this plugin lines that only contain whitespace are also matched.
|
|
||||||
|
|
||||||
### Setup:
|
|
||||||
- Add the following command to `~/.ideavimrc`: `Plug 'dbakker/vim-paragraph-motion'`
|
|
||||||
<details>
|
|
||||||
<summary>Alternative syntax</summary>
|
|
||||||
<code>Plugin 'dbakker/vim-paragraph-motion'</code>
|
|
||||||
<br/>
|
|
||||||
<code>Plug 'https://github.com/dbakker/vim-paragraph-motion'</code>
|
|
||||||
<br/>
|
|
||||||
<code>Plug 'vim-paragraph-motion'</code>
|
|
||||||
<br/>
|
|
||||||
<code>Plug 'https://github.com/vim-scripts/Improved-paragraph-motion'</code>
|
|
||||||
<br/>
|
|
||||||
<code>Plug 'vim-scripts/Improved-paragraph-motion'</code>
|
|
||||||
<br/>
|
|
||||||
<code>Plug 'Improved-paragraph-motion'</code>
|
|
||||||
<br/>
|
|
||||||
<code>set vim-paragraph-motion</code>
|
|
||||||
</details>
|
|
||||||
|
|
||||||
### Instructions
|
|
||||||
|
|
||||||
https://github.com/dbakker/vim-paragraph-motion#vim-paragraph-motion
|
|
||||||
|
|
||||||
</details>
|
|
||||||
|
|
||||||
<details>
|
|
||||||
<summary><h2>Peekaboo: Extends " @ CTRL-r to show a popup of the register contents</h2></summary>
|
|
||||||
|
|
||||||
By Julien Phalip
|
|
||||||
Original plugin: [vim-peekaboo](https://github.com/junegunn/vim-peekaboo).
|
|
||||||
|
|
||||||
### Summary:
|
|
||||||
Peekaboo extends " and @ in normal mode and <CTRL-R> in insert mode so you can see the contents of the registers.
|
|
||||||
|
|
||||||
### Setup
|
|
||||||
|
|
||||||
Add `set peekaboo` to your `~/.ideavimrc` file, then run `:source ~/.ideavimrc`
|
|
||||||
or restart the IDE.
|
|
||||||
|
|
||||||
### Instructions
|
|
||||||
|
|
||||||
https://plugins.jetbrains.com/plugin/25776-vim-peekaboo
|
|
||||||
</details>
|
|
||||||
|
|
||||||
<details>
|
|
||||||
<summary><h2>quick-scope: Always-on highlight for a unique character in every word on a line to help use f, F, etc.</h2></summary>
|
|
||||||
|
|
||||||
Original plugin: [quick-scope](https://github.com/unblevable/quick-scope).
|
|
||||||
|
|
||||||
### Summary:
|
|
||||||
An always-on highlight for a unique character in every word on a line to help you use f, F and family.
|
|
||||||
|
|
||||||
This plugin should help you get to any word on a line in two or three keystrokes with Vim's built-in f<char>
|
|
||||||
(which moves your cursor to <char>).
|
|
||||||
|
|
||||||
### Setup:
|
|
||||||
- Install [IdeaVim-Quickscope](https://plugins.jetbrains.com/plugin/19417-ideavim-quickscope) plugin.
|
|
||||||
- Add the following command to `~/.ideavimrc`: `set quickscope`
|
|
||||||
|
|
||||||
### Instructions
|
|
||||||
|
|
||||||
https://plugins.jetbrains.com/plugin/19417-ideavim-quickscope
|
|
||||||
|
|
||||||
</details>
|
|
||||||
|
|
||||||
<details>
|
|
||||||
<summary><h2>ReplaceWithRegister: Adds two-in-one command that replaces text with the contents of a register.</h2></summary>
|
|
||||||
|
|
||||||
By [igrekster](https://github.com/igrekster)
|
By [igrekster](https://github.com/igrekster)
|
||||||
Original plugin: [ReplaceWithRegister](https://github.com/vim-scripts/ReplaceWithRegister).
|
Original plugin: [ReplaceWithRegister](https://github.com/vim-scripts/ReplaceWithRegister).
|
||||||
|
|
||||||
### Summary:
|
|
||||||
This plugin offers a two-in-one command that replaces text covered by a
|
|
||||||
{motion}, entire line(s) or the current selection with the contents of a
|
|
||||||
register; the old text is deleted into the black-hole register, i.e. it's
|
|
||||||
gone. (But of course, the command can be easily undone.)
|
|
||||||
|
|
||||||
### Setup:
|
### Setup:
|
||||||
- Add the following command to `~/.ideavimrc`: `Plug 'vim-scripts/ReplaceWithRegister'`
|
- Add the following command to `~/.ideavimrc`: `Plug 'vim-scripts/ReplaceWithRegister'`
|
||||||
<details>
|
<details>
|
||||||
@ -464,99 +203,78 @@ gone. (But of course, the command can be easily undone.)
|
|||||||
<br/>
|
<br/>
|
||||||
<code>set ReplaceWithRegister</code>
|
<code>set ReplaceWithRegister</code>
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
### Instructions
|
### Instructions
|
||||||
|
|
||||||
https://github.com/vim-scripts/ReplaceWithRegister/blob/master/doc/ReplaceWithRegister.txt
|
https://github.com/vim-scripts/ReplaceWithRegister/blob/master/doc/ReplaceWithRegister.txt
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary><h2>sneak: Jump to any location specified by two characters</h2></summary>
|
<summary><h2>argtextobj</h2></summary>
|
||||||
|
|
||||||
<img src="images/sneakIcon.svg" width="80" height="80" alt="icon"/>
|
Original plugin: [argtextobj.vim](https://www.vim.org/scripts/script.php?script_id=2699).
|
||||||
|
|
||||||
By [Mikhail Levchenko](https://github.com/Mishkun)
|
|
||||||
Original repository with the plugin: https://github.com/Mishkun/ideavim-sneak
|
|
||||||
Original plugin: [vim-sneak](https://github.com/justinmk/vim-sneak).
|
|
||||||
|
|
||||||
### Summary:
|
|
||||||
Jump to any location specified by two characters.
|
|
||||||
|
|
||||||
### Setup:
|
|
||||||
- Add the following command to `~/.ideavimrc`: `Plug 'justinmk/vim-sneak'`
|
|
||||||
|
|
||||||
### Instructions
|
|
||||||
|
|
||||||
* Type `s` and two chars to start sneaking in forward direction
|
|
||||||
* Type `S` and two chars to start sneaking in backward direction
|
|
||||||
* Type `;` or `,` to proceed with sneaking just as if you were using `f` or `t` commands
|
|
||||||
|
|
||||||
</details>
|
|
||||||
|
|
||||||
<details>
|
|
||||||
<summary><h2>surround: Adds provides mappings to easily delete, change, and add surroundings in pairs</h2></summary>
|
|
||||||
|
|
||||||
Original plugin: [vim-surround](https://github.com/tpope/vim-surround).
|
|
||||||
|
|
||||||
### Summary:
|
|
||||||
Surround.vim is all about "surroundings": parentheses, brackets, quotes, XML tags, and more.
|
|
||||||
The plugin provides mappings to easily delete, change and add such surroundings in pairs.
|
|
||||||
|
|
||||||
### Setup:
|
### Setup:
|
||||||
- Add the following command to `~/.ideavimrc`: `Plug 'tpope/vim-surround'`
|
- Add the following command to `~/.ideavimrc`: `Plug 'vim-scripts/argtextobj.vim'`
|
||||||
<details>
|
<details>
|
||||||
<summary>Alternative syntax</summary>
|
<summary>Alternative syntax</summary>
|
||||||
<code>Plugin 'tpope/vim-surround'</code>
|
<code>Plugin 'vim-scripts/argtextobj.vim'</code>
|
||||||
<br/>
|
<br/>
|
||||||
<code>Plug 'https://www.vim.org/scripts/script.php?script_id=1697'</code>
|
<code>Plug 'https://github.com/vim-scripts/argtextobj.vim'</code>
|
||||||
<br/>
|
<br/>
|
||||||
<code>Plug 'vim-surround'</code>
|
<code>Plug 'argtextobj.vim'</code>
|
||||||
<br/>
|
<br/>
|
||||||
<code>set surround</code>
|
<code>Plug 'https://www.vim.org/scripts/script.php?script_id=2699'</code>
|
||||||
|
<br/>
|
||||||
|
<code>set argtextobj</code>
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
### Instructions
|
### Instructions
|
||||||
|
|
||||||
https://github.com/tpope/vim-surround/blob/master/doc/surround.txt
|
By default, only the arguments inside parenthesis are considered. To extend the functionality
|
||||||
|
to other types of brackets, set `g:argtextobj_pairs` variable to a comma-separated
|
||||||
|
list of colon-separated pairs (same as VIM's `matchpairs` option), like
|
||||||
|
`let g:argtextobj_pairs="(:),{:},<:>"`. The order of pairs matters when
|
||||||
|
handling symbols that can also be operators: `func(x << 5, 20) >> 17`. To handle
|
||||||
|
this syntax parenthesis, must come before angle brackets in the list.
|
||||||
|
|
||||||
|
https://www.vim.org/scripts/script.php?script_id=2699
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary><h2>Switch: Switch some text under the cursor based on regex patterns</h2></summary>
|
<summary><h2>exchange</h2></summary>
|
||||||
|
|
||||||
By Julien Phalip
|
|
||||||
Original plugin: [switch.vim](https://github.com/AndrewRadev/switch.vim).
|
|
||||||
|
|
||||||
### Summary:
|
|
||||||
The purpose of the plugin is to switch some text under the cursor based on regex patterns.
|
|
||||||
The main entry point is a single command, :Switch.
|
|
||||||
When the command is executed,
|
|
||||||
the plugin looks for one of a few specific patterns under the cursor and performs a substitution depending on it.
|
|
||||||
|
|
||||||
### Setup
|
|
||||||
|
|
||||||
Add `set switch` to your `~/.ideavimrc` file, then run `:source ~/.ideavimrc`
|
|
||||||
or restart the IDE.
|
|
||||||
|
|
||||||
|
By [fan-tom](https://github.com/fan-tom)
|
||||||
|
Original plugin: [vim-exchange](https://github.com/tommcdo/vim-exchange).
|
||||||
|
|
||||||
|
### Setup:
|
||||||
|
- Add the following command to `~/.ideavimrc`: `Plug 'tommcdo/vim-exchange'`
|
||||||
|
<details>
|
||||||
|
<summary>Alternative syntax</summary>
|
||||||
|
<code>Plugin 'tommcdo/vim-exchange'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'https://github.com/tommcdo/vim-exchange'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'vim-exchange'</code>
|
||||||
|
<br/>
|
||||||
|
<code>set exchange</code>
|
||||||
|
</details>
|
||||||
|
|
||||||
### Instructions
|
### Instructions
|
||||||
|
|
||||||
https://plugins.jetbrains.com/plugin/25899-vim-switch
|
https://github.com/tommcdo/vim-exchange/blob/master/doc/exchange.txt
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary><h2>textobj-entire: Adds mapping for selecting entire contents of file regardless of cursor position</h2></summary>
|
<summary><h2>textobj-entire</h2></summary>
|
||||||
|
|
||||||
By [Alexandre Grison](https://github.com/agrison)
|
By [Alexandre Grison](https://github.com/agrison)
|
||||||
Original plugin: [vim-textobj-entire](https://github.com/kana/vim-textobj-entire).
|
Original plugin: [vim-textobj-entire](https://github.com/kana/vim-textobj-entire).
|
||||||
|
|
||||||
### Summary:
|
|
||||||
vim-textobj-entire is a Vim plugin to provide text objects
|
|
||||||
(ae and ie by default) to select the entire content of a buffer.
|
|
||||||
Though these are trivial operations (e.g. ggVG), text object versions are more handy,
|
|
||||||
because you do not have to be conscious of the cursor position (e.g. vae).
|
|
||||||
|
|
||||||
### Setup:
|
### Setup:
|
||||||
- Add the following command to `~/.ideavimrc`: `Plug 'kana/vim-textobj-entire'`
|
- Add the following command to `~/.ideavimrc`: `Plug 'kana/vim-textobj-entire'`
|
||||||
<details>
|
<details>
|
||||||
@ -577,13 +295,158 @@ https://github.com/kana/vim-textobj-entire/blob/master/doc/textobj-entire.txt
|
|||||||
</details>
|
</details>
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary><h2>Which-Key: Displays available keybindings in popup</h2></summary>
|
<summary><h2>highlightedyank</h2></summary>
|
||||||
|
|
||||||
|
By [KostkaBrukowa](https://github.com/KostkaBrukowa)
|
||||||
|
Original plugin: [vim-highlightedyank](https://github.com/machakann/vim-highlightedyank).
|
||||||
|
|
||||||
|
### Setup:
|
||||||
|
- Add the following command to `~/.ideavimrc`: `Plug 'machakann/vim-highlightedyank'`
|
||||||
|
<details>
|
||||||
|
<summary>Alternative syntax</summary>
|
||||||
|
<code>Plugin 'machakann/vim-highlightedyank'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'https://github.com/machakann/vim-highlightedyank'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'vim-highlightedyank'</code>
|
||||||
|
<br/>
|
||||||
|
<code>set highlightedyank</code>
|
||||||
|
</details>
|
||||||
|
|
||||||
|
### Instructions
|
||||||
|
|
||||||
|
If you want to optimize highlight duration, assign a time in milliseconds:
|
||||||
|
`let g:highlightedyank_highlight_duration = "1000"`
|
||||||
|
A negative number makes the highlight persistent.
|
||||||
|
|
||||||
|
If you want to change background color of highlight you can provide the rgba of the color you want e.g.
|
||||||
|
`let g:highlightedyank_highlight_color = "rgba(160, 160, 160, 155)"`
|
||||||
|
|
||||||
|
If you want to change text color of highlight you can provide the rgba of the color you want e.g.
|
||||||
|
`let g:highlightedyank_highlight_foreground_color = "rgba(0, 0, 0, 255)"`
|
||||||
|
|
||||||
|
https://github.com/machakann/vim-highlightedyank/blob/master/doc/highlightedyank.txt
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><h2>vim-paragraph-motion</h2></summary>
|
||||||
|
|
||||||
|
Original plugin: [vim-paragraph-motion](https://github.com/dbakker/vim-paragraph-motion).
|
||||||
|
|
||||||
|
### Setup:
|
||||||
|
- Add the following command to `~/.ideavimrc`: `Plug 'dbakker/vim-paragraph-motion'`
|
||||||
|
<details>
|
||||||
|
<summary>Alternative syntax</summary>
|
||||||
|
<code>Plugin 'dbakker/vim-paragraph-motion'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'https://github.com/dbakker/vim-paragraph-motion'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'vim-paragraph-motion'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'https://github.com/vim-scripts/Improved-paragraph-motion'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'vim-scripts/Improved-paragraph-motion'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'Improved-paragraph-motion'</code>
|
||||||
|
<br/>
|
||||||
|
<code>set vim-paragraph-motion</code>
|
||||||
|
</details>
|
||||||
|
|
||||||
|
### Instructions
|
||||||
|
|
||||||
|
https://github.com/dbakker/vim-paragraph-motion#vim-paragraph-motion
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><h2>vim-indent-object</h2></summary>
|
||||||
|
|
||||||
|
By [Shrikant Sharat Kandula](https://github.com/sharat87)
|
||||||
|
Original plugin: [vim-indent-object](https://github.com/michaeljsmith/vim-indent-object).
|
||||||
|
|
||||||
|
### Setup:
|
||||||
|
- Add the following command to `~/.ideavimrc`: `Plug 'michaeljsmith/vim-indent-object'`
|
||||||
|
<details>
|
||||||
|
<summary>Alternative syntax</summary>
|
||||||
|
<code>Plugin 'michaeljsmith/vim-indent-object'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'https://github.com/michaeljsmith/vim-indent-object'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'vim-indent-object'</code>
|
||||||
|
<br/>
|
||||||
|
<code>set textobj-indent</code>
|
||||||
|
</details>
|
||||||
|
|
||||||
|
### Instructions
|
||||||
|
|
||||||
|
https://github.com/michaeljsmith/vim-indent-object/blob/master/doc/indent-object.txt
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><h2>matchit.vim</h2></summary>
|
||||||
|
|
||||||
|
By [Martin Yzeiri](https://github.com/myzeiri)
|
||||||
|
Original plugin: [matchit.vim](https://github.com/chrisbra/matchit).
|
||||||
|
|
||||||
|
### Setup:
|
||||||
|
- Add the following command to `~/.ideavimrc`: `packadd matchit`
|
||||||
|
<details>
|
||||||
|
<summary>Alternative syntax</summary>
|
||||||
|
<code>Plug 'vim-matchit'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'chrisbra/matchit'</code>
|
||||||
|
<br/>
|
||||||
|
<code>set matchit</code>
|
||||||
|
</details>
|
||||||
|
|
||||||
|
### Instructions
|
||||||
|
|
||||||
|
https://github.com/adelarsq/vim-matchit/blob/master/doc/matchit.txt
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><h2>IdeaVim-Quickscope</h2></summary>
|
||||||
|
|
||||||
|
Original plugin: [quick-scope](https://github.com/unblevable/quick-scope).
|
||||||
|
|
||||||
|
### Setup:
|
||||||
|
- Install [IdeaVim-Quickscope](https://plugins.jetbrains.com/plugin/19417-ideavim-quickscope) plugin.
|
||||||
|
- Add the following command to `~/.ideavimrc`: `set quickscope`
|
||||||
|
|
||||||
|
### Instructions
|
||||||
|
|
||||||
|
https://plugins.jetbrains.com/plugin/19417-ideavim-quickscope
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><h2>Mini.ai: Extend and create a/i textobjects (IMPORTANT: The plugin is not related with artificial intelligence)</h2></summary>
|
||||||
|
|
||||||
|
### Features:
|
||||||
|
Provides additional text object motions for handling quotes and brackets. The following motions are included:
|
||||||
|
|
||||||
|
- aq: Around any quotes.
|
||||||
|
- iq: Inside any quotes.
|
||||||
|
- ab: Around any parentheses, curly braces, and square brackets.
|
||||||
|
- ib: Inside any parentheses, curly braces, and square brackets.
|
||||||
|
|
||||||
|
Original plugin: [mini.ai](https://github.com/echasnovski/mini.ai).
|
||||||
|
|
||||||
|
### Setup:
|
||||||
|
- Add the following command to `~/.ideavimrc`: `set mini-ai`
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><h2>Which-Key</h2></summary>
|
||||||
|
|
||||||
Original plugin: [vim-which-key](https://github.com/liuchengxu/vim-which-key).
|
Original plugin: [vim-which-key](https://github.com/liuchengxu/vim-which-key).
|
||||||
|
|
||||||
### Summary:
|
|
||||||
vim-which-key is vim port of emacs-which-key that displays available keybindings in popup.
|
|
||||||
|
|
||||||
### Setup:
|
### Setup:
|
||||||
- Install [Which-Key](https://plugins.jetbrains.com/plugin/15976-which-key) plugin.
|
- Install [Which-Key](https://plugins.jetbrains.com/plugin/15976-which-key) plugin.
|
||||||
- Add the following command to `~/.ideavimrc`: `set which-key`
|
- Add the following command to `~/.ideavimrc`: `set which-key`
|
||||||
@ -593,3 +456,49 @@ vim-which-key is vim port of emacs-which-key that displays available keybindings
|
|||||||
https://github.com/TheBlob42/idea-which-key?tab=readme-ov-file#installation
|
https://github.com/TheBlob42/idea-which-key?tab=readme-ov-file#installation
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
<details>
|
||||||
|
<summary><h2>Vim Peekaboo</h2></summary>
|
||||||
|
|
||||||
|
By Julien Phalip
|
||||||
|
Original plugin: [vim-peekaboo](https://github.com/junegunn/vim-peekaboo).
|
||||||
|
|
||||||
|
### Setup
|
||||||
|
|
||||||
|
Add `set peekaboo` to your `~/.ideavimrc` file, then run `:source ~/.ideavimrc`
|
||||||
|
or restart the IDE.
|
||||||
|
|
||||||
|
### Instructions
|
||||||
|
|
||||||
|
https://plugins.jetbrains.com/plugin/25776-vim-peekaboo
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><h2>FunctionTextObj</h2></summary>
|
||||||
|
|
||||||
|
By Julien Phalip
|
||||||
|
|
||||||
|
### Setup
|
||||||
|
|
||||||
|
Add `set functiontextobj` to your `~/.ideavimrc` file, then run `:source ~/.ideavimrc`
|
||||||
|
or restart the IDE.
|
||||||
|
|
||||||
|
### Instructions
|
||||||
|
|
||||||
|
https://plugins.jetbrains.com/plugin/25897-vim-functiontextobj
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><h2>Switch</h2></summary>
|
||||||
|
|
||||||
|
By Julien Phalip
|
||||||
|
Original plugin: [switch.vim](https://github.com/AndrewRadev/switch.vim).
|
||||||
|
|
||||||
|
### Setup
|
||||||
|
|
||||||
|
Add `set switch` to your `~/.ideavimrc` file, then run `:source ~/.ideavimrc`
|
||||||
|
or restart the IDE.
|
||||||
|
|
||||||
|
### Instructions
|
||||||
|
|
||||||
|
https://plugins.jetbrains.com/plugin/25899-vim-switch
|
||||||
|
|
||||||
|
@ -16,11 +16,11 @@
|
|||||||
# https://data.services.jetbrains.com/products?code=IC
|
# https://data.services.jetbrains.com/products?code=IC
|
||||||
# Maven releases are here: https://www.jetbrains.com/intellij-repository/releases
|
# Maven releases are here: https://www.jetbrains.com/intellij-repository/releases
|
||||||
# And snapshots: https://www.jetbrains.com/intellij-repository/snapshots
|
# And snapshots: https://www.jetbrains.com/intellij-repository/snapshots
|
||||||
ideaVersion=2025.1
|
ideaVersion=2024.3
|
||||||
# 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-47
|
version=chylex-45
|
||||||
javaVersion=21
|
javaVersion=21
|
||||||
remoteRobotVersion=0.11.23
|
remoteRobotVersion=0.11.23
|
||||||
antlrVersion=4.10.1
|
antlrVersion=4.10.1
|
||||||
|
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,6 +1,6 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12.1-bin.zip
|
||||||
networkTimeout=10000
|
networkTimeout=10000
|
||||||
validateDistributionUrl=true
|
validateDistributionUrl=true
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
3
gradlew
vendored
3
gradlew
vendored
@ -86,7 +86,8 @@ done
|
|||||||
# shellcheck disable=SC2034
|
# shellcheck disable=SC2034
|
||||||
APP_BASE_NAME=${0##*/}
|
APP_BASE_NAME=${0##*/}
|
||||||
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
||||||
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
|
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
|
||||||
|
' "$PWD" ) || exit
|
||||||
|
|
||||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
MAX_FD=maximum
|
MAX_FD=maximum
|
||||||
|
@ -20,17 +20,17 @@ repositories {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compileOnly("org.jetbrains.kotlin:kotlin-stdlib:2.1.21")
|
compileOnly("org.jetbrains.kotlin:kotlin-stdlib:2.1.10")
|
||||||
|
|
||||||
implementation("io.ktor:ktor-client-core:3.1.3")
|
implementation("io.ktor:ktor-client-core:3.1.1")
|
||||||
implementation("io.ktor:ktor-client-cio:3.1.3")
|
implementation("io.ktor:ktor-client-cio:3.1.1")
|
||||||
implementation("io.ktor:ktor-client-content-negotiation:3.1.3")
|
implementation("io.ktor:ktor-client-content-negotiation:3.1.1")
|
||||||
implementation("io.ktor:ktor-serialization-kotlinx-json:3.1.3")
|
implementation("io.ktor:ktor-serialization-kotlinx-json:3.1.1")
|
||||||
implementation("io.ktor:ktor-client-auth:3.1.3")
|
implementation("io.ktor:ktor-client-auth:3.1.1")
|
||||||
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.0.202503040940-r")
|
implementation("org.eclipse.jgit:org.eclipse.jgit.ssh.apache:7.1.0.202411261347-r")
|
||||||
implementation("com.vdurmont:semver4j:3.1.0")
|
implementation("com.vdurmont:semver4j:3.1.0")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,8 +43,6 @@ val knownPlugins = setOf(
|
|||||||
"com.julienphalip.ideavim.peekaboo", // https://plugins.jetbrains.com/plugin/25776-vim-peekaboo
|
"com.julienphalip.ideavim.peekaboo", // https://plugins.jetbrains.com/plugin/25776-vim-peekaboo
|
||||||
"com.julienphalip.ideavim.switch", // https://plugins.jetbrains.com/plugin/25899-vim-switch
|
"com.julienphalip.ideavim.switch", // https://plugins.jetbrains.com/plugin/25899-vim-switch
|
||||||
"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.ugarosa.idea.edgemotion", // https://plugins.jetbrains.com/plugin/27211-edgemotion
|
|
||||||
)
|
)
|
||||||
|
|
||||||
suspend fun main() {
|
suspend fun main() {
|
||||||
|
@ -355,12 +355,7 @@ public class VimPlugin implements PersistentStateComponent<Element>, Disposable
|
|||||||
if (unsubscribe) {
|
if (unsubscribe) {
|
||||||
VimListenerManager.INSTANCE.turnOff();
|
VimListenerManager.INSTANCE.turnOff();
|
||||||
}
|
}
|
||||||
// Use getServiceIfCreated to avoid creating the service during the dispose (this is prohibited by the platform)
|
injector.getCommandLine().fullReset();
|
||||||
@Nullable VimCommandLineService service =
|
|
||||||
ApplicationManager.getApplication().getServiceIfCreated(VimCommandLineService.class);
|
|
||||||
if (service != null) {
|
|
||||||
service.fullReset();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unregister vim actions in command mode
|
// Unregister vim actions in command mode
|
||||||
RegisterActions.unregisterActions();
|
RegisterActions.unregisterActions();
|
||||||
@ -376,7 +371,8 @@ public class VimPlugin implements PersistentStateComponent<Element>, Disposable
|
|||||||
if (isEnabled() && !ApplicationManager.getApplication().isUnitTestMode()) {
|
if (isEnabled() && !ApplicationManager.getApplication().isUnitTestMode()) {
|
||||||
stateUpdated = true;
|
stateUpdated = true;
|
||||||
if (SystemInfo.isMac) {
|
if (SystemInfo.isMac) {
|
||||||
final Boolean enabled = MacKeyRepeat.INSTANCE.isEnabled();
|
final MacKeyRepeat keyRepeat = MacKeyRepeat.getInstance();
|
||||||
|
final Boolean enabled = keyRepeat.isEnabled();
|
||||||
final Boolean isKeyRepeat = getEditor().isKeyRepeat();
|
final Boolean isKeyRepeat = getEditor().isKeyRepeat();
|
||||||
if ((enabled == null || !enabled) && (isKeyRepeat == null || isKeyRepeat)) {
|
if ((enabled == null || !enabled) && (isKeyRepeat == null || isKeyRepeat)) {
|
||||||
// This system property is used in IJ ui robot to hide the startup tips
|
// This system property is used in IJ ui robot to hide the startup tips
|
||||||
@ -386,7 +382,7 @@ public class VimPlugin implements PersistentStateComponent<Element>, Disposable
|
|||||||
if (showNotification) {
|
if (showNotification) {
|
||||||
if (VimPlugin.getNotifications().enableRepeatingMode() == Messages.YES) {
|
if (VimPlugin.getNotifications().enableRepeatingMode() == Messages.YES) {
|
||||||
getEditor().setKeyRepeat(true);
|
getEditor().setKeyRepeat(true);
|
||||||
MacKeyRepeat.INSTANCE.setEnabled(true);
|
keyRepeat.setEnabled(true);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
getEditor().setKeyRepeat(false);
|
getEditor().setKeyRepeat(false);
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
package com.maddyhome.idea.vim.action
|
package com.maddyhome.idea.vim.action
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableSet
|
import com.google.common.collect.ImmutableSet
|
||||||
import com.intellij.codeInsight.completion.CompletionService
|
|
||||||
import com.intellij.codeInsight.lookup.LookupManager
|
import com.intellij.codeInsight.lookup.LookupManager
|
||||||
import com.intellij.openapi.actionSystem.ActionManager
|
import com.intellij.openapi.actionSystem.ActionManager
|
||||||
import com.intellij.openapi.actionSystem.ActionUpdateThread
|
import com.intellij.openapi.actionSystem.ActionUpdateThread
|
||||||
@ -183,6 +182,9 @@ class VimShortcutKeyAction : AnAction(), DumbAware/*, LightEditCompatible*/ {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (editor.inInsertMode) {
|
if (editor.inInsertMode) {
|
||||||
|
if (keyCode == KeyEvent.VK_ENTER) {
|
||||||
|
return ActionEnableStatus.no("Enter action in insert mode", LogLevel.INFO)
|
||||||
|
}
|
||||||
if (keyCode == KeyEvent.VK_TAB) {
|
if (keyCode == KeyEvent.VK_TAB) {
|
||||||
// TODO: This stops VimEditorTab seeing <Tab> in insert mode and correctly scrolling the view
|
// TODO: This stops VimEditorTab seeing <Tab> in insert mode and correctly scrolling the view
|
||||||
// There are multiple actions registered for VK_TAB. The important items, in order, are this, the Live
|
// There are multiple actions registered for VK_TAB. The important items, in order, are this, the Live
|
||||||
@ -209,10 +211,6 @@ class VimShortcutKeyAction : AnAction(), DumbAware/*, LightEditCompatible*/ {
|
|||||||
return ActionEnableStatus.yes("Vim only editor keys", LogLevel.INFO)
|
return ActionEnableStatus.yes("Vim only editor keys", LogLevel.INFO)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CompletionService.getCompletionService().currentCompletion != null) {
|
|
||||||
return ActionEnableStatus.no("Code completion active", LogLevel.INFO)
|
|
||||||
}
|
|
||||||
|
|
||||||
val savedShortcutConflicts = VimPlugin.getKey().savedShortcutConflicts
|
val savedShortcutConflicts = VimPlugin.getKey().savedShortcutConflicts
|
||||||
val info = savedShortcutConflicts[keyStroke]
|
val info = savedShortcutConflicts[keyStroke]
|
||||||
return when (info?.forEditor(editor.vim)) {
|
return when (info?.forEditor(editor.vim)) {
|
||||||
|
78
src/main/java/com/maddyhome/idea/vim/command/CommandState.kt
Normal file
78
src/main/java/com/maddyhome/idea/vim/command/CommandState.kt
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2003-2023 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.command
|
||||||
|
|
||||||
|
import com.intellij.openapi.editor.Editor
|
||||||
|
import com.maddyhome.idea.vim.KeyHandler
|
||||||
|
import com.maddyhome.idea.vim.api.injector
|
||||||
|
import com.maddyhome.idea.vim.state.VimStateMachine
|
||||||
|
import org.jetbrains.annotations.ApiStatus
|
||||||
|
|
||||||
|
/**
|
||||||
|
* COMPATIBILITY-LAYER: Additional class
|
||||||
|
* Please see: https://jb.gg/zo8n0r
|
||||||
|
*/
|
||||||
|
@Deprecated("Use `injector.vimState`")
|
||||||
|
@ApiStatus.ScheduledForRemoval
|
||||||
|
class CommandState(private val machine: VimStateMachine) {
|
||||||
|
|
||||||
|
val mode: Mode
|
||||||
|
get() {
|
||||||
|
val myMode = machine.mode
|
||||||
|
return when (myMode) {
|
||||||
|
is com.maddyhome.idea.vim.state.mode.Mode.CMD_LINE -> Mode.CMD_LINE
|
||||||
|
com.maddyhome.idea.vim.state.mode.Mode.INSERT -> Mode.INSERT
|
||||||
|
is com.maddyhome.idea.vim.state.mode.Mode.NORMAL -> Mode.COMMAND
|
||||||
|
is com.maddyhome.idea.vim.state.mode.Mode.OP_PENDING -> Mode.OP_PENDING
|
||||||
|
com.maddyhome.idea.vim.state.mode.Mode.REPLACE -> Mode.REPLACE
|
||||||
|
is com.maddyhome.idea.vim.state.mode.Mode.SELECT -> Mode.SELECT
|
||||||
|
is com.maddyhome.idea.vim.state.mode.Mode.VISUAL -> Mode.VISUAL
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@get:Deprecated(
|
||||||
|
"Use `KeyHandler.keyHandlerState.commandBuilder", ReplaceWith(
|
||||||
|
"KeyHandler.getInstance().keyHandlerState.commandBuilder",
|
||||||
|
"com.maddyhome.idea.vim.KeyHandler"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
@get:ApiStatus.ScheduledForRemoval
|
||||||
|
val commandBuilder: CommandBuilder
|
||||||
|
get() = KeyHandler.getInstance().keyHandlerState.commandBuilder
|
||||||
|
|
||||||
|
@Deprecated(
|
||||||
|
"Use `KeyHandler.keyHandlerState.mappingState", ReplaceWith(
|
||||||
|
"KeyHandler.getInstance().keyHandlerState.mappingState",
|
||||||
|
"com.maddyhome.idea.vim.KeyHandler"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
val mappingState: MappingState
|
||||||
|
get() = KeyHandler.getInstance().keyHandlerState.mappingState
|
||||||
|
|
||||||
|
enum class Mode {
|
||||||
|
// Basic modes
|
||||||
|
COMMAND, VISUAL, SELECT, INSERT, CMD_LINE, /*EX*/
|
||||||
|
|
||||||
|
// Additional modes
|
||||||
|
OP_PENDING, REPLACE /*, VISUAL_REPLACE*/, INSERT_NORMAL, INSERT_VISUAL, INSERT_SELECT
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class SubMode {
|
||||||
|
NONE, VISUAL_CHARACTER, VISUAL_LINE, VISUAL_BLOCK
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@JvmStatic
|
||||||
|
@Deprecated("Use `injector.vimState`")
|
||||||
|
@ApiStatus.ScheduledForRemoval
|
||||||
|
fun getInstance(editor: Editor): CommandState {
|
||||||
|
return CommandState(injector.vimState)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -11,17 +11,16 @@ package com.maddyhome.idea.vim.customization.feature.terminal
|
|||||||
import com.intellij.openapi.editor.Editor
|
import com.intellij.openapi.editor.Editor
|
||||||
import com.maddyhome.idea.vim.key.IdeaVimDisablerExtensionPoint
|
import com.maddyhome.idea.vim.key.IdeaVimDisablerExtensionPoint
|
||||||
import org.jetbrains.plugins.terminal.block.util.TerminalDataContextUtils.isAlternateBufferEditor
|
import org.jetbrains.plugins.terminal.block.util.TerminalDataContextUtils.isAlternateBufferEditor
|
||||||
import org.jetbrains.plugins.terminal.block.util.TerminalDataContextUtils.isAlternateBufferModelEditor
|
|
||||||
import org.jetbrains.plugins.terminal.block.util.TerminalDataContextUtils.isOutputEditor
|
import org.jetbrains.plugins.terminal.block.util.TerminalDataContextUtils.isOutputEditor
|
||||||
import org.jetbrains.plugins.terminal.block.util.TerminalDataContextUtils.isOutputModelEditor
|
|
||||||
import org.jetbrains.plugins.terminal.block.util.TerminalDataContextUtils.isPromptEditor
|
import org.jetbrains.plugins.terminal.block.util.TerminalDataContextUtils.isPromptEditor
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The only implementation is defined right here.
|
* The only implementation is defined right here.
|
||||||
*/
|
*/
|
||||||
|
// [VERSION UPDATE] 2025.1+ Add 2 new predicates
|
||||||
internal class IdeaVimTerminalDisablerExtension : IdeaVimDisablerExtensionPoint {
|
internal class IdeaVimTerminalDisablerExtension : IdeaVimDisablerExtensionPoint {
|
||||||
override fun isDisabledForEditor(editor: Editor): Boolean {
|
override fun isDisabledForEditor(editor: Editor): Boolean {
|
||||||
return editor.isPromptEditor || editor.isOutputEditor || editor.isAlternateBufferEditor
|
return editor.isPromptEditor || editor.isOutputEditor || editor.isAlternateBufferEditor
|
||||||
|| editor.isOutputModelEditor || editor.isAlternateBufferModelEditor
|
// || editor.isOutputModelEditor || editor.isAlternateBufferModelEditor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -214,13 +214,7 @@ object VimExtensionFacade {
|
|||||||
|
|
||||||
/** Set the current contents of the given register */
|
/** Set the current contents of the given register */
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun setRegisterForCaret(
|
fun setRegisterForCaret(register: Char, caret: ImmutableVimCaret, keys: List<KeyStroke?>?) {
|
||||||
editor: VimEditor,
|
|
||||||
context: ExecutionContext,
|
|
||||||
register: Char,
|
|
||||||
caret: ImmutableVimCaret,
|
|
||||||
keys: List<KeyStroke?>?,
|
|
||||||
) {
|
|
||||||
caret.registerStorage.setKeys(register, keys?.filterNotNull() ?: emptyList())
|
caret.registerStorage.setKeys(register, keys?.filterNotNull() ?: emptyList())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -221,16 +221,14 @@ internal class CommentaryExtension : VimExtension {
|
|||||||
val endOffset = editor.vim.getLineEndOffset(logicalLine, true)
|
val endOffset = editor.vim.getLineEndOffset(logicalLine, true)
|
||||||
val startElement = file.findElementAt(startOffset) ?: return false
|
val startElement = file.findElementAt(startOffset) ?: return false
|
||||||
var next: PsiElement? = startElement
|
var next: PsiElement? = startElement
|
||||||
var hasComment = false
|
|
||||||
while (next != null && next.textRange.startOffset <= endOffset) {
|
while (next != null && next.textRange.startOffset <= endOffset) {
|
||||||
when {
|
if (next !is PsiWhiteSpace && !isComment(next)) {
|
||||||
next is PsiWhiteSpace -> {} // Skip whitespace elementl
|
return false
|
||||||
isComment(next) -> hasComment = true // Mark when we find a comment
|
|
||||||
else -> return false // Non-comment content found, exit early
|
|
||||||
}
|
}
|
||||||
next = PsiTreeUtil.nextLeaf(next, true)
|
next = PsiTreeUtil.nextLeaf(next, true)
|
||||||
}
|
}
|
||||||
return hasComment
|
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isComment(element: PsiElement) =
|
private fun isComment(element: PsiElement) =
|
||||||
|
@ -11,7 +11,6 @@ import com.intellij.openapi.actionSystem.DataContext
|
|||||||
import com.intellij.openapi.application.runWriteAction
|
import com.intellij.openapi.application.runWriteAction
|
||||||
import com.intellij.openapi.diagnostic.logger
|
import com.intellij.openapi.diagnostic.logger
|
||||||
import com.intellij.openapi.editor.Editor
|
import com.intellij.openapi.editor.Editor
|
||||||
import com.maddyhome.idea.vim.KeyHandler
|
|
||||||
import com.maddyhome.idea.vim.VimPlugin
|
import com.maddyhome.idea.vim.VimPlugin
|
||||||
import com.maddyhome.idea.vim.api.ExecutionContext
|
import com.maddyhome.idea.vim.api.ExecutionContext
|
||||||
import com.maddyhome.idea.vim.api.VimCaret
|
import com.maddyhome.idea.vim.api.VimCaret
|
||||||
@ -142,10 +141,6 @@ internal class VimSurroundExtension : VimExtension {
|
|||||||
runWriteAction {
|
runWriteAction {
|
||||||
// Leave visual mode
|
// Leave visual mode
|
||||||
editor.exitVisualMode()
|
editor.exitVisualMode()
|
||||||
|
|
||||||
// Reset the key handler so that the command trie is updated for the new mode (Normal)
|
|
||||||
// TODO: This should probably be handled by ToHandlerMapping.execute
|
|
||||||
KeyHandler.getInstance().reset(editor)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -174,8 +169,8 @@ internal class VimSurroundExtension : VimExtension {
|
|||||||
val surroundings = editor.sortedCarets()
|
val surroundings = editor.sortedCarets()
|
||||||
.map {
|
.map {
|
||||||
val oldValue: List<KeyStroke>? = getRegisterForCaret(editor, context, REGISTER, it)
|
val oldValue: List<KeyStroke>? = getRegisterForCaret(editor, context, REGISTER, it)
|
||||||
setRegisterForCaret(editor, context, REGISTER, it, null)
|
setRegisterForCaret(REGISTER, it, null)
|
||||||
SurroundingInfo(editor, context, it, null, oldValue, false)
|
SurroundingInfo(it, null, oldValue, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete surrounding's content
|
// Delete surrounding's content
|
||||||
@ -264,16 +259,9 @@ internal class VimSurroundExtension : VimExtension {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private data class SurroundingInfo(
|
private data class SurroundingInfo(val caret: VimCaret, var innerText: List<KeyStroke>?, val oldRegisterContent: List<KeyStroke>?, var isValidSurrounding: Boolean) {
|
||||||
val editor: VimEditor,
|
|
||||||
val context: ExecutionContext,
|
|
||||||
val caret: VimCaret,
|
|
||||||
var innerText: List<KeyStroke>?,
|
|
||||||
val oldRegisterContent: List<KeyStroke>?,
|
|
||||||
var isValidSurrounding: Boolean,
|
|
||||||
) {
|
|
||||||
fun restoreRegister() {
|
fun restoreRegister() {
|
||||||
setRegisterForCaret(editor, context, REGISTER, caret, oldRegisterContent)
|
setRegisterForCaret(REGISTER, caret, oldRegisterContent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.maddyhome.idea.vim.group
|
package com.maddyhome.idea.vim.group
|
||||||
|
|
||||||
import com.intellij.codeInsight.actions.AsyncActionExecutionService
|
import com.intellij.codeInsight.actions.AsyncActionExecutionService.Companion.getInstance
|
||||||
import com.intellij.openapi.Disposable
|
import com.intellij.openapi.Disposable
|
||||||
import com.intellij.openapi.actionSystem.IdeActions
|
import com.intellij.openapi.actionSystem.IdeActions
|
||||||
import com.intellij.openapi.application.ApplicationManager
|
import com.intellij.openapi.application.ApplicationManager
|
||||||
@ -15,7 +15,6 @@ import com.intellij.openapi.command.CommandProcessor
|
|||||||
import com.intellij.openapi.command.UndoConfirmationPolicy
|
import com.intellij.openapi.command.UndoConfirmationPolicy
|
||||||
import com.intellij.openapi.diagnostic.logger
|
import com.intellij.openapi.diagnostic.logger
|
||||||
import com.intellij.openapi.editor.Editor
|
import com.intellij.openapi.editor.Editor
|
||||||
import com.intellij.openapi.editor.actionSystem.TypedActionHandler
|
|
||||||
import com.intellij.openapi.editor.actions.EnterAction
|
import com.intellij.openapi.editor.actions.EnterAction
|
||||||
import com.intellij.openapi.editor.event.EditorMouseEvent
|
import com.intellij.openapi.editor.event.EditorMouseEvent
|
||||||
import com.intellij.openapi.editor.event.EditorMouseListener
|
import com.intellij.openapi.editor.event.EditorMouseListener
|
||||||
@ -34,7 +33,7 @@ import com.maddyhome.idea.vim.common.TextRange
|
|||||||
import com.maddyhome.idea.vim.group.visual.vimSetSystemSelectionSilently
|
import com.maddyhome.idea.vim.group.visual.vimSetSystemSelectionSilently
|
||||||
import com.maddyhome.idea.vim.handler.commandContinuation
|
import com.maddyhome.idea.vim.handler.commandContinuation
|
||||||
import com.maddyhome.idea.vim.helper.inInsertMode
|
import com.maddyhome.idea.vim.helper.inInsertMode
|
||||||
import com.maddyhome.idea.vim.key.KeyHandlerKeeper
|
import com.maddyhome.idea.vim.key.KeyHandlerKeeper.Companion.getInstance
|
||||||
import com.maddyhome.idea.vim.listener.VimInsertListener
|
import com.maddyhome.idea.vim.listener.VimInsertListener
|
||||||
import com.maddyhome.idea.vim.newapi.IjVimCaret
|
import com.maddyhome.idea.vim.newapi.IjVimCaret
|
||||||
import com.maddyhome.idea.vim.newapi.IjVimCopiedText
|
import com.maddyhome.idea.vim.newapi.IjVimCopiedText
|
||||||
@ -62,21 +61,8 @@ class ChangeGroup : VimChangeGroupBase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun type(vimEditor: VimEditor, context: ExecutionContext, key: Char) {
|
override fun type(vimEditor: VimEditor, context: ExecutionContext, key: Char) {
|
||||||
doType(vimEditor, context) {
|
|
||||||
it.execute(vimEditor.ij, key, context.ij)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun type(vimEditor: VimEditor, context: ExecutionContext, string: String) {
|
|
||||||
doType(vimEditor, context) { handler ->
|
|
||||||
string.forEach { char ->
|
|
||||||
handler.execute(vimEditor.ij, char, context.ij)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun doType(vimEditor: VimEditor, context: ExecutionContext, action: (TypedActionHandler) -> Unit) {
|
|
||||||
val editor = (vimEditor as IjVimEditor).editor
|
val editor = (vimEditor as IjVimEditor).editor
|
||||||
|
val ijContext = context.ij
|
||||||
val doc = vimEditor.editor.document
|
val doc = vimEditor.editor.document
|
||||||
|
|
||||||
val undo = injector.undo
|
val undo = injector.undo
|
||||||
@ -89,9 +75,8 @@ class ChangeGroup : VimChangeGroupBase() {
|
|||||||
}
|
}
|
||||||
CommandProcessor.getInstance().executeCommand(
|
CommandProcessor.getInstance().executeCommand(
|
||||||
editor.project, {
|
editor.project, {
|
||||||
ApplicationManager.getApplication().runWriteAction {
|
ApplicationManager.getApplication()
|
||||||
action(KeyHandlerKeeper.getInstance().originalHandler)
|
.runWriteAction { getInstance().originalHandler.execute(editor, key, ijContext) }
|
||||||
}
|
|
||||||
}, "", doc,
|
}, "", doc,
|
||||||
UndoConfirmationPolicy.DEFAULT, doc
|
UndoConfirmationPolicy.DEFAULT, doc
|
||||||
)
|
)
|
||||||
@ -165,7 +150,7 @@ class ChangeGroup : VimChangeGroupBase() {
|
|||||||
var copiedText: IjVimCopiedText? = null
|
var copiedText: IjVimCopiedText? = null
|
||||||
try {
|
try {
|
||||||
if (injector.registerGroup.isPrimaryRegisterSupported()) {
|
if (injector.registerGroup.isPrimaryRegisterSupported()) {
|
||||||
copiedText = injector.clipboardManager.getPrimaryContent() as IjVimCopiedText
|
copiedText = injector.clipboardManager.getPrimaryContent(editor, context) as IjVimCopiedText
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
// FIXME: [isPrimaryRegisterSupported()] is not implemented perfectly, so there might be thrown an exception after trying to access the primary selection
|
// FIXME: [isPrimaryRegisterSupported()] is not implemented perfectly, so there might be thrown an exception after trying to access the primary selection
|
||||||
@ -184,7 +169,7 @@ class ChangeGroup : VimChangeGroupBase() {
|
|||||||
restoreCursor(editor, caret, (caret as IjVimCaret).caret.logicalPosition.line)
|
restoreCursor(editor, caret, (caret as IjVimCaret).caret.logicalPosition.line)
|
||||||
}
|
}
|
||||||
if (project != null) {
|
if (project != null) {
|
||||||
AsyncActionExecutionService.getInstance(project)
|
getInstance(project)
|
||||||
.withExecutionAfterAction(IdeActions.ACTION_EDITOR_AUTO_INDENT_LINES, actionExecution, afterAction)
|
.withExecutionAfterAction(IdeActions.ACTION_EDITOR_AUTO_INDENT_LINES, actionExecution, afterAction)
|
||||||
} else {
|
} else {
|
||||||
actionExecution.invoke()
|
actionExecution.invoke()
|
||||||
|
@ -31,8 +31,10 @@ open class GlobalIjOptions(scope: OptionAccessScope) : OptionsPropertiesBase(sco
|
|||||||
|
|
||||||
// Temporary options to control work-in-progress behaviour
|
// Temporary options to control work-in-progress behaviour
|
||||||
var closenotebooks: Boolean by optionProperty(IjOptions.closenotebooks)
|
var closenotebooks: Boolean by optionProperty(IjOptions.closenotebooks)
|
||||||
|
var commandOrMotionAnnotation: Boolean by optionProperty(IjOptions.commandOrMotionAnnotation)
|
||||||
var oldundo: Boolean by optionProperty(IjOptions.oldundo)
|
var oldundo: Boolean by optionProperty(IjOptions.oldundo)
|
||||||
var unifyjumps: Boolean by optionProperty(IjOptions.unifyjumps)
|
var unifyjumps: Boolean by optionProperty(IjOptions.unifyjumps)
|
||||||
|
var vimscriptFunctionAnnotation: Boolean by optionProperty(IjOptions.vimscriptFunctionAnnotation)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -141,8 +141,12 @@ object IjOptions {
|
|||||||
// Temporary feature flags during development, not really intended for external use
|
// Temporary feature flags during development, not really intended for external use
|
||||||
val closenotebooks: ToggleOption =
|
val closenotebooks: ToggleOption =
|
||||||
addOption(ToggleOption("closenotebooks", GLOBAL, "closenotebooks", true, isHidden = true))
|
addOption(ToggleOption("closenotebooks", GLOBAL, "closenotebooks", true, isHidden = true))
|
||||||
|
val commandOrMotionAnnotation: ToggleOption =
|
||||||
|
addOption(ToggleOption("commandormotionannotation", GLOBAL, "commandormotionannotation", true, isHidden = true))
|
||||||
val oldundo: ToggleOption = addOption(ToggleOption("oldundo", GLOBAL, "oldundo", true, isHidden = true))
|
val oldundo: ToggleOption = addOption(ToggleOption("oldundo", GLOBAL, "oldundo", true, isHidden = true))
|
||||||
val unifyjumps: ToggleOption = addOption(ToggleOption("unifyjumps", GLOBAL, "unifyjumps", true, isHidden = true))
|
val unifyjumps: ToggleOption = addOption(ToggleOption("unifyjumps", GLOBAL, "unifyjumps", true, isHidden = true))
|
||||||
|
val vimscriptFunctionAnnotation: ToggleOption =
|
||||||
|
addOption(ToggleOption("vimscriptfunctionannotation", GLOBAL, "vimscriptfunctionannotation", true, isHidden = true))
|
||||||
|
|
||||||
// This needs to be Option<out VimDataType> so that it can work with derived option types, such as NumberOption, which
|
// This needs to be Option<out VimDataType> so that it can work with derived option types, such as NumberOption, which
|
||||||
// derives from Option<VimInt>
|
// derives from Option<VimInt>
|
||||||
|
@ -58,7 +58,7 @@ public class KeyGroup extends VimKeyGroupBase implements PersistentStateComponen
|
|||||||
public void registerRequiredShortcutKeys(@NotNull VimEditor editor) {
|
public void registerRequiredShortcutKeys(@NotNull VimEditor editor) {
|
||||||
EventFacade.getInstance()
|
EventFacade.getInstance()
|
||||||
.registerCustomShortcutSet(VimShortcutKeyAction.getInstance(), toShortcutSet(getRequiredShortcutKeys()),
|
.registerCustomShortcutSet(VimShortcutKeyAction.getInstance(), toShortcutSet(getRequiredShortcutKeys()),
|
||||||
((IjVimEditor)editor).getEditor().getContentComponent());
|
((IjVimEditor)editor).getEditor().getComponent());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void registerShortcutsForLookup(@NotNull LookupImpl lookup) {
|
public void registerShortcutsForLookup(@NotNull LookupImpl lookup) {
|
||||||
@ -69,7 +69,7 @@ public class KeyGroup extends VimKeyGroupBase implements PersistentStateComponen
|
|||||||
|
|
||||||
void unregisterShortcutKeys(@NotNull VimEditor editor) {
|
void unregisterShortcutKeys(@NotNull VimEditor editor) {
|
||||||
EventFacade.getInstance().unregisterCustomShortcutSet(VimShortcutKeyAction.getInstance(),
|
EventFacade.getInstance().unregisterCustomShortcutSet(VimShortcutKeyAction.getInstance(),
|
||||||
((IjVimEditor)editor).getEditor().getContentComponent());
|
((IjVimEditor)editor).getEditor().getComponent());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -37,7 +37,6 @@ 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.handler.KeyMapIssue
|
import com.maddyhome.idea.vim.handler.KeyMapIssue
|
||||||
import com.maddyhome.idea.vim.helper.MessageHelper
|
import com.maddyhome.idea.vim.helper.MessageHelper
|
||||||
import com.maddyhome.idea.vim.icons.VimIcons
|
|
||||||
import com.maddyhome.idea.vim.key.ShortcutOwner
|
import com.maddyhome.idea.vim.key.ShortcutOwner
|
||||||
import com.maddyhome.idea.vim.key.ShortcutOwnerInfo
|
import com.maddyhome.idea.vim.key.ShortcutOwnerInfo
|
||||||
import com.maddyhome.idea.vim.newapi.globalIjOptions
|
import com.maddyhome.idea.vim.newapi.globalIjOptions
|
||||||
@ -136,30 +135,8 @@ internal class NotificationService(private val project: Project?) {
|
|||||||
).notify(project)
|
).notify(project)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
fun notifyActionId(id: String?, candidates: List<String>? = null) {
|
||||||
* Shows a notification that the user can reenable IdeaVim by clicking on the IdeaVim icon in the status bar.
|
ActionIdNotifier.notifyActionId(id, project, candidates)
|
||||||
*/
|
|
||||||
fun showReenableNotification(project: Project) {
|
|
||||||
val notification = Notification(
|
|
||||||
IDEAVIM_NOTIFICATION_ID,
|
|
||||||
IDEAVIM_NOTIFICATION_TITLE,
|
|
||||||
"IdeaVim has been disabled. You can reenable it by clicking on the gray IdeaVim icon in the status bar.",
|
|
||||||
NotificationType.INFORMATION,
|
|
||||||
)
|
|
||||||
notification.icon = VimIcons.IDEAVIM_DISABLED
|
|
||||||
|
|
||||||
notification.addAction(object : DumbAwareAction("Reenable IdeaVim") {
|
|
||||||
override fun actionPerformed(e: AnActionEvent) {
|
|
||||||
VimPlugin.setEnabled(true)
|
|
||||||
notification.expire()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
notification.notify(project)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun notifyActionId(id: String?, candidates: List<String>? = null, intentionName: String?) {
|
|
||||||
ActionIdNotifier.notifyActionId(id, project, candidates, intentionName)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun notifyKeymapIssues(issues: ArrayList<KeyMapIssue>) {
|
fun notifyKeymapIssues(issues: ArrayList<KeyMapIssue>) {
|
||||||
@ -237,15 +214,12 @@ internal class NotificationService(private val project: Project?) {
|
|||||||
object ActionIdNotifier {
|
object ActionIdNotifier {
|
||||||
private var notification: Notification? = null
|
private var notification: Notification? = null
|
||||||
|
|
||||||
fun notifyActionId(id: String?, project: Project?, candidates: List<String>? = null, intentionName: String? = null) {
|
fun notifyActionId(id: String?, project: Project?, candidates: List<String>? = null) {
|
||||||
notification?.expire()
|
notification?.expire()
|
||||||
|
|
||||||
val possibleIDs = candidates?.distinct()?.sorted()
|
val possibleIDs = candidates?.distinct()?.sorted()
|
||||||
val content = when {
|
val content = when {
|
||||||
id != null -> "Action ID: <code>$id</code><br><br>"
|
id != null -> "Action ID: <code>$id</code><br><br>"
|
||||||
possibleIDs.isNullOrEmpty() && !intentionName.isNullOrEmpty() -> {
|
|
||||||
"Intention \"$intentionName\" does not have an action ID.<br><br>"
|
|
||||||
}
|
|
||||||
possibleIDs.isNullOrEmpty() -> "<i>Cannot detect action ID</i><br><br>"
|
possibleIDs.isNullOrEmpty() -> "<i>Cannot detect action ID</i><br><br>"
|
||||||
possibleIDs.size == 1 -> "Possible action ID: <code>${possibleIDs[0]}</code><br><br>"
|
possibleIDs.size == 1 -> "Possible action ID: <code>${possibleIDs[0]}</code><br><br>"
|
||||||
else -> {
|
else -> {
|
||||||
|
@ -44,7 +44,7 @@ internal class SystemMarks {
|
|||||||
|
|
||||||
internal fun Project.createLineBookmark(editor: Editor, line: Int, mnemonic: Char): LineBookmark? {
|
internal fun Project.createLineBookmark(editor: Editor, line: Int, mnemonic: Char): LineBookmark? {
|
||||||
val bookmarksManager = BookmarksManager.getInstance(this) ?: return null
|
val bookmarksManager = BookmarksManager.getInstance(this) ?: return null
|
||||||
val lineBookmarkProvider = LineBookmarkProvider.Util.find(this) ?: return null
|
val lineBookmarkProvider = LineBookmarkProvider.find(this) ?: return null
|
||||||
val bookmark = lineBookmarkProvider.createBookmark(editor, line) as LineBookmark? ?: return null
|
val bookmark = lineBookmarkProvider.createBookmark(editor, line) as LineBookmark? ?: return null
|
||||||
val type = BookmarkType.get(mnemonic)
|
val type = BookmarkType.get(mnemonic)
|
||||||
if (type == BookmarkType.DEFAULT) return null
|
if (type == BookmarkType.DEFAULT) return null
|
||||||
|
@ -19,7 +19,6 @@ import com.intellij.openapi.editor.Caret
|
|||||||
import com.intellij.openapi.editor.RangeMarker
|
import com.intellij.openapi.editor.RangeMarker
|
||||||
import com.intellij.openapi.editor.ex.EditorEx
|
import com.intellij.openapi.editor.ex.EditorEx
|
||||||
import com.intellij.openapi.ide.CopyPasteManager
|
import com.intellij.openapi.ide.CopyPasteManager
|
||||||
import com.intellij.util.PlatformUtils
|
|
||||||
import com.maddyhome.idea.vim.VimPlugin
|
import com.maddyhome.idea.vim.VimPlugin
|
||||||
import com.maddyhome.idea.vim.api.ExecutionContext
|
import com.maddyhome.idea.vim.api.ExecutionContext
|
||||||
import com.maddyhome.idea.vim.api.VimCaret
|
import com.maddyhome.idea.vim.api.VimCaret
|
||||||
@ -207,9 +206,8 @@ internal class PutGroup : VimPutBase() {
|
|||||||
startOffset: Int,
|
startOffset: Int,
|
||||||
endOffset: Int,
|
endOffset: Int,
|
||||||
): Int {
|
): Int {
|
||||||
// Temp fix for VIM-2808 for Rider and Clion. Should be removed after rider will fix it's issues
|
// Temp fix for VIM-2808. Should be removed after rider will fix it's issues
|
||||||
// Disable for client due to VIM-3857
|
if (isRider() || isClionNova()) return endOffset
|
||||||
if (isRider() || isClionNova() || PlatformUtils.isJetBrainsClient()) return endOffset
|
|
||||||
|
|
||||||
val startLine = editor.offsetToBufferPosition(startOffset).line
|
val startLine = editor.offsetToBufferPosition(startOffset).line
|
||||||
val endLine = editor.offsetToBufferPosition(endOffset - 1).line
|
val endLine = editor.offsetToBufferPosition(endOffset - 1).line
|
||||||
|
@ -96,7 +96,7 @@ internal object IdeaSelectionControl {
|
|||||||
} else {
|
} else {
|
||||||
logger.debug("None of carets have selection. State before adjustment: ${editor.vim.mode}")
|
logger.debug("None of carets have selection. State before adjustment: ${editor.vim.mode}")
|
||||||
if (editor.vim.inVisualMode) editor.vim.exitVisualMode()
|
if (editor.vim.inVisualMode) editor.vim.exitVisualMode()
|
||||||
if (editor.vim.inSelectMode) editor.vim.exitSelectMode(false)
|
if (editor.vim.inSelectMode) editor.exitSelectMode(false)
|
||||||
|
|
||||||
if (editor.vim.inNormalMode) {
|
if (editor.vim.inNormalMode) {
|
||||||
activateMode(editor, chooseNonSelectionMode(editor))
|
activateMode(editor, chooseNonSelectionMode(editor))
|
||||||
|
@ -17,6 +17,7 @@ import com.intellij.openapi.keymap.KeymapManagerListener
|
|||||||
import com.intellij.openapi.keymap.ex.KeymapManagerEx
|
import com.intellij.openapi.keymap.ex.KeymapManagerEx
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.openapi.startup.ProjectActivity
|
import com.intellij.openapi.startup.ProjectActivity
|
||||||
|
import com.jetbrains.rd.util.ConcurrentHashMap
|
||||||
import com.maddyhome.idea.vim.VimPlugin
|
import com.maddyhome.idea.vim.VimPlugin
|
||||||
import com.maddyhome.idea.vim.api.injector
|
import com.maddyhome.idea.vim.api.injector
|
||||||
import com.maddyhome.idea.vim.api.key
|
import com.maddyhome.idea.vim.api.key
|
||||||
@ -27,8 +28,6 @@ import kotlinx.coroutines.flow.MutableSharedFlow
|
|||||||
import kotlinx.coroutines.flow.collectLatest
|
import kotlinx.coroutines.flow.collectLatest
|
||||||
import kotlinx.coroutines.flow.debounce
|
import kotlinx.coroutines.flow.debounce
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.jetbrains.annotations.NonNls
|
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
|
||||||
|
|
||||||
|
|
||||||
// We use alarm with delay to avoid many actions in case many events are fired at the same time
|
// We use alarm with delay to avoid many actions in case many events are fired at the same time
|
||||||
@ -68,7 +67,11 @@ internal class IdeaVimCorrectorKeymapChangedListener : KeymapManagerListener {
|
|||||||
check(correctorRequester.tryEmit(Unit))
|
check(correctorRequester.tryEmit(Unit))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun shortcutsChanged(keymap: Keymap, actionIds: @NonNls Collection<String>, fromSettings: Boolean) {
|
override fun shortcutChanged(keymap: Keymap, actionId: String) {
|
||||||
|
check(correctorRequester.tryEmit(Unit))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun shortcutChanged(keymap: Keymap, actionId: String, fromSettings: Boolean) {
|
||||||
check(correctorRequester.tryEmit(Unit))
|
check(correctorRequester.tryEmit(Unit))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,6 @@ import kotlinx.coroutines.flow.MutableSharedFlow
|
|||||||
import kotlinx.coroutines.flow.collectLatest
|
import kotlinx.coroutines.flow.collectLatest
|
||||||
import kotlinx.coroutines.flow.debounce
|
import kotlinx.coroutines.flow.debounce
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.jetbrains.annotations.NonNls
|
|
||||||
import javax.swing.KeyStroke
|
import javax.swing.KeyStroke
|
||||||
|
|
||||||
// We use alarm with delay to avoid many notifications in case many events are fired at the same time
|
// We use alarm with delay to avoid many notifications in case many events are fired at the same time
|
||||||
@ -68,7 +67,11 @@ internal class IdeaVimKeymapChangedListener : KeymapManagerListener {
|
|||||||
check(keyCheckRequests.tryEmit(Unit))
|
check(keyCheckRequests.tryEmit(Unit))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun shortcutsChanged(keymap: Keymap, actionIds: @NonNls Collection<String>, fromSettings: Boolean) {
|
override fun shortcutChanged(keymap: Keymap, actionId: String) {
|
||||||
|
check(keyCheckRequests.tryEmit(Unit))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun shortcutChanged(keymap: Keymap, actionId: String, fromSettings: Boolean) {
|
||||||
check(keyCheckRequests.tryEmit(Unit))
|
check(keyCheckRequests.tryEmit(Unit))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -60,7 +60,7 @@ internal fun Editor.updateCaretsVisualAttributes() {
|
|||||||
* Used when Vim emulation is disabled
|
* Used when Vim emulation is disabled
|
||||||
*/
|
*/
|
||||||
internal fun Editor.removeCaretsVisualAttributes() {
|
internal fun Editor.removeCaretsVisualAttributes() {
|
||||||
caretModel.allCarets.forEach { it.visualAttributes = CaretVisualAttributes.getDefault() }
|
caretModel.allCarets.forEach { it.visualAttributes = CaretVisualAttributes.DEFAULT }
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun Editor.hasBlockOrUnderscoreCaret() = isBlockCursorOverride() ||
|
internal fun Editor.hasBlockOrUnderscoreCaret() = isBlockCursorOverride() ||
|
||||||
@ -95,8 +95,8 @@ private fun Editor.updatePrimaryCaretVisualAttributes() {
|
|||||||
|
|
||||||
// Make sure the caret is visible as soon as it's set. It might be invisible while blinking
|
// Make sure the caret is visible as soon as it's set. It might be invisible while blinking
|
||||||
// NOTE: At the moment, this causes project leak in tests
|
// NOTE: At the moment, this causes project leak in tests
|
||||||
// IJPL-928 - this will be fixed in 2025.2
|
// IJPL-928 - this will be fixed in 2024.2
|
||||||
// [VERSION UPDATE] 2025.2 - remove if wrapping
|
// [VERSION UPDATE] 2024.2 - remove if wrapping
|
||||||
if (!ApplicationManager.getApplication().isUnitTestMode) {
|
if (!ApplicationManager.getApplication().isUnitTestMode) {
|
||||||
(this as? EditorEx)?.setCaretVisible(true)
|
(this as? EditorEx)?.setCaretVisible(true)
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2003-2023 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.helper
|
||||||
|
|
||||||
|
import com.intellij.openapi.actionSystem.DataContext
|
||||||
|
import com.intellij.openapi.actionSystem.PlatformDataKeys
|
||||||
|
import com.intellij.openapi.editor.Editor
|
||||||
|
import com.intellij.openapi.editor.ex.util.EditorUtil
|
||||||
|
import com.intellij.openapi.util.Key
|
||||||
|
import com.intellij.openapi.util.UserDataHolder
|
||||||
|
|
||||||
|
@Deprecated("Do not use context wrappers, use existing provided contexts. If no context available, use `injector.getExecutionContextManager().getEditorExecutionContext(editor)`")
|
||||||
|
internal class EditorDataContext @Deprecated("Please use `init` method") constructor(
|
||||||
|
private val editor: Editor,
|
||||||
|
private val editorContext: DataContext,
|
||||||
|
private val contextDelegate: DataContext? = null,
|
||||||
|
) : DataContext, UserDataHolder {
|
||||||
|
/**
|
||||||
|
* Returns the object corresponding to the specified data identifier. Some of the supported data identifiers are
|
||||||
|
* defined in the [PlatformDataKeys] class.
|
||||||
|
*
|
||||||
|
* @param dataId the data identifier for which the value is requested.
|
||||||
|
* @return the value, or null if no value is available in the current context for this identifier.
|
||||||
|
*/
|
||||||
|
override fun getData(dataId: String): Any? = when {
|
||||||
|
PlatformDataKeys.EDITOR.name == dataId -> editor
|
||||||
|
PlatformDataKeys.PROJECT.name == dataId -> editor.project
|
||||||
|
PlatformDataKeys.VIRTUAL_FILE.name == dataId -> EditorHelper.getVirtualFile(editor)
|
||||||
|
else -> editorContext.getData(dataId) ?: contextDelegate?.getData(dataId)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun <T : Any?> getUserData(key: Key<T>): T? {
|
||||||
|
return if (contextDelegate is UserDataHolder) {
|
||||||
|
contextDelegate.getUserData(key)
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun <T : Any?> putUserData(key: Key<T>, value: T?) {
|
||||||
|
if (contextDelegate is UserDataHolder) {
|
||||||
|
contextDelegate.putUserData(key, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
@JvmStatic
|
||||||
|
fun init(editor: Editor, contextDelegate: DataContext? = null): EditorDataContext {
|
||||||
|
val editorContext = EditorUtil.getEditorDataContext(editor)
|
||||||
|
return if (contextDelegate is EditorDataContext) {
|
||||||
|
if (editor === contextDelegate.editor) {
|
||||||
|
contextDelegate
|
||||||
|
} else {
|
||||||
|
EditorDataContext(editor, editorContext, contextDelegate.contextDelegate)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
EditorDataContext(editor, editorContext, contextDelegate)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -8,7 +8,6 @@
|
|||||||
|
|
||||||
package com.maddyhome.idea.vim.helper;
|
package com.maddyhome.idea.vim.helper;
|
||||||
|
|
||||||
import com.intellij.injected.editor.VirtualFileWindow;
|
|
||||||
import com.intellij.openapi.editor.*;
|
import com.intellij.openapi.editor.*;
|
||||||
import com.intellij.openapi.editor.ex.util.EditorUtil;
|
import com.intellij.openapi.editor.ex.util.EditorUtil;
|
||||||
import com.intellij.openapi.editor.impl.EditorImpl;
|
import com.intellij.openapi.editor.impl.EditorImpl;
|
||||||
@ -16,7 +15,6 @@ import com.intellij.openapi.fileEditor.FileDocumentManager;
|
|||||||
import com.intellij.openapi.util.SystemInfo;
|
import com.intellij.openapi.util.SystemInfo;
|
||||||
import com.intellij.openapi.util.registry.Registry;
|
import com.intellij.openapi.util.registry.Registry;
|
||||||
import com.intellij.openapi.vfs.VirtualFile;
|
import com.intellij.openapi.vfs.VirtualFile;
|
||||||
import com.intellij.openapi.vfs.VirtualFileUtil;
|
|
||||||
import com.intellij.testFramework.LightVirtualFile;
|
import com.intellij.testFramework.LightVirtualFile;
|
||||||
import com.maddyhome.idea.vim.api.EngineEditorHelperKt;
|
import com.maddyhome.idea.vim.api.EngineEditorHelperKt;
|
||||||
import com.maddyhome.idea.vim.api.VimEditor;
|
import com.maddyhome.idea.vim.api.VimEditor;
|
||||||
@ -654,21 +652,7 @@ public class EditorHelper {
|
|||||||
*/
|
*/
|
||||||
public static boolean isFileEditor(@NotNull Editor editor) {
|
public static boolean isFileEditor(@NotNull Editor editor) {
|
||||||
final VirtualFile virtualFile = getVirtualFile(editor);
|
final VirtualFile virtualFile = getVirtualFile(editor);
|
||||||
if (virtualFile == null) return false;
|
return virtualFile != null && !(virtualFile instanceof LightVirtualFile);
|
||||||
if (virtualFile instanceof LightVirtualFile) {
|
|
||||||
var hostVirtualFile = getHostFileFromInjectedFile(virtualFile);
|
|
||||||
if (hostVirtualFile == null) return false;
|
|
||||||
return !(hostVirtualFile instanceof LightVirtualFile);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static @Nullable VirtualFile getHostFileFromInjectedFile(@NotNull VirtualFile virtualFile) {
|
|
||||||
final var vf = VirtualFileUtil.originalFileOrSelf(virtualFile);
|
|
||||||
if (vf instanceof VirtualFileWindow) {
|
|
||||||
return ((VirtualFileWindow)vf).getDelegate();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -14,7 +14,6 @@ import com.intellij.codeWithMe.ClientId
|
|||||||
import com.intellij.openapi.editor.Caret
|
import com.intellij.openapi.editor.Caret
|
||||||
import com.intellij.openapi.editor.CaretState
|
import com.intellij.openapi.editor.CaretState
|
||||||
import com.intellij.openapi.editor.Editor
|
import com.intellij.openapi.editor.Editor
|
||||||
import com.intellij.openapi.editor.EditorKind
|
|
||||||
import com.intellij.openapi.editor.ex.util.EditorUtil
|
import com.intellij.openapi.editor.ex.util.EditorUtil
|
||||||
import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx
|
import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx
|
||||||
import com.intellij.util.ui.table.JBTableRowEditor
|
import com.intellij.util.ui.table.JBTableRowEditor
|
||||||
@ -43,14 +42,9 @@ internal val Editor.isIdeaVimDisabledHere: Boolean
|
|||||||
return (ideaVimDisabledInDialog(ideaVimSupportValue) && isInDialog()) ||
|
return (ideaVimDisabledInDialog(ideaVimSupportValue) && isInDialog()) ||
|
||||||
!ClientId.isCurrentlyUnderLocalId || // CWM-927
|
!ClientId.isCurrentlyUnderLocalId || // CWM-927
|
||||||
(ideaVimDisabledForSingleLine(ideaVimSupportValue) && isSingleLine()) ||
|
(ideaVimDisabledForSingleLine(ideaVimSupportValue) && isSingleLine()) ||
|
||||||
IdeaVimDisablerExtensionPoint.isDisabledForEditor(this) ||
|
IdeaVimDisablerExtensionPoint.isDisabledForEditor(this)
|
||||||
isAiChat() // VIM-3786
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Editor.isAiChat(): Boolean {
|
|
||||||
return EditorHelper.getVirtualFile(this)?.name?.contains("AIAssistantInput") == true
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun ideaVimDisabledInDialog(ideaVimSupportValue: StringListOptionValue): Boolean {
|
private fun ideaVimDisabledInDialog(ideaVimSupportValue: StringListOptionValue): Boolean {
|
||||||
return !ideaVimSupportValue.contains(IjOptionConstants.ideavimsupport_dialog)
|
return !ideaVimSupportValue.contains(IjOptionConstants.ideavimsupport_dialog)
|
||||||
&& !ideaVimSupportValue.contains(IjOptionConstants.ideavimsupport_dialoglegacy)
|
&& !ideaVimSupportValue.contains(IjOptionConstants.ideavimsupport_dialoglegacy)
|
||||||
@ -77,19 +71,6 @@ internal fun Editor.isPrimaryEditor(): Boolean {
|
|||||||
return fileEditorManager.allEditors.any { fileEditor -> this == EditorUtil.getEditorEx(fileEditor) }
|
return fileEditorManager.allEditors.any { fileEditor -> this == EditorUtil.getEditorEx(fileEditor) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if the editor should be treated like a terminal. I.e. switch to Insert mode automatically
|
|
||||||
*
|
|
||||||
* A "terminal" editor is an editor used for purposes other than mainstream editing, such as a terminal, console, log
|
|
||||||
* viewer, etc. In this instance, the editor is writable, the document is writable, but it's not backed by a real file
|
|
||||||
* and it's not the diff viewer. We also check that if it's an injected language fragment backed by a real file.
|
|
||||||
*/
|
|
||||||
internal fun Editor.isTerminalEditor(): Boolean {
|
|
||||||
return !isViewer
|
|
||||||
&& document.isWritable
|
|
||||||
&& this.editorKind == EditorKind.CONSOLE
|
|
||||||
}
|
|
||||||
|
|
||||||
// Optimized clone of com.intellij.ide.ui.laf.darcula.DarculaUIUtil.isTableCellEditor
|
// Optimized clone of com.intellij.ide.ui.laf.darcula.DarculaUIUtil.isTableCellEditor
|
||||||
private fun isTableCellEditor(c: Component): Boolean {
|
private fun isTableCellEditor(c: Component): Boolean {
|
||||||
return (java.lang.Boolean.TRUE == (c as JComponent).getClientProperty("JComboBox.isTableCellEditor")) ||
|
return (java.lang.Boolean.TRUE == (c as JComponent).getClientProperty("JComboBox.isTableCellEditor")) ||
|
||||||
|
@ -8,15 +8,19 @@
|
|||||||
|
|
||||||
package com.maddyhome.idea.vim.helper
|
package com.maddyhome.idea.vim.helper
|
||||||
|
|
||||||
import com.intellij.execution.actions.StopAction
|
import com.intellij.openapi.actionSystem.ActionGroup
|
||||||
import com.intellij.openapi.actionSystem.ActionManager
|
import com.intellij.openapi.actionSystem.ActionManager
|
||||||
import com.intellij.openapi.actionSystem.ActionPlaces
|
import com.intellij.openapi.actionSystem.ActionPlaces
|
||||||
import com.intellij.openapi.actionSystem.AnAction
|
import com.intellij.openapi.actionSystem.AnAction
|
||||||
|
import com.intellij.openapi.actionSystem.AnActionEvent
|
||||||
import com.intellij.openapi.actionSystem.EmptyAction
|
import com.intellij.openapi.actionSystem.EmptyAction
|
||||||
import com.intellij.openapi.actionSystem.IdeActions
|
import com.intellij.openapi.actionSystem.IdeActions
|
||||||
import com.intellij.openapi.actionSystem.PlatformDataKeys
|
import com.intellij.openapi.actionSystem.PlatformDataKeys
|
||||||
import com.intellij.openapi.actionSystem.ex.ActionUtil
|
import com.intellij.openapi.actionSystem.ex.ActionUtil
|
||||||
|
import com.intellij.openapi.actionSystem.ex.ActionUtil.performDumbAwareWithCallbacks
|
||||||
import com.intellij.openapi.actionSystem.impl.ProxyShortcutSet
|
import com.intellij.openapi.actionSystem.impl.ProxyShortcutSet
|
||||||
|
import com.intellij.openapi.actionSystem.impl.SimpleDataContext
|
||||||
|
import com.intellij.openapi.actionSystem.impl.Utils
|
||||||
import com.intellij.openapi.application.ex.ApplicationManagerEx
|
import com.intellij.openapi.application.ex.ApplicationManagerEx
|
||||||
import com.intellij.openapi.command.CommandProcessor
|
import com.intellij.openapi.command.CommandProcessor
|
||||||
import com.intellij.openapi.command.UndoConfirmationPolicy
|
import com.intellij.openapi.command.UndoConfirmationPolicy
|
||||||
@ -24,7 +28,9 @@ import com.intellij.openapi.components.Service
|
|||||||
import com.intellij.openapi.diagnostic.thisLogger
|
import com.intellij.openapi.diagnostic.thisLogger
|
||||||
import com.intellij.openapi.editor.actionSystem.DocCommandGroupId
|
import com.intellij.openapi.editor.actionSystem.DocCommandGroupId
|
||||||
import com.intellij.openapi.progress.util.ProgressIndicatorUtils
|
import com.intellij.openapi.progress.util.ProgressIndicatorUtils
|
||||||
|
import com.intellij.openapi.ui.popup.JBPopupFactory
|
||||||
import com.intellij.openapi.util.NlsContexts
|
import com.intellij.openapi.util.NlsContexts
|
||||||
|
import com.intellij.openapi.util.registry.Registry
|
||||||
import com.maddyhome.idea.vim.RegisterActions
|
import com.maddyhome.idea.vim.RegisterActions
|
||||||
import com.maddyhome.idea.vim.api.ExecutionContext
|
import com.maddyhome.idea.vim.api.ExecutionContext
|
||||||
import com.maddyhome.idea.vim.api.NativeAction
|
import com.maddyhome.idea.vim.api.NativeAction
|
||||||
@ -32,11 +38,14 @@ import com.maddyhome.idea.vim.api.VimActionExecutor
|
|||||||
import com.maddyhome.idea.vim.api.VimEditor
|
import com.maddyhome.idea.vim.api.VimEditor
|
||||||
import com.maddyhome.idea.vim.command.OperatorArguments
|
import com.maddyhome.idea.vim.command.OperatorArguments
|
||||||
import com.maddyhome.idea.vim.handler.EditorActionHandlerBase
|
import com.maddyhome.idea.vim.handler.EditorActionHandlerBase
|
||||||
|
import com.maddyhome.idea.vim.ide.isRider
|
||||||
import com.maddyhome.idea.vim.newapi.IjNativeAction
|
import com.maddyhome.idea.vim.newapi.IjNativeAction
|
||||||
import com.maddyhome.idea.vim.newapi.ij
|
import com.maddyhome.idea.vim.newapi.ij
|
||||||
|
import com.maddyhome.idea.vim.newapi.runFromVimKey
|
||||||
import org.jetbrains.annotations.NonNls
|
import org.jetbrains.annotations.NonNls
|
||||||
import java.awt.Component
|
import java.awt.Component
|
||||||
import javax.swing.JComponent
|
import javax.swing.JComponent
|
||||||
|
import javax.swing.SwingUtilities
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
internal class IjActionExecutor : VimActionExecutor {
|
internal class IjActionExecutor : VimActionExecutor {
|
||||||
@ -55,11 +64,8 @@ internal class IjActionExecutor : VimActionExecutor {
|
|||||||
override val ACTION_EXPAND_REGION_RECURSIVELY: String
|
override val ACTION_EXPAND_REGION_RECURSIVELY: String
|
||||||
get() = IdeActions.ACTION_EXPAND_REGION_RECURSIVELY
|
get() = IdeActions.ACTION_EXPAND_REGION_RECURSIVELY
|
||||||
override val ACTION_EXPAND_COLLAPSE_TOGGLE: String
|
override val ACTION_EXPAND_COLLAPSE_TOGGLE: String
|
||||||
get() = IdeActions.ACTION_EXPAND_COLLAPSE_TOGGLE_REGION
|
// [VERSION UPDATE] 2024.3+ Replace raw "ExpandCollapseToggleAction" with IdeActions.ACTION_EXPAND_COLLAPSE_TOGGLE_REGION from the platform.
|
||||||
override val ACTION_UNDO: String
|
get() = "ExpandCollapseToggleAction"
|
||||||
get() = IdeActions.ACTION_UNDO
|
|
||||||
override val ACTION_REDO: String
|
|
||||||
get() = IdeActions.ACTION_REDO
|
|
||||||
|
|
||||||
var isRunningActionFromVim: Boolean = false
|
var isRunningActionFromVim: Boolean = false
|
||||||
|
|
||||||
@ -71,28 +77,78 @@ internal class IjActionExecutor : VimActionExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val ijAction = (action as IjNativeAction).action
|
val ijAction = (action as IjNativeAction).action
|
||||||
try {
|
if (Registry.`is`("ideavim.old.action.execution", true) || isRider()) {
|
||||||
isRunningActionFromVim = true
|
return manualActionExecution(context, ijAction)
|
||||||
// The context component should be editor. This is especially important when running the `:action` commands
|
} else {
|
||||||
// because at the moment of execution, the focused component is Ex Field, not editor.
|
try {
|
||||||
val contextComponent = editor?.ij?.contentComponent
|
isRunningActionFromVim = true
|
||||||
val place = ijAction.choosePlace()
|
// The context component should be editor. This is especially important when running the `:action` commands
|
||||||
val res = ActionManager.getInstance().tryToExecute(ijAction, null, contextComponent, place, true)
|
// because at the moment of execution, the focused component is Ex Field, not editor.
|
||||||
res.waitFor(5_000)
|
val contextComponent = editor?.ij?.contentComponent
|
||||||
return res.isDone
|
val res = ActionManager.getInstance().tryToExecute(ijAction, null, contextComponent, "IdeaVim", true)
|
||||||
} finally {
|
res.waitFor(5_000)
|
||||||
isRunningActionFromVim = false
|
return res.isDone
|
||||||
|
} finally {
|
||||||
|
isRunningActionFromVim = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: We should find a proper place for the IdeaVim actions
|
private fun manualActionExecution(
|
||||||
// Currently, we use "IdeaVim" except a few actions
|
context: ExecutionContext,
|
||||||
private fun AnAction.choosePlace(): String {
|
ijAction: AnAction,
|
||||||
// StopAction works fine if `StopAction.isPlaceGlobal` returns true
|
): Boolean {
|
||||||
// Or if there is a specific data stored in the context. This data, however, is stored
|
/**
|
||||||
// only if the run window is in focus.
|
* Data context that defines that some action was started from IdeaVim.
|
||||||
if (this is StopAction) return ActionPlaces.ACTION_SEARCH
|
* You can call use [runFromVimKey] key to define if intellij action was started from IdeaVim
|
||||||
return "IdeaVim"
|
*/
|
||||||
|
val dataContext = SimpleDataContext.getSimpleContext(runFromVimKey, true, context.ij)
|
||||||
|
|
||||||
|
val actionId = ActionManager.getInstance().getId(ijAction)
|
||||||
|
@Suppress("removal", "DEPRECATION") val event = AnActionEvent(
|
||||||
|
null,
|
||||||
|
dataContext,
|
||||||
|
ActionPlaces.KEYBOARD_SHORTCUT,
|
||||||
|
ijAction.templatePresentation.clone(),
|
||||||
|
ActionManager.getInstance(),
|
||||||
|
0,
|
||||||
|
)
|
||||||
|
Utils.initUpdateSession(event)
|
||||||
|
// beforeActionPerformedUpdate should be called to update the action. It fixes some rider-specific problems
|
||||||
|
// because rider uses an async update method. See VIM-1819.
|
||||||
|
// This method executes inside lastUpdateAndCheckDumb
|
||||||
|
// Another related issue: VIM-2604
|
||||||
|
|
||||||
|
// This is a hack to fix the tests and fix VIM-3332
|
||||||
|
// We should get rid of it in VIM-3376
|
||||||
|
if (actionId == "RunClass" || actionId == IdeActions.ACTION_COMMENT_LINE || actionId == IdeActions.ACTION_COMMENT_BLOCK) {
|
||||||
|
@Suppress("removal", "OverrideOnly", "DEPRECATION")
|
||||||
|
ijAction.beforeActionPerformedUpdate(event)
|
||||||
|
if (!event.presentation.isEnabled) return false
|
||||||
|
} else {
|
||||||
|
if (!ActionUtil.lastUpdateAndCheckDumb(ijAction, event, false)) return false
|
||||||
|
}
|
||||||
|
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, dataContext, false, null, -1)
|
||||||
|
val component = dataContext.getData(PlatformDataKeys.CONTEXT_COMPONENT)
|
||||||
|
if (component != null) {
|
||||||
|
val window = SwingUtilities.getWindowAncestor(component)
|
||||||
|
if (window != null) {
|
||||||
|
popup.showInCenterOf(window)
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
popup.showInFocusCenter()
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
performDumbAwareWithCallbacks(ijAction, event) {
|
||||||
|
@Suppress("OverrideOnly")
|
||||||
|
ijAction.actionPerformed(event)
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2003-2023 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.helper;
|
||||||
|
|
||||||
|
import com.google.common.io.CharStreams;
|
||||||
|
import org.jetbrains.annotations.NonNls;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author vlan
|
||||||
|
*/
|
||||||
|
public class MacKeyRepeat {
|
||||||
|
@VimNlsSafe public static final String FMT = "defaults %s -globalDomain ApplePressAndHoldEnabled";
|
||||||
|
@NotNull private static final MacKeyRepeat INSTANCE = new MacKeyRepeat();
|
||||||
|
@NonNls private static final String EXEC_COMMAND = "launchctl stop com.apple.SystemUIServer.agent";
|
||||||
|
@NonNls private static final String delete = "delete";
|
||||||
|
@NonNls private static final String write = "write";
|
||||||
|
@NonNls private static final String read = "read";
|
||||||
|
|
||||||
|
public static @NotNull MacKeyRepeat getInstance() {
|
||||||
|
return INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static @NotNull String read(@NotNull InputStream stream) throws IOException {
|
||||||
|
return CharStreams.toString(new InputStreamReader(stream));
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable Boolean isEnabled() {
|
||||||
|
final String command = String.format(FMT, read);
|
||||||
|
try {
|
||||||
|
final Process process = Runtime.getRuntime().exec(command);
|
||||||
|
final String data = read(process.getInputStream()).trim();
|
||||||
|
try {
|
||||||
|
return Integer.parseInt(data) == 0;
|
||||||
|
}
|
||||||
|
catch (NumberFormatException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (IOException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnabled(@Nullable Boolean value) {
|
||||||
|
final String command;
|
||||||
|
if (value == null) {
|
||||||
|
command = String.format(FMT, delete);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
final String arg = value ? "0" : "1";
|
||||||
|
command = String.format(FMT, write) + " " + arg;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
final Runtime runtime = Runtime.getRuntime();
|
||||||
|
final Process defaults = runtime.exec(command);
|
||||||
|
defaults.waitFor();
|
||||||
|
final Process restartSystemUI = runtime.exec(EXEC_COMMAND);
|
||||||
|
restartSystemUI.waitFor();
|
||||||
|
}
|
||||||
|
catch (IOException | InterruptedException ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,54 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2003-2023 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.helper
|
|
||||||
|
|
||||||
import com.google.common.io.CharStreams
|
|
||||||
import java.io.IOException
|
|
||||||
import java.io.InputStream
|
|
||||||
import java.io.InputStreamReader
|
|
||||||
|
|
||||||
object MacKeyRepeat {
|
|
||||||
var isEnabled: Boolean?
|
|
||||||
get() {
|
|
||||||
return try {
|
|
||||||
val process = Runtime.getRuntime().exec(READ_COMMAND)
|
|
||||||
val data = read(process.inputStream).trim().toIntOrNull() ?: return null
|
|
||||||
data == 0
|
|
||||||
} catch (_: IOException) {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
set(value) {
|
|
||||||
val command: Array<String>
|
|
||||||
if (value == null) {
|
|
||||||
command = DELETE_COMMAND
|
|
||||||
} else {
|
|
||||||
val arg = if (value) "0" else "1"
|
|
||||||
command = WRITE_COMMAND + arg
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
val runtime = Runtime.getRuntime()
|
|
||||||
val defaults = runtime.exec(command)
|
|
||||||
defaults.waitFor()
|
|
||||||
val restartSystemUI: Process = runtime.exec(EXEC_COMMAND)
|
|
||||||
restartSystemUI.waitFor()
|
|
||||||
} catch (_: IOException) {
|
|
||||||
} catch (_: InterruptedException) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private val EXEC_COMMAND = arrayOf("launchctl", "stop", "com.apple.SystemUIServer.agent")
|
|
||||||
private val READ_COMMAND = arrayOf("defaults", "read", "-globalDomain", "ApplePressAndHoldEnabled")
|
|
||||||
private val WRITE_COMMAND = arrayOf("defaults", "write", "-globalDomain", "ApplePressAndHoldEnabled")
|
|
||||||
private val DELETE_COMMAND = arrayOf("defaults", "delete", "-globalDomain", "ApplePressAndHoldEnabled")
|
|
||||||
|
|
||||||
@Throws(IOException::class)
|
|
||||||
private fun read(stream: InputStream): String {
|
|
||||||
return CharStreams.toString(InputStreamReader(stream))
|
|
||||||
}
|
|
||||||
}
|
|
@ -24,6 +24,28 @@ import com.maddyhome.idea.vim.newapi.IjVimEditor
|
|||||||
import com.maddyhome.idea.vim.newapi.vim
|
import com.maddyhome.idea.vim.newapi.vim
|
||||||
import com.maddyhome.idea.vim.state.mode.inSelectMode
|
import com.maddyhome.idea.vim.state.mode.inSelectMode
|
||||||
|
|
||||||
|
/** [adjustCaretPosition] - if true, caret will be moved one char left if it's on the line end */
|
||||||
|
internal fun Editor.exitSelectMode(adjustCaretPosition: Boolean) {
|
||||||
|
val vimEditor = this.vim
|
||||||
|
if (!vimEditor.inSelectMode) return
|
||||||
|
|
||||||
|
vimEditor.mode = vimEditor.mode.returnTo
|
||||||
|
SelectionVimListenerSuppressor.lock().use {
|
||||||
|
this.caretModel.allCarets.forEach {
|
||||||
|
// NOTE: I think it should be write action, but the exception shows only an absence of the read action
|
||||||
|
injector.application.runReadAction { it.removeSelection() }
|
||||||
|
it.vim.vimSelectionStartClear()
|
||||||
|
if (adjustCaretPosition && !vimEditor.isEndAllowed) {
|
||||||
|
val lineEnd = IjVimEditor(this).getLineEndForOffset(it.offset)
|
||||||
|
val lineStart = IjVimEditor(this).getLineStartForOffset(it.offset)
|
||||||
|
if (it.offset == lineEnd && it.offset != lineStart) {
|
||||||
|
it.moveToInlayAwareOffset(it.offset - 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** [adjustCaretPosition] - if true, caret will be moved one char left if it's on the line end */
|
/** [adjustCaretPosition] - if true, caret will be moved one char left if it's on the line end */
|
||||||
internal fun VimEditor.exitSelectMode(adjustCaretPosition: Boolean) {
|
internal fun VimEditor.exitSelectMode(adjustCaretPosition: Boolean) {
|
||||||
if (!this.inSelectMode) return
|
if (!this.inSelectMode) return
|
||||||
|
@ -42,7 +42,7 @@ public class PsiHelper {
|
|||||||
if (file == null) {
|
if (file == null) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
StructureViewBuilder structureViewBuilder = LanguageStructureViewBuilder.getInstance().getStructureViewBuilder(file);
|
StructureViewBuilder structureViewBuilder = LanguageStructureViewBuilder.INSTANCE.getStructureViewBuilder(file);
|
||||||
if (!(structureViewBuilder instanceof TreeBasedStructureViewBuilder builder)) return -1;
|
if (!(structureViewBuilder instanceof TreeBasedStructureViewBuilder builder)) return -1;
|
||||||
StructureViewModel model = builder.createStructureViewModel(editor);
|
StructureViewModel model = builder.createStructureViewModel(editor);
|
||||||
|
|
||||||
|
@ -19,7 +19,6 @@ import com.intellij.openapi.fileEditor.TextEditor
|
|||||||
import com.intellij.openapi.fileEditor.TextEditorWithPreview
|
import com.intellij.openapi.fileEditor.TextEditorWithPreview
|
||||||
import com.intellij.openapi.fileEditor.impl.text.TextEditorProvider
|
import com.intellij.openapi.fileEditor.impl.text.TextEditorProvider
|
||||||
import com.intellij.openapi.util.registry.Registry
|
import com.intellij.openapi.util.registry.Registry
|
||||||
import com.intellij.util.PlatformUtils
|
|
||||||
import com.maddyhome.idea.vim.VimPlugin
|
import com.maddyhome.idea.vim.VimPlugin
|
||||||
import com.maddyhome.idea.vim.api.ExecutionContext
|
import com.maddyhome.idea.vim.api.ExecutionContext
|
||||||
import com.maddyhome.idea.vim.api.VimCaret
|
import com.maddyhome.idea.vim.api.VimCaret
|
||||||
@ -44,12 +43,6 @@ internal class UndoRedoHelper : VimTimestampBasedUndoService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun undo(editor: VimEditor, context: ExecutionContext): Boolean {
|
override fun undo(editor: VimEditor, context: ExecutionContext): Boolean {
|
||||||
if (PlatformUtils.isJetBrainsClient()) {
|
|
||||||
// Note: Remote Dev has special hacks for undo/redo, so we don't use the manager.
|
|
||||||
// The action is sent directly to the backend using the internal API.
|
|
||||||
return injector.actionExecutor.executeAction(editor, injector.actionExecutor.ACTION_UNDO, context)
|
|
||||||
}
|
|
||||||
|
|
||||||
val ijContext = context.context as DataContext
|
val ijContext = context.context as DataContext
|
||||||
val project = PlatformDataKeys.PROJECT.getData(ijContext) ?: return false
|
val project = PlatformDataKeys.PROJECT.getData(ijContext) ?: return false
|
||||||
val textEditor = getTextEditor(editor.ij)
|
val textEditor = getTextEditor(editor.ij)
|
||||||
@ -113,10 +106,6 @@ internal class UndoRedoHelper : VimTimestampBasedUndoService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun redo(editor: VimEditor, context: ExecutionContext): Boolean {
|
override fun redo(editor: VimEditor, context: ExecutionContext): Boolean {
|
||||||
if (PlatformUtils.isJetBrainsClient()) {
|
|
||||||
return injector.actionExecutor.executeAction(editor, injector.actionExecutor.ACTION_REDO, context)
|
|
||||||
}
|
|
||||||
|
|
||||||
val ijContext = context.context as DataContext
|
val ijContext = context.context as DataContext
|
||||||
val project = PlatformDataKeys.PROJECT.getData(ijContext) ?: return false
|
val project = PlatformDataKeys.PROJECT.getData(ijContext) ?: return false
|
||||||
val textEditor = getTextEditor(editor.ij)
|
val textEditor = getTextEditor(editor.ij)
|
||||||
|
@ -10,6 +10,8 @@ package com.maddyhome.idea.vim.listener
|
|||||||
|
|
||||||
import com.intellij.execution.impl.ConsoleViewImpl
|
import com.intellij.execution.impl.ConsoleViewImpl
|
||||||
import com.intellij.openapi.application.ApplicationManager
|
import com.intellij.openapi.application.ApplicationManager
|
||||||
|
import com.intellij.openapi.editor.Editor
|
||||||
|
import com.intellij.openapi.editor.EditorKind
|
||||||
import com.maddyhome.idea.vim.KeyHandler
|
import com.maddyhome.idea.vim.KeyHandler
|
||||||
import com.maddyhome.idea.vim.LastUsedEditorInfo
|
import com.maddyhome.idea.vim.LastUsedEditorInfo
|
||||||
import com.maddyhome.idea.vim.VimPlugin
|
import com.maddyhome.idea.vim.VimPlugin
|
||||||
@ -17,8 +19,8 @@ import com.maddyhome.idea.vim.api.ExecutionContext
|
|||||||
import com.maddyhome.idea.vim.api.VimEditor
|
import com.maddyhome.idea.vim.api.VimEditor
|
||||||
import com.maddyhome.idea.vim.api.injector
|
import com.maddyhome.idea.vim.api.injector
|
||||||
import com.maddyhome.idea.vim.common.EditorListener
|
import com.maddyhome.idea.vim.common.EditorListener
|
||||||
|
import com.maddyhome.idea.vim.helper.EditorHelper
|
||||||
import com.maddyhome.idea.vim.helper.inInsertMode
|
import com.maddyhome.idea.vim.helper.inInsertMode
|
||||||
import com.maddyhome.idea.vim.helper.isTerminalEditor
|
|
||||||
import com.maddyhome.idea.vim.newapi.ij
|
import com.maddyhome.idea.vim.newapi.ij
|
||||||
import com.maddyhome.idea.vim.state.mode.Mode
|
import com.maddyhome.idea.vim.state.mode.Mode
|
||||||
|
|
||||||
@ -55,7 +57,7 @@ class IJEditorFocusListener : EditorListener {
|
|||||||
// to know that a read-only editor that is hosting a console view with a running process can be treated as writable.
|
// to know that a read-only editor that is hosting a console view with a running process can be treated as writable.
|
||||||
|
|
||||||
val ijEditor = editor.ij
|
val ijEditor = editor.ij
|
||||||
val isCurrentEditorTerminal = ijEditor.isTerminalEditor()
|
val isCurrentEditorTerminal = isTerminal(ijEditor)
|
||||||
|
|
||||||
KeyHandler.getInstance().lastUsedEditorInfo = LastUsedEditorInfo(currentEditorHashCode, false)
|
KeyHandler.getInstance().lastUsedEditorInfo = LastUsedEditorInfo(currentEditorHashCode, false)
|
||||||
|
|
||||||
@ -64,10 +66,8 @@ class IJEditorFocusListener : EditorListener {
|
|||||||
VimPlugin.getChange().insertBeforeCursor(editor, context)
|
VimPlugin.getChange().insertBeforeCursor(editor, context)
|
||||||
KeyHandler.getInstance().lastUsedEditorInfo = LastUsedEditorInfo(currentEditorHashCode, true)
|
KeyHandler.getInstance().lastUsedEditorInfo = LastUsedEditorInfo(currentEditorHashCode, true)
|
||||||
}
|
}
|
||||||
if (isCurrentEditorTerminal) {
|
if (isCurrentEditorTerminal && !ijEditor.inInsertMode) {
|
||||||
if (!ijEditor.inInsertMode) {
|
switchToInsertMode.run()
|
||||||
switchToInsertMode.run()
|
|
||||||
}
|
|
||||||
} else if (ijEditor.isInsertMode && (oldEditorInfo.isInsertModeForced || !ijEditor.document.isWritable)) {
|
} else if (ijEditor.isInsertMode && (oldEditorInfo.isInsertModeForced || !ijEditor.document.isWritable)) {
|
||||||
val context: ExecutionContext = injector.executionContextManager.getEditorExecutionContext(editor)
|
val context: ExecutionContext = injector.executionContextManager.getEditorExecutionContext(editor)
|
||||||
val mode = injector.vimState.mode
|
val mode = injector.vimState.mode
|
||||||
@ -87,4 +87,12 @@ class IJEditorFocusListener : EditorListener {
|
|||||||
}
|
}
|
||||||
KeyHandler.getInstance().reset(editor)
|
KeyHandler.getInstance().reset(editor)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// By "terminal" we refer to some editor that should switch to INSERT mode on focus
|
||||||
|
private fun isTerminal(ijEditor: Editor): Boolean {
|
||||||
|
return !ijEditor.isViewer &&
|
||||||
|
!EditorHelper.isFileEditor(ijEditor) &&
|
||||||
|
ijEditor.document.isWritable &&
|
||||||
|
ijEditor.editorKind != EditorKind.DIFF
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,6 @@ import com.intellij.codeInsight.template.impl.TemplateManagerImpl
|
|||||||
import com.intellij.codeInsight.template.impl.TemplateState
|
import com.intellij.codeInsight.template.impl.TemplateState
|
||||||
import com.intellij.codeInsight.template.impl.actions.NextVariableAction
|
import com.intellij.codeInsight.template.impl.actions.NextVariableAction
|
||||||
import com.intellij.find.FindModelListener
|
import com.intellij.find.FindModelListener
|
||||||
import com.intellij.ide.actions.ApplyIntentionAction
|
|
||||||
import com.intellij.openapi.actionSystem.ActionManager
|
import com.intellij.openapi.actionSystem.ActionManager
|
||||||
import com.intellij.openapi.actionSystem.ActionUpdateThread
|
import com.intellij.openapi.actionSystem.ActionUpdateThread
|
||||||
import com.intellij.openapi.actionSystem.AnAction
|
import com.intellij.openapi.actionSystem.AnAction
|
||||||
@ -100,14 +99,10 @@ internal object IdeaSpecifics {
|
|||||||
} else {
|
} else {
|
||||||
emptyList()
|
emptyList()
|
||||||
}
|
}
|
||||||
val intentionName = if (action is ApplyIntentionAction) {
|
|
||||||
action.name
|
|
||||||
}
|
|
||||||
else null
|
|
||||||
|
|
||||||
// We can still get empty ID and empty candidates. Notably, for the tool window toggle buttons on the new UI.
|
// We can still get empty ID and empty candidates. Notably, for the tool window toggle buttons on the new UI.
|
||||||
// We could filter out action events with `place == ActionPlaces.TOOLWINDOW_TOOLBAR_BAR`
|
// We could filter out action events with `place == ActionPlaces.TOOLWINDOW_TOOLBAR_BAR`
|
||||||
VimPlugin.getNotifications(event.dataContext.getData(CommonDataKeys.PROJECT)).notifyActionId(id, candidates, intentionName)
|
VimPlugin.getNotifications(event.dataContext.getData(CommonDataKeys.PROJECT)).notifyActionId(id, candidates)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,7 +9,6 @@
|
|||||||
package com.maddyhome.idea.vim.listener
|
package com.maddyhome.idea.vim.listener
|
||||||
|
|
||||||
import com.intellij.openapi.actionSystem.ActionManager
|
import com.intellij.openapi.actionSystem.ActionManager
|
||||||
import com.intellij.openapi.actionSystem.ActionPlaces
|
|
||||||
import com.intellij.openapi.actionSystem.AnAction
|
import com.intellij.openapi.actionSystem.AnAction
|
||||||
import com.intellij.openapi.actionSystem.AnActionEvent
|
import com.intellij.openapi.actionSystem.AnActionEvent
|
||||||
import com.intellij.openapi.actionSystem.AnActionResult
|
import com.intellij.openapi.actionSystem.AnActionResult
|
||||||
@ -17,8 +16,6 @@ import com.intellij.openapi.actionSystem.CommonDataKeys
|
|||||||
import com.intellij.openapi.actionSystem.IdeActions
|
import com.intellij.openapi.actionSystem.IdeActions
|
||||||
import com.intellij.openapi.actionSystem.ex.AnActionListener
|
import com.intellij.openapi.actionSystem.ex.AnActionListener
|
||||||
import com.intellij.openapi.editor.Editor
|
import com.intellij.openapi.editor.Editor
|
||||||
import com.intellij.openapi.editor.actionSystem.EditorAction
|
|
||||||
import com.intellij.openapi.editor.actions.EnterAction
|
|
||||||
import com.intellij.openapi.editor.event.CaretEvent
|
import com.intellij.openapi.editor.event.CaretEvent
|
||||||
import com.intellij.openapi.editor.event.CaretListener
|
import com.intellij.openapi.editor.event.CaretListener
|
||||||
import com.maddyhome.idea.vim.VimPlugin
|
import com.maddyhome.idea.vim.VimPlugin
|
||||||
@ -27,16 +24,10 @@ import com.maddyhome.idea.vim.group.visual.IdeaSelectionControl
|
|||||||
import com.maddyhome.idea.vim.group.visual.moveCaretOneCharLeftFromSelectionEnd
|
import com.maddyhome.idea.vim.group.visual.moveCaretOneCharLeftFromSelectionEnd
|
||||||
import com.maddyhome.idea.vim.helper.getTopLevelEditor
|
import com.maddyhome.idea.vim.helper.getTopLevelEditor
|
||||||
import com.maddyhome.idea.vim.helper.isIdeaVimDisabledHere
|
import com.maddyhome.idea.vim.helper.isIdeaVimDisabledHere
|
||||||
import com.maddyhome.idea.vim.newapi.vim
|
|
||||||
|
|
||||||
internal class RiderActionListener : AnActionListener {
|
internal class RiderActionListener : AnActionListener {
|
||||||
|
|
||||||
private var editor: Editor? = null
|
private var editor: Editor? = null
|
||||||
private fun shouldExecuteOnFrontend(action: EditorAction): Boolean {
|
|
||||||
val isInsertMode = editor?.vim?.insertMode
|
|
||||||
return isInsertMode == false && action is EnterAction
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun beforeActionPerformed(action: AnAction, event: AnActionEvent) {
|
override fun beforeActionPerformed(action: AnAction, event: AnActionEvent) {
|
||||||
if (VimPlugin.isNotEnabled()) return
|
if (VimPlugin.isNotEnabled()) return
|
||||||
|
|
||||||
@ -44,12 +35,6 @@ internal class RiderActionListener : AnActionListener {
|
|||||||
if (hostEditor != null) {
|
if (hostEditor != null) {
|
||||||
editor = hostEditor
|
editor = hostEditor
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fixes RIDER-123506
|
|
||||||
if (action is EditorAction) {
|
|
||||||
val key = ActionPlaces.EXECUTE_EDITOR_ACTION_ON_FRONTEND
|
|
||||||
editor?.putUserData(key, shouldExecuteOnFrontend(action))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun afterActionPerformed(action: AnAction, event: AnActionEvent, result: AnActionResult) {
|
override fun afterActionPerformed(action: AnAction, event: AnActionEvent, result: AnActionResult) {
|
||||||
|
@ -468,9 +468,7 @@ internal object VimListenerManager {
|
|||||||
openingEditor == null -> LocalOptionInitialisationScenario.EDIT
|
openingEditor == null -> LocalOptionInitialisationScenario.EDIT
|
||||||
else -> LocalOptionInitialisationScenario.NEW
|
else -> LocalOptionInitialisationScenario.NEW
|
||||||
}
|
}
|
||||||
SlowOperations.knownIssue("VIM-3648").use {
|
EditorListeners.add(event.editor, openingEditor?.vim ?: injector.fallbackWindow, scenario)
|
||||||
EditorListeners.add(event.editor, openingEditor?.vim ?: injector.fallbackWindow, scenario)
|
|
||||||
}
|
|
||||||
firstEditorInitialised = true
|
firstEditorInitialised = true
|
||||||
} else {
|
} else {
|
||||||
// We've got a virtual file, so FileOpenedSyncListener will be called. Save data
|
// We've got a virtual file, so FileOpenedSyncListener will be called. Save data
|
||||||
@ -819,7 +817,7 @@ internal object VimListenerManager {
|
|||||||
if (editor.inVisualMode) {
|
if (editor.inVisualMode) {
|
||||||
editor.vim.exitVisualMode()
|
editor.vim.exitVisualMode()
|
||||||
} else if (editor.vim.inSelectMode) {
|
} else if (editor.vim.inSelectMode) {
|
||||||
editor.vim.exitSelectMode(false)
|
editor.exitSelectMode(false)
|
||||||
KeyHandler.getInstance().reset(editor.vim)
|
KeyHandler.getInstance().reset(editor.vim)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ internal class IntellijMark(bookmark: LineBookmark, override val col: Int, proje
|
|||||||
|
|
||||||
private val project: WeakReference<Project?> = WeakReference(project)
|
private val project: WeakReference<Project?> = WeakReference(project)
|
||||||
|
|
||||||
override val key = BookmarksManager.getInstance(project)?.getType(bookmark)?.mnemonic ?: ' '
|
override val key = BookmarksManager.getInstance(project)?.getType(bookmark)?.mnemonic!!
|
||||||
override val line: Int
|
override val line: Int
|
||||||
get() = getMark()?.line ?: 0
|
get() = getMark()?.line ?: 0
|
||||||
override val filepath: String
|
override val filepath: String
|
||||||
|
@ -39,16 +39,26 @@ import java.io.IOException
|
|||||||
|
|
||||||
@Service
|
@Service
|
||||||
internal class IjClipboardManager : VimClipboardManager {
|
internal class IjClipboardManager : VimClipboardManager {
|
||||||
override fun getPrimaryContent(): IjVimCopiedText? {
|
@Deprecated("Please use com.maddyhome.idea.vim.api.VimClipboardManager#getPrimaryTextAndTransferableData")
|
||||||
|
override fun getPrimaryTextAndTransferableData(): Pair<String, List<Any>?>? {
|
||||||
val clipboard = Toolkit.getDefaultToolkit()?.systemSelection ?: return null
|
val clipboard = Toolkit.getDefaultToolkit()?.systemSelection ?: return null
|
||||||
val contents = clipboard.getContents(null) ?: return null
|
val contents = clipboard.getContents(null) ?: return null
|
||||||
val (text, transferableData) = getTextAndTransferableData(contents) ?: return null
|
return getTextAndTransferableData(contents)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getPrimaryContent(editor: VimEditor, context: ExecutionContext): IjVimCopiedText? {
|
||||||
|
val (text, transferableData) = getPrimaryTextAndTransferableData() ?: return null
|
||||||
return IjVimCopiedText(text, transferableData ?: emptyList())
|
return IjVimCopiedText(text, transferableData ?: emptyList())
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getClipboardContent(editor: VimEditor, context: ExecutionContext): VimCopiedText? {
|
@Deprecated("Please use com.maddyhome.idea.vim.api.VimClipboardManager#getClipboardTextAndTransferableData")
|
||||||
|
override fun getClipboardTextAndTransferableData(): Pair<String, List<Any>?>? {
|
||||||
val contents = getContents() ?: return null
|
val contents = getContents() ?: return null
|
||||||
val (text, transferableData) = getTextAndTransferableData(contents) ?: return null
|
return getTextAndTransferableData(contents)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getClipboardContent(editor: VimEditor, context: ExecutionContext): VimCopiedText? {
|
||||||
|
val (text, transferableData) = getClipboardTextAndTransferableData() ?: return null
|
||||||
return IjVimCopiedText(text, transferableData ?: emptyList())
|
return IjVimCopiedText(text, transferableData ?: emptyList())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,6 +125,14 @@ internal class IjClipboardManager : VimClipboardManager {
|
|||||||
// return setPrimaryText(entry.text, entry.rawText, entry.transferableData) != null
|
// return setPrimaryText(entry.text, entry.rawText, entry.transferableData) != null
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
@Deprecated("Please use com.maddyhome.idea.vim.api.VimClipboardManager#setPrimaryText")
|
||||||
|
override fun setPrimaryText(text: String, rawText: String, transferableData: List<Any>): Transferable? {
|
||||||
|
return handleTextSetting(text, rawText, transferableData) { content ->
|
||||||
|
val clipboard = Toolkit.getDefaultToolkit()?.systemSelection ?: return@handleTextSetting null
|
||||||
|
clipboard.setContents(content, EmptyClipboardOwner.INSTANCE)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun collectCopiedText(
|
override fun collectCopiedText(
|
||||||
editor: VimEditor,
|
editor: VimEditor,
|
||||||
context: ExecutionContext,
|
context: ExecutionContext,
|
||||||
@ -242,6 +260,6 @@ internal class IjClipboardManager : VimClipboardManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data class IjVimCopiedText(override val text: String, override val transferableData: List<Any>) : VimCopiedText {
|
data class IjVimCopiedText(override val text: String, val transferableData: List<Any>) : VimCopiedText {
|
||||||
override fun updateText(newText: String): VimCopiedText = IjVimCopiedText(newText, transferableData)
|
override fun updateText(newText: String): VimCopiedText = IjVimCopiedText(newText, transferableData)
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ internal class IjVimApplication : VimApplicationBase() {
|
|||||||
return ApplicationManager.getApplication().isDispatchThread
|
return ApplicationManager.getApplication().isDispatchThread
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun invokeLater(editor: VimEditor, action: () -> Unit) {
|
override fun invokeLater(action: () -> Unit, editor: VimEditor) {
|
||||||
ApplicationManager.getApplication()
|
ApplicationManager.getApplication()
|
||||||
.invokeLater(action, ModalityState.stateForComponent((editor as IjVimEditor).editor.component))
|
.invokeLater(action, ModalityState.stateForComponent((editor as IjVimEditor).editor.component))
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ import com.maddyhome.idea.vim.api.VimIndentConfig
|
|||||||
import com.maddyhome.idea.vim.api.VimScrollingModel
|
import com.maddyhome.idea.vim.api.VimScrollingModel
|
||||||
import com.maddyhome.idea.vim.api.VimSelectionModel
|
import com.maddyhome.idea.vim.api.VimSelectionModel
|
||||||
import com.maddyhome.idea.vim.api.VimVisualPosition
|
import com.maddyhome.idea.vim.api.VimVisualPosition
|
||||||
import com.maddyhome.idea.vim.api.VimVirtualFile
|
import com.maddyhome.idea.vim.api.VirtualFile
|
||||||
import com.maddyhome.idea.vim.api.injector
|
import com.maddyhome.idea.vim.api.injector
|
||||||
import com.maddyhome.idea.vim.common.IndentConfig
|
import com.maddyhome.idea.vim.common.IndentConfig
|
||||||
import com.maddyhome.idea.vim.common.LiveRange
|
import com.maddyhome.idea.vim.common.LiveRange
|
||||||
@ -301,13 +301,12 @@ internal class IjVimEditor(editor: Editor) : MutableLinearEditor, VimEditorBase(
|
|||||||
return editor.logicalPositionToOffset(logicalPosition)
|
return editor.logicalPositionToOffset(logicalPosition)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getVirtualFile(): VimVirtualFile? {
|
override fun getVirtualFile(): VirtualFile? {
|
||||||
val vf = EditorHelper.getVirtualFile(editor)
|
val vf = EditorHelper.getVirtualFile(editor)
|
||||||
return vf?.let {
|
return vf?.let {
|
||||||
object : VimVirtualFile {
|
object : VirtualFile {
|
||||||
override val path: String = vf.path
|
override val path: String = vf.path
|
||||||
override val protocol: String = vf.fileSystem.protocol
|
override val protocol: String = vf.fileSystem.protocol
|
||||||
override val extension: String? = vf.extension
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -213,6 +213,16 @@ internal class IjVimInjector : VimInjectorBase() {
|
|||||||
override val redrawService: VimRedrawService
|
override val redrawService: VimRedrawService
|
||||||
get() = service()
|
get() = service()
|
||||||
|
|
||||||
|
@Deprecated("Please use VimInjector.vimState", replaceWith = ReplaceWith("vimState"))
|
||||||
|
override fun commandStateFor(editor: VimEditor): VimStateMachine {
|
||||||
|
return vimState
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated("Please use VimInjector.vimState", replaceWith = ReplaceWith("vimState"))
|
||||||
|
override fun commandStateFor(editor: Any): VimStateMachine {
|
||||||
|
return vimState
|
||||||
|
}
|
||||||
|
|
||||||
override val engineEditorHelper: EngineEditorHelper
|
override val engineEditorHelper: EngineEditorHelper
|
||||||
get() = service<IjEditorHelper>()
|
get() = service<IjEditorHelper>()
|
||||||
override val editorGroup: VimEditorGroup
|
override val editorGroup: VimEditorGroup
|
||||||
|
@ -1,99 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.troubleshooting
|
|
||||||
|
|
||||||
import com.intellij.openapi.fileEditor.FileEditor
|
|
||||||
import com.intellij.openapi.project.DumbAware
|
|
||||||
import com.intellij.openapi.project.Project
|
|
||||||
import com.intellij.openapi.vfs.VirtualFile
|
|
||||||
import com.intellij.ui.EditorNotificationPanel
|
|
||||||
import com.intellij.ui.EditorNotificationProvider
|
|
||||||
import com.intellij.ui.EditorNotifications
|
|
||||||
import com.intellij.util.PlatformUtils
|
|
||||||
import com.maddyhome.idea.vim.KeyHandler
|
|
||||||
import com.maddyhome.idea.vim.VimPlugin
|
|
||||||
import com.maddyhome.idea.vim.api.injector
|
|
||||||
import com.maddyhome.idea.vim.icons.VimIcons
|
|
||||||
import com.maddyhome.idea.vim.vimscript.services.VimRcService
|
|
||||||
import java.util.function.Function
|
|
||||||
import javax.swing.JComponent
|
|
||||||
|
|
||||||
private var warningExplicitlyDisabled = false
|
|
||||||
|
|
||||||
private object CommandsCounter {
|
|
||||||
var commandsBeforeAutoDisable = 10
|
|
||||||
var initialized = false
|
|
||||||
|
|
||||||
@Synchronized
|
|
||||||
fun init() {
|
|
||||||
if (initialized) return
|
|
||||||
initialized = true
|
|
||||||
KeyHandler.getInstance().addCommandListener {
|
|
||||||
commandsBeforeAutoDisable -= 1
|
|
||||||
if (commandsBeforeAutoDisable <= 0) {
|
|
||||||
warningExplicitlyDisabled = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Warning for the new users who may install IdeaVim plugin accidentally.
|
|
||||||
*/
|
|
||||||
internal class AccidentalInstallDetectorEditorNotificationProvider : EditorNotificationProvider, DumbAware {
|
|
||||||
override fun collectNotificationData(
|
|
||||||
project: Project,
|
|
||||||
file: VirtualFile,
|
|
||||||
): Function<in FileEditor, out JComponent?>? {
|
|
||||||
|
|
||||||
CommandsCounter.init()
|
|
||||||
|
|
||||||
// Note: Currently, enable this only for GoLand as it was a request from this IDE (VIM-3784).
|
|
||||||
// However, we can enable it for other IDEs if needed.
|
|
||||||
if (!PlatformUtils.isGoIde()) return null
|
|
||||||
|
|
||||||
if (warningExplicitlyDisabled) return null
|
|
||||||
if (VimPlugin.isNotEnabled()) return null
|
|
||||||
if (VimRcService.findIdeaVimRc() != null) return null
|
|
||||||
if (!injector.enabler.isNewIdeaVimUser()) return null
|
|
||||||
|
|
||||||
return Function { fileEditor: FileEditor ->
|
|
||||||
val panel = EditorNotificationPanel(fileEditor, EditorNotificationPanel.Status.Info)
|
|
||||||
panel.text = getText()
|
|
||||||
panel.icon(VimIcons.IDEAVIM)
|
|
||||||
|
|
||||||
KeyHandler.getInstance().addCommandListener {
|
|
||||||
if (CommandsCounter.commandsBeforeAutoDisable <= 0) {
|
|
||||||
KeyHandler.getInstance().removeAllCommandListeners()
|
|
||||||
EditorNotifications.getInstance(project).removeNotificationsForProvider(this)
|
|
||||||
}
|
|
||||||
panel.text = getText()
|
|
||||||
panel.invalidate()
|
|
||||||
panel.repaint()
|
|
||||||
}
|
|
||||||
|
|
||||||
@Suppress("DialogTitleCapitalization")
|
|
||||||
panel.createActionLabel("Disable IdeaVim") {
|
|
||||||
VimPlugin.setEnabled(false)
|
|
||||||
VimPlugin.getNotifications(project).showReenableNotification(project)
|
|
||||||
EditorNotifications.getInstance(project).removeNotificationsForProvider(this)
|
|
||||||
warningExplicitlyDisabled = true
|
|
||||||
}
|
|
||||||
panel.createActionLabel("Dismiss") {
|
|
||||||
EditorNotifications.getInstance(project).removeNotificationsForProvider(this)
|
|
||||||
warningExplicitlyDisabled = true
|
|
||||||
}
|
|
||||||
panel
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getText(): String {
|
|
||||||
return "<html>You’re using the IdeaVim plugin. If you’re not familiar with Vim, consider disabling it. This message will disappear after ${CommandsCounter.commandsBeforeAutoDisable} commands.</html>"
|
|
||||||
}
|
|
||||||
}
|
|
@ -428,6 +428,14 @@ public class ExEntryPanel extends JPanel implements VimCommandLine {
|
|||||||
return active;
|
return active;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Use getVisibleText()
|
||||||
|
*/
|
||||||
|
@Deprecated(forRemoval = true)
|
||||||
|
public @NotNull String getText() {
|
||||||
|
return entry.getText();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NotNull String getVisibleText() {
|
public @NotNull String getVisibleText() {
|
||||||
return entry.getText();
|
return entry.getText();
|
||||||
|
@ -132,9 +132,6 @@
|
|||||||
key="ideavim.only.in.editor.component"/>
|
key="ideavim.only.in.editor.component"/>
|
||||||
<registryKey defaultValue="false" description="Old action execution mechanism" key="ideavim.old.action.execution"
|
<registryKey defaultValue="false" description="Old action execution mechanism" key="ideavim.old.action.execution"
|
||||||
restartRequired="false"/>
|
restartRequired="false"/>
|
||||||
|
|
||||||
<editorNotificationProvider
|
|
||||||
implementation="com.maddyhome.idea.vim.troubleshooting.AccidentalInstallDetectorEditorNotificationProvider"/>
|
|
||||||
</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/*)"/>
|
||||||
|
@ -85,23 +85,11 @@ E545=E545: Missing colon: {0}
|
|||||||
E546=E546: Illegal mode: {0}
|
E546=E546: Illegal mode: {0}
|
||||||
E548=E548: Digit expected: {0}
|
E548=E548: Digit expected: {0}
|
||||||
E549=E549: Illegal percentage: {0}
|
E549=E549: Illegal percentage: {0}
|
||||||
E691=E691: Can only compare List with List
|
|
||||||
E692=E692: Invalid operation for List
|
|
||||||
E694=E694: Invalid operation for Funcrefs
|
|
||||||
E695=E695: Cannot index a Funcref
|
|
||||||
E701=E701: Invalid type for len()
|
E701=E701: Invalid type for len()
|
||||||
E703=E703: Using a Funcref as a Number
|
|
||||||
E728=E728: Using a Dictionary as a Number
|
|
||||||
E729=E729: Using a Funcref as a String
|
|
||||||
E730=E730: Using a List as a String
|
E730=E730: Using a List as a String
|
||||||
E731=E731: Using a Dictionary as a String
|
E731=E731: Using a Dictionary as a String
|
||||||
E735=E735: Can only compare Dictionary with Dictionary
|
|
||||||
E736=E736: Invalid operation for Dictionary
|
|
||||||
E745=E745: Using a List as a Number
|
|
||||||
E774=E774: 'operatorfunc' is empty
|
E774=E774: 'operatorfunc' is empty
|
||||||
E804=E804: Cannot use '%' with Float
|
|
||||||
E805=E805: Using a Float as a Number
|
E805=E805: Using a Float as a Number
|
||||||
E806=E806: Using a Float as a String
|
|
||||||
E808=E808: Number or Float required
|
E808=E808: Number or Float required
|
||||||
e841.reserved.name.cannot.be.used.for.user.defined.command=E841: Reserved name, cannot be used for user defined command
|
e841.reserved.name.cannot.be.used.for.user.defined.command=E841: Reserved name, cannot be used for user defined command
|
||||||
E939=E939: Positive count required
|
E939=E939: Positive count required
|
||||||
|
@ -1,108 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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 org.jetbrains.plugins.ideavim.action
|
|
||||||
|
|
||||||
import com.maddyhome.idea.vim.api.injector
|
|
||||||
import org.jetbrains.plugins.ideavim.VimTestCase
|
|
||||||
import org.junit.jupiter.api.Disabled
|
|
||||||
import org.junit.jupiter.api.Test
|
|
||||||
|
|
||||||
class ChangeCaseTest : VimTestCase() {
|
|
||||||
/**
|
|
||||||
* Note: The tests for duplicated commands (gugu and gUgU) might fail due to issues with the test environment,
|
|
||||||
* specifically related to file refresh operations. This is a known issue with the test infrastructure
|
|
||||||
* and not with the actual functionality being tested.
|
|
||||||
*
|
|
||||||
* The tests for guu and gUU test the same functionality and should pass.
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
fun testChangeCaseLowerLineAction() {
|
|
||||||
typeTextInFile(
|
|
||||||
injector.parser.parseKeys("guu"),
|
|
||||||
"""
|
|
||||||
H${c}ELLO WORLD
|
|
||||||
${c}THIS IS A TEST
|
|
||||||
${c}FOR CASE CONVERSION
|
|
||||||
|
|
||||||
""".trimIndent(),
|
|
||||||
)
|
|
||||||
assertState(
|
|
||||||
"""
|
|
||||||
${c}hello world
|
|
||||||
${c}this is a test
|
|
||||||
${c}for case conversion
|
|
||||||
|
|
||||||
""".trimIndent()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Disabled("Not yet supported")
|
|
||||||
@Test
|
|
||||||
fun testChangeCaseLowerLineActionDuplicated() {
|
|
||||||
typeTextInFile(
|
|
||||||
injector.parser.parseKeys("gugu"),
|
|
||||||
"""
|
|
||||||
H${c}ELLO WORLD
|
|
||||||
${c}THIS IS A TEST
|
|
||||||
${c}FOR CASE CONVERSION
|
|
||||||
|
|
||||||
""".trimIndent(),
|
|
||||||
)
|
|
||||||
assertState(
|
|
||||||
"""
|
|
||||||
${c}hello world
|
|
||||||
${c}this is a test
|
|
||||||
${c}for case conversion
|
|
||||||
|
|
||||||
""".trimIndent()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun testChangeCaseUpperLineAction() {
|
|
||||||
typeTextInFile(
|
|
||||||
injector.parser.parseKeys("gUU"),
|
|
||||||
"""
|
|
||||||
h${c}ello world
|
|
||||||
${c}this is a test
|
|
||||||
${c}for case conversion
|
|
||||||
|
|
||||||
""".trimIndent(),
|
|
||||||
)
|
|
||||||
assertState(
|
|
||||||
"""
|
|
||||||
${c}HELLO WORLD
|
|
||||||
${c}THIS IS A TEST
|
|
||||||
${c}FOR CASE CONVERSION
|
|
||||||
|
|
||||||
""".trimIndent()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Disabled("Not yet supported")
|
|
||||||
@Test
|
|
||||||
fun testChangeCaseUpperLineActionDuplicated() {
|
|
||||||
typeTextInFile(
|
|
||||||
injector.parser.parseKeys("gUgU"),
|
|
||||||
"""
|
|
||||||
h${c}ello world
|
|
||||||
${c}this is a test
|
|
||||||
${c}for case conversion
|
|
||||||
|
|
||||||
""".trimIndent(),
|
|
||||||
)
|
|
||||||
assertState(
|
|
||||||
"""
|
|
||||||
${c}HELLO WORLD
|
|
||||||
${c}THIS IS A TEST
|
|
||||||
${c}FOR CASE CONVERSION
|
|
||||||
|
|
||||||
""".trimIndent()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,102 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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 org.jetbrains.plugins.ideavim.action
|
|
||||||
|
|
||||||
import com.maddyhome.idea.vim.api.injector
|
|
||||||
import org.jetbrains.plugins.ideavim.VimTestCase
|
|
||||||
import org.junit.jupiter.api.Disabled
|
|
||||||
import org.junit.jupiter.api.Test
|
|
||||||
|
|
||||||
class ChangeRot13Test : VimTestCase() {
|
|
||||||
@Test
|
|
||||||
fun testChangeRot13MotionAction() {
|
|
||||||
typeTextInFile(
|
|
||||||
injector.parser.parseKeys("g?2w"),
|
|
||||||
"H${c}ello World ${c}This is a ${c}test for ROT13 ${c}encoding\n",
|
|
||||||
)
|
|
||||||
assertState("H${c}ryyb Jbeyq ${c}Guvf vf a ${c}grfg sbe ROT13 ${c}rapbqvat\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun testChangeRot13VisualAction() {
|
|
||||||
typeTextInFile(
|
|
||||||
injector.parser.parseKeys("v2wg?"),
|
|
||||||
"H${c}ello World ${c}This is a ${c}test for ROT13 ${c}encoding\n",
|
|
||||||
)
|
|
||||||
assertState("H${c}ryyb Jbeyq Guvf vf n ${c}grfg sbe EOT13 ${c}rapbqvat\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun testChangeRot13LineAction() {
|
|
||||||
typeTextInFile(
|
|
||||||
injector.parser.parseKeys("g??"),
|
|
||||||
"""
|
|
||||||
H${c}ello World
|
|
||||||
${c}This is a test
|
|
||||||
${c}for ROT13 encoding
|
|
||||||
|
|
||||||
""".trimIndent(),
|
|
||||||
)
|
|
||||||
assertState(
|
|
||||||
"""
|
|
||||||
${c}Uryyb Jbeyq
|
|
||||||
${c}Guvf vf n grfg
|
|
||||||
${c}sbe EBG13 rapbqvat
|
|
||||||
|
|
||||||
""".trimIndent()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Disabled("Not yet supported")
|
|
||||||
@Test
|
|
||||||
fun testChangeRot13LineActionDuplicated() {
|
|
||||||
typeTextInFile(
|
|
||||||
injector.parser.parseKeys("g?g?"),
|
|
||||||
"""
|
|
||||||
H${c}ello World
|
|
||||||
${c}This is a test
|
|
||||||
${c}for ROT13 encoding
|
|
||||||
|
|
||||||
""".trimIndent(),
|
|
||||||
)
|
|
||||||
assertState(
|
|
||||||
"""
|
|
||||||
${c}Uryyb Jbeyq
|
|
||||||
${c}Guvf vf n grfg
|
|
||||||
${c}sbe EBG13 rapbqvat
|
|
||||||
|
|
||||||
""".trimIndent()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@Test
|
|
||||||
fun testChangeRot13NonEnglishLetters() {
|
|
||||||
typeTextInFile(
|
|
||||||
injector.parser.parseKeys("g?$"),
|
|
||||||
"${c}Привет мир! Hello world!\n",
|
|
||||||
)
|
|
||||||
assertState("${c}Привет мир! Uryyb jbeyq!\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun testChangeRot13FullAlphabet() {
|
|
||||||
typeTextInFile(
|
|
||||||
injector.parser.parseKeys("g?$"),
|
|
||||||
"${c}abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\n",
|
|
||||||
)
|
|
||||||
assertState("${c}nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun testChangeRot13Symbols() {
|
|
||||||
typeTextInFile(
|
|
||||||
injector.parser.parseKeys("g?$"),
|
|
||||||
"${c}!@#$%^&*()_+-=[]{}|;:'\",.<>/?\n",
|
|
||||||
)
|
|
||||||
assertState("${c}!@#$%^&*()_+-=[]{}|;:'\",.<>/?\n")
|
|
||||||
}
|
|
||||||
}
|
|
@ -9,6 +9,7 @@
|
|||||||
package org.jetbrains.plugins.ideavim.action.copy
|
package org.jetbrains.plugins.ideavim.action.copy
|
||||||
|
|
||||||
import com.intellij.notification.ActionCenter
|
import com.intellij.notification.ActionCenter
|
||||||
|
import com.intellij.notification.EventLog
|
||||||
import com.intellij.notification.Notification
|
import com.intellij.notification.Notification
|
||||||
import com.intellij.openapi.application.ApplicationManager
|
import com.intellij.openapi.application.ApplicationManager
|
||||||
import com.maddyhome.idea.vim.VimPlugin
|
import com.maddyhome.idea.vim.VimPlugin
|
||||||
@ -104,7 +105,7 @@ class IdeaPutNotificationsTest : VimTestCase() {
|
|||||||
}
|
}
|
||||||
typeText(injector.parser.parseKeys("p"))
|
typeText(injector.parser.parseKeys("p"))
|
||||||
|
|
||||||
val notifications = ActionCenter.getNotifications(fixture.project)
|
val notifications = EventLog.getLogModel(fixture.project).notifications
|
||||||
kotlin.test.assertTrue(notifications.isEmpty() || notifications.last().isExpired || OptionConstants.clipboard_ideaput !in notifications.last().content)
|
kotlin.test.assertTrue(notifications.isEmpty() || notifications.last().isExpired || OptionConstants.clipboard_ideaput !in notifications.last().content)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,12 +77,4 @@ class AsciiCommandTest : VimTestCase() {
|
|||||||
enterCommand("ascii")
|
enterCommand("ascii")
|
||||||
assertEquals("<⓪> 9450, Hex 24ea, Oct 22352, Digr (0", VimPlugin.getMessage())
|
assertEquals("<⓪> 9450, Hex 24ea, Oct 22352, Digr (0", VimPlugin.getMessage())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `test shows custom digraph with 32-bit Unicode codepoint`() {
|
|
||||||
configureByText("🔴")
|
|
||||||
enterCommand("digraph cr 128308")
|
|
||||||
enterCommand("ascii")
|
|
||||||
assertEquals("<🔴> 128308, Hex 1f534, Oct 372464, Digr cr", VimPlugin.getMessage())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -33,26 +33,20 @@ class DigraphsCommandTest : VimTestCase() {
|
|||||||
@Test
|
@Test
|
||||||
fun `test add custom digraph`() {
|
fun `test add custom digraph`() {
|
||||||
enterCommand("digraph (0 9450")
|
enterCommand("digraph (0 9450")
|
||||||
assertEquals('⓪', injector.digraphGroup.getCharacterForDigraph('(', '0').toChar())
|
assertEquals('⓪', injector.digraphGroup.getCharacterForDigraph('(', '0'))
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `test add custom 32-bit digraph`() {
|
|
||||||
enterCommand("digraph cr 128308")
|
|
||||||
assertEquals("🔴", String(Character.toChars(injector.digraphGroup.getCharacterForDigraph('c', 'r'))))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `test add custom digraph matches reversed characters`() {
|
fun `test add custom digraph matches reversed characters`() {
|
||||||
enterCommand("digraph (0 9450")
|
enterCommand("digraph (0 9450")
|
||||||
assertEquals('⓪', injector.digraphGroup.getCharacterForDigraph('0', '(').toChar())
|
assertEquals('⓪', injector.digraphGroup.getCharacterForDigraph('0', '('))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `test add multiple custom digraphs`() {
|
fun `test add multiple custom digraphs`() {
|
||||||
enterCommand("digraph (0 9450 (1 9312")
|
enterCommand("digraph (0 9450 (1 9312")
|
||||||
assertEquals('⓪', injector.digraphGroup.getCharacterForDigraph('(', '0').toChar())
|
assertEquals('⓪', injector.digraphGroup.getCharacterForDigraph('(', '0'))
|
||||||
assertEquals('①', injector.digraphGroup.getCharacterForDigraph('(', '1').toChar())
|
assertEquals('①', injector.digraphGroup.getCharacterForDigraph('(', '1'))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -86,14 +80,14 @@ class DigraphsCommandTest : VimTestCase() {
|
|||||||
@Test
|
@Test
|
||||||
fun `test add custom digraph with more than two characters add custom digraph with initial two characters`() {
|
fun `test add custom digraph with more than two characters add custom digraph with initial two characters`() {
|
||||||
enterCommand("digraph aaaa 9450")
|
enterCommand("digraph aaaa 9450")
|
||||||
assertEquals('⓪', injector.digraphGroup.getCharacterForDigraph('a', 'a').toChar())
|
assertEquals('⓪', injector.digraphGroup.getCharacterForDigraph('a', 'a'))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `test add custom digraphs until error`() {
|
fun `test add custom digraphs until error`() {
|
||||||
enterCommand("digraph (0 9450 (1 9312 (2")
|
enterCommand("digraph (0 9450 (1 9312 (2")
|
||||||
assertEquals('⓪', injector.digraphGroup.getCharacterForDigraph('(', '0').toChar())
|
assertEquals('⓪', injector.digraphGroup.getCharacterForDigraph('(', '0'))
|
||||||
assertEquals('①', injector.digraphGroup.getCharacterForDigraph('(', '1').toChar())
|
assertEquals('①', injector.digraphGroup.getCharacterForDigraph('(', '1'))
|
||||||
assertPluginError(true)
|
assertPluginError(true)
|
||||||
assertPluginErrorMessageContains("E39: Number expected")
|
assertPluginErrorMessageContains("E39: Number expected")
|
||||||
}
|
}
|
||||||
@ -101,15 +95,15 @@ class DigraphsCommandTest : VimTestCase() {
|
|||||||
@Test
|
@Test
|
||||||
fun `test custom digraph overwrites existing custom digraph`() {
|
fun `test custom digraph overwrites existing custom digraph`() {
|
||||||
enterCommand("digraph (0 9450")
|
enterCommand("digraph (0 9450")
|
||||||
assertEquals('⓪', injector.digraphGroup.getCharacterForDigraph('(', '0').toChar())
|
assertEquals('⓪', injector.digraphGroup.getCharacterForDigraph('(', '0'))
|
||||||
enterCommand("digraph (0 10003")
|
enterCommand("digraph (0 10003")
|
||||||
assertEquals('✓', injector.digraphGroup.getCharacterForDigraph('(', '0').toChar())
|
assertEquals('✓', injector.digraphGroup.getCharacterForDigraph('(', '0'))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `test custom digraph overwrites existing default digraph`() {
|
fun `test custom digraph overwrites existing default digraph`() {
|
||||||
enterCommand("digraph OK 9450")
|
enterCommand("digraph OK 9450")
|
||||||
assertEquals('⓪', injector.digraphGroup.getCharacterForDigraph('O', 'K').toChar())
|
assertEquals('⓪', injector.digraphGroup.getCharacterForDigraph('O', 'K'))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -871,244 +865,6 @@ class DigraphsCommandTest : VimTestCase() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `test digraph output with 32-bit custom digraphs`() {
|
|
||||||
enterCommand("digraph cr 128308") // 🔴
|
|
||||||
assertCommandOutput(
|
|
||||||
"digraphs",
|
|
||||||
"""
|
|
||||||
|NU ^@ 10 SH ^A 1 SX ^B 2 EX ^C 3 ET ^D 4 EQ ^E 5
|
|
||||||
|AK ^F 6 BL ^G 7 BS ^H 8 HT ^I 9 LF ^J 10 VT ^K 11
|
|
||||||
|FF ^L 12 CR ^M 13 SO ^N 14 SI ^O 15 DL ^P 16 D1 ^Q 17
|
|
||||||
|D2 ^R 18 D3 ^S 19 D4 ^T 20 NK ^U 21 SY ^V 22 EB ^W 23
|
|
||||||
|CN ^X 24 EM ^Y 25 SB ^Z 26 EC ^[ 27 FS ^\ 28 GS ^] 29
|
|
||||||
|RS ^^ 30 US ^_ 31 SP 32 Nb # 35 DO $ 36 At @ 64
|
|
||||||
|<( [ 91 // \ 92 )> ] 93 '> ^ 94 '! ` 96 (! { 123
|
|
||||||
|!! | 124 !) } 125 '? ~ 126 DT ^? 127 PA <80> 128 HO <81> 129
|
|
||||||
|BH <82> 130 NH <83> 131 IN <84> 132 NL <85> 133 SA <86> 134 ES <87> 135
|
|
||||||
|HS <88> 136 HJ <89> 137 VS <8a> 138 PD <8b> 139 PU <8c> 140 RI <8d> 141
|
|
||||||
|S2 <8e> 142 S3 <8f> 143 DC <90> 144 P1 <91> 145 P2 <92> 146 TS <93> 147
|
|
||||||
|CC <94> 148 MW <95> 149 SG <96> 150 EG <97> 151 SS <98> 152 GC <99> 153
|
|
||||||
|SC <9a> 154 CI <9b> 155 ST <9c> 156 OC <9d> 157 PM <9e> 158 AC <9f> 159
|
|
||||||
|NS 160 !I ¡ 161 ~! ¡ 161 Ct ¢ 162 c| ¢ 162 Pd £ 163
|
|
||||||
|$$ £ 163 Cu ¤ 164 ox ¤ 164 Ye ¥ 165 Y- ¥ 165 BB ¦ 166
|
|
||||||
||| ¦ 166 SE § 167 ': ¨ 168 Co © 169 cO © 169 -a ª 170
|
|
||||||
|<< « 171 NO ¬ 172 -, ¬ 172 -- <ad> 173 Rg ® 174 'm ¯ 175
|
|
||||||
|-= ¯ 175 DG ° 176 ~o ° 176 +- ± 177 2S ² 178 22 ² 178
|
|
||||||
|3S ³ 179 33 ³ 179 '' ´ 180 My µ 181 PI ¶ 182 pp ¶ 182
|
|
||||||
|.M · 183 ~. · 183 ', ¸ 184 1S ¹ 185 11 ¹ 185 -o º 186
|
|
||||||
|>> » 187 14 ¼ 188 12 ½ 189 34 ¾ 190 ?I ¿ 191 ~? ¿ 191
|
|
||||||
|A! À 192 A` À 192 A' Á 193 A> Â 194 A^ Â 194 A? Ã 195
|
|
||||||
|A~ Ã 195 A: Ä 196 A" Ä 196 AA Å 197 A@ Å 197 AE Æ 198
|
|
||||||
|C, Ç 199 E! È 200 E` È 200 E' É 201 E> Ê 202 E^ Ê 202
|
|
||||||
|E: Ë 203 E" Ë 203 I! Ì 204 I` Ì 204 I' Í 205 I> Î 206
|
|
||||||
|I^ Î 206 I: Ï 207 I" Ï 207 D- Ð 208 N? Ñ 209 N~ Ñ 209
|
|
||||||
|O! Ò 210 O` Ò 210 O' Ó 211 O> Ô 212 O^ Ô 212 O? Õ 213
|
|
||||||
|O~ Õ 213 O: Ö 214 *X × 215 /\ × 215 O/ Ø 216 U! Ù 217
|
|
||||||
|U` Ù 217 U' Ú 218 U> Û 219 U^ Û 219 U: Ü 220 Y' Ý 221
|
|
||||||
|TH Þ 222 Ip Þ 222 ss ß 223 a! à 224 a` à 224 a' á 225
|
|
||||||
|a> â 226 a^ â 226 a? ã 227 a~ ã 227 a: ä 228 a" ä 228
|
|
||||||
|aa å 229 a@ å 229 ae æ 230 c, ç 231 e! è 232 e` è 232
|
|
||||||
|e' é 233 e> ê 234 e^ ê 234 e: ë 235 e" ë 235 i! ì 236
|
|
||||||
|i` ì 236 i' í 237 i> î 238 i^ î 238 i: ï 239 d- ð 240
|
|
||||||
|n? ñ 241 n~ ñ 241 o! ò 242 o` ò 242 o' ó 243 o> ô 244
|
|
||||||
|o^ ô 244 o? õ 245 o~ õ 245 o: ö 246 -: ÷ 247 o/ ø 248
|
|
||||||
|u! ù 249 u` ù 249 u' ú 250 u> û 251 u^ û 251 u: ü 252
|
|
||||||
|y' ý 253 th þ 254 y: ÿ 255 y" ÿ 255 A- Ā 256 a- ā 257
|
|
||||||
|A( Ă 258 a( ă 259 A; Ą 260 a; ą 261 C' Ć 262 c' ć 263
|
|
||||||
|C> Ĉ 264 c> ĉ 265 C. Ċ 266 c. ċ 267 C< Č 268 c< č 269
|
|
||||||
|D< Ď 270 d< ď 271 D/ Đ 272 d/ đ 273 E- Ē 274 e- ē 275
|
|
||||||
|E( Ĕ 276 e( ĕ 277 E. Ė 278 e. ė 279 E; Ę 280 e; ę 281
|
|
||||||
|E< Ě 282 e< ě 283 G> Ĝ 284 g> ĝ 285 G( Ğ 286 g( ğ 287
|
|
||||||
|G. Ġ 288 g. ġ 289 G, Ģ 290 g, ģ 291 H> Ĥ 292 h> ĥ 293
|
|
||||||
|H/ Ħ 294 h/ ħ 295 I? Ĩ 296 i? ĩ 297 I- Ī 298 i- ī 299
|
|
||||||
|I( Ĭ 300 i( ĭ 301 I; Į 302 i; į 303 I. İ 304 i. ı 305
|
|
||||||
|IJ IJ 306 ij ij 307 J> Ĵ 308 j> ĵ 309 K, Ķ 310 k, ķ 311
|
|
||||||
|kk ĸ 312 L' Ĺ 313 l' ĺ 314 L, Ļ 315 l, ļ 316 L< Ľ 317
|
|
||||||
|l< ľ 318 L. Ŀ 319 l. ŀ 320 L/ Ł 321 l/ ł 322 N' Ń 323
|
|
||||||
|n' ń 324 N, Ņ 325 n, ņ 326 N< Ň 327 n< ň 328 'n ʼn 329
|
|
||||||
|NG Ŋ 330 ng ŋ 331 O- Ō 332 o- ō 333 O( Ŏ 334 o( ŏ 335
|
|
||||||
|O" Ő 336 o" ő 337 OE Œ 338 oe œ 339 R' Ŕ 340 r' ŕ 341
|
|
||||||
|R, Ŗ 342 r, ŗ 343 R< Ř 344 r< ř 345 S' Ś 346 s' ś 347
|
|
||||||
|S> Ŝ 348 s> ŝ 349 S, Ş 350 s, ş 351 S< Š 352 s< š 353
|
|
||||||
|T, Ţ 354 t, ţ 355 T< Ť 356 t< ť 357 T/ Ŧ 358 t/ ŧ 359
|
|
||||||
|U? Ũ 360 u? ũ 361 U- Ū 362 u- ū 363 U( Ŭ 364 u( ŭ 365
|
|
||||||
|U0 Ů 366 u0 ů 367 U" Ű 368 u" ű 369 U; Ų 370 u; ų 371
|
|
||||||
|W> Ŵ 372 w> ŵ 373 Y> Ŷ 374 y> ŷ 375 Y: Ÿ 376 Z' Ź 377
|
|
||||||
|z' ź 378 Z. Ż 379 z. ż 380 Z< Ž 381 z< ž 382 O9 Ơ 416
|
|
||||||
|o9 ơ 417 OI Ƣ 418 oi ƣ 419 yr Ʀ 422 U9 Ư 431 u9 ư 432
|
|
||||||
|Z/ Ƶ 437 z/ ƶ 438 ED Ʒ 439 A< Ǎ 461 a< ǎ 462 I< Ǐ 463
|
|
||||||
|i< ǐ 464 O< Ǒ 465 o< ǒ 466 U< Ǔ 467 u< ǔ 468 A1 Ǟ 478
|
|
||||||
|a1 ǟ 479 A7 Ǡ 480 a7 ǡ 481 A3 Ǣ 482 a3 ǣ 483 G/ Ǥ 484
|
|
||||||
|g/ ǥ 485 G< Ǧ 486 g< ǧ 487 K< Ǩ 488 k< ǩ 489 O; Ǫ 490
|
|
||||||
|o; ǫ 491 O1 Ǭ 492 o1 ǭ 493 EZ Ǯ 494 ez ǯ 495 j< ǰ 496
|
|
||||||
|G' Ǵ 500 g' ǵ 501 ;S ʿ 703 '< ˇ 711 '( ˘ 728 '. ˙ 729
|
|
||||||
|'0 ˚ 730 '; ˛ 731 '" ˝ 733 A% Ά 902 E% Έ 904 Y% Ή 905
|
|
||||||
|I% Ί 906 O% Ό 908 U% Ύ 910 W% Ώ 911 i3 ΐ 912 A* Α 913
|
|
||||||
|B* Β 914 G* Γ 915 D* Δ 916 E* Ε 917 Z* Ζ 918 Y* Η 919
|
|
||||||
|H* Θ 920 I* Ι 921 K* Κ 922 L* Λ 923 M* Μ 924 N* Ν 925
|
|
||||||
|C* Ξ 926 O* Ο 927 P* Π 928 R* Ρ 929 S* Σ 931 T* Τ 932
|
|
||||||
|U* Υ 933 F* Φ 934 X* Χ 935 Q* Ψ 936 W* Ω 937 J* Ϊ 938
|
|
||||||
|V* Ϋ 939 a% ά 940 e% έ 941 y% ή 942 i% ί 943 u3 ΰ 944
|
|
||||||
|a* α 945 b* β 946 g* γ 947 d* δ 948 e* ε 949 z* ζ 950
|
|
||||||
|y* η 951 h* θ 952 i* ι 953 k* κ 954 l* λ 955 m* μ 956
|
|
||||||
|n* ν 957 c* ξ 958 o* ο 959 p* π 960 r* ρ 961 *s ς 962
|
|
||||||
|s* σ 963 t* τ 964 u* υ 965 f* φ 966 x* χ 967 q* ψ 968
|
|
||||||
|w* ω 969 j* ϊ 970 v* ϋ 971 o% ό 972 u% ύ 973 w% ώ 974
|
|
||||||
|'G Ϙ 984 ,G ϙ 985 T3 Ϛ 986 t3 ϛ 987 M3 Ϝ 988 m3 ϝ 989
|
|
||||||
|K3 Ϟ 990 k3 ϟ 991 P3 Ϡ 992 p3 ϡ 993 '% ϴ 1012 j3 ϵ 1013
|
|
||||||
|IO Ё 1025 D% Ђ 1026 G% Ѓ 1027 IE Є 1028 DS Ѕ 1029 II І 1030
|
|
||||||
|YI Ї 1031 J% Ј 1032 LJ Љ 1033 NJ Њ 1034 Ts Ћ 1035 KJ Ќ 1036
|
|
||||||
|V% Ў 1038 DZ Џ 1039 A= А 1040 B= Б 1041 V= В 1042 G= Г 1043
|
|
||||||
|D= Д 1044 E= Е 1045 Z% Ж 1046 Z= З 1047 I= И 1048 J= Й 1049
|
|
||||||
|K= К 1050 L= Л 1051 M= М 1052 N= Н 1053 O= О 1054 P= П 1055
|
|
||||||
|R= Р 1056 S= С 1057 T= Т 1058 U= У 1059 F= Ф 1060 H= Х 1061
|
|
||||||
|C= Ц 1062 C% Ч 1063 S% Ш 1064 Sc Щ 1065 =" Ъ 1066 Y= Ы 1067
|
|
||||||
|%" Ь 1068 JE Э 1069 JU Ю 1070 JA Я 1071 a= а 1072 b= б 1073
|
|
||||||
|v= в 1074 g= г 1075 d= д 1076 e= е 1077 z% ж 1078 z= з 1079
|
|
||||||
|i= и 1080 j= й 1081 k= к 1082 l= л 1083 m= м 1084 n= н 1085
|
|
||||||
|o= о 1086 p= п 1087 r= р 1088 s= с 1089 t= т 1090 u= у 1091
|
|
||||||
|f= ф 1092 h= х 1093 c= ц 1094 c% ч 1095 s% ш 1096 sc щ 1097
|
|
||||||
|=' ъ 1098 y= ы 1099 %' ь 1100 je э 1101 ju ю 1102 ja я 1103
|
|
||||||
|io ё 1105 d% ђ 1106 g% ѓ 1107 ie є 1108 ds ѕ 1109 ii і 1110
|
|
||||||
|yi ї 1111 j% ј 1112 lj љ 1113 nj њ 1114 ts ћ 1115 kj ќ 1116
|
|
||||||
|v% ў 1118 dz џ 1119 Y3 Ѣ 1122 y3 ѣ 1123 O3 Ѫ 1130 o3 ѫ 1131
|
|
||||||
|F3 Ѳ 1138 f3 ѳ 1139 V3 Ѵ 1140 v3 ѵ 1141 C3 Ҁ 1152 c3 ҁ 1153
|
|
||||||
|G3 Ґ 1168 g3 ґ 1169 A+ א 1488 B+ ב 1489 G+ ג 1490 D+ ד 1491
|
|
||||||
|H+ ה 1492 W+ ו 1493 Z+ ז 1494 X+ ח 1495 Tj ט 1496 J+ י 1497
|
|
||||||
|K% ך 1498 K+ כ 1499 L+ ל 1500 M% ם 1501 M+ מ 1502 N% ן 1503
|
|
||||||
|N+ נ 1504 S+ ס 1505 E+ ע 1506 P% ף 1507 P+ פ 1508 Zj ץ 1509
|
|
||||||
|ZJ צ 1510 Q+ ק 1511 R+ ר 1512 Sh ש 1513 T+ ת 1514 ,+ ، 1548
|
|
||||||
|;+ ؛ 1563 ?+ ؟ 1567 H' ء 1569 aM آ 1570 aH أ 1571 wH ؤ 1572
|
|
||||||
|ah إ 1573 yH ئ 1574 a+ ا 1575 b+ ب 1576 tm ة 1577 t+ ت 1578
|
|
||||||
|tk ث 1579 g+ ج 1580 hk ح 1581 x+ خ 1582 d+ د 1583 dk ذ 1584
|
|
||||||
|r+ ر 1585 z+ ز 1586 s+ س 1587 sn ش 1588 c+ ص 1589 dd ض 1590
|
|
||||||
|tj ط 1591 zH ظ 1592 e+ ع 1593 i+ غ 1594 ++ ـ 1600 f+ ف 1601
|
|
||||||
|q+ ق 1602 k+ ك 1603 l+ ل 1604 m+ م 1605 n+ ن 1606 h+ ه 1607
|
|
||||||
|w+ و 1608 j+ ى 1609 y+ ي 1610 :+ ً 1611 "+ ٌ 1612 =+ ٍ 1613
|
|
||||||
|/+ َ 1614 '+ ُ 1615 1+ ِ 1616 3+ ّ 1617 0+ ْ 1618 aS ٰ 1648
|
|
||||||
|p+ پ 1662 v+ ڤ 1700 gf گ 1711 0a ۰ 1776 1a ۱ 1777 2a ۲ 1778
|
|
||||||
|3a ۳ 1779 4a ۴ 1780 5a ۵ 1781 6a ۶ 1782 7a ۷ 1783 8a ۸ 1784
|
|
||||||
|9a ۹ 1785 B. Ḃ 7682 b. ḃ 7683 B_ Ḇ 7686 b_ ḇ 7687 D. Ḋ 7690
|
|
||||||
|d. ḋ 7691 D_ Ḏ 7694 d_ ḏ 7695 D, Ḑ 7696 d, ḑ 7697 F. Ḟ 7710
|
|
||||||
|f. ḟ 7711 G- Ḡ 7712 g- ḡ 7713 H. Ḣ 7714 h. ḣ 7715 H: Ḧ 7718
|
|
||||||
|h: ḧ 7719 H, Ḩ 7720 h, ḩ 7721 K' Ḱ 7728 k' ḱ 7729 K_ Ḵ 7732
|
|
||||||
|k_ ḵ 7733 L_ Ḻ 7738 l_ ḻ 7739 M' Ḿ 7742 m' ḿ 7743 M. Ṁ 7744
|
|
||||||
|m. ṁ 7745 N. Ṅ 7748 n. ṅ 7749 N_ Ṉ 7752 n_ ṉ 7753 P' Ṕ 7764
|
|
||||||
|p' ṕ 7765 P. Ṗ 7766 p. ṗ 7767 R. Ṙ 7768 r. ṙ 7769 R_ Ṟ 7774
|
|
||||||
|r_ ṟ 7775 S. Ṡ 7776 s. ṡ 7777 T. Ṫ 7786 t. ṫ 7787 T_ Ṯ 7790
|
|
||||||
|t_ ṯ 7791 V? Ṽ 7804 v? ṽ 7805 W! Ẁ 7808 W` Ẁ 7808 w! ẁ 7809
|
|
||||||
|w` ẁ 7809 W' Ẃ 7810 w' ẃ 7811 W: Ẅ 7812 w: ẅ 7813 W. Ẇ 7814
|
|
||||||
|w. ẇ 7815 X. Ẋ 7818 x. ẋ 7819 X: Ẍ 7820 x: ẍ 7821 Y. Ẏ 7822
|
|
||||||
|y. ẏ 7823 Z> Ẑ 7824 z> ẑ 7825 Z_ Ẕ 7828 z_ ẕ 7829 h_ ẖ 7830
|
|
||||||
|t: ẗ 7831 w0 ẘ 7832 y0 ẙ 7833 A2 Ả 7842 a2 ả 7843 E2 Ẻ 7866
|
|
||||||
|e2 ẻ 7867 E? Ẽ 7868 e? ẽ 7869 I2 Ỉ 7880 i2 ỉ 7881 O2 Ỏ 7886
|
|
||||||
|o2 ỏ 7887 U2 Ủ 7910 u2 ủ 7911 Y! Ỳ 7922 Y` Ỳ 7922 y! ỳ 7923
|
|
||||||
|y` ỳ 7923 Y2 Ỷ 7926 y2 ỷ 7927 Y? Ỹ 7928 y? ỹ 7929 ;' ἀ 7936
|
|
||||||
|,' ἁ 7937 ;! ἂ 7938 ,! ἃ 7939 ?; ἄ 7940 ?, ἅ 7941 !: ἆ 7942
|
|
||||||
|?: ἇ 7943 1N 8194 1M 8195 3M 8196 4M 8197 6M 8198
|
|
||||||
|1T 8201 1H 8202 -1 ‐ 8208 -N – 8211 -M — 8212 -3 ― 8213
|
|
||||||
|!2 ‖ 8214 =2 ‗ 8215 '6 ‘ 8216 '9 ’ 8217 .9 ‚ 8218 9' ‛ 8219
|
|
||||||
|"6 “ 8220 "9 ” 8221 :9 „ 8222 9" ‟ 8223 /- † 8224 /= ‡ 8225
|
|
||||||
|oo • 8226 .. ‥ 8229 ,. … 8230 %0 ‰ 8240 1' ′ 8242 2' ″ 8243
|
|
||||||
|3' ‴ 8244 4' ⁗ 8279 1" ‵ 8245 2" ‶ 8246 3" ‷ 8247 Ca ‸ 8248
|
|
||||||
|<1 ‹ 8249 >1 › 8250 :X ※ 8251 '- ‾ 8254 /f ⁄ 8260 0S ⁰ 8304
|
|
||||||
|4S ⁴ 8308 5S ⁵ 8309 6S ⁶ 8310 7S ⁷ 8311 8S ⁸ 8312 9S ⁹ 8313
|
|
||||||
|+S ⁺ 8314 -S ⁻ 8315 =S ⁼ 8316 (S ⁽ 8317 )S ⁾ 8318 nS ⁿ 8319
|
|
||||||
|0s ₀ 8320 1s ₁ 8321 2s ₂ 8322 3s ₃ 8323 4s ₄ 8324 5s ₅ 8325
|
|
||||||
|6s ₆ 8326 7s ₇ 8327 8s ₈ 8328 9s ₉ 8329 +s ₊ 8330 -s ₋ 8331
|
|
||||||
|=s ₌ 8332 (s ₍ 8333 )s ₎ 8334 Li ₤ 8356 Pt ₧ 8359 W= ₩ 8361
|
|
||||||
|=e € 8364 Eu € 8364 =R ₽ 8381 =P ₽ 8381 oC ℃ 8451 co ℅ 8453
|
|
||||||
|oF ℉ 8457 N0 № 8470 PO ℗ 8471 Rx ℞ 8478 SM ℠ 8480 TM ™ 8482
|
|
||||||
|Om Ω 8486 AO Å 8491 13 ⅓ 8531 23 ⅔ 8532 15 ⅕ 8533 25 ⅖ 8534
|
|
||||||
|35 ⅗ 8535 45 ⅘ 8536 16 ⅙ 8537 56 ⅚ 8538 18 ⅛ 8539 38 ⅜ 8540
|
|
||||||
|58 ⅝ 8541 78 ⅞ 8542 1R Ⅰ 8544 2R Ⅱ 8545 3R Ⅲ 8546 4R Ⅳ 8547
|
|
||||||
|5R Ⅴ 8548 6R Ⅵ 8549 7R Ⅶ 8550 8R Ⅷ 8551 9R Ⅸ 8552 aR Ⅹ 8553
|
|
||||||
|bR Ⅺ 8554 cR Ⅻ 8555 1r ⅰ 8560 2r ⅱ 8561 3r ⅲ 8562 4r ⅳ 8563
|
|
||||||
|5r ⅴ 8564 6r ⅵ 8565 7r ⅶ 8566 8r ⅷ 8567 9r ⅸ 8568 ar ⅹ 8569
|
|
||||||
|br ⅺ 8570 cr ⅻ 8571 <- ← 8592 -! ↑ 8593 -> → 8594 -v ↓ 8595
|
|
||||||
|<> ↔ 8596 UD ↕ 8597 <= ⇐ 8656 => ⇒ 8658 == ⇔ 8660 FA ∀ 8704
|
|
||||||
|dP ∂ 8706 TE ∃ 8707 /0 ∅ 8709 DE ∆ 8710 NB ∇ 8711 (- ∈ 8712
|
|
||||||
|-) ∋ 8715 *P ∏ 8719 +Z ∑ 8721 -2 − 8722 -+ ∓ 8723 *- ∗ 8727
|
|
||||||
|Ob ∘ 8728 Sb ∙ 8729 RT √ 8730 0( ∝ 8733 00 ∞ 8734 -L ∟ 8735
|
|
||||||
|-V ∠ 8736 PP ∥ 8741 AN ∧ 8743 OR ∨ 8744 (U ∩ 8745 )U ∪ 8746
|
|
||||||
|In ∫ 8747 DI ∬ 8748 Io ∮ 8750 .: ∴ 8756 :. ∵ 8757 :R ∶ 8758
|
|
||||||
|:: ∷ 8759 ?1 ∼ 8764 CG ∾ 8766 ?- ≃ 8771 ?= ≅ 8773 ?2 ≈ 8776
|
|
||||||
|=? ≌ 8780 HI ≓ 8787 != ≠ 8800 =3 ≡ 8801 =< ≤ 8804 >= ≥ 8805
|
|
||||||
|<* ≪ 8810 *> ≫ 8811 !< ≮ 8814 !> ≯ 8815 (C ⊂ 8834 )C ⊃ 8835
|
|
||||||
|(_ ⊆ 8838 )_ ⊇ 8839 0. ⊙ 8857 02 ⊚ 8858 -T ⊥ 8869 .P ⋅ 8901
|
|
||||||
|:3 ⋮ 8942 .3 ⋯ 8943 Eh ⌂ 8962 <7 ⌈ 8968 >7 ⌉ 8969 7< ⌊ 8970
|
|
||||||
|7> ⌋ 8971 NI ⌐ 8976 (A ⌒ 8978 TR ⌕ 8981 Iu ⌠ 8992 Il ⌡ 8993
|
|
||||||
|</ 〈 9001 /> 〉 9002 Vs ␣ 9251 1h ⑀ 9280 3h ⑁ 9281 2h ⑂ 9282
|
|
||||||
|4h ⑃ 9283 1j ⑆ 9286 2j ⑇ 9287 3j ⑈ 9288 4j ⑉ 9289 1. ⒈ 9352
|
|
||||||
|2. ⒉ 9353 3. ⒊ 9354 4. ⒋ 9355 5. ⒌ 9356 6. ⒍ 9357 7. ⒎ 9358
|
|
||||||
|8. ⒏ 9359 9. ⒐ 9360 hh ─ 9472 HH ━ 9473 vv │ 9474 VV ┃ 9475
|
|
||||||
|3- ┄ 9476 3_ ┅ 9477 3! ┆ 9478 3/ ┇ 9479 4- ┈ 9480 4_ ┉ 9481
|
|
||||||
|4! ┊ 9482 4/ ┋ 9483 dr ┌ 9484 dR ┍ 9485 Dr ┎ 9486 DR ┏ 9487
|
|
||||||
|dl ┐ 9488 dL ┑ 9489 Dl ┒ 9490 LD ┓ 9491 ur └ 9492 uR ┕ 9493
|
|
||||||
|Ur ┖ 9494 UR ┗ 9495 ul ┘ 9496 uL ┙ 9497 Ul ┚ 9498 UL ┛ 9499
|
|
||||||
|vr ├ 9500 vR ┝ 9501 Vr ┠ 9504 VR ┣ 9507 vl ┤ 9508 vL ┥ 9509
|
|
||||||
|Vl ┨ 9512 VL ┫ 9515 dh ┬ 9516 dH ┯ 9519 Dh ┰ 9520 DH ┳ 9523
|
|
||||||
|uh ┴ 9524 uH ┷ 9527 Uh ┸ 9528 UH ┻ 9531 vh ┼ 9532 vH ┿ 9535
|
|
||||||
|Vh ╂ 9538 VH ╋ 9547 FD ╱ 9585 BD ╲ 9586 TB ▀ 9600 LB ▄ 9604
|
|
||||||
|FB █ 9608 lB ▌ 9612 RB ▐ 9616 .S ░ 9617 :S ▒ 9618 ?S ▓ 9619
|
|
||||||
|fS ■ 9632 OS □ 9633 RO ▢ 9634 Rr ▣ 9635 RF ▤ 9636 RY ▥ 9637
|
|
||||||
|RH ▦ 9638 RZ ▧ 9639 RK ▨ 9640 RX ▩ 9641 sB ▪ 9642 SR ▬ 9644
|
|
||||||
|Or ▭ 9645 UT ▲ 9650 uT △ 9651 PR ▶ 9654 Tr ▷ 9655 Dt ▼ 9660
|
|
||||||
|dT ▽ 9661 PL ◀ 9664 Tl ◁ 9665 Db ◆ 9670 Dw ◇ 9671 LZ ◊ 9674
|
|
||||||
|0m ○ 9675 0o ◎ 9678 0M ● 9679 0L ◐ 9680 0R ◑ 9681 Sn ◘ 9688
|
|
||||||
|Ic ◙ 9689 Fd ◢ 9698 Bd ◣ 9699 *2 ★ 9733 *1 ☆ 9734 <H ☜ 9756
|
|
||||||
|>H ☞ 9758 0u ☺ 9786 0U ☻ 9787 SU ☼ 9788 Fm ♀ 9792 Ml ♂ 9794
|
|
||||||
|cS ♠ 9824 cH ♡ 9825 cD ♢ 9826 cC ♣ 9827 Md ♩ 9833 M8 ♪ 9834
|
|
||||||
|M2 ♫ 9835 Mb ♭ 9837 Mx ♮ 9838 MX ♯ 9839 OK ✓ 10003 XX ✗ 10007
|
|
||||||
|-X ✠ 10016 IS 12288 ,_ 、 12289 ._ 。 12290 +" 〃 12291 +_ 〄 12292
|
|
||||||
|*_ 々 12293 ;_ 〆 12294 0_ 〇 12295 <+ 《 12298 >+ 》 12299 <' 「 12300
|
|
||||||
|>' 」 12301 <" 『 12302 >" 』 12303 (" 【 12304 )" 】 12305 =T 〒 12306
|
|
||||||
|=_ 〓 12307 (' 〔 12308 )' 〕 12309 (I 〖 12310 )I 〗 12311 -? 〜 12316
|
|
||||||
|A5 ぁ 12353 a5 あ 12354 I5 ぃ 12355 i5 い 12356 U5 ぅ 12357 u5 う 12358
|
|
||||||
|E5 ぇ 12359 e5 え 12360 O5 ぉ 12361 o5 お 12362 ka か 12363 ga が 12364
|
|
||||||
|ki き 12365 gi ぎ 12366 ku く 12367 gu ぐ 12368 ke け 12369 ge げ 12370
|
|
||||||
|ko こ 12371 go ご 12372 sa さ 12373 za ざ 12374 si し 12375 zi じ 12376
|
|
||||||
|su す 12377 zu ず 12378 se せ 12379 ze ぜ 12380 so そ 12381 zo ぞ 12382
|
|
||||||
|ta た 12383 da だ 12384 ti ち 12385 di ぢ 12386 tU っ 12387 tu つ 12388
|
|
||||||
|du づ 12389 te て 12390 de で 12391 to と 12392 do ど 12393 na な 12394
|
|
||||||
|ni に 12395 nu ぬ 12396 ne ね 12397 no の 12398 ha は 12399 ba ば 12400
|
|
||||||
|pa ぱ 12401 hi ひ 12402 bi び 12403 pi ぴ 12404 hu ふ 12405 bu ぶ 12406
|
|
||||||
|pu ぷ 12407 he へ 12408 be べ 12409 pe ぺ 12410 ho ほ 12411 bo ぼ 12412
|
|
||||||
|po ぽ 12413 ma ま 12414 mi み 12415 mu む 12416 me め 12417 mo も 12418
|
|
||||||
|yA ゃ 12419 ya や 12420 yU ゅ 12421 yu ゆ 12422 yO ょ 12423 yo よ 12424
|
|
||||||
|ra ら 12425 ri り 12426 ru る 12427 re れ 12428 ro ろ 12429 wA ゎ 12430
|
|
||||||
|wa わ 12431 wi ゐ 12432 we ゑ 12433 wo を 12434 n5 ん 12435 vu ゔ 12436
|
|
||||||
|"5 ゛ 12443 05 ゜ 12444 *5 ゝ 12445 +5 ゞ 12446 a6 ァ 12449 A6 ア 12450
|
|
||||||
|i6 ィ 12451 I6 イ 12452 u6 ゥ 12453 U6 ウ 12454 e6 ェ 12455 E6 エ 12456
|
|
||||||
|o6 ォ 12457 O6 オ 12458 Ka カ 12459 Ga ガ 12460 Ki キ 12461 Gi ギ 12462
|
|
||||||
|Ku ク 12463 Gu グ 12464 Ke ケ 12465 Ge ゲ 12466 Ko コ 12467 Go ゴ 12468
|
|
||||||
|Sa サ 12469 Za ザ 12470 Si シ 12471 Zi ジ 12472 Su ス 12473 Zu ズ 12474
|
|
||||||
|Se セ 12475 Ze ゼ 12476 So ソ 12477 Zo ゾ 12478 Ta タ 12479 Da ダ 12480
|
|
||||||
|Ti チ 12481 Di ヂ 12482 TU ッ 12483 Tu ツ 12484 Du ヅ 12485 Te テ 12486
|
|
||||||
|De デ 12487 To ト 12488 Do ド 12489 Na ナ 12490 Ni ニ 12491 Nu ヌ 12492
|
|
||||||
|Ne ネ 12493 No ノ 12494 Ha ハ 12495 Ba バ 12496 Pa パ 12497 Hi ヒ 12498
|
|
||||||
|Bi ビ 12499 Pi ピ 12500 Hu フ 12501 Bu ブ 12502 Pu プ 12503 He ヘ 12504
|
|
||||||
|Be ベ 12505 Pe ペ 12506 Ho ホ 12507 Bo ボ 12508 Po ポ 12509 Ma マ 12510
|
|
||||||
|Mi ミ 12511 Mu ム 12512 Me メ 12513 Mo モ 12514 YA ャ 12515 Ya ヤ 12516
|
|
||||||
|YU ュ 12517 Yu ユ 12518 YO ョ 12519 Yo ヨ 12520 Ra ラ 12521 Ri リ 12522
|
|
||||||
|Ru ル 12523 Re レ 12524 Ro ロ 12525 WA ヮ 12526 Wa ワ 12527 Wi ヰ 12528
|
|
||||||
|We ヱ 12529 Wo ヲ 12530 N6 ン 12531 Vu ヴ 12532 KA ヵ 12533 KE ヶ 12534
|
|
||||||
|Va ヷ 12535 Vi ヸ 12536 Ve ヹ 12537 Vo ヺ 12538 .6 ・ 12539 -6 ー 12540
|
|
||||||
|*6 ヽ 12541 +6 ヾ 12542 b4 ㄅ 12549 p4 ㄆ 12550 m4 ㄇ 12551 f4 ㄈ 12552
|
|
||||||
|d4 ㄉ 12553 t4 ㄊ 12554 n4 ㄋ 12555 l4 ㄌ 12556 g4 ㄍ 12557 k4 ㄎ 12558
|
|
||||||
|h4 ㄏ 12559 j4 ㄐ 12560 q4 ㄑ 12561 x4 ㄒ 12562 zh ㄓ 12563 ch ㄔ 12564
|
|
||||||
|sh ㄕ 12565 r4 ㄖ 12566 z4 ㄗ 12567 c4 ㄘ 12568 s4 ㄙ 12569 a4 ㄚ 12570
|
|
||||||
|o4 ㄛ 12571 e4 ㄜ 12572 ai ㄞ 12574 ei ㄟ 12575 au ㄠ 12576 ou ㄡ 12577
|
|
||||||
|an ㄢ 12578 en ㄣ 12579 aN ㄤ 12580 eN ㄥ 12581 er ㄦ 12582 i4 ㄧ 12583
|
|
||||||
|u4 ㄨ 12584 iu ㄩ 12585 v4 ㄪ 12586 nG ㄫ 12587 gn ㄬ 12588 1c ㈠ 12832
|
|
||||||
|2c ㈡ 12833 3c ㈢ 12834 4c ㈣ 12835 5c ㈤ 12836 6c ㈥ 12837 7c ㈦ 12838
|
|
||||||
|8c ㈧ 12839 9c ㈨ 12840 ff ff 64256 fi fi 64257 fl fl 64258 ft ſt 64261
|
|
||||||
|st st 64262 cr 🔴 128308
|
|
||||||
""".trimMargin()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `test digraph output with headers and custom digraphs`() {
|
fun `test digraph output with headers and custom digraphs`() {
|
||||||
enterCommand("digraphs (0 9450 (2 9313 (1 9312")
|
enterCommand("digraphs (0 9450 (2 9313 (1 9312")
|
||||||
|
@ -13,7 +13,7 @@ import com.intellij.openapi.application.ApplicationManager
|
|||||||
import com.maddyhome.idea.vim.VimPlugin
|
import com.maddyhome.idea.vim.VimPlugin
|
||||||
import com.maddyhome.idea.vim.api.injector
|
import com.maddyhome.idea.vim.api.injector
|
||||||
import com.maddyhome.idea.vim.api.options
|
import com.maddyhome.idea.vim.api.options
|
||||||
import com.maddyhome.idea.vim.history.VimHistory
|
import com.maddyhome.idea.vim.history.HistoryConstants
|
||||||
import com.maddyhome.idea.vim.newapi.vim
|
import com.maddyhome.idea.vim.newapi.vim
|
||||||
import org.jetbrains.plugins.ideavim.SkipNeovimReason
|
import org.jetbrains.plugins.ideavim.SkipNeovimReason
|
||||||
import org.jetbrains.plugins.ideavim.TestWithoutNeovim
|
import org.jetbrains.plugins.ideavim.TestWithoutNeovim
|
||||||
@ -240,7 +240,7 @@ class GlobalCommandTest : VimTestCase() {
|
|||||||
@Test
|
@Test
|
||||||
fun `test check history`() {
|
fun `test check history`() {
|
||||||
VimPlugin.getHistory().clear()
|
VimPlugin.getHistory().clear()
|
||||||
val initialEntries = VimPlugin.getHistory().getEntries(VimHistory.Type.Command, 0, 0)
|
val initialEntries = VimPlugin.getHistory().getEntries(HistoryConstants.COMMAND, 0, 0)
|
||||||
doTest(
|
doTest(
|
||||||
"g/found/d",
|
"g/found/d",
|
||||||
initialText,
|
initialText,
|
||||||
@ -252,7 +252,7 @@ class GlobalCommandTest : VimTestCase() {
|
|||||||
hard by the torrent of a mountain pass.
|
hard by the torrent of a mountain pass.
|
||||||
""".trimIndent(),
|
""".trimIndent(),
|
||||||
)
|
)
|
||||||
val entries = VimPlugin.getHistory().getEntries(VimHistory.Type.Command, 0, 0)
|
val entries = VimPlugin.getHistory().getEntries(HistoryConstants.COMMAND, 0, 0)
|
||||||
kotlin.test.assertEquals(1, entries.size - initialEntries.size)
|
kotlin.test.assertEquals(1, entries.size - initialEntries.size)
|
||||||
val element = entries.last()
|
val element = entries.last()
|
||||||
kotlin.test.assertEquals("g/found/d", element.entry)
|
kotlin.test.assertEquals("g/found/d", element.entry)
|
||||||
|
@ -10,7 +10,6 @@ package org.jetbrains.plugins.ideavim.ex.implementation.commands
|
|||||||
import com.intellij.idea.TestFor
|
import com.intellij.idea.TestFor
|
||||||
import com.intellij.testFramework.LoggedErrorProcessor
|
import com.intellij.testFramework.LoggedErrorProcessor
|
||||||
import com.maddyhome.idea.vim.KeyHandler
|
import com.maddyhome.idea.vim.KeyHandler
|
||||||
import com.maddyhome.idea.vim.api.globalOptions
|
|
||||||
import com.maddyhome.idea.vim.api.injector
|
import com.maddyhome.idea.vim.api.injector
|
||||||
import com.maddyhome.idea.vim.api.keys
|
import com.maddyhome.idea.vim.api.keys
|
||||||
import com.maddyhome.idea.vim.command.MappingMode
|
import com.maddyhome.idea.vim.command.MappingMode
|
||||||
@ -22,7 +21,6 @@ import org.jetbrains.plugins.ideavim.SkipNeovimReason
|
|||||||
import org.jetbrains.plugins.ideavim.TestWithoutNeovim
|
import org.jetbrains.plugins.ideavim.TestWithoutNeovim
|
||||||
import org.jetbrains.plugins.ideavim.VimTestCase
|
import org.jetbrains.plugins.ideavim.VimTestCase
|
||||||
import org.jetbrains.plugins.ideavim.exceptionMappingOwner
|
import org.jetbrains.plugins.ideavim.exceptionMappingOwner
|
||||||
import org.jetbrains.plugins.ideavim.waitAndAssert
|
|
||||||
import org.junit.jupiter.api.AfterEach
|
import org.junit.jupiter.api.AfterEach
|
||||||
import org.junit.jupiter.api.Disabled
|
import org.junit.jupiter.api.Disabled
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
@ -107,16 +105,16 @@ class MapCommandTest : VimTestCase() {
|
|||||||
enterCommand("imap <C-Down> <C-O>gt")
|
enterCommand("imap <C-Down> <C-O>gt")
|
||||||
enterCommand("nmap ,f <Plug>Foo")
|
enterCommand("nmap ,f <Plug>Foo")
|
||||||
enterCommand("nmap <Plug>Foo iHello<Esc>")
|
enterCommand("nmap <Plug>Foo iHello<Esc>")
|
||||||
|
enterCommand("imap")
|
||||||
assertCommandOutput("imap",
|
assertExOutput(
|
||||||
"""
|
"""
|
||||||
|i <C-Down> <C-O>gt
|
|i <C-Down> <C-O>gt
|
||||||
|i bar <Esc>
|
|i bar <Esc>
|
||||||
|i foo bar
|
|i foo bar
|
||||||
""".trimMargin(),
|
""".trimMargin(),
|
||||||
)
|
)
|
||||||
|
enterCommand("map")
|
||||||
assertCommandOutput("map",
|
assertExOutput(
|
||||||
"""
|
"""
|
||||||
| <C-Down> gt
|
| <C-Down> gt
|
||||||
|n <Plug>Foo iHello<Esc>
|
|n <Plug>Foo iHello<Esc>
|
||||||
@ -144,9 +142,11 @@ class MapCommandTest : VimTestCase() {
|
|||||||
configureByText("\n")
|
configureByText("\n")
|
||||||
addTestMaps()
|
addTestMaps()
|
||||||
|
|
||||||
|
enterCommand("map")
|
||||||
|
|
||||||
// Note that Vim doesn't appear to have an order. Items are kinda sorted, but also not. I.e. `m{something}` are
|
// Note that Vim doesn't appear to have an order. Items are kinda sorted, but also not. I.e. `m{something}` are
|
||||||
// grouped together, but followed later by `g{something}`. We'll sort by {lhs}, so we're at least consistent
|
// grouped together, but followed later by `g{something}`. We'll sort by {lhs}, so we're at least consistent
|
||||||
assertCommandOutput("map",
|
assertExOutput(
|
||||||
"""
|
"""
|
||||||
| all foo
|
| all foo
|
||||||
|n normal foo
|
|n normal foo
|
||||||
@ -163,7 +163,9 @@ class MapCommandTest : VimTestCase() {
|
|||||||
configureByText("\n")
|
configureByText("\n")
|
||||||
addTestMaps()
|
addTestMaps()
|
||||||
|
|
||||||
assertCommandOutput("nmap",
|
enterCommand("nmap")
|
||||||
|
|
||||||
|
assertExOutput(
|
||||||
"""
|
"""
|
||||||
| all foo
|
| all foo
|
||||||
|n normal foo
|
|n normal foo
|
||||||
@ -176,7 +178,9 @@ class MapCommandTest : VimTestCase() {
|
|||||||
configureByText("\n")
|
configureByText("\n")
|
||||||
addTestMaps()
|
addTestMaps()
|
||||||
|
|
||||||
assertCommandOutput("vmap",
|
enterCommand("vmap")
|
||||||
|
|
||||||
|
assertExOutput(
|
||||||
"""
|
"""
|
||||||
| all foo
|
| all foo
|
||||||
|s select foo
|
|s select foo
|
||||||
@ -191,7 +195,9 @@ class MapCommandTest : VimTestCase() {
|
|||||||
configureByText("\n")
|
configureByText("\n")
|
||||||
addTestMaps()
|
addTestMaps()
|
||||||
|
|
||||||
assertCommandOutput("smap",
|
enterCommand("smap")
|
||||||
|
|
||||||
|
assertExOutput(
|
||||||
"""
|
"""
|
||||||
| all foo
|
| all foo
|
||||||
|s select foo
|
|s select foo
|
||||||
@ -205,7 +211,9 @@ class MapCommandTest : VimTestCase() {
|
|||||||
configureByText("\n")
|
configureByText("\n")
|
||||||
addTestMaps()
|
addTestMaps()
|
||||||
|
|
||||||
assertCommandOutput("xmap",
|
enterCommand("xmap")
|
||||||
|
|
||||||
|
assertExOutput(
|
||||||
"""
|
"""
|
||||||
| all foo
|
| all foo
|
||||||
|x visual foo
|
|x visual foo
|
||||||
@ -219,7 +227,9 @@ class MapCommandTest : VimTestCase() {
|
|||||||
configureByText("\n")
|
configureByText("\n")
|
||||||
addTestMaps()
|
addTestMaps()
|
||||||
|
|
||||||
assertCommandOutput("omap",
|
enterCommand("omap")
|
||||||
|
|
||||||
|
assertExOutput(
|
||||||
"""
|
"""
|
||||||
| all foo
|
| all foo
|
||||||
|o op-pending foo
|
|o op-pending foo
|
||||||
@ -232,7 +242,9 @@ class MapCommandTest : VimTestCase() {
|
|||||||
configureByText("\n")
|
configureByText("\n")
|
||||||
addTestMaps()
|
addTestMaps()
|
||||||
|
|
||||||
assertCommandOutput("map!",
|
enterCommand("map!")
|
||||||
|
|
||||||
|
assertExOutput(
|
||||||
"""
|
"""
|
||||||
|c cmdline foo
|
|c cmdline foo
|
||||||
|i insert foo
|
|i insert foo
|
||||||
@ -255,7 +267,9 @@ class MapCommandTest : VimTestCase() {
|
|||||||
configureByText("\n")
|
configureByText("\n")
|
||||||
addTestMaps()
|
addTestMaps()
|
||||||
|
|
||||||
assertCommandOutput("imap",
|
enterCommand("imap")
|
||||||
|
|
||||||
|
assertExOutput(
|
||||||
"""
|
"""
|
||||||
|i insert foo
|
|i insert foo
|
||||||
|! insert+cmdline foo
|
|! insert+cmdline foo
|
||||||
@ -269,7 +283,9 @@ class MapCommandTest : VimTestCase() {
|
|||||||
configureByText("\n")
|
configureByText("\n")
|
||||||
addTestMaps()
|
addTestMaps()
|
||||||
|
|
||||||
assertCommandOutput("lmap",
|
enterCommand("lmap")
|
||||||
|
|
||||||
|
assertExOutput(
|
||||||
"""
|
"""
|
||||||
|l lang foo
|
|l lang foo
|
||||||
""".trimMargin()
|
""".trimMargin()
|
||||||
@ -281,7 +297,9 @@ class MapCommandTest : VimTestCase() {
|
|||||||
configureByText("\n")
|
configureByText("\n")
|
||||||
addTestMaps()
|
addTestMaps()
|
||||||
|
|
||||||
assertCommandOutput("cmap",
|
enterCommand("cmap")
|
||||||
|
|
||||||
|
assertExOutput(
|
||||||
"""
|
"""
|
||||||
|c cmdline foo
|
|c cmdline foo
|
||||||
|! insert+cmdline foo
|
|! insert+cmdline foo
|
||||||
@ -295,9 +313,10 @@ class MapCommandTest : VimTestCase() {
|
|||||||
addTestMaps() // Adds a mapping of all for NVO
|
addTestMaps() // Adds a mapping of all for NVO
|
||||||
|
|
||||||
enterCommand("sunmap all") // Removes Select from the NVO mapping for foo
|
enterCommand("sunmap all") // Removes Select from the NVO mapping for foo
|
||||||
|
enterCommand("map")
|
||||||
|
|
||||||
// Note that the formatting is exactly how Vim shows it. Messy, isn't it?
|
// Note that the formatting is exactly how Vim shows it. Messy, isn't it?
|
||||||
assertCommandOutput("map",
|
assertExOutput(
|
||||||
"""
|
"""
|
||||||
|noxall foo
|
|noxall foo
|
||||||
|n normal foo
|
|n normal foo
|
||||||
@ -315,8 +334,9 @@ class MapCommandTest : VimTestCase() {
|
|||||||
addTestMaps() // Adds a mapping of all for NVO
|
addTestMaps() // Adds a mapping of all for NVO
|
||||||
|
|
||||||
enterCommand("vunmap all") // Removes Visual+Select from the NVO mapping for foo
|
enterCommand("vunmap all") // Removes Visual+Select from the NVO mapping for foo
|
||||||
|
enterCommand("map")
|
||||||
|
|
||||||
assertCommandOutput("map",
|
assertExOutput(
|
||||||
"""
|
"""
|
||||||
|no all foo
|
|no all foo
|
||||||
|n normal foo
|
|n normal foo
|
||||||
@ -335,7 +355,8 @@ class MapCommandTest : VimTestCase() {
|
|||||||
enterCommand("vmap foo baz") // Visual, Select
|
enterCommand("vmap foo baz") // Visual, Select
|
||||||
|
|
||||||
// Just to be sure we're set up correctly
|
// Just to be sure we're set up correctly
|
||||||
assertCommandOutput("map",
|
enterCommand("map")
|
||||||
|
assertExOutput(
|
||||||
"""
|
"""
|
||||||
|no foo bar
|
|no foo bar
|
||||||
|v foo baz
|
|v foo baz
|
||||||
@ -345,7 +366,8 @@ class MapCommandTest : VimTestCase() {
|
|||||||
enterCommand("sunmap foo")
|
enterCommand("sunmap foo")
|
||||||
enterCommand("ounmap foo")
|
enterCommand("ounmap foo")
|
||||||
|
|
||||||
assertCommandOutput("map",
|
enterCommand("map")
|
||||||
|
assertExOutput(
|
||||||
"""
|
"""
|
||||||
|n foo bar
|
|n foo bar
|
||||||
|x foo baz
|
|x foo baz
|
||||||
@ -361,7 +383,8 @@ class MapCommandTest : VimTestCase() {
|
|||||||
enterCommand("nmap fee bap")
|
enterCommand("nmap fee bap")
|
||||||
enterCommand("nmap zzz ppp")
|
enterCommand("nmap zzz ppp")
|
||||||
|
|
||||||
assertCommandOutput("map f",
|
enterCommand("map f")
|
||||||
|
assertExOutput(
|
||||||
"""
|
"""
|
||||||
|n fee bap
|
|n fee bap
|
||||||
| foo bar
|
| foo bar
|
||||||
@ -374,7 +397,8 @@ class MapCommandTest : VimTestCase() {
|
|||||||
configureByText("\n")
|
configureByText("\n")
|
||||||
enterCommand("map foo bar")
|
enterCommand("map foo bar")
|
||||||
|
|
||||||
assertCommandOutput("map ",
|
enterCommand("map ")
|
||||||
|
assertExOutput(
|
||||||
"""
|
"""
|
||||||
| foo bar
|
| foo bar
|
||||||
""".trimMargin()
|
""".trimMargin()
|
||||||
@ -386,7 +410,8 @@ class MapCommandTest : VimTestCase() {
|
|||||||
configureByText("\n")
|
configureByText("\n")
|
||||||
enterCommand("imap foo bar")
|
enterCommand("imap foo bar")
|
||||||
|
|
||||||
assertCommandOutput("imap f ",
|
enterCommand("imap f ")
|
||||||
|
assertExOutput(
|
||||||
"""
|
"""
|
||||||
|i foo bar
|
|i foo bar
|
||||||
""".trimMargin()
|
""".trimMargin()
|
||||||
@ -404,7 +429,7 @@ class MapCommandTest : VimTestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `test dd with mapping starting with d`() {
|
fun testddWithMapping() {
|
||||||
configureByText(
|
configureByText(
|
||||||
"""
|
"""
|
||||||
Hello$c 1
|
Hello$c 1
|
||||||
@ -435,8 +460,8 @@ class MapCommandTest : VimTestCase() {
|
|||||||
configureByText("\n")
|
configureByText("\n")
|
||||||
enterCommand("inoremap jj <Esc>")
|
enterCommand("inoremap jj <Esc>")
|
||||||
enterCommand("imap foo bar")
|
enterCommand("imap foo bar")
|
||||||
|
enterCommand("imap")
|
||||||
assertCommandOutput("imap",
|
assertExOutput(
|
||||||
"""
|
"""
|
||||||
|i foo bar
|
|i foo bar
|
||||||
|i jj * <Esc>
|
|i jj * <Esc>
|
||||||
@ -466,7 +491,8 @@ class MapCommandTest : VimTestCase() {
|
|||||||
""".trimIndent(),
|
""".trimIndent(),
|
||||||
)
|
)
|
||||||
assertOffset(1)
|
assertOffset(1)
|
||||||
assertCommandOutput("nmap", "n <Right> * <Nop>")
|
enterCommand("nmap")
|
||||||
|
assertExOutput("n <Right> * <Nop>")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -479,8 +505,8 @@ class MapCommandTest : VimTestCase() {
|
|||||||
enterCommand("nmap <script> ,e /e<CR>")
|
enterCommand("nmap <script> ,e /e<CR>")
|
||||||
enterCommand("nmap <expr> ,f '/f<CR>'")
|
enterCommand("nmap <expr> ,f '/f<CR>'")
|
||||||
enterCommand("nmap <unique> ,g /g<CR>")
|
enterCommand("nmap <unique> ,g /g<CR>")
|
||||||
|
enterCommand("nmap")
|
||||||
assertCommandOutput("nmap",
|
assertExOutput(
|
||||||
"""
|
"""
|
||||||
|n ,a /a<CR>
|
|n ,a /a<CR>
|
||||||
|n ,b /b<CR>
|
|n ,b /b<CR>
|
||||||
@ -587,8 +613,8 @@ class MapCommandTest : VimTestCase() {
|
|||||||
typeText("i" + "#" + "<Esc>")
|
typeText("i" + "#" + "<Esc>")
|
||||||
assertState("#\n")
|
assertState("#\n")
|
||||||
assertMode(Mode.NORMAL())
|
assertMode(Mode.NORMAL())
|
||||||
|
enterCommand("imap")
|
||||||
assertCommandOutput("imap", "i # * X<C-H>#")
|
assertExOutput("i # * X<C-H>#")
|
||||||
}
|
}
|
||||||
|
|
||||||
// VIM-679 |:map|
|
// VIM-679 |:map|
|
||||||
@ -612,7 +638,8 @@ class MapCommandTest : VimTestCase() {
|
|||||||
""".trimIndent(),
|
""".trimIndent(),
|
||||||
)
|
)
|
||||||
assertMode(Mode.NORMAL())
|
assertMode(Mode.NORMAL())
|
||||||
assertCommandOutput("map", " <C-X>i dd")
|
enterCommand("map")
|
||||||
|
assertExOutput(" <C-X>i dd")
|
||||||
typeText("<C-X>i")
|
typeText("<C-X>i")
|
||||||
assertState("bar\n")
|
assertState("bar\n")
|
||||||
}
|
}
|
||||||
@ -727,59 +754,6 @@ class MapCommandTest : VimTestCase() {
|
|||||||
assertState("Bye\n")
|
assertState("Bye\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `test map applies longest mapping`() {
|
|
||||||
configureByText("\n")
|
|
||||||
enterCommand("imap ab AB")
|
|
||||||
enterCommand("imap abcd ABCD")
|
|
||||||
typeText("i", "abcd", "<Esc>")
|
|
||||||
assertState("ABCD\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `test map falls back to previous longest mapping when abandoned`() {
|
|
||||||
configureByText("\n")
|
|
||||||
enterCommand("imap abc ABC")
|
|
||||||
enterCommand("imap abcd ABCD")
|
|
||||||
typeText("i", "abcg", "<Esc>")
|
|
||||||
assertState("ABCg\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `test map falls back to previous longest mapping when abandoned with shorter prefix`() {
|
|
||||||
configureByText("\n")
|
|
||||||
enterCommand("imap ab AB")
|
|
||||||
enterCommand("imap abcd ABCD")
|
|
||||||
typeText("i", "abcg", "<Esc>")
|
|
||||||
assertState("ABcg\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `test map falls back to previous longest mapping after timeout`() {
|
|
||||||
configureByText("\n")
|
|
||||||
enterCommand("imap ab AB")
|
|
||||||
enterCommand("imap abcd ABCD")
|
|
||||||
enterCommand("set timeoutlen=100")
|
|
||||||
typeText("i", "abc")
|
|
||||||
waitAndAssert(injector.globalOptions().timeoutlen + 100) {
|
|
||||||
fixture.editor.document.text == "ABc\n"
|
|
||||||
}
|
|
||||||
assertState("ABc\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `test map falls back to previous longest mapping after timeout with shorter prefix`() {
|
|
||||||
configureByText("\n")
|
|
||||||
enterCommand("imap ab AB")
|
|
||||||
enterCommand("imap abcde ABCDE")
|
|
||||||
enterCommand("set timeoutlen=100")
|
|
||||||
typeText("i", "abcd")
|
|
||||||
waitAndAssert(injector.globalOptions().timeoutlen + 100) {
|
|
||||||
fixture.editor.document.text == "ABcd\n"
|
|
||||||
}
|
|
||||||
assertState("ABcd\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestWithoutNeovim(SkipNeovimReason.PLUG)
|
@TestWithoutNeovim(SkipNeovimReason.PLUG)
|
||||||
@Test
|
@Test
|
||||||
fun testPlugMapping() {
|
fun testPlugMapping() {
|
||||||
@ -799,6 +773,16 @@ class MapCommandTest : VimTestCase() {
|
|||||||
assertState("123${c}7890")
|
assertState("123${c}7890")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestWithoutNeovim(SkipNeovimReason.PLUG)
|
||||||
|
@Test
|
||||||
|
fun testIncompleteMapping() {
|
||||||
|
configureByText("123${c}4567890")
|
||||||
|
enterCommand("map <Plug>(Hi)l lll")
|
||||||
|
enterCommand("map I <Plug>(Hi)")
|
||||||
|
typeText("Ih")
|
||||||
|
assertState("12${c}34567890")
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testIntersectingCommands2() {
|
fun testIntersectingCommands2() {
|
||||||
configureByText("123${c}4567890")
|
configureByText("123${c}4567890")
|
||||||
@ -807,86 +791,6 @@ class MapCommandTest : VimTestCase() {
|
|||||||
assertState("123${c}567890")
|
assertState("123${c}567890")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `test partial Plug mapping`() {
|
|
||||||
doTest(
|
|
||||||
listOf("i", "Xy"),
|
|
||||||
"Lorem $c ipsum dolor sit amet",
|
|
||||||
"Lorem Hello ipsum dolor sit amet",
|
|
||||||
Mode.INSERT
|
|
||||||
) {
|
|
||||||
enterCommand("imap <Plug>xy Hello")
|
|
||||||
enterCommand("imap X <Plug>x")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `test abandoned Plug mapping replays all keys as text`() {
|
|
||||||
// The default Vim behaviour for an abandoned mapping is to replay it, character by character, even if that makes no
|
|
||||||
// sense for the mode or mapping, and will move the caret or delete text or whatever. This is also true for <Plug>
|
|
||||||
// mappings, even though `<Plug>` is a special char that can't be typed by the user. When used in Insert mode, Vim
|
|
||||||
// expands the special char to the string "<Plug>".
|
|
||||||
doTest(
|
|
||||||
listOf("i", "Xz"),
|
|
||||||
"Lorem $c ipsum dolor sit amet",
|
|
||||||
"Lorem <Plug>xz ipsum dolor sit amet",
|
|
||||||
Mode.INSERT
|
|
||||||
) {
|
|
||||||
enterCommand("imap <Plug>xy Hello")
|
|
||||||
enterCommand("imap X <Plug>x")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `test partial Action mapping`() {
|
|
||||||
doTest(
|
|
||||||
listOf("i", "X(EditorToggleCase)"),
|
|
||||||
"Lorem ${c}ipsum dolor sit amet",
|
|
||||||
"Lorem IPSUM dolor sit amet",
|
|
||||||
Mode.INSERT
|
|
||||||
) {
|
|
||||||
enterCommand("imap X <Action>")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `test abandoned Action mapping replays all keys as text`() {
|
|
||||||
// The mapping is looking for `<Action>(...)`, so we need to feed it a key that is not part of this mapping. A space
|
|
||||||
// char will work
|
|
||||||
doTest(
|
|
||||||
listOf("i", "X( "),
|
|
||||||
"Lorem $c ipsum dolor sit amet",
|
|
||||||
"Lorem <Action>( ipsum dolor sit amet",
|
|
||||||
Mode.INSERT
|
|
||||||
) {
|
|
||||||
enterCommand("imap X <Action>")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `test abandoned Action mapping replays all keys as text 2`() {
|
|
||||||
doTest(
|
|
||||||
listOf("i", "Xz"),
|
|
||||||
"Lorem $c ipsum dolor sit amet",
|
|
||||||
"Lorem <Action>z ipsum dolor sit amet",
|
|
||||||
Mode.INSERT
|
|
||||||
) {
|
|
||||||
enterCommand("imap X <Action>")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `test timedout Action mapping replays all keys as text`() {
|
|
||||||
configureByText("Lorem $c ipsum dolor sit amet")
|
|
||||||
enterCommand("imap X <Action>")
|
|
||||||
enterCommand("set timeoutlen=100")
|
|
||||||
typeText("i", "X")
|
|
||||||
waitAndAssert(injector.globalOptions().timeoutlen + 100) {
|
|
||||||
fixture.editor.document.text == "Lorem <Action> ipsum dolor sit amet"
|
|
||||||
}
|
|
||||||
assertState("Lorem <Action> ipsum dolor sit amet")
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestWithoutNeovim(reason = SkipNeovimReason.DIFFERENT)
|
@TestWithoutNeovim(reason = SkipNeovimReason.DIFFERENT)
|
||||||
@Test
|
@Test
|
||||||
fun testMapZero() {
|
fun testMapZero() {
|
||||||
@ -999,7 +903,7 @@ class MapCommandTest : VimTestCase() {
|
|||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `test rhs with triangle brackets`() {
|
fun `test rhc with triangle brackets`() {
|
||||||
configureByText("\n")
|
configureByText("\n")
|
||||||
enterCommand("inoremap p <p>")
|
enterCommand("inoremap p <p>")
|
||||||
typeText("ip")
|
typeText("ip")
|
||||||
@ -1038,8 +942,8 @@ class MapCommandTest : VimTestCase() {
|
|||||||
enterCommand("nmap ,g :action Back<C-M>")
|
enterCommand("nmap ,g :action Back<C-M>")
|
||||||
enterCommand("nmap ,h :action Back<C-m>")
|
enterCommand("nmap ,h :action Back<C-m>")
|
||||||
enterCommand("nmap ,i :action Back<c-m>")
|
enterCommand("nmap ,i :action Back<c-m>")
|
||||||
|
enterCommand("nmap")
|
||||||
assertCommandOutput("nmap",
|
assertExOutput(
|
||||||
"""
|
"""
|
||||||
|n ,a <Action>(Back)
|
|n ,a <Action>(Back)
|
||||||
|n ,b <Action>(Back)
|
|n ,b <Action>(Back)
|
||||||
@ -1066,8 +970,8 @@ class MapCommandTest : VimTestCase() {
|
|||||||
enterCommand("nnoremap ,g :action Back<C-M>")
|
enterCommand("nnoremap ,g :action Back<C-M>")
|
||||||
enterCommand("nnoremap ,h :action Back<C-m>")
|
enterCommand("nnoremap ,h :action Back<C-m>")
|
||||||
enterCommand("nnoremap ,i :action Back<c-m>")
|
enterCommand("nnoremap ,i :action Back<c-m>")
|
||||||
|
enterCommand("nnoremap")
|
||||||
assertCommandOutput("nnoremap",
|
assertExOutput(
|
||||||
"""
|
"""
|
||||||
|n ,a <Action>(Back)
|
|n ,a <Action>(Back)
|
||||||
|n ,b <Action>(Back)
|
|n ,b <Action>(Back)
|
||||||
|
@ -148,7 +148,7 @@ class MoveCommandTest : VimTestCase() {
|
|||||||
enterCommand("m 0")
|
enterCommand("m 0")
|
||||||
assertState(
|
assertState(
|
||||||
"""
|
"""
|
||||||
${c}For example: homework, homework, homework, homework, homework, homework, homework, homework, homework.
|
For example: homewor${c}k, homework, homework, homework, homework, homework, homework, homework, homework.
|
||||||
====
|
====
|
||||||
My mother taught me this trick: if you repeat something over and over again it loses its meaning.
|
My mother taught me this trick: if you repeat something over and over again it loses its meaning.
|
||||||
See, nothing.
|
See, nothing.
|
||||||
@ -173,8 +173,8 @@ class MoveCommandTest : VimTestCase() {
|
|||||||
|Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.
|
|Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.
|
||||||
|Morbi nec luctus tortor, id venenatis lacus.
|
|Morbi nec luctus tortor, id venenatis lacus.
|
||||||
|Nunc sit amet tellus vel purus cursus posuere et at purus.
|
|Nunc sit amet tellus vel purus cursus posuere et at purus.
|
||||||
|${c}Ut id dapibus augue.
|
|Ut id dapibus augue.
|
||||||
|Pellentesque orci dolor, tristique quis rutrum non, scelerisque id dui.
|
|${c}Pellentesque orci dolor, tristique quis rutrum non, scelerisque id dui.
|
||||||
""".trimMargin()
|
""".trimMargin()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -194,7 +194,7 @@ class MoveCommandTest : VimTestCase() {
|
|||||||
assertState(
|
assertState(
|
||||||
"""
|
"""
|
||||||
For example: homework, homework, homework, homework, homework, homework, homework, homework, homework.
|
For example: homework, homework, homework, homework, homework, homework, homework, homework, homework.
|
||||||
${c}See, nothing.
|
See, nothing.
|
||||||
====
|
====
|
||||||
My mother taught me this trick: if you repeat something over and over again it loses its meaning.
|
My mother taught me this trick: if you repeat something over and over again it loses its meaning.
|
||||||
""".trimIndent(),
|
""".trimIndent(),
|
||||||
@ -216,7 +216,7 @@ class MoveCommandTest : VimTestCase() {
|
|||||||
"""
|
"""
|
||||||
====
|
====
|
||||||
My mother taught me this trick: if you repeat something over and over again it loses its meaning.
|
My mother taught me this trick: if you repeat something over and over again it loses its meaning.
|
||||||
${c}See, nothing.
|
See, not${c}hing.
|
||||||
For example: homework, homework, homework, homework, homework, homework, homework, homework, homework.
|
For example: homework, homework, homework, homework, homework, homework, homework, homework, homework.
|
||||||
""".trimIndent(),
|
""".trimIndent(),
|
||||||
)
|
)
|
||||||
@ -238,103 +238,8 @@ class MoveCommandTest : VimTestCase() {
|
|||||||
====
|
====
|
||||||
My mother taught me this trick: if you repeat something over and over again it loses its meaning.
|
My mother taught me this trick: if you repeat something over and over again it loses its meaning.
|
||||||
See, nothing.
|
See, nothing.
|
||||||
${c}For example: homework, homework, homework, homework, homework, homework, homework, homework, homework.
|
For example: homewor${c}k, homework, homework, homework, homework, homework, homework, homework, homework.
|
||||||
""".trimIndent(),
|
""".trimIndent(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// VIM-3837
|
|
||||||
@Test
|
|
||||||
fun `test moving relative line positions caret correctly`() {
|
|
||||||
doTest(
|
|
||||||
exCommand("+2m."), // Move the line 2 lines below, to below the current line
|
|
||||||
"""
|
|
||||||
|2
|
|
||||||
|1
|
|
||||||
|${c}3
|
|
||||||
|1
|
|
||||||
|2
|
|
||||||
""".trimMargin(),
|
|
||||||
"""
|
|
||||||
|2
|
|
||||||
|1
|
|
||||||
|3
|
|
||||||
|${c}2
|
|
||||||
|1
|
|
||||||
""".trimMargin()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `test moving relative line positions caret correctly 2`() {
|
|
||||||
doTest(
|
|
||||||
exCommand("+2m."), // Move the line 2 lines below, to below the current line
|
|
||||||
"""
|
|
||||||
|Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
|
||||||
|Morbi nec luctus tortor, id venenatis lacus.
|
|
||||||
|Nunc sit amet ${c}tellus vel purus cursus posuere et at purus.
|
|
||||||
|Ut id dapibus augue.
|
|
||||||
|Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.
|
|
||||||
|Pellentesque orci dolor, tristique quis rutrum non, scelerisque id dui.
|
|
||||||
""".trimMargin(),
|
|
||||||
"""
|
|
||||||
|Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
|
||||||
|Morbi nec luctus tortor, id venenatis lacus.
|
|
||||||
|Nunc sit amet tellus vel purus cursus posuere et at purus.
|
|
||||||
|${c}Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.
|
|
||||||
|Ut id dapibus augue.
|
|
||||||
|Pellentesque orci dolor, tristique quis rutrum non, scelerisque id dui.
|
|
||||||
""".trimMargin()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `test moving lines positions caret correctly with nostartofline option`() {
|
|
||||||
doTest(
|
|
||||||
exCommand("+2m."), // Move the line 2 lines below, to below the current line
|
|
||||||
"""
|
|
||||||
|Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
|
||||||
|Morbi nec luctus tortor, id venenatis lacus.
|
|
||||||
|Nunc sit amet ${c}tellus vel purus cursus posuere et at purus.
|
|
||||||
|Ut id dapibus augue.
|
|
||||||
|Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.
|
|
||||||
|Pellentesque orci dolor, tristique quis rutrum non, scelerisque id dui.
|
|
||||||
""".trimMargin(),
|
|
||||||
"""
|
|
||||||
|Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
|
||||||
|Morbi nec luctus tortor, id venenatis lacus.
|
|
||||||
|Nunc sit amet tellus vel purus cursus posuere et at purus.
|
|
||||||
|Orci varius na${c}toque penatibus et magnis dis parturient montes, nascetur ridiculus mus.
|
|
||||||
|Ut id dapibus augue.
|
|
||||||
|Pellentesque orci dolor, tristique quis rutrum non, scelerisque id dui.
|
|
||||||
""".trimMargin()
|
|
||||||
) {
|
|
||||||
enterCommand("set nostartofline")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `test moving lines positions caret correctly with nostartofline option on shorter line`() {
|
|
||||||
doTest(
|
|
||||||
exCommand("+2m."), // Move the line 2 lines below, to below the current line
|
|
||||||
"""
|
|
||||||
|Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
|
||||||
|Morbi nec luctus tortor, id ${c}venenatis lacus.
|
|
||||||
|Nunc sit amet tellus vel purus cursus posuere et at purus.
|
|
||||||
|Ut id dapibus augue.
|
|
||||||
|Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.
|
|
||||||
|Pellentesque orci dolor, tristique quis rutrum non, scelerisque id dui.
|
|
||||||
""".trimMargin(),
|
|
||||||
"""
|
|
||||||
|Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
|
||||||
|Morbi nec luctus tortor, id venenatis lacus.
|
|
||||||
|Ut id dapibus augue${c}.
|
|
||||||
|Nunc sit amet tellus vel purus cursus posuere et at purus.
|
|
||||||
|Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.
|
|
||||||
|Pellentesque orci dolor, tristique quis rutrum non, scelerisque id dui.
|
|
||||||
""".trimMargin()
|
|
||||||
) {
|
|
||||||
enterCommand("set nostartofline")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -8,40 +8,33 @@
|
|||||||
|
|
||||||
package org.jetbrains.plugins.ideavim.ex.implementation.commands
|
package org.jetbrains.plugins.ideavim.ex.implementation.commands
|
||||||
|
|
||||||
import com.maddyhome.idea.vim.state.mode.Mode
|
/*
|
||||||
import org.jetbrains.plugins.ideavim.VimTestCase
|
|
||||||
import org.junit.jupiter.api.Test
|
|
||||||
|
|
||||||
class NormalCommandTest : VimTestCase() {
|
class NormalCommandTest : VimTestCase() {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `test simple execution`() {
|
fun `test simple execution`() {
|
||||||
doTest(exCommand("normal x"), "123<caret>456", "123<caret>56")
|
doTest("normal x", "123<caret>456", "123<caret>56")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `test short command`() {
|
fun `test short command`() {
|
||||||
doTest(exCommand("norm x"), "123<caret>456", "123<caret>56")
|
doTest("norm x", "123<caret>456", "123<caret>56")
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `test normal command automatically exits Insert mode`() {
|
|
||||||
doTest(exCommand("normal iFoo"), "123<caret>456", "123Fo<caret>o456", Mode.NORMAL())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `test multiple commands`() {
|
fun `test multiple commands`() {
|
||||||
doTest(exCommand("normal xiNewText"), "123<caret>456", "123NewTex<caret>t56")
|
doTest("normal xiNewText", "123<caret>456", "123NewTex<caret>t56")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `test normal command with current line range moves caret to start of line before executing command`() {
|
fun `test range single stroke`() {
|
||||||
doTest(exCommand(".norm x"), "123<caret>456", "<caret>23456")
|
doTest(".norm x", "123<caret>456", "<caret>23456")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `test normal command with multi-line range`() {
|
fun `test range multiple strokes`() {
|
||||||
doTest(
|
doTest(
|
||||||
exCommand("1,3norm x"),
|
"1,3norm x",
|
||||||
"""
|
"""
|
||||||
123456
|
123456
|
||||||
123456
|
123456
|
||||||
@ -60,7 +53,7 @@ class NormalCommandTest : VimTestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `test normal command with single letter mapping`() {
|
fun `test with mapping`() {
|
||||||
configureByText(
|
configureByText(
|
||||||
"""
|
"""
|
||||||
<caret>123456
|
<caret>123456
|
||||||
@ -68,8 +61,8 @@ class NormalCommandTest : VimTestCase() {
|
|||||||
123456
|
123456
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
)
|
)
|
||||||
enterCommand("map G dd")
|
typeText(commandToKeys("map G dd"))
|
||||||
enterCommand("normal G")
|
typeText(commandToKeys("normal G"))
|
||||||
assertState(
|
assertState(
|
||||||
"""
|
"""
|
||||||
<caret>123456
|
<caret>123456
|
||||||
@ -79,28 +72,7 @@ class NormalCommandTest : VimTestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `test normal command with multi-letter mapping`() {
|
fun `test with disabled mapping`() {
|
||||||
doTest(
|
|
||||||
exCommand("normal dd"),
|
|
||||||
"""
|
|
||||||
|${c}Lorem ipsum dolor sit amet,
|
|
||||||
|consectetur adipiscing elit
|
|
||||||
|Sed in orci mauris.
|
|
||||||
|Cras id tellus in ex imperdiet egestas.
|
|
||||||
""".trimMargin(),
|
|
||||||
"""
|
|
||||||
|Lorem ipsum dolor sit amet,
|
|
||||||
|consectetur adipiscing elit
|
|
||||||
|Sed in orci mauris.
|
|
||||||
|${c}Cras id tellus in ex imperdiet egestas.
|
|
||||||
""".trimMargin(),
|
|
||||||
) {
|
|
||||||
enterCommand("map dd G")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `test normal command with disabled mapping`() {
|
|
||||||
configureByText(
|
configureByText(
|
||||||
"""
|
"""
|
||||||
<caret>123456
|
<caret>123456
|
||||||
@ -108,8 +80,8 @@ class NormalCommandTest : VimTestCase() {
|
|||||||
123456
|
123456
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
)
|
)
|
||||||
enterCommand("map G dd")
|
typeText(commandToKeys("map G dd"))
|
||||||
enterCommand("normal! G")
|
typeText(commandToKeys("normal! G"))
|
||||||
assertState(
|
assertState(
|
||||||
"""
|
"""
|
||||||
123456
|
123456
|
||||||
@ -120,7 +92,7 @@ class NormalCommandTest : VimTestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `test normal from Visual mode runs command on start of each line in range`() {
|
fun `test from visual mode`() {
|
||||||
configureByText(
|
configureByText(
|
||||||
"""
|
"""
|
||||||
<caret>123456
|
<caret>123456
|
||||||
@ -130,8 +102,8 @@ class NormalCommandTest : VimTestCase() {
|
|||||||
123456
|
123456
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
)
|
)
|
||||||
typeText("Vjj")
|
typeText(parseKeys("Vjj"))
|
||||||
enterCommand("normal x") // Will give `:'<,'>normal x`
|
typeText(commandToKeys("normal x"))
|
||||||
assertState(
|
assertState(
|
||||||
"""
|
"""
|
||||||
23456
|
23456
|
||||||
@ -144,7 +116,7 @@ class NormalCommandTest : VimTestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `test normal command switches to Visual mode`() {
|
fun `test execute visual mode`() {
|
||||||
configureByText(
|
configureByText(
|
||||||
"""
|
"""
|
||||||
<caret>123456
|
<caret>123456
|
||||||
@ -154,8 +126,8 @@ class NormalCommandTest : VimTestCase() {
|
|||||||
123456
|
123456
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
)
|
)
|
||||||
enterCommand("normal Vjj")
|
typeText(commandToKeys("normal Vjj"))
|
||||||
typeText("x")
|
typeText(parseKeys("x"))
|
||||||
assertState(
|
assertState(
|
||||||
"""
|
"""
|
||||||
<caret>123456
|
<caret>123456
|
||||||
@ -176,8 +148,8 @@ class NormalCommandTest : VimTestCase() {
|
|||||||
123456
|
123456
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
)
|
)
|
||||||
typeText("qqxq", "jVjjj")
|
typeText(parseKeys("qqxq", "jVjjj"))
|
||||||
enterCommand("norm @q")
|
typeText(commandToKeys("norm @q"))
|
||||||
assertState(
|
assertState(
|
||||||
"""
|
"""
|
||||||
23456
|
23456
|
||||||
@ -193,22 +165,29 @@ class NormalCommandTest : VimTestCase() {
|
|||||||
@Test
|
@Test
|
||||||
fun `test command executes at selection start`() {
|
fun `test command executes at selection start`() {
|
||||||
configureByText("hello <caret>world !")
|
configureByText("hello <caret>world !")
|
||||||
typeText("vw")
|
typeText(parseKeys("vw"))
|
||||||
enterCommand("<C-u>norm x")
|
typeText(parseKeys(":<C-u>norm x<CR>"))
|
||||||
assertState("hello <caret>orld !")
|
assertState("hello <caret>orld !")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `test false escape`() {
|
fun `test false escape`() {
|
||||||
configureByText("hello <caret>world !")
|
configureByText("hello <caret>world !")
|
||||||
enterCommand("norm i<Esc>")
|
typeText(commandToKeys("norm i<Esc>"))
|
||||||
assertState("hello <Esc<caret>>world !")
|
assertState("hello <Esc<caret>>world !")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `test C-R`() {
|
fun `test C-R`() {
|
||||||
configureByText("""myprop: "my value"""")
|
configureByText("myprop: \"my value\"")
|
||||||
enterCommand("""exe "norm ^dei-\<C-R>\"-"""")
|
typeText(commandToKeys("exe \"norm ^dei-\\<C-R>\\\"-\""))
|
||||||
assertState("""-myprop-: "my value"""")
|
assertState("-myprop-: \"my value\"")
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun doTest(command: String, before: String, after: String) {
|
||||||
|
myFixture.configureByText("a.java", before)
|
||||||
|
typeText(commandToKeys(command))
|
||||||
|
myFixture.checkResult(after)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
@ -1,109 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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 org.jetbrains.plugins.ideavim.ex.implementation.commands
|
|
||||||
|
|
||||||
import com.maddyhome.idea.vim.ex.ExOutputModel
|
|
||||||
import com.maddyhome.idea.vim.vimscript.model.commands.SmileCommand
|
|
||||||
import org.jetbrains.plugins.ideavim.VimTestCase
|
|
||||||
import org.junit.jupiter.api.Test
|
|
||||||
import kotlin.test.assertEquals
|
|
||||||
|
|
||||||
class SmileCommandTest : VimTestCase() {
|
|
||||||
|
|
||||||
private fun loadResourceContent(resourcePath: String): String {
|
|
||||||
return SmileCommand::class.java.getResourceAsStream(resourcePath)
|
|
||||||
?.bufferedReader()
|
|
||||||
?.use { it.readText() }
|
|
||||||
?: throw IllegalStateException("Could not load resource: $resourcePath")
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `test smile command with default file`() {
|
|
||||||
configureByText("\n")
|
|
||||||
typeText(commandToKeys("smile"))
|
|
||||||
|
|
||||||
val output: String = ExOutputModel.getInstance(fixture.editor).text.trimEnd()
|
|
||||||
val expectedContent: String = loadResourceContent(SmileCommand.DEFAULT_RESOURCE_PATH).trimEnd()
|
|
||||||
|
|
||||||
assertEquals(expectedContent, output)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `test smile command with kotlin file`() {
|
|
||||||
configureByText("\n")
|
|
||||||
configureByFileName("Test.kt")
|
|
||||||
typeText(commandToKeys("smile"))
|
|
||||||
|
|
||||||
val output = ExOutputModel.getInstance(fixture.editor).text.trimEnd()
|
|
||||||
val expectedContent = loadResourceContent(SmileCommand.KOTLIN_RESOURCE_PATH).trimEnd()
|
|
||||||
|
|
||||||
assertEquals(expectedContent, output)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `test smile command with kotlin script file`() {
|
|
||||||
configureByText("\n")
|
|
||||||
configureByFileName("Test.kts")
|
|
||||||
typeText(commandToKeys("smile"))
|
|
||||||
|
|
||||||
val output: String = ExOutputModel.getInstance(fixture.editor).text.trimEnd()
|
|
||||||
val expectedContent: String = loadResourceContent(SmileCommand.KOTLIN_RESOURCE_PATH).trimEnd()
|
|
||||||
|
|
||||||
assertEquals(expectedContent, output)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `test smile command with java file`() {
|
|
||||||
configureByText("\n")
|
|
||||||
configureByFileName("Test.java")
|
|
||||||
typeText(commandToKeys("smile"))
|
|
||||||
|
|
||||||
val output: String = ExOutputModel.getInstance(fixture.editor).text.trimEnd()
|
|
||||||
val expectedContent: String = loadResourceContent(SmileCommand.JAVA_RESOURCE_PATH).trimEnd()
|
|
||||||
|
|
||||||
assertEquals(expectedContent, output)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `test smile command with python file`() {
|
|
||||||
configureByText("\n")
|
|
||||||
configureByFileName("Test.py")
|
|
||||||
typeText(commandToKeys("smile"))
|
|
||||||
|
|
||||||
val output: String = ExOutputModel.getInstance(fixture.editor).text.trimEnd()
|
|
||||||
val expectedContent: String = loadResourceContent(SmileCommand.PYTHON_RESOURCE_PATH).trimEnd()
|
|
||||||
|
|
||||||
assertEquals(expectedContent, output)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `test smile command with unknown file extension`() {
|
|
||||||
configureByText("\n")
|
|
||||||
configureByFileName("Test.unknown")
|
|
||||||
typeText(commandToKeys("smile"))
|
|
||||||
|
|
||||||
val output: String = ExOutputModel.getInstance(fixture.editor).text.trimEnd()
|
|
||||||
val expectedContent: String = loadResourceContent(SmileCommand.DEFAULT_RESOURCE_PATH).trimEnd()
|
|
||||||
|
|
||||||
assertEquals(expectedContent, output)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `test smile command with gitignore file`() {
|
|
||||||
configureByText("\n")
|
|
||||||
configureByFileName(".gitignore")
|
|
||||||
typeText(commandToKeys("smile"))
|
|
||||||
|
|
||||||
val output: String = ExOutputModel.getInstance(fixture.editor).text.trimEnd()
|
|
||||||
val expectedContent: String = loadResourceContent(SmileCommand.DEFAULT_RESOURCE_PATH).trimEnd()
|
|
||||||
|
|
||||||
assertEquals(expectedContent, output)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -192,32 +192,6 @@ class SubstituteCommandTest : VimTestCase() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptionTest(
|
|
||||||
VimOption(TestOptionConstants.smartcase, doesntAffectTest = true),
|
|
||||||
VimOption(TestOptionConstants.ignorecase, doesntAffectTest = true),
|
|
||||||
)
|
|
||||||
@TestWithoutNeovim(reason = SkipNeovimReason.OPTION)
|
|
||||||
fun `test ampersand group`() {
|
|
||||||
doTest(
|
|
||||||
exCommand("s/a\\|b/z&/g"),
|
|
||||||
"${c}abcdefg",
|
|
||||||
"zazbcdefg",
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@OptionTest(
|
|
||||||
VimOption(TestOptionConstants.smartcase, doesntAffectTest = true),
|
|
||||||
VimOption(TestOptionConstants.ignorecase, doesntAffectTest = true),
|
|
||||||
)
|
|
||||||
@TestWithoutNeovim(reason = SkipNeovimReason.OPTION)
|
|
||||||
fun `test missing group`() {
|
|
||||||
doTest(
|
|
||||||
exCommand("s/b/<\\7>/"),
|
|
||||||
"${c}abc",
|
|
||||||
"a<>c",
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@OptionTest(
|
@OptionTest(
|
||||||
VimOption(TestOptionConstants.smartcase, doesntAffectTest = true),
|
VimOption(TestOptionConstants.smartcase, doesntAffectTest = true),
|
||||||
VimOption(TestOptionConstants.ignorecase, doesntAffectTest = true),
|
VimOption(TestOptionConstants.ignorecase, doesntAffectTest = true),
|
||||||
@ -1354,60 +1328,4 @@ class SubstituteCommandTest : VimTestCase() {
|
|||||||
" comment ",
|
" comment ",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// VIM-3510
|
|
||||||
@OptionTest(
|
|
||||||
VimOption(TestOptionConstants.smartcase, doesntAffectTest = true),
|
|
||||||
VimOption(TestOptionConstants.ignorecase, doesntAffectTest = true),
|
|
||||||
)
|
|
||||||
@TestWithoutNeovim(reason = SkipNeovimReason.OPTION)
|
|
||||||
fun `test replace action U`() {
|
|
||||||
doTest(
|
|
||||||
exCommand("s/\\(foo\\)/\\U\\1bar/"),
|
|
||||||
"${c}a foo",
|
|
||||||
"a FOOBAR",
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// VIM-3510
|
|
||||||
@OptionTest(
|
|
||||||
VimOption(TestOptionConstants.smartcase, doesntAffectTest = true),
|
|
||||||
VimOption(TestOptionConstants.ignorecase, doesntAffectTest = true),
|
|
||||||
)
|
|
||||||
@TestWithoutNeovim(reason = SkipNeovimReason.OPTION)
|
|
||||||
fun `test replace action U and E`() {
|
|
||||||
doTest(
|
|
||||||
exCommand("s/\\(foo\\)/\\U\\1\\ebar/"),
|
|
||||||
"${c}a foo",
|
|
||||||
"a FOObar",
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// VIM-3510
|
|
||||||
@OptionTest(
|
|
||||||
VimOption(TestOptionConstants.smartcase, doesntAffectTest = true),
|
|
||||||
VimOption(TestOptionConstants.ignorecase, doesntAffectTest = true),
|
|
||||||
)
|
|
||||||
@TestWithoutNeovim(reason = SkipNeovimReason.OPTION)
|
|
||||||
fun `test replace action u`() {
|
|
||||||
doTest(
|
|
||||||
exCommand("s/\\(foo\\)/\\u\\1bar/"),
|
|
||||||
"${c}a foo",
|
|
||||||
"a Foobar",
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// VIM-3510
|
|
||||||
@OptionTest(
|
|
||||||
VimOption(TestOptionConstants.smartcase, doesntAffectTest = true),
|
|
||||||
VimOption(TestOptionConstants.ignorecase, doesntAffectTest = true),
|
|
||||||
)
|
|
||||||
@TestWithoutNeovim(reason = SkipNeovimReason.OPTION)
|
|
||||||
fun `test replace action u and empty group`() {
|
|
||||||
doTest(
|
|
||||||
exCommand("s/a foo\\(\\)/a foo\\u\\1bar/"),
|
|
||||||
"${c}a foo",
|
|
||||||
"a fooBar",
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,6 @@ package org.jetbrains.plugins.ideavim.ex.implementation.expressions.datatypes
|
|||||||
|
|
||||||
import com.maddyhome.idea.vim.vimscript.model.datatypes.VimFloat
|
import com.maddyhome.idea.vim.vimscript.model.datatypes.VimFloat
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import java.util.Locale
|
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
class VimFloatTest {
|
class VimFloatTest {
|
||||||
@ -24,15 +23,4 @@ class VimFloatTest {
|
|||||||
fun `round 7 digits`() {
|
fun `round 7 digits`() {
|
||||||
assertEquals("1.0", VimFloat(0.9999999).toString())
|
assertEquals("1.0", VimFloat(0.9999999).toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `use point as decimal separator always`() {
|
|
||||||
val oldLocale = Locale.getDefault()
|
|
||||||
Locale.setDefault(Locale.GERMANY) // In Germany, they use a comma as a decimal separator, i.e., "3,14".
|
|
||||||
try {
|
|
||||||
assertEquals("3.14", VimFloat(3.14).toString())
|
|
||||||
} finally {
|
|
||||||
Locale.setDefault(oldLocale)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,6 @@ package org.jetbrains.plugins.ideavim.ex.implementation.expressions.operators
|
|||||||
import com.maddyhome.idea.vim.ex.ExException
|
import com.maddyhome.idea.vim.ex.ExException
|
||||||
import com.maddyhome.idea.vim.vimscript.model.datatypes.VimString
|
import com.maddyhome.idea.vim.vimscript.model.datatypes.VimString
|
||||||
import com.maddyhome.idea.vim.vimscript.parser.VimscriptParser
|
import com.maddyhome.idea.vim.vimscript.parser.VimscriptParser
|
||||||
import org.jetbrains.plugins.ideavim.VimTestCase
|
|
||||||
import org.jetbrains.plugins.ideavim.ex.evaluate
|
import org.jetbrains.plugins.ideavim.ex.evaluate
|
||||||
import org.jetbrains.plugins.ideavim.productForArguments
|
import org.jetbrains.plugins.ideavim.productForArguments
|
||||||
import org.junit.jupiter.params.ParameterizedTest
|
import org.junit.jupiter.params.ParameterizedTest
|
||||||
@ -19,7 +18,7 @@ import org.junit.jupiter.params.provider.Arguments
|
|||||||
import org.junit.jupiter.params.provider.MethodSource
|
import org.junit.jupiter.params.provider.MethodSource
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
class ConcatenationOperatorTest : VimTestCase() {
|
class ConcatenationOperatorTest {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@ -48,7 +47,7 @@ class ConcatenationOperatorTest : VimTestCase() {
|
|||||||
try {
|
try {
|
||||||
VimscriptParser.parseExpression("3.4$sp1$operator${sp2}2")!!.evaluate()
|
VimscriptParser.parseExpression("3.4$sp1$operator${sp2}2")!!.evaluate()
|
||||||
} catch (e: ExException) {
|
} catch (e: ExException) {
|
||||||
assertEquals("E806: Using a Float as a String", e.message)
|
assertEquals("E806: using Float as a String", e.message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,7 +57,7 @@ class ConcatenationOperatorTest : VimTestCase() {
|
|||||||
try {
|
try {
|
||||||
VimscriptParser.parseExpression("3.4$sp1$operator${sp2}2.2")!!.evaluate()
|
VimscriptParser.parseExpression("3.4$sp1$operator${sp2}2.2")!!.evaluate()
|
||||||
} catch (e: ExException) {
|
} catch (e: ExException) {
|
||||||
assertEquals("E806: Using a Float as a String", e.message)
|
assertEquals("E806: using Float as a String", e.message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,7 +67,7 @@ class ConcatenationOperatorTest : VimTestCase() {
|
|||||||
try {
|
try {
|
||||||
VimscriptParser.parseExpression("'string'$sp1$operator${sp2}3.4")!!.evaluate()
|
VimscriptParser.parseExpression("'string'$sp1$operator${sp2}3.4")!!.evaluate()
|
||||||
} catch (e: ExException) {
|
} catch (e: ExException) {
|
||||||
assertEquals("E806: Using a Float as a String", e.message)
|
assertEquals("E806: using Float as a String", e.message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,80 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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 org.jetbrains.plugins.ideavim.ex.implementation.expressions.operators
|
|
||||||
|
|
||||||
import com.maddyhome.idea.vim.api.globalOptions
|
|
||||||
import com.maddyhome.idea.vim.api.injector
|
|
||||||
import com.maddyhome.idea.vim.vimscript.parser.VimscriptParser
|
|
||||||
import org.jetbrains.plugins.ideavim.VimTestCase
|
|
||||||
import org.jetbrains.plugins.ideavim.ex.evaluate
|
|
||||||
import org.junit.jupiter.api.Test
|
|
||||||
import kotlin.test.assertFalse
|
|
||||||
import kotlin.test.assertTrue
|
|
||||||
|
|
||||||
class DoesNotMatchOperatorTest : VimTestCase() {
|
|
||||||
@Test
|
|
||||||
fun `test does not match operator returns false when pattern matches string`() {
|
|
||||||
assertFalse(evaluate("'lorem ipsum' !~ 'l*sum'").asBoolean())
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `test does not match operator returns true when pattern does not match string`() {
|
|
||||||
assertTrue(evaluate("'lorem ipsum' !~ 'l*foo'").asBoolean())
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `test does not match operator returns false when pattern matches case`() {
|
|
||||||
assertFalse(evaluate("'Lorem Ipsum' !~ 'L*I'").asBoolean())
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `test does not match operator returns true when pattern does not match case`() {
|
|
||||||
assertTrue(evaluate("'Lorem Ipsum' !~ 'l*i'").asBoolean())
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `test does not match operator with 'noignorecase' returns false with different case pattern`() {
|
|
||||||
injector.globalOptions().ignorecase = true // Default is false
|
|
||||||
assertFalse(evaluate("'Lorem Ipsum' !~ 'l*i'").asBoolean())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Case-sensitive operator
|
|
||||||
@Test
|
|
||||||
fun `test case-sensitive does not match operator returns false when pattern matches string`() {
|
|
||||||
assertFalse(evaluate("'lorem ipsum' !~# 'l*sum'").asBoolean())
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `test case-sensitive does not match operator returns true when pattern does not match string`() {
|
|
||||||
assertTrue(evaluate("'lorem ipsum' !~# 'l*foo'").asBoolean())
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `test case-sensitive does not match operator returns true when pattern does not match string case`() {
|
|
||||||
assertTrue(evaluate("'lorem ipsum' !~# 'L*Sum'").asBoolean())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Case-insensitive operator
|
|
||||||
@Test
|
|
||||||
fun `test case-insensitive does not match operator returns false when pattern matches string`() {
|
|
||||||
assertFalse(evaluate("'lorem ipsum' !~? 'l*sum'").asBoolean())
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `test case-insensitive does not match operator returns true when pattern does not match string`() {
|
|
||||||
assertTrue(evaluate("'lorem ipsum' !~? 'l*foo'").asBoolean())
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `test case-insensitive does not match operator returns false when pattern does not match string case`() {
|
|
||||||
assertFalse(evaluate("'lorem ipsum' !~? 'L*Sum'").asBoolean())
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun evaluate(expression: String) = VimscriptParser.parseExpression(expression)!!.evaluate()
|
|
||||||
}
|
|
@ -8,9 +8,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.plugins.ideavim.ex.implementation.expressions.operators
|
package org.jetbrains.plugins.ideavim.ex.implementation.expressions.operators
|
||||||
|
|
||||||
import com.maddyhome.idea.vim.vimscript.model.datatypes.VimDataType
|
|
||||||
import com.maddyhome.idea.vim.vimscript.model.datatypes.VimDictionary
|
|
||||||
import com.maddyhome.idea.vim.vimscript.model.datatypes.VimFloat
|
|
||||||
import com.maddyhome.idea.vim.vimscript.model.datatypes.VimInt
|
import com.maddyhome.idea.vim.vimscript.model.datatypes.VimInt
|
||||||
import com.maddyhome.idea.vim.vimscript.model.datatypes.VimList
|
import com.maddyhome.idea.vim.vimscript.model.datatypes.VimList
|
||||||
import com.maddyhome.idea.vim.vimscript.model.datatypes.VimString
|
import com.maddyhome.idea.vim.vimscript.model.datatypes.VimString
|
||||||
@ -23,67 +20,25 @@ import kotlin.test.assertEquals
|
|||||||
class FalsyOperatorTest : VimTestCase() {
|
class FalsyOperatorTest : VimTestCase() {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `test non-zero Number treated as truthy`() {
|
fun `left expression is true`() {
|
||||||
assertEquals(VimInt(42), VimscriptParser.parseExpression("42 ?? 999")!!.evaluate())
|
assertEquals(VimInt("42"), VimscriptParser.parseExpression("42 ?? 999")!!.evaluate())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `test non-zero negative Number treated as truthy`() {
|
fun `left expression is false`() {
|
||||||
assertEquals(VimInt(-1), VimscriptParser.parseExpression("-1 ?? 999")!!.evaluate())
|
assertEquals(VimInt("42"), VimscriptParser.parseExpression("0 ?? 42")!!.evaluate())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `test Number 0 is treated as falsy`() {
|
fun `empty list as a left expression`() {
|
||||||
assertEquals(VimInt(42), VimscriptParser.parseExpression("0 ?? 42")!!.evaluate())
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `test zero Float is treated as falsy`() {
|
|
||||||
assertEquals(VimInt(42), VimscriptParser.parseExpression("0.0 ?? 42")!!.evaluate())
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `test non-zero Float treated as truthy`() {
|
|
||||||
assertEquals(VimFloat(42.0), VimscriptParser.parseExpression("42.0 ?? 999")!!.evaluate())
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `test empty String treated as falsy`() {
|
|
||||||
assertEquals(VimString("string is empty"), VimscriptParser.parseExpression("'' ?? 'string is empty'")!!.evaluate())
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `test String '0' treated as falsy`() {
|
|
||||||
assertEquals(VimString("string is empty"), VimscriptParser.parseExpression("'0' ?? 'string is empty'")!!.evaluate())
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `test non-empty String treated as truthy`() {
|
|
||||||
assertEquals(VimString("string is not empty"), VimscriptParser.parseExpression("'string is not empty' ?? 'string is empty'")!!.evaluate())
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `test empty list treated as falsy`() {
|
|
||||||
assertEquals(VimString("list is empty"), VimscriptParser.parseExpression("[] ?? 'list is empty'")!!.evaluate())
|
assertEquals(VimString("list is empty"), VimscriptParser.parseExpression("[] ?? 'list is empty'")!!.evaluate())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `test non-empty List treated as truthy`() {
|
fun `nonempty list as a left expression`() {
|
||||||
assertEquals(
|
assertEquals(
|
||||||
VimList(mutableListOf(VimInt(1), VimInt(2), VimInt(3))),
|
VimList(mutableListOf(VimInt(1), VimInt(2), VimInt(3))),
|
||||||
VimscriptParser.parseExpression("[1, 2, 3] ?? 'list is empty'")!!.evaluate(),
|
VimscriptParser.parseExpression("[1, 2, 3] ?? 'list is empty'")!!.evaluate(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `test empty Dictionary treated as falsy`() {
|
|
||||||
assertEquals(VimString("dict is empty"), VimscriptParser.parseExpression("{} ?? 'dict is empty'")!!.evaluate())
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `test non-empty Dictionary treated as truthy`() {
|
|
||||||
val dictionary = LinkedHashMap<VimString, VimDataType>()
|
|
||||||
dictionary.put(VimString("1"), VimInt(1))
|
|
||||||
assertEquals(VimDictionary(dictionary), VimscriptParser.parseExpression("{'1': 1} ?? 'dict is empty'")!!.evaluate())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,80 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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 org.jetbrains.plugins.ideavim.ex.implementation.expressions.operators
|
|
||||||
|
|
||||||
import com.maddyhome.idea.vim.api.globalOptions
|
|
||||||
import com.maddyhome.idea.vim.api.injector
|
|
||||||
import com.maddyhome.idea.vim.vimscript.parser.VimscriptParser
|
|
||||||
import org.jetbrains.plugins.ideavim.VimTestCase
|
|
||||||
import org.jetbrains.plugins.ideavim.ex.evaluate
|
|
||||||
import org.junit.jupiter.api.Test
|
|
||||||
import kotlin.test.assertFalse
|
|
||||||
import kotlin.test.assertTrue
|
|
||||||
|
|
||||||
class MatchesOperatorTest : VimTestCase() {
|
|
||||||
@Test
|
|
||||||
fun `test matches operator returns true when pattern matches string`() {
|
|
||||||
assertTrue(evaluate("'lorem ipsum' =~ 'l*sum'").asBoolean())
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `test matches operator returns false when pattern does not match string`() {
|
|
||||||
assertFalse(evaluate("'lorem ipsum' =~ 'l*foo'").asBoolean())
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `test matches operator returns true when pattern matches case`() {
|
|
||||||
assertTrue(evaluate("'Lorem Ipsum' =~ 'L*I'").asBoolean())
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `test matches operator returns false when pattern does not match case`() {
|
|
||||||
assertFalse(evaluate("'Lorem Ipsum' =~ 'l*i'").asBoolean())
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `test matches operator with 'noignorecase' returns true with different case pattern`() {
|
|
||||||
injector.globalOptions().ignorecase = true // Default is false
|
|
||||||
assertTrue(evaluate("'Lorem Ipsum' =~ 'l*i'").asBoolean())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Case-sensitive operator
|
|
||||||
@Test
|
|
||||||
fun `test case-sensitive matches operator returns true when pattern matches string`() {
|
|
||||||
assertTrue(evaluate("'lorem ipsum' =~# 'l*sum'").asBoolean())
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `test case-sensitive matches operator returns false when pattern does not match string`() {
|
|
||||||
assertFalse(evaluate("'lorem ipsum' =~# 'l*foo'").asBoolean())
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `test case-sensitive matches operator returns false when pattern does not match string case`() {
|
|
||||||
assertFalse(evaluate("'lorem ipsum' =~# 'L*Sum'").asBoolean())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Case-insensitive operator
|
|
||||||
@Test
|
|
||||||
fun `test case-insensitive matches operator returns true when pattern matches string`() {
|
|
||||||
assertTrue(evaluate("'lorem ipsum' =~? 'l*sum'").asBoolean())
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `test case-insensitive matches operator returns false when pattern does not match string`() {
|
|
||||||
assertFalse(evaluate("'lorem ipsum' =~? 'l*foo'").asBoolean())
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `test case-insensitive matches operator returns true when pattern does not match string case`() {
|
|
||||||
assertTrue(evaluate("'lorem ipsum' =~? 'L*Sum'").asBoolean())
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun evaluate(expression: String) = VimscriptParser.parseExpression(expression)!!.evaluate()
|
|
||||||
}
|
|
@ -37,7 +37,8 @@ class ColFunctionTest : VimTestCase() {
|
|||||||
// With selection - make sure to delete the '<,'> that is automatically prepended when entering Command-line mode
|
// With selection - make sure to delete the '<,'> that is automatically prepended when entering Command-line mode
|
||||||
// with a selection
|
// with a selection
|
||||||
typeText("vll")
|
typeText("vll")
|
||||||
assertCommandOutput("""<C-U>echo col("v")""", "5")
|
typeText(":<C-U>echo col(\"v\")<CR>") // enterCommand/assertCommandOutput cannot handle <C-U>!
|
||||||
|
assertExOutput("5")
|
||||||
|
|
||||||
// Remove selection and check again - note that exiting Command-line mode removes selection and switches back to
|
// Remove selection and check again - note that exiting Command-line mode removes selection and switches back to
|
||||||
// Normal. This <esc> does nothing
|
// Normal. This <esc> does nothing
|
||||||
|
@ -32,7 +32,8 @@ class LineFunctionTest : VimTestCase() {
|
|||||||
// With selection - make sure to delete the '<,'> that is automatically prepended when entering Command-line mode
|
// With selection - make sure to delete the '<,'> that is automatically prepended when entering Command-line mode
|
||||||
// with a selection
|
// with a selection
|
||||||
typeText("vj")
|
typeText("vj")
|
||||||
assertCommandOutput("""<C-U>echo line("v")""", "3")
|
typeText(""":<C-U>echo line("v")<CR>""") // enterCommand/assertCommandOutput cannot handle <C-U>!
|
||||||
|
assertExOutput("3")
|
||||||
|
|
||||||
// Remove selection and check again - note that exiting Command-line mode removes selection and switches back to
|
// Remove selection and check again - note that exiting Command-line mode removes selection and switches back to
|
||||||
// Normal. This <esc> does nothing
|
// Normal. This <esc> does nothing
|
||||||
@ -45,50 +46,4 @@ class LineFunctionTest : VimTestCase() {
|
|||||||
"0 1 5 0 5 0"
|
"0 1 5 0 5 0"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `test line with selection`() {
|
|
||||||
doTest(
|
|
||||||
listOf("V2j", "q"),
|
|
||||||
"""
|
|
||||||
|1
|
|
||||||
|${c}2
|
|
||||||
|3
|
|
||||||
|4
|
|
||||||
|5
|
|
||||||
""".trimMargin(),
|
|
||||||
"""
|
|
||||||
|1
|
|
||||||
|2
|
|
||||||
|3
|
|
||||||
|4 - line(v)==${c}2
|
|
||||||
|5
|
|
||||||
""".trimMargin(),
|
|
||||||
) {
|
|
||||||
enterCommand("vmap <expr> q '<Esc>a - line(v)=='.line('v').'<Esc>'")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `test line with reverse selection`() {
|
|
||||||
doTest(
|
|
||||||
listOf("V2k", "q"),
|
|
||||||
"""
|
|
||||||
|1
|
|
||||||
|2
|
|
||||||
|3
|
|
||||||
|${c}4
|
|
||||||
|5
|
|
||||||
""".trimMargin(),
|
|
||||||
"""
|
|
||||||
|1
|
|
||||||
|2 - line(v)==${c}4
|
|
||||||
|3
|
|
||||||
|4
|
|
||||||
|5
|
|
||||||
""".trimMargin(),
|
|
||||||
) {
|
|
||||||
enterCommand("vmap <expr> q '<Esc>a - line(v)=='.line('v').'<Esc>'")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,9 @@ class RegisterVariableTest : VimTestCase() {
|
|||||||
typeText("vl\"zy")
|
typeText("vl\"zy")
|
||||||
val vimEditor = fixture.editor.vim
|
val vimEditor = fixture.editor.vim
|
||||||
val context = injector.executionContextManager.getEditorExecutionContext(vimEditor)
|
val context = injector.executionContextManager.getEditorExecutionContext(vimEditor)
|
||||||
val register = injector.registerGroup.getRegisters(vimEditor, context).first { reg -> reg.name == 'z' }
|
val register = injector.registerGroup.getRegisters(vimEditor, context)
|
||||||
|
.filter { reg -> reg.name == 'z' }
|
||||||
|
.first()
|
||||||
assertEquals("ab", register.text)
|
assertEquals("ab", register.text)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.plugins.ideavim.extension.miniai
|
package org.jetbrains.plugins.ideavim.extension.miniai
|
||||||
|
|
||||||
|
import com.intellij.ide.highlighter.JavaFileType
|
||||||
import com.maddyhome.idea.vim.state.mode.Mode
|
import com.maddyhome.idea.vim.state.mode.Mode
|
||||||
import org.jetbrains.plugins.ideavim.VimTestCase
|
import org.jetbrains.plugins.ideavim.VimTestCase
|
||||||
import org.junit.jupiter.api.BeforeEach
|
import org.junit.jupiter.api.BeforeEach
|
||||||
@ -30,6 +31,7 @@ class MiniAIExtensionTest : VimTestCase() {
|
|||||||
"<caret>This is a \"'simple'\" test",
|
"<caret>This is a \"'simple'\" test",
|
||||||
"This is a \"<caret>\" test",
|
"This is a \"<caret>\" test",
|
||||||
Mode.INSERT,
|
Mode.INSERT,
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -42,6 +44,7 @@ class MiniAIExtensionTest : VimTestCase() {
|
|||||||
"'balanced'false <caret>string'balanced'",
|
"'balanced'false <caret>string'balanced'",
|
||||||
"'balanced'false string'<caret>'",
|
"'balanced'false string'<caret>'",
|
||||||
Mode.INSERT,
|
Mode.INSERT,
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -54,6 +57,7 @@ class MiniAIExtensionTest : VimTestCase() {
|
|||||||
"\"balanced\"false <caret>string\"balanced\"",
|
"\"balanced\"false <caret>string\"balanced\"",
|
||||||
"\"balanced\"false string\"<caret>\"",
|
"\"balanced\"false string\"<caret>\"",
|
||||||
Mode.INSERT,
|
Mode.INSERT,
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -66,6 +70,7 @@ class MiniAIExtensionTest : VimTestCase() {
|
|||||||
"`balanced`false <caret>string`balanced`",
|
"`balanced`false <caret>string`balanced`",
|
||||||
"`balanced`false string`<caret>`",
|
"`balanced`false string`<caret>`",
|
||||||
Mode.INSERT,
|
Mode.INSERT,
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -82,6 +87,7 @@ class MiniAIExtensionTest : VimTestCase() {
|
|||||||
'""",
|
'""",
|
||||||
"''",
|
"''",
|
||||||
Mode.INSERT,
|
Mode.INSERT,
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -97,6 +103,7 @@ class MiniAIExtensionTest : VimTestCase() {
|
|||||||
"""",
|
"""",
|
||||||
"\"\"",
|
"\"\"",
|
||||||
Mode.INSERT,
|
Mode.INSERT,
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -113,6 +120,7 @@ class MiniAIExtensionTest : VimTestCase() {
|
|||||||
`""",
|
`""",
|
||||||
"``",
|
"``",
|
||||||
Mode.INSERT,
|
Mode.INSERT,
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -134,6 +142,7 @@ class MiniAIExtensionTest : VimTestCase() {
|
|||||||
'<caret>'
|
'<caret>'
|
||||||
""",
|
""",
|
||||||
Mode.INSERT,
|
Mode.INSERT,
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -152,6 +161,7 @@ print(something)
|
|||||||
{}
|
{}
|
||||||
""",
|
""",
|
||||||
Mode.INSERT,
|
Mode.INSERT,
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -173,6 +183,7 @@ print(something)
|
|||||||
}
|
}
|
||||||
""".trimIndent(),
|
""".trimIndent(),
|
||||||
Mode.INSERT,
|
Mode.INSERT,
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -185,6 +196,7 @@ print(something)
|
|||||||
"<caret>This is a `'simple'` test",
|
"<caret>This is a `'simple'` test",
|
||||||
"This is a `<caret>` test",
|
"This is a `<caret>` test",
|
||||||
Mode.INSERT,
|
Mode.INSERT,
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -198,6 +210,7 @@ print(something)
|
|||||||
"<caret>This is a '\"simple\"' test",
|
"<caret>This is a '\"simple\"' test",
|
||||||
"This is a '<caret>' test",
|
"This is a '<caret>' test",
|
||||||
Mode.INSERT,
|
Mode.INSERT,
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -209,6 +222,7 @@ print(something)
|
|||||||
"this 'simple<caret> \"test\"'",
|
"this 'simple<caret> \"test\"'",
|
||||||
"this '<caret>'",
|
"this '<caret>'",
|
||||||
Mode.INSERT,
|
Mode.INSERT,
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -220,6 +234,7 @@ print(something)
|
|||||||
"this 'simple<caret> \"test\"'",
|
"this 'simple<caret> \"test\"'",
|
||||||
"this '<caret>'",
|
"this '<caret>'",
|
||||||
Mode.NORMAL(),
|
Mode.NORMAL(),
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -231,6 +246,7 @@ print(something)
|
|||||||
"this \"simple<caret> 'test'\"",
|
"this \"simple<caret> 'test'\"",
|
||||||
"this \"<caret>\"",
|
"this \"<caret>\"",
|
||||||
Mode.INSERT,
|
Mode.INSERT,
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -242,6 +258,7 @@ print(something)
|
|||||||
"this \"simple<caret> 'test'\"",
|
"this \"simple<caret> 'test'\"",
|
||||||
"this \"<caret>\"",
|
"this \"<caret>\"",
|
||||||
Mode.NORMAL(),
|
Mode.NORMAL(),
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -253,6 +270,7 @@ print(something)
|
|||||||
"this `simple<caret> \"test\"`",
|
"this `simple<caret> \"test\"`",
|
||||||
"this `<caret>`",
|
"this `<caret>`",
|
||||||
Mode.INSERT,
|
Mode.INSERT,
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -264,6 +282,7 @@ print(something)
|
|||||||
"this `simple<caret> \"test\"`",
|
"this `simple<caret> \"test\"`",
|
||||||
"this `<caret>`",
|
"this `<caret>`",
|
||||||
Mode.NORMAL(),
|
Mode.NORMAL(),
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -275,6 +294,7 @@ print(something)
|
|||||||
"this 'simple<caret> \"test\"'",
|
"this 'simple<caret> \"test\"'",
|
||||||
"this <caret>",
|
"this <caret>",
|
||||||
Mode.INSERT,
|
Mode.INSERT,
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -286,6 +306,7 @@ print(something)
|
|||||||
"this 'simple<caret> \"test\"' test",
|
"this 'simple<caret> \"test\"' test",
|
||||||
"this <caret> test",
|
"this <caret> test",
|
||||||
Mode.NORMAL(),
|
Mode.NORMAL(),
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -297,6 +318,7 @@ print(something)
|
|||||||
"this \"simple<caret> 'test'\"",
|
"this \"simple<caret> 'test'\"",
|
||||||
"this <caret>",
|
"this <caret>",
|
||||||
Mode.INSERT,
|
Mode.INSERT,
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -308,6 +330,7 @@ print(something)
|
|||||||
"this \"simple<caret> 'test'\" test",
|
"this \"simple<caret> 'test'\" test",
|
||||||
"this <caret> test",
|
"this <caret> test",
|
||||||
Mode.NORMAL(),
|
Mode.NORMAL(),
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -319,6 +342,7 @@ print(something)
|
|||||||
"this `simple<caret> \"test\"`",
|
"this `simple<caret> \"test\"`",
|
||||||
"this <caret>",
|
"this <caret>",
|
||||||
Mode.INSERT,
|
Mode.INSERT,
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -330,6 +354,7 @@ print(something)
|
|||||||
"this `simple<caret> \"test\"` test",
|
"this `simple<caret> \"test\"` test",
|
||||||
"this <caret> test",
|
"this <caret> test",
|
||||||
Mode.NORMAL(),
|
Mode.NORMAL(),
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -342,6 +367,7 @@ print(something)
|
|||||||
"this 'simple \"<caret>test\"'",
|
"this 'simple \"<caret>test\"'",
|
||||||
"this 'simple <caret>'",
|
"this 'simple <caret>'",
|
||||||
Mode.INSERT,
|
Mode.INSERT,
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -353,6 +379,7 @@ print(something)
|
|||||||
"this 'simple \"<caret>test\"'",
|
"this 'simple \"<caret>test\"'",
|
||||||
"this 'simple '",
|
"this 'simple '",
|
||||||
Mode.NORMAL(),
|
Mode.NORMAL(),
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -365,6 +392,7 @@ print(something)
|
|||||||
"this 'simple \"nested `<caret>test`\"'",
|
"this 'simple \"nested `<caret>test`\"'",
|
||||||
"this 'simple \"nested <caret>\"'",
|
"this 'simple \"nested <caret>\"'",
|
||||||
Mode.INSERT,
|
Mode.INSERT,
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -376,6 +404,7 @@ print(something)
|
|||||||
"this 'simple \"nested `<caret>test`\"'",
|
"this 'simple \"nested `<caret>test`\"'",
|
||||||
"this 'simple \"nested <caret>\"'",
|
"this 'simple \"nested <caret>\"'",
|
||||||
Mode.NORMAL(),
|
Mode.NORMAL(),
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -387,6 +416,7 @@ print(something)
|
|||||||
"<caret>This is a 'simple' test",
|
"<caret>This is a 'simple' test",
|
||||||
"This is a '<caret>' test",
|
"This is a '<caret>' test",
|
||||||
Mode.INSERT,
|
Mode.INSERT,
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -399,6 +429,7 @@ print(something)
|
|||||||
"<caret>This is a 'simple test",
|
"<caret>This is a 'simple test",
|
||||||
"<caret>This is a 'simple test",
|
"<caret>This is a 'simple test",
|
||||||
Mode.NORMAL(),
|
Mode.NORMAL(),
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -411,6 +442,7 @@ print(something)
|
|||||||
"<caret>This is a \"simple\" test",
|
"<caret>This is a \"simple\" test",
|
||||||
"This is a \"<caret>\" test",
|
"This is a \"<caret>\" test",
|
||||||
Mode.INSERT,
|
Mode.INSERT,
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -423,6 +455,7 @@ print(something)
|
|||||||
"<caret>This is a \"simple test",
|
"<caret>This is a \"simple test",
|
||||||
"<caret>This is a \"simple test",
|
"<caret>This is a \"simple test",
|
||||||
Mode.NORMAL(),
|
Mode.NORMAL(),
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -435,6 +468,7 @@ print(something)
|
|||||||
"<caret>This is a `simple` test",
|
"<caret>This is a `simple` test",
|
||||||
"This is a `<caret>` test",
|
"This is a `<caret>` test",
|
||||||
Mode.INSERT,
|
Mode.INSERT,
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -447,6 +481,7 @@ print(something)
|
|||||||
"<caret>This is a `simple test",
|
"<caret>This is a `simple test",
|
||||||
"<caret>This is a `simple test",
|
"<caret>This is a `simple test",
|
||||||
Mode.NORMAL(),
|
Mode.NORMAL(),
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -459,6 +494,7 @@ print(something)
|
|||||||
"<caret>This is a 'simple' test",
|
"<caret>This is a 'simple' test",
|
||||||
"This is a <caret> test",
|
"This is a <caret> test",
|
||||||
Mode.INSERT,
|
Mode.INSERT,
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -471,6 +507,7 @@ print(something)
|
|||||||
"<caret>This is a 'simple test",
|
"<caret>This is a 'simple test",
|
||||||
"<caret>This is a 'simple test",
|
"<caret>This is a 'simple test",
|
||||||
Mode.NORMAL(),
|
Mode.NORMAL(),
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -483,6 +520,7 @@ print(something)
|
|||||||
"<caret>This is a \"simple\" test",
|
"<caret>This is a \"simple\" test",
|
||||||
"This is a <caret> test",
|
"This is a <caret> test",
|
||||||
Mode.INSERT,
|
Mode.INSERT,
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -495,6 +533,7 @@ print(something)
|
|||||||
"<caret>This is a \"simple test",
|
"<caret>This is a \"simple test",
|
||||||
"<caret>This is a \"simple test",
|
"<caret>This is a \"simple test",
|
||||||
Mode.NORMAL(),
|
Mode.NORMAL(),
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -506,6 +545,7 @@ print(something)
|
|||||||
"<caret>This is a `simple` test",
|
"<caret>This is a `simple` test",
|
||||||
"This is a <caret> test",
|
"This is a <caret> test",
|
||||||
Mode.INSERT,
|
Mode.INSERT,
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -518,6 +558,7 @@ print(something)
|
|||||||
"<caret>This is a `simple test",
|
"<caret>This is a `simple test",
|
||||||
"<caret>This is a `simple test",
|
"<caret>This is a `simple test",
|
||||||
Mode.NORMAL(),
|
Mode.NORMAL(),
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -529,6 +570,7 @@ print(something)
|
|||||||
"<caret>This is a (simple) test",
|
"<caret>This is a (simple) test",
|
||||||
"This is a (<caret>) test",
|
"This is a (<caret>) test",
|
||||||
Mode.INSERT,
|
Mode.INSERT,
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -541,6 +583,7 @@ print(something)
|
|||||||
"<caret>This is a (simple test",
|
"<caret>This is a (simple test",
|
||||||
"<caret>This is a (simple test",
|
"<caret>This is a (simple test",
|
||||||
Mode.NORMAL(),
|
Mode.NORMAL(),
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -553,6 +596,7 @@ print(something)
|
|||||||
"<caret>This is a [simple] test",
|
"<caret>This is a [simple] test",
|
||||||
"This is a [<caret>] test",
|
"This is a [<caret>] test",
|
||||||
Mode.INSERT,
|
Mode.INSERT,
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -565,6 +609,7 @@ print(something)
|
|||||||
"<caret>This is a [simple test",
|
"<caret>This is a [simple test",
|
||||||
"<caret>This is a [simple test",
|
"<caret>This is a [simple test",
|
||||||
Mode.NORMAL(),
|
Mode.NORMAL(),
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -577,6 +622,7 @@ print(something)
|
|||||||
"<caret>This is a {simple} test",
|
"<caret>This is a {simple} test",
|
||||||
"This is a {<caret>} test",
|
"This is a {<caret>} test",
|
||||||
Mode.INSERT,
|
Mode.INSERT,
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -589,6 +635,7 @@ print(something)
|
|||||||
"<caret>This is a {simple test",
|
"<caret>This is a {simple test",
|
||||||
"<caret>This is a {simple test",
|
"<caret>This is a {simple test",
|
||||||
Mode.NORMAL(),
|
Mode.NORMAL(),
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -601,6 +648,7 @@ print(something)
|
|||||||
"<caret>This is a (simple) test",
|
"<caret>This is a (simple) test",
|
||||||
"This is a <caret> test",
|
"This is a <caret> test",
|
||||||
Mode.INSERT,
|
Mode.INSERT,
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -613,6 +661,7 @@ print(something)
|
|||||||
"<caret>This is a (simple test",
|
"<caret>This is a (simple test",
|
||||||
"<caret>This is a (simple test",
|
"<caret>This is a (simple test",
|
||||||
Mode.NORMAL(),
|
Mode.NORMAL(),
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -625,6 +674,7 @@ print(something)
|
|||||||
"<caret>This is a [simple] test",
|
"<caret>This is a [simple] test",
|
||||||
"This is a <caret> test",
|
"This is a <caret> test",
|
||||||
Mode.INSERT,
|
Mode.INSERT,
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -636,6 +686,7 @@ print(something)
|
|||||||
"<caret>This is a [simple test",
|
"<caret>This is a [simple test",
|
||||||
"<caret>This is a [simple test",
|
"<caret>This is a [simple test",
|
||||||
Mode.NORMAL(),
|
Mode.NORMAL(),
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -648,6 +699,7 @@ print(something)
|
|||||||
"<caret>This is a {simple} test",
|
"<caret>This is a {simple} test",
|
||||||
"This is a <caret> test",
|
"This is a <caret> test",
|
||||||
Mode.INSERT,
|
Mode.INSERT,
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -660,6 +712,7 @@ print(something)
|
|||||||
"<caret>This is a {simple test",
|
"<caret>This is a {simple test",
|
||||||
"<caret>This is a {simple test",
|
"<caret>This is a {simple test",
|
||||||
Mode.NORMAL(),
|
Mode.NORMAL(),
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -672,6 +725,7 @@ print(something)
|
|||||||
"<caret>This is a 'simple' test",
|
"<caret>This is a 'simple' test",
|
||||||
"This is a '<caret>' test",
|
"This is a '<caret>' test",
|
||||||
Mode.NORMAL(),
|
Mode.NORMAL(),
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -684,6 +738,7 @@ print(something)
|
|||||||
"<caret>This is a 'simple test",
|
"<caret>This is a 'simple test",
|
||||||
"<caret>This is a 'simple test",
|
"<caret>This is a 'simple test",
|
||||||
Mode.NORMAL(),
|
Mode.NORMAL(),
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -696,6 +751,7 @@ print(something)
|
|||||||
"<caret>This is a \"simple\" test",
|
"<caret>This is a \"simple\" test",
|
||||||
"This is a \"<caret>\" test",
|
"This is a \"<caret>\" test",
|
||||||
Mode.NORMAL(),
|
Mode.NORMAL(),
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -708,6 +764,7 @@ print(something)
|
|||||||
"<caret>This is a \"simple test",
|
"<caret>This is a \"simple test",
|
||||||
"<caret>This is a \"simple test",
|
"<caret>This is a \"simple test",
|
||||||
Mode.NORMAL(),
|
Mode.NORMAL(),
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -720,6 +777,7 @@ print(something)
|
|||||||
"<caret>This is a `simple` test",
|
"<caret>This is a `simple` test",
|
||||||
"This is a `<caret>` test",
|
"This is a `<caret>` test",
|
||||||
Mode.NORMAL(),
|
Mode.NORMAL(),
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -732,6 +790,7 @@ print(something)
|
|||||||
"<caret>This is a `simple test",
|
"<caret>This is a `simple test",
|
||||||
"<caret>This is a `simple test",
|
"<caret>This is a `simple test",
|
||||||
Mode.NORMAL(),
|
Mode.NORMAL(),
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -744,6 +803,7 @@ print(something)
|
|||||||
"<caret>This is a 'simple' test",
|
"<caret>This is a 'simple' test",
|
||||||
"This is a <caret> test",
|
"This is a <caret> test",
|
||||||
Mode.NORMAL(),
|
Mode.NORMAL(),
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -755,6 +815,7 @@ print(something)
|
|||||||
"<caret>This is a 'simple test",
|
"<caret>This is a 'simple test",
|
||||||
"<caret>This is a 'simple test",
|
"<caret>This is a 'simple test",
|
||||||
Mode.NORMAL(),
|
Mode.NORMAL(),
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -767,6 +828,7 @@ print(something)
|
|||||||
"<caret>This is a \"simple\" test",
|
"<caret>This is a \"simple\" test",
|
||||||
"This is a <caret> test",
|
"This is a <caret> test",
|
||||||
Mode.NORMAL(),
|
Mode.NORMAL(),
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -779,6 +841,7 @@ print(something)
|
|||||||
"<caret>This is a \"simple test",
|
"<caret>This is a \"simple test",
|
||||||
"<caret>This is a \"simple test",
|
"<caret>This is a \"simple test",
|
||||||
Mode.NORMAL(),
|
Mode.NORMAL(),
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -791,6 +854,7 @@ print(something)
|
|||||||
"<caret>This is a `simple` test",
|
"<caret>This is a `simple` test",
|
||||||
"This is a <caret> test",
|
"This is a <caret> test",
|
||||||
Mode.NORMAL(),
|
Mode.NORMAL(),
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -803,6 +867,7 @@ print(something)
|
|||||||
"<caret>This is a `simple test",
|
"<caret>This is a `simple test",
|
||||||
"<caret>This is a `simple test",
|
"<caret>This is a `simple test",
|
||||||
Mode.NORMAL(),
|
Mode.NORMAL(),
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -815,6 +880,7 @@ print(something)
|
|||||||
"<caret>This is a (simple) test",
|
"<caret>This is a (simple) test",
|
||||||
"This is a (<caret>) test",
|
"This is a (<caret>) test",
|
||||||
Mode.NORMAL(),
|
Mode.NORMAL(),
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -827,6 +893,7 @@ print(something)
|
|||||||
"<caret>This is a (simple test",
|
"<caret>This is a (simple test",
|
||||||
"<caret>This is a (simple test",
|
"<caret>This is a (simple test",
|
||||||
Mode.NORMAL(),
|
Mode.NORMAL(),
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -839,6 +906,7 @@ print(something)
|
|||||||
"<caret>This is a [simple] test",
|
"<caret>This is a [simple] test",
|
||||||
"This is a [<caret>] test",
|
"This is a [<caret>] test",
|
||||||
Mode.NORMAL(),
|
Mode.NORMAL(),
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -851,6 +919,7 @@ print(something)
|
|||||||
"<caret>This is a [simple test",
|
"<caret>This is a [simple test",
|
||||||
"<caret>This is a [simple test",
|
"<caret>This is a [simple test",
|
||||||
Mode.NORMAL(),
|
Mode.NORMAL(),
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -863,6 +932,7 @@ print(something)
|
|||||||
"<caret>This is a {simple} test",
|
"<caret>This is a {simple} test",
|
||||||
"This is a {<caret>} test",
|
"This is a {<caret>} test",
|
||||||
Mode.NORMAL(),
|
Mode.NORMAL(),
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -875,6 +945,7 @@ print(something)
|
|||||||
"<caret>This is a {simple test",
|
"<caret>This is a {simple test",
|
||||||
"<caret>This is a {simple test",
|
"<caret>This is a {simple test",
|
||||||
Mode.NORMAL(),
|
Mode.NORMAL(),
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -887,6 +958,7 @@ print(something)
|
|||||||
"<caret>This is a (simple) test",
|
"<caret>This is a (simple) test",
|
||||||
"This is a <caret> test",
|
"This is a <caret> test",
|
||||||
Mode.NORMAL(),
|
Mode.NORMAL(),
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -899,6 +971,7 @@ print(something)
|
|||||||
"<caret>This is a (simple test",
|
"<caret>This is a (simple test",
|
||||||
"<caret>This is a (simple test",
|
"<caret>This is a (simple test",
|
||||||
Mode.NORMAL(),
|
Mode.NORMAL(),
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -911,6 +984,7 @@ print(something)
|
|||||||
"<caret>This is a [simple] test",
|
"<caret>This is a [simple] test",
|
||||||
"This is a <caret> test",
|
"This is a <caret> test",
|
||||||
Mode.NORMAL(),
|
Mode.NORMAL(),
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -923,6 +997,7 @@ print(something)
|
|||||||
"<caret>This is a [simple test",
|
"<caret>This is a [simple test",
|
||||||
"<caret>This is a [simple test",
|
"<caret>This is a [simple test",
|
||||||
Mode.NORMAL(),
|
Mode.NORMAL(),
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -935,6 +1010,7 @@ print(something)
|
|||||||
"<caret>This is a {simple} test",
|
"<caret>This is a {simple} test",
|
||||||
"This is a <caret> test",
|
"This is a <caret> test",
|
||||||
Mode.NORMAL(),
|
Mode.NORMAL(),
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
@ -947,6 +1023,7 @@ print(something)
|
|||||||
"<caret>This is a {simple test",
|
"<caret>This is a {simple test",
|
||||||
"<caret>This is a {simple test",
|
"<caret>This is a {simple test",
|
||||||
Mode.NORMAL(),
|
Mode.NORMAL(),
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
assertSelection(null)
|
assertSelection(null)
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.plugins.ideavim.extension.replacewithregister
|
package org.jetbrains.plugins.ideavim.extension.replacewithregister
|
||||||
|
|
||||||
import com.intellij.idea.TestFor
|
|
||||||
import com.intellij.openapi.application.ApplicationManager
|
import com.intellij.openapi.application.ApplicationManager
|
||||||
import com.maddyhome.idea.vim.VimPlugin
|
import com.maddyhome.idea.vim.VimPlugin
|
||||||
import com.maddyhome.idea.vim.api.injector
|
import com.maddyhome.idea.vim.api.injector
|
||||||
@ -651,137 +650,4 @@ class ReplaceWithRegisterTest : VimTestCase() {
|
|||||||
assertState("one two three")
|
assertState("one two three")
|
||||||
enterCommand("set clipboard&")
|
enterCommand("set clipboard&")
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestFor(issues = ["VIM-2263"])
|
|
||||||
@Test
|
|
||||||
fun `test replace with count from register a`() {
|
|
||||||
val before = """
|
|
||||||
${c}first line
|
|
||||||
second line
|
|
||||||
third line
|
|
||||||
fourth line
|
|
||||||
fifth line
|
|
||||||
""".trimIndent()
|
|
||||||
|
|
||||||
configureByText(before)
|
|
||||||
typeText("\"ay$")
|
|
||||||
|
|
||||||
val context = injector.executionContextManager.getEditorExecutionContext(fixture.editor.vim)
|
|
||||||
|
|
||||||
val aRegText = injector.registerGroup.getRegister(fixture.editor.vim, context, 'a' )!!.text
|
|
||||||
assertEquals("first line", aRegText)
|
|
||||||
|
|
||||||
val defaultRegText = injector.registerGroup.getRegister(fixture.editor.vim, context, '"' )!!.text
|
|
||||||
assertEquals("first line", defaultRegText )
|
|
||||||
|
|
||||||
typeText("j")
|
|
||||||
typeText("y$")
|
|
||||||
|
|
||||||
val aRegTextAfter = injector.registerGroup.getRegister(fixture.editor.vim, context, 'a' )!!.text
|
|
||||||
assertEquals("first line", aRegTextAfter)
|
|
||||||
|
|
||||||
val defaultRegTextAfter = injector.registerGroup.getRegister(fixture.editor.vim, context, '"' )!!.text
|
|
||||||
assertEquals("second line", defaultRegTextAfter )
|
|
||||||
|
|
||||||
typeText("\"a2grr")
|
|
||||||
|
|
||||||
val expected = """
|
|
||||||
first line
|
|
||||||
${c}first line
|
|
||||||
fourth line
|
|
||||||
fifth line
|
|
||||||
""".trimIndent()
|
|
||||||
|
|
||||||
assertState(expected)
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestFor(issues = ["VIM-2263"])
|
|
||||||
@Test
|
|
||||||
fun `test replace from the register a (without count)`() {
|
|
||||||
val before = """
|
|
||||||
${c}first line
|
|
||||||
second line
|
|
||||||
third line
|
|
||||||
fourth line
|
|
||||||
fifth line
|
|
||||||
""".trimIndent()
|
|
||||||
|
|
||||||
configureByText(before)
|
|
||||||
typeText("\"ay$")
|
|
||||||
|
|
||||||
val context = injector.executionContextManager.getEditorExecutionContext(fixture.editor.vim)
|
|
||||||
|
|
||||||
val aRegText = injector.registerGroup.getRegister(fixture.editor.vim, context, 'a' )!!.text
|
|
||||||
assertEquals("first line", aRegText)
|
|
||||||
|
|
||||||
val defaultRegText = injector.registerGroup.getRegister(fixture.editor.vim, context, '"' )!!.text
|
|
||||||
assertEquals("first line", defaultRegText )
|
|
||||||
|
|
||||||
typeText("j")
|
|
||||||
typeText("y$")
|
|
||||||
|
|
||||||
val aRegTextAfter = injector.registerGroup.getRegister(fixture.editor.vim, context, 'a' )!!.text
|
|
||||||
assertEquals("first line", aRegTextAfter)
|
|
||||||
|
|
||||||
val defaultRegTextAfter = injector.registerGroup.getRegister(fixture.editor.vim, context, '"' )!!.text
|
|
||||||
assertEquals("second line", defaultRegTextAfter )
|
|
||||||
|
|
||||||
typeText("\"agrr")
|
|
||||||
|
|
||||||
val expected = """
|
|
||||||
first line
|
|
||||||
${c}first line
|
|
||||||
third line
|
|
||||||
fourth line
|
|
||||||
fifth line
|
|
||||||
""".trimIndent()
|
|
||||||
|
|
||||||
assertState(expected)
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestFor(issues = ["VIM-2263"])
|
|
||||||
@Test
|
|
||||||
fun `test replace from the register a to the end of the line`() {
|
|
||||||
val before = """
|
|
||||||
${c}first line
|
|
||||||
second line
|
|
||||||
third line
|
|
||||||
fourth line
|
|
||||||
fifth line
|
|
||||||
""".trimIndent()
|
|
||||||
|
|
||||||
configureByText(before)
|
|
||||||
typeText("\"ayiw")
|
|
||||||
|
|
||||||
val context = injector.executionContextManager.getEditorExecutionContext(fixture.editor.vim)
|
|
||||||
|
|
||||||
val aRegText = injector.registerGroup.getRegister(fixture.editor.vim, context, 'a' )!!.text
|
|
||||||
assertEquals("first", aRegText)
|
|
||||||
|
|
||||||
val defaultRegText = injector.registerGroup.getRegister(fixture.editor.vim, context, '"' )!!.text
|
|
||||||
assertEquals("first", defaultRegText )
|
|
||||||
|
|
||||||
typeText("j")
|
|
||||||
typeText("y$")
|
|
||||||
typeText("w")
|
|
||||||
|
|
||||||
val aRegTextAfter = injector.registerGroup.getRegister(fixture.editor.vim, context, 'a' )!!.text
|
|
||||||
assertEquals("first", aRegTextAfter)
|
|
||||||
|
|
||||||
val defaultRegTextAfter = injector.registerGroup.getRegister(fixture.editor.vim, context, '"' )!!.text
|
|
||||||
assertEquals("second line", defaultRegTextAfter )
|
|
||||||
|
|
||||||
typeText("\"agr$")
|
|
||||||
|
|
||||||
val expected = """
|
|
||||||
first line
|
|
||||||
second firs${c}t
|
|
||||||
third line
|
|
||||||
fourth line
|
|
||||||
fifth line
|
|
||||||
""".trimIndent()
|
|
||||||
|
|
||||||
assertState(expected)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -633,17 +633,6 @@ class VimSurroundExtensionTest : VimTestCase() {
|
|||||||
doTest(listOf(motion), before, after, Mode.NORMAL())
|
doTest(listOf(motion), before, after, Mode.NORMAL())
|
||||||
}
|
}
|
||||||
|
|
||||||
// VIM-3841
|
|
||||||
@Test
|
|
||||||
fun `test return to Normal mode after surround in Visual mode`() {
|
|
||||||
doTest(
|
|
||||||
listOf("veS\"", "i"),
|
|
||||||
"lorem ${c}ipsum dolor sit amet",
|
|
||||||
"lorem ${c}\"ipsum\" dolor sit amet",
|
|
||||||
Mode.INSERT,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun removeWhiteSpaceWithClosingBracketParams() = listOf(
|
fun removeWhiteSpaceWithClosingBracketParams() = listOf(
|
||||||
|
@ -32,7 +32,7 @@ class VimListenersTest : VimTestCase() {
|
|||||||
super.setUp(testInfo)
|
super.setUp(testInfo)
|
||||||
|
|
||||||
val manager =
|
val manager =
|
||||||
FileEditorManagerImpl(fixture.project, (fixture.project as ComponentManagerEx).getCoroutineScope().childScope(name = "VimListenersTest"))
|
FileEditorManagerImpl(fixture.project, (fixture.project as ComponentManagerEx).getCoroutineScope().childScope())
|
||||||
fixture.project.replaceService(FileEditorManager::class.java, manager, fixture.testRootDisposable)
|
fixture.project.replaceService(FileEditorManager::class.java, manager, fixture.testRootDisposable)
|
||||||
|
|
||||||
VimListenerTestObject.disposedCounter = 0
|
VimListenerTestObject.disposedCounter = 0
|
||||||
|
@ -67,7 +67,7 @@ class EffectiveOptionChangeListenerTest : VimTestCase() {
|
|||||||
|
|
||||||
// Copied from FileEditorManagerTestCase to allow us to split windows
|
// Copied from FileEditorManagerTestCase to allow us to split windows
|
||||||
manager =
|
manager =
|
||||||
FileEditorManagerImpl(fixture.project, (fixture.project as ComponentManagerEx).getCoroutineScope().childScope(name = "EffectiveOptionChangeListenerTest"))
|
FileEditorManagerImpl(fixture.project, (fixture.project as ComponentManagerEx).getCoroutineScope().childScope())
|
||||||
fixture.project.replaceService(FileEditorManager::class.java, manager, fixture.testRootDisposable)
|
fixture.project.replaceService(FileEditorManager::class.java, manager, fixture.testRootDisposable)
|
||||||
|
|
||||||
// Create a new editor that will represent a new buffer in a separate window. It will have default values
|
// Create a new editor that will represent a new buffer in a separate window. It will have default values
|
||||||
|
@ -61,7 +61,7 @@ class OptionDeclaredScopeTest : VimTestCase() {
|
|||||||
super.setUp(testInfo)
|
super.setUp(testInfo)
|
||||||
|
|
||||||
// Copied from FileEditorManagerTestCase to allow us to split windows
|
// Copied from FileEditorManagerTestCase to allow us to split windows
|
||||||
fileEditorManager = FileEditorManagerImpl(fixture.project, (fixture.project as ComponentManagerEx).getCoroutineScope().childScope(name = "OptionDeclaredScopeTest"))
|
fileEditorManager = FileEditorManagerImpl(fixture.project, (fixture.project as ComponentManagerEx).getCoroutineScope().childScope())
|
||||||
fixture.project.replaceService(FileEditorManager::class.java, fileEditorManager, fixture.testRootDisposable)
|
fixture.project.replaceService(FileEditorManager::class.java, fileEditorManager, fixture.testRootDisposable)
|
||||||
|
|
||||||
// Create a new editor that will represent a new buffer in a separate window. It will have default values
|
// Create a new editor that will represent a new buffer in a separate window. It will have default values
|
||||||
@ -160,7 +160,7 @@ class OptionDeclaredScopeTest : VimTestCase() {
|
|||||||
}
|
}
|
||||||
val virtualFile = editor.virtualFile
|
val virtualFile = editor.virtualFile
|
||||||
|
|
||||||
if (virtualFile != null) {
|
if (editorWindow != null && virtualFile != null) {
|
||||||
editorWindow.closeFile(virtualFile)
|
editorWindow.closeFile(virtualFile)
|
||||||
editorWindow.requestFocus(true)
|
editorWindow.requestFocus(true)
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ class TextWidthOptionMapperTest : VimTestCase() {
|
|||||||
|
|
||||||
// Copied from FileEditorManagerTestCase to allow us to split windows
|
// Copied from FileEditorManagerTestCase to allow us to split windows
|
||||||
val manager =
|
val manager =
|
||||||
FileEditorManagerImpl(fixture.project, (fixture.project as ComponentManagerEx).getCoroutineScope().childScope(name = "TextWidthOptionMapperTest"))
|
FileEditorManagerImpl(fixture.project, (fixture.project as ComponentManagerEx).getCoroutineScope().childScope())
|
||||||
fixture.project.replaceService(FileEditorManager::class.java, manager, fixture.testRootDisposable)
|
fixture.project.replaceService(FileEditorManager::class.java, manager, fixture.testRootDisposable)
|
||||||
|
|
||||||
ApplicationManager.getApplication().invokeAndWait {
|
ApplicationManager.getApplication().invokeAndWait {
|
||||||
|
@ -37,7 +37,7 @@ class WrapOptionMapperTest : VimTestCase() {
|
|||||||
|
|
||||||
// Copied from FileEditorManagerTestCase to allow us to split windows
|
// Copied from FileEditorManagerTestCase to allow us to split windows
|
||||||
manager =
|
manager =
|
||||||
FileEditorManagerImpl(fixture.project, (fixture.project as ComponentManagerEx).getCoroutineScope().childScope(name = "WrapOptionMapperTest"))
|
FileEditorManagerImpl(fixture.project, (fixture.project as ComponentManagerEx).getCoroutineScope().childScope())
|
||||||
fixture.project.replaceService(FileEditorManager::class.java, manager, fixture.testRootDisposable)
|
fixture.project.replaceService(FileEditorManager::class.java, manager, fixture.testRootDisposable)
|
||||||
|
|
||||||
configureByText("\n")
|
configureByText("\n")
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.plugins.ideavim.ui
|
package org.jetbrains.plugins.ideavim.ui
|
||||||
|
|
||||||
import com.maddyhome.idea.vim.api.globalOptions
|
|
||||||
import com.maddyhome.idea.vim.api.injector
|
import com.maddyhome.idea.vim.api.injector
|
||||||
import com.maddyhome.idea.vim.ui.ShowCmd
|
import com.maddyhome.idea.vim.ui.ShowCmd
|
||||||
import org.jetbrains.plugins.ideavim.SkipNeovimReason
|
import org.jetbrains.plugins.ideavim.SkipNeovimReason
|
||||||
@ -17,6 +16,7 @@ import org.jetbrains.plugins.ideavim.VimBehaviorDiffers
|
|||||||
import org.jetbrains.plugins.ideavim.VimTestCase
|
import org.jetbrains.plugins.ideavim.VimTestCase
|
||||||
import org.jetbrains.plugins.ideavim.waitAndAssert
|
import org.jetbrains.plugins.ideavim.waitAndAssert
|
||||||
import org.junit.jupiter.api.BeforeEach
|
import org.junit.jupiter.api.BeforeEach
|
||||||
|
import org.junit.jupiter.api.Disabled
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import org.junit.jupiter.api.TestInfo
|
import org.junit.jupiter.api.TestInfo
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
@ -87,12 +87,15 @@ class ShowCmdTest : VimTestCase() {
|
|||||||
assertEquals("32d", getShowCmdText())
|
assertEquals("32d", getShowCmdText())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: This test fails because IdeaVim's mapping handler doesn't correctly expand unhandled keys on timeout
|
||||||
@Test
|
@Test
|
||||||
|
@Disabled
|
||||||
fun `test showcmd expands ambiguous mapped keys on timeout`() {
|
fun `test showcmd expands ambiguous mapped keys on timeout`() {
|
||||||
|
// `rrr` should timeout and replay `rr` which is mapped to `42`
|
||||||
enterCommand("nmap rr 42")
|
enterCommand("nmap rr 42")
|
||||||
enterCommand("nmap rrr 55")
|
enterCommand("nmap rrr 55")
|
||||||
typeText(injector.parser.parseKeys("12rr"))
|
typeText(injector.parser.parseKeys("12rr"))
|
||||||
waitAndAssert(injector.globalOptions().timeoutlen + 100) { "1242" == getShowCmdText() }
|
waitAndAssert { "1242" == getShowCmdText() }
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestWithoutNeovim(reason = SkipNeovimReason.SHOW_CMD)
|
@TestWithoutNeovim(reason = SkipNeovimReason.SHOW_CMD)
|
||||||
|
@ -137,7 +137,7 @@ abstract class VimTestCase {
|
|||||||
VimPlugin.getSearch().resetState()
|
VimPlugin.getSearch().resetState()
|
||||||
if (VimPlugin.isNotEnabled()) VimPlugin.setEnabled(true)
|
if (VimPlugin.isNotEnabled()) VimPlugin.setEnabled(true)
|
||||||
injector.globalOptions().ideastrictmode = true
|
injector.globalOptions().ideastrictmode = true
|
||||||
Checks.reset()
|
VimTestCase.Checks.reset()
|
||||||
clearClipboard()
|
clearClipboard()
|
||||||
|
|
||||||
// Make sure the entry text field gets a bounds, or we won't be able to work out caret location
|
// Make sure the entry text field gets a bounds, or we won't be able to work out caret location
|
||||||
@ -442,9 +442,9 @@ abstract class VimTestCase {
|
|||||||
editor,
|
editor,
|
||||||
)
|
)
|
||||||
val project = fixture.project
|
val project = fixture.project
|
||||||
when (Checks.keyHandler) {
|
when (VimTestCase.Checks.keyHandler) {
|
||||||
Checks.KeyHandlerMethod.DIRECT_TO_VIM -> typeText(keys.filterNotNull(), editor, project)
|
VimTestCase.Checks.KeyHandlerMethod.DIRECT_TO_VIM -> typeText(keys.filterNotNull(), editor, project)
|
||||||
Checks.KeyHandlerMethod.VIA_IDE -> typeTextViaIde(keys.filterNotNull(), editor)
|
VimTestCase.Checks.KeyHandlerMethod.VIA_IDE -> typeTextViaIde(keys.filterNotNull(), editor)
|
||||||
}
|
}
|
||||||
return editor
|
return editor
|
||||||
}
|
}
|
||||||
@ -749,7 +749,7 @@ abstract class VimTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected fun assertCaretsVisualAttributes() {
|
protected fun assertCaretsVisualAttributes() {
|
||||||
if (!Checks.caretShape) return
|
if (!VimTestCase.Checks.caretShape) return
|
||||||
val editor = fixture.editor
|
val editor = fixture.editor
|
||||||
val attributes = GuiCursorOptionHelper.getAttributes(getGuiCursorMode(editor))
|
val attributes = GuiCursorOptionHelper.getAttributes(getGuiCursorMode(editor))
|
||||||
val colour = editor.colorsScheme.getColor(EditorColors.CARET_COLOR)
|
val colour = editor.colorsScheme.getColor(EditorColors.CARET_COLOR)
|
||||||
@ -946,8 +946,8 @@ abstract class VimTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Disable or enable checks for the particular test
|
// Disable or enable checks for the particular test
|
||||||
protected inline fun setupChecks(setup: Checks.() -> Unit) {
|
protected inline fun setupChecks(setup: VimTestCase.Checks.() -> Unit) {
|
||||||
Checks.setup()
|
VimTestCase.Checks.setup()
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun assertExException(expectedErrorMessage: String, action: () -> Unit) {
|
protected fun assertExException(expectedErrorMessage: String, action: () -> Unit) {
|
||||||
@ -1082,24 +1082,11 @@ abstract class VimTestCase {
|
|||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun commandToKeys(command: String): List<KeyStroke> {
|
fun commandToKeys(command: String): List<KeyStroke> {
|
||||||
val keys: MutableList<KeyStroke> = ArrayList()
|
val keys: MutableList<KeyStroke> = ArrayList()
|
||||||
|
if (!command.startsWith(":")) {
|
||||||
keys.addAll(injector.parser.parseKeys(":"))
|
keys.addAll(injector.parser.parseKeys(":"))
|
||||||
var startIndex = if (command.startsWith(":")) 1 else 0
|
|
||||||
|
|
||||||
// Special case support for <C-U>
|
|
||||||
startIndex = if (command.substring(startIndex).startsWith("<C-U>", ignoreCase = true)) {
|
|
||||||
keys.addAll(injector.parser.parseKeys("<C-U>"))
|
|
||||||
startIndex + 5
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
startIndex
|
|
||||||
}
|
|
||||||
// We don't parse the rest of the command, to avoid parsing special keys in e.g. maps. Note that values such as
|
|
||||||
// `<expr>` or `<args>` would be correctly handled by parseKeys
|
|
||||||
keys.addAll(injector.parser.stringToKeys(command.substring(startIndex)))
|
|
||||||
if (keys.last().keyCode != KeyEvent.VK_ENTER) {
|
|
||||||
keys.addAll(injector.parser.parseKeys("<Enter>"))
|
|
||||||
}
|
}
|
||||||
|
keys.addAll(injector.parser.stringToKeys(command)) // Avoids trying to parse 'command ... <args>' as a special char
|
||||||
|
keys.addAll(injector.parser.parseKeys("<Enter>"))
|
||||||
return keys
|
return keys
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,21 +32,18 @@ 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.12.2")
|
testImplementation("org.junit.vintage:junit-vintage-engine:5.12.0")
|
||||||
|
|
||||||
intellijPlatform {
|
intellijPlatform {
|
||||||
// Snapshots don't use installers
|
// Snapshots don't use installers
|
||||||
// https://plugins.jetbrains.com/docs/intellij/tools-intellij-platform-gradle-plugin-dependencies-extension.html#target-versions-installers
|
// https://plugins.jetbrains.com/docs/intellij/tools-intellij-platform-gradle-plugin-dependencies-extension.html#target-versions-installers
|
||||||
var useInstaller = "EAP-SNAPSHOT" !in ideaVersion
|
val useInstaller = "EAP-SNAPSHOT" !in ideaVersion
|
||||||
if (ideaType == "RD") {
|
|
||||||
// Using Rider as a target IntelliJ Platform with `useInstaller = true` is currently not supported, please set `useInstaller = false` instead. See: https://github.com/JetBrains/intellij-platform-gradle-plugin/issues/1852
|
|
||||||
useInstaller = false
|
|
||||||
}
|
|
||||||
|
|
||||||
create(ideaType, ideaVersion, useInstaller)
|
create(ideaType, ideaVersion, useInstaller)
|
||||||
testFramework(TestFrameworkType.Platform)
|
testFramework(TestFrameworkType.Platform)
|
||||||
testFramework(TestFrameworkType.JUnit5)
|
testFramework(TestFrameworkType.JUnit5)
|
||||||
bundledPlugins("com.intellij.java", "org.jetbrains.plugins.yaml")
|
bundledPlugins("com.intellij.java", "org.jetbrains.plugins.yaml")
|
||||||
|
instrumentationTools()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,7 +15,6 @@ import org.jetbrains.plugins.ideavim.VimBehaviorDiffers
|
|||||||
import org.jetbrains.plugins.ideavim.VimJavaTestCase
|
import org.jetbrains.plugins.ideavim.VimJavaTestCase
|
||||||
import org.jetbrains.yaml.YAMLFileType
|
import org.jetbrains.yaml.YAMLFileType
|
||||||
import org.junit.jupiter.api.BeforeEach
|
import org.junit.jupiter.api.BeforeEach
|
||||||
import org.junit.jupiter.api.Disabled
|
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import org.junit.jupiter.api.TestInfo
|
import org.junit.jupiter.api.TestInfo
|
||||||
|
|
||||||
@ -438,6 +437,63 @@ class CommentaryExtensionTest : VimJavaTestCase() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `test text object deletes single line comment from leading whitespace 2`() {
|
||||||
|
doTest(
|
||||||
|
"dgc",
|
||||||
|
"""
|
||||||
|
<caret>
|
||||||
|
|
||||||
|
// Comment 1
|
||||||
|
final Int value = 42;
|
||||||
|
""".trimIndent(),
|
||||||
|
"""
|
||||||
|
final Int value = 42;
|
||||||
|
""".trimIndent(),
|
||||||
|
Mode.NORMAL(),
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `test text object deletes single line comment from leading whitespace 3`() {
|
||||||
|
doTest(
|
||||||
|
"dgc",
|
||||||
|
"""
|
||||||
|
final Int value1 = 42;
|
||||||
|
<caret>
|
||||||
|
|
||||||
|
// Comment 1
|
||||||
|
final Int value2 = 42;
|
||||||
|
""".trimIndent(),
|
||||||
|
"""
|
||||||
|
final Int value1 = 42;
|
||||||
|
final Int value2 = 42;
|
||||||
|
""".trimIndent(),
|
||||||
|
Mode.NORMAL(),
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `test text object deletes single line comment from trailing whitespace`() {
|
||||||
|
doTest(
|
||||||
|
"dgc",
|
||||||
|
"""
|
||||||
|
|
||||||
|
// Comment 1
|
||||||
|
<caret>
|
||||||
|
|
||||||
|
final Int value = 42;
|
||||||
|
""".trimIndent(),
|
||||||
|
"""
|
||||||
|
final Int value = 42;
|
||||||
|
""".trimIndent(),
|
||||||
|
Mode.NORMAL(),
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `test text object deletes single line comments separated by whitespace`() {
|
fun `test text object deletes single line comments separated by whitespace`() {
|
||||||
doTest(
|
doTest(
|
||||||
@ -449,10 +505,26 @@ class CommentaryExtensionTest : VimJavaTestCase() {
|
|||||||
final Int value = 42;
|
final Int value = 42;
|
||||||
""".trimIndent(),
|
""".trimIndent(),
|
||||||
"""
|
"""
|
||||||
|
final Int value = 42;
|
||||||
|
""".trimIndent(),
|
||||||
|
Mode.NORMAL(),
|
||||||
|
JavaFileType.INSTANCE,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `test text object deletes disjointed single line comments from whitespace`() {
|
||||||
|
doTest(
|
||||||
|
"dgc",
|
||||||
|
"""
|
||||||
|
// Comment 1
|
||||||
|
<caret>
|
||||||
// Comment 2
|
// Comment 2
|
||||||
final Int value = 42;
|
final Int value = 42;
|
||||||
""".trimIndent(),
|
""".trimIndent(),
|
||||||
|
"""
|
||||||
|
final Int value = 42;
|
||||||
|
""".trimIndent(),
|
||||||
Mode.NORMAL(),
|
Mode.NORMAL(),
|
||||||
JavaFileType.INSTANCE,
|
JavaFileType.INSTANCE,
|
||||||
)
|
)
|
||||||
@ -583,10 +655,6 @@ class CommentaryExtensionTest : VimJavaTestCase() {
|
|||||||
final Int value = 42;
|
final Int value = 42;
|
||||||
""".trimIndent(),
|
""".trimIndent(),
|
||||||
"""
|
"""
|
||||||
|
|
||||||
/* Comment 1
|
|
||||||
* Comment 2
|
|
||||||
* Comment 3 */
|
|
||||||
final Int value = 42;
|
final Int value = 42;
|
||||||
""".trimIndent(),
|
""".trimIndent(),
|
||||||
Mode.NORMAL(),
|
Mode.NORMAL(),
|
||||||
@ -636,7 +704,8 @@ class CommentaryExtensionTest : VimJavaTestCase() {
|
|||||||
doTest(
|
doTest(
|
||||||
"dgc",
|
"dgc",
|
||||||
"""
|
"""
|
||||||
/**<caret>
|
<caret>
|
||||||
|
/**
|
||||||
* Cool summary, dude
|
* Cool summary, dude
|
||||||
* @param value the value, innit
|
* @param value the value, innit
|
||||||
* @param name what's your name?
|
* @param name what's your name?
|
||||||
@ -694,79 +763,6 @@ class CommentaryExtensionTest : VimJavaTestCase() {
|
|||||||
}
|
}
|
||||||
""".trimIndent(),
|
""".trimIndent(),
|
||||||
"""
|
"""
|
||||||
|
|
||||||
/* Block comment */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Cool summary, dude
|
|
||||||
* @param value the value, innit
|
|
||||||
* @param name what's your name?
|
|
||||||
*/
|
|
||||||
public void something(int value, String name) {
|
|
||||||
}
|
|
||||||
""".trimIndent(),
|
|
||||||
Mode.NORMAL(),
|
|
||||||
JavaFileType.INSTANCE,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `test text object deletes JavaDoc comment and adjoining comments separated by whitespace 2`() {
|
|
||||||
doTest(
|
|
||||||
"dgc",
|
|
||||||
"""
|
|
||||||
// This should be deleted too
|
|
||||||
|
|
||||||
/* <caret>Block comment */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Cool summary, dude
|
|
||||||
* @param value the value, innit
|
|
||||||
* @param name what's your name?
|
|
||||||
*/
|
|
||||||
public void something(int value, String name) {
|
|
||||||
}
|
|
||||||
""".trimIndent(),
|
|
||||||
"""
|
|
||||||
// This should be deleted too
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Cool summary, dude
|
|
||||||
* @param value the value, innit
|
|
||||||
* @param name what's your name?
|
|
||||||
*/
|
|
||||||
public void something(int value, String name) {
|
|
||||||
}
|
|
||||||
""".trimIndent(),
|
|
||||||
Mode.NORMAL(),
|
|
||||||
JavaFileType.INSTANCE,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `test text object deletes JavaDoc comment and adjoining comments separated by whitespace 3`() {
|
|
||||||
doTest(
|
|
||||||
"dgc",
|
|
||||||
"""
|
|
||||||
// This should be deleted too
|
|
||||||
|
|
||||||
/* Block comment */
|
|
||||||
|
|
||||||
/**<caret>
|
|
||||||
* Cool summary, dude
|
|
||||||
* @param value the value, innit
|
|
||||||
* @param name what's your name?
|
|
||||||
*/
|
|
||||||
public void something(int value, String name) {
|
|
||||||
}
|
|
||||||
""".trimIndent(),
|
|
||||||
"""
|
|
||||||
// This should be deleted too
|
|
||||||
|
|
||||||
/* Block comment */
|
|
||||||
|
|
||||||
public void something(int value, String name) {
|
public void something(int value, String name) {
|
||||||
}
|
}
|
||||||
""".trimIndent(),
|
""".trimIndent(),
|
||||||
@ -875,7 +871,6 @@ class CommentaryExtensionTest : VimJavaTestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Disabled("Doesn't work with the new version of IntelliJ and gradle plugin")
|
|
||||||
fun `test block comment falls back to line comment when not available`() {
|
fun `test block comment falls back to line comment when not available`() {
|
||||||
doTest(
|
doTest(
|
||||||
"gcw",
|
"gcw",
|
||||||
|
@ -25,16 +25,17 @@ 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.12.2")
|
testImplementation("org.junit.vintage:junit-vintage-engine:5.12.0")
|
||||||
|
|
||||||
intellijPlatform {
|
intellijPlatform {
|
||||||
// Snapshots don't use installers
|
// Snapshots don't use installers
|
||||||
// https://plugins.jetbrains.com/docs/intellij/tools-intellij-platform-gradle-plugin-dependencies-extension.html#target-versions-installers
|
// https://plugins.jetbrains.com/docs/intellij/tools-intellij-platform-gradle-plugin-dependencies-extension.html#target-versions-installers
|
||||||
val useInstaller = "EAP-SNAPSHOT" !in ideaVersion
|
val useInstaller = "EAP-SNAPSHOT" !in ideaVersion
|
||||||
|
|
||||||
create(ideaType, ideaVersion, false)
|
create(ideaType, ideaVersion, useInstaller)
|
||||||
testFramework(TestFrameworkType.Platform)
|
testFramework(TestFrameworkType.Platform)
|
||||||
testFramework(TestFrameworkType.JUnit5)
|
testFramework(TestFrameworkType.JUnit5)
|
||||||
|
instrumentationTools()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,17 +25,18 @@ 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.12.2")
|
testImplementation("org.junit.vintage:junit-vintage-engine:5.12.0")
|
||||||
|
|
||||||
intellijPlatform {
|
intellijPlatform {
|
||||||
// Snapshots don't use installers
|
// Snapshots don't use installers
|
||||||
// https://plugins.jetbrains.com/docs/intellij/tools-intellij-platform-gradle-plugin-dependencies-extension.html#target-versions-installers
|
// https://plugins.jetbrains.com/docs/intellij/tools-intellij-platform-gradle-plugin-dependencies-extension.html#target-versions-installers
|
||||||
val useInstaller = "EAP-SNAPSHOT" !in ideaVersion
|
val useInstaller = "EAP-SNAPSHOT" !in ideaVersion
|
||||||
|
|
||||||
create(ideaType, ideaVersion, false)
|
create(ideaType, ideaVersion, useInstaller)
|
||||||
bundledPlugins("com.intellij.java")
|
bundledPlugins("com.intellij.java")
|
||||||
testFramework(TestFrameworkType.Platform)
|
testFramework(TestFrameworkType.Platform)
|
||||||
testFramework(TestFrameworkType.JUnit5)
|
testFramework(TestFrameworkType.JUnit5)
|
||||||
|
instrumentationTools()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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.12.2")
|
testFixturesImplementation("org.junit.jupiter:junit-jupiter:5.12.0")
|
||||||
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
|
||||||
|
@ -16,6 +16,7 @@ import com.intellij.remoterobot.fixtures.FixtureName
|
|||||||
import com.intellij.remoterobot.fixtures.JTreeFixture
|
import com.intellij.remoterobot.fixtures.JTreeFixture
|
||||||
import com.intellij.remoterobot.search.locators.byXpath
|
import com.intellij.remoterobot.search.locators.byXpath
|
||||||
import com.intellij.remoterobot.stepsProcessing.step
|
import com.intellij.remoterobot.stepsProcessing.step
|
||||||
|
import com.intellij.remoterobot.utils.WaitForConditionTimeoutException
|
||||||
import com.intellij.remoterobot.utils.waitFor
|
import com.intellij.remoterobot.utils.waitFor
|
||||||
import java.time.Duration
|
import java.time.Duration
|
||||||
|
|
||||||
@ -32,7 +33,12 @@ class IdeaFrame(
|
|||||||
|
|
||||||
val projectViewTree: JTreeFixture
|
val projectViewTree: JTreeFixture
|
||||||
get() {
|
get() {
|
||||||
return find<JTreeFixture>(byXpath("MyProjectViewTree", "//div[@class='MyProjectViewTree']"), Duration.ofSeconds(30))
|
return try {
|
||||||
|
find<JTreeFixture>(byXpath("MyProjectViewTree", "//div[@class='MyProjectViewTree']"), Duration.ofSeconds(30))
|
||||||
|
} catch (_: WaitForConditionTimeoutException) {
|
||||||
|
// [VERSION UPDATE] 2025.1+ Leave only MyProjectViewTree.
|
||||||
|
find<JTreeFixture>(byXpath("ProjectViewTree", "//div[@class='ProjectViewTree']"), Duration.ofSeconds(30))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val projectName
|
val projectName
|
||||||
|
@ -13,10 +13,9 @@ import com.intellij.remoterobot.stepsProcessing.StepWorker
|
|||||||
|
|
||||||
object StepsLogger {
|
object StepsLogger {
|
||||||
private var initializaed = false
|
private var initializaed = false
|
||||||
private val initializationLock = Any()
|
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun init() = synchronized(initializationLock) {
|
fun init() = synchronized(initializaed) {
|
||||||
if (initializaed.not()) {
|
if (initializaed.not()) {
|
||||||
StepWorker.registerProcessor(StepLogger())
|
StepWorker.registerProcessor(StepLogger())
|
||||||
initializaed = true
|
initializaed = true
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
import com.intellij.remoterobot.RemoteRobot
|
import com.intellij.remoterobot.RemoteRobot
|
||||||
import com.intellij.remoterobot.data.RemoteComponent
|
import com.intellij.remoterobot.data.RemoteComponent
|
||||||
import com.intellij.remoterobot.fixtures.CommonContainerFixture
|
import com.intellij.remoterobot.fixtures.CommonContainerFixture
|
||||||
|
import com.intellij.remoterobot.fixtures.ComponentFixture
|
||||||
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.search.locators.byXpath
|
import com.intellij.remoterobot.search.locators.byXpath
|
||||||
@ -24,10 +25,13 @@ class ManageLicensesFrame(remoteRobot: RemoteRobot, remoteComponent: RemoteCompo
|
|||||||
CommonContainerFixture(remoteRobot, remoteComponent) {
|
CommonContainerFixture(remoteRobot, remoteComponent) {
|
||||||
|
|
||||||
fun enableFreeTier() {
|
fun enableFreeTier() {
|
||||||
radioButton("Activation code").click()
|
find<ComponentFixture>(
|
||||||
/// Note: The license code is obfuscated, so we use the class `W`. But a better solution is required.
|
byXpath(
|
||||||
textFields(byXpath("//div[@class='W']")).first().text = System.getenv("RIDER_LICENSE")
|
"//div[@class='SegmentedButton' and @action='Start trial (null)']",
|
||||||
button("Activate").click()
|
)
|
||||||
|
).click()
|
||||||
|
// checkBox("I agree with", contains = true).select()
|
||||||
|
button("Start Free 30-Day Trial").click()
|
||||||
button("Close").click()
|
button("Close").click()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,54 +45,9 @@ class RiderUiTest {
|
|||||||
val editor = editor("Program.cs")
|
val editor = editor("Program.cs")
|
||||||
|
|
||||||
testEnterWorksInNormalMode(editor)
|
testEnterWorksInNormalMode(editor)
|
||||||
testReformatCodeUsingMappingWithSpace(editor)
|
|
||||||
testEnterInInsertMode(editor)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun IdeaFrame.testEnterInInsertMode(editor: Editor) {
|
|
||||||
editor.findText(" for more information").click()
|
|
||||||
keyboard {
|
|
||||||
enterText("A")
|
|
||||||
enter()
|
|
||||||
}
|
|
||||||
Thread.sleep(1000)
|
|
||||||
assertEquals(
|
|
||||||
"""
|
|
||||||
|// See https://aka.ms/new-console-template for more information
|
|
||||||
|
|
|
||||||
|
|
|
||||||
|Console.WriteLine("Hello, World!");
|
|
||||||
""".trimMargin(), editor.text
|
|
||||||
)
|
|
||||||
|
|
||||||
keyboard {
|
|
||||||
escape()
|
|
||||||
enterText("dd")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun IdeaFrame.testReformatCodeUsingMappingWithSpace(editor: Editor) {
|
|
||||||
editor.findText(" for more information").click()
|
|
||||||
keyboard {
|
|
||||||
enterText("jj>>")
|
|
||||||
|
|
||||||
enterText(":map <Space>x <Action>(ReformatCode)")
|
|
||||||
enter()
|
|
||||||
|
|
||||||
enterText(" x")
|
|
||||||
}
|
|
||||||
|
|
||||||
Thread.sleep(1000)
|
|
||||||
assertEquals(
|
|
||||||
"""
|
|
||||||
|// See https://aka.ms/new-console-template for more information
|
|
||||||
|
|
|
||||||
|Console.WriteLine("Hello, World!");
|
|
||||||
""".trimMargin(), editor.text
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun IdeaFrame.testEnterWorksInNormalMode(editor: Editor) {
|
private fun IdeaFrame.testEnterWorksInNormalMode(editor: Editor) {
|
||||||
editor.findText(" for more information").click()
|
editor.findText(" for more information").click()
|
||||||
keyboard {
|
keyboard {
|
||||||
|
@ -45,13 +45,13 @@ afterEvaluate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
testImplementation("org.junit.jupiter:junit-jupiter-api:5.12.2")
|
testImplementation("org.junit.jupiter:junit-jupiter-api:5.12.0")
|
||||||
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.12.2")
|
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.12.0")
|
||||||
|
|
||||||
// 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.12.2")
|
testRuntimeOnly("org.junit.vintage:junit-vintage-engine:5.12.0")
|
||||||
|
|
||||||
// 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")
|
||||||
|
@ -34,8 +34,6 @@ import com.maddyhome.idea.vim.key.consumers.SelectRegisterConsumer
|
|||||||
import com.maddyhome.idea.vim.state.KeyHandlerState
|
import com.maddyhome.idea.vim.state.KeyHandlerState
|
||||||
import com.maddyhome.idea.vim.state.VimStateMachine
|
import com.maddyhome.idea.vim.state.VimStateMachine
|
||||||
import com.maddyhome.idea.vim.state.mode.Mode
|
import com.maddyhome.idea.vim.state.mode.Mode
|
||||||
import org.jetbrains.annotations.ApiStatus
|
|
||||||
import java.util.concurrent.ConcurrentLinkedDeque
|
|
||||||
import javax.swing.KeyStroke
|
import javax.swing.KeyStroke
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -44,7 +42,7 @@ import javax.swing.KeyStroke
|
|||||||
*/
|
*/
|
||||||
// TODO for future refactorings (PRs are welcome)
|
// TODO for future refactorings (PRs are welcome)
|
||||||
// 1. avoid using handleKeyRecursionCount & shouldRecord
|
// 1. avoid using handleKeyRecursionCount & shouldRecord
|
||||||
// 2. maybe we can live without allowKeyMappings: Boolean
|
// 2. maybe we can live without allowKeyMappings: Boolean & mappingCompleted: Boolean
|
||||||
class KeyHandler {
|
class KeyHandler {
|
||||||
private val keyConsumers: List<KeyConsumer> = listOf(
|
private val keyConsumers: List<KeyConsumer> = listOf(
|
||||||
ModalInputConsumer(),
|
ModalInputConsumer(),
|
||||||
@ -61,24 +59,6 @@ class KeyHandler {
|
|||||||
)
|
)
|
||||||
private var handleKeyRecursionCount = 0
|
private var handleKeyRecursionCount = 0
|
||||||
|
|
||||||
private var commandListener: ConcurrentLinkedDeque<() -> Unit> = ConcurrentLinkedDeque()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is an internal API of IdeaVim. External plugins must not use it.
|
|
||||||
*/
|
|
||||||
@ApiStatus.Internal
|
|
||||||
fun addCommandListener(listener: () -> Unit) {
|
|
||||||
commandListener.add(listener)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is an internal API of IdeaVim. External plugins must not use it.
|
|
||||||
*/
|
|
||||||
@ApiStatus.Internal
|
|
||||||
fun removeAllCommandListeners() {
|
|
||||||
commandListener.clear()
|
|
||||||
}
|
|
||||||
|
|
||||||
// KeyHandlerState requires injector.keyGroup to be initialized and that's why we don't create it immediately and have this here
|
// KeyHandlerState requires injector.keyGroup to be initialized and that's why we don't create it immediately and have this here
|
||||||
// TODO figure out a better solution
|
// TODO figure out a better solution
|
||||||
private val defaultKeyHandlerState by lazy { KeyHandlerState() }
|
private val defaultKeyHandlerState by lazy { KeyHandlerState() }
|
||||||
@ -103,15 +83,14 @@ class KeyHandler {
|
|||||||
* @param context The data context
|
* @param context The data context
|
||||||
*/
|
*/
|
||||||
fun handleKey(editor: VimEditor, key: KeyStroke, context: ExecutionContext, keyState: KeyHandlerState) {
|
fun handleKey(editor: VimEditor, key: KeyStroke, context: ExecutionContext, keyState: KeyHandlerState) {
|
||||||
commandListener.forEach { it() }
|
|
||||||
handleKey(editor, key, context, allowKeyMappings = true, mappingCompleted = false, keyState)
|
handleKey(editor, key, context, allowKeyMappings = true, mappingCompleted = false, keyState)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handling input keys with additional parameters
|
* Handling input keys with additional parameters
|
||||||
*
|
*
|
||||||
* @param allowKeyMappings If we allow key mappings or not
|
* @param allowKeyMappings - If we allow key mappings or not
|
||||||
* @param mappingCompleted No longer used
|
* @param mappingCompleted - if true, we don't check if the mapping is incomplete
|
||||||
*/
|
*/
|
||||||
fun handleKey(
|
fun handleKey(
|
||||||
editor: VimEditor,
|
editor: VimEditor,
|
||||||
@ -121,7 +100,13 @@ class KeyHandler {
|
|||||||
mappingCompleted: Boolean,
|
mappingCompleted: Boolean,
|
||||||
keyState: KeyHandlerState,
|
keyState: KeyHandlerState,
|
||||||
) {
|
) {
|
||||||
val result = processKey(key, editor, allowKeyMappings, KeyProcessResult.SynchronousKeyProcessBuilder(keyState))
|
val result = processKey(
|
||||||
|
key,
|
||||||
|
editor,
|
||||||
|
allowKeyMappings,
|
||||||
|
mappingCompleted,
|
||||||
|
KeyProcessResult.SynchronousKeyProcessBuilder(keyState)
|
||||||
|
)
|
||||||
if (result is KeyProcessResult.Executable) {
|
if (result is KeyProcessResult.Executable) {
|
||||||
result.execute(editor, context)
|
result.execute(editor, context)
|
||||||
}
|
}
|
||||||
@ -134,30 +119,31 @@ class KeyHandler {
|
|||||||
* Alternatively, if we understand the key, we return a 'KeyProcessResult.Executable', which contains a runnable that
|
* Alternatively, if we understand the key, we return a 'KeyProcessResult.Executable', which contains a runnable that
|
||||||
* could execute the key if needed.
|
* could execute the key if needed.
|
||||||
*/
|
*/
|
||||||
private fun processKey(
|
fun processKey(
|
||||||
key: KeyStroke,
|
key: KeyStroke,
|
||||||
editor: VimEditor,
|
editor: VimEditor,
|
||||||
allowKeyMappings: Boolean,
|
allowKeyMappings: Boolean,
|
||||||
keyProcessResultBuilder: KeyProcessResult.KeyProcessResultBuilder,
|
mappingCompleted: Boolean,
|
||||||
|
processBuilder: KeyProcessResult.KeyProcessResultBuilder,
|
||||||
): KeyProcessResult {
|
): KeyProcessResult {
|
||||||
synchronized(lock) {
|
synchronized(lock) {
|
||||||
logger.trace {
|
logger.trace {
|
||||||
"""
|
"""
|
||||||
------- Key Handler -------
|
------- Key Handler -------
|
||||||
Start key processing. allowKeyMappings: $allowKeyMappings
|
Start key processing. allowKeyMappings: $allowKeyMappings, mappingCompleted: $mappingCompleted
|
||||||
Key: $key
|
Key: $key
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
}
|
}
|
||||||
logger.trace { keyProcessResultBuilder.state.toString() }
|
logger.trace { processBuilder.state.toString() }
|
||||||
logger.trace { "Mode = ${editor.mode}" }
|
logger.trace { "Mode = ${editor.mode}" }
|
||||||
val maxMapDepth = injector.globalOptions().maxmapdepth
|
val maxMapDepth = injector.globalOptions().maxmapdepth
|
||||||
if (handleKeyRecursionCount >= maxMapDepth) {
|
if (handleKeyRecursionCount >= maxMapDepth) {
|
||||||
keyProcessResultBuilder.addExecutionStep { _, lambdaEditor, _ ->
|
processBuilder.addExecutionStep { _, lambdaEditor, _ ->
|
||||||
logger.warn("Key handling, maximum recursion of the key received. maxdepth=$maxMapDepth")
|
logger.warn("Key handling, maximum recursion of the key received. maxdepth=$maxMapDepth")
|
||||||
injector.messages.showStatusBarMessage(lambdaEditor, injector.messages.message("E223"))
|
injector.messages.showStatusBarMessage(lambdaEditor, injector.messages.message("E223"))
|
||||||
injector.messages.indicateError()
|
injector.messages.indicateError()
|
||||||
}
|
}
|
||||||
return keyProcessResultBuilder.build()
|
return processBuilder.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
injector.messages.clearError()
|
injector.messages.clearError()
|
||||||
@ -167,25 +153,25 @@ class KeyHandler {
|
|||||||
handleKeyRecursionCount++
|
handleKeyRecursionCount++
|
||||||
try {
|
try {
|
||||||
val isProcessed = keyConsumers.any {
|
val isProcessed = keyConsumers.any {
|
||||||
it.consumeKey(key, editor, allowKeyMappings, keyProcessResultBuilder)
|
it.consumeKey(key, editor, allowKeyMappings, mappingCompleted, processBuilder)
|
||||||
}
|
}
|
||||||
if (isProcessed) {
|
if (isProcessed) {
|
||||||
logger.trace { "Key was successfully caught by consumer" }
|
logger.trace { "Key was successfully caught by consumer" }
|
||||||
keyProcessResultBuilder.addExecutionStep { lambdaKeyState, lambdaEditor, lambdaContext ->
|
processBuilder.addExecutionStep { lambdaKeyState, lambdaEditor, lambdaContext ->
|
||||||
finishedCommandPreparation(lambdaEditor, lambdaContext, key, shouldRecord, lambdaKeyState)
|
finishedCommandPreparation(lambdaEditor, lambdaContext, key, shouldRecord, lambdaKeyState)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Key wasn't processed by any of the consumers, so we reset our key state
|
// Key wasn't processed by any of the consumers, so we reset our key state
|
||||||
onUnknownKey(editor, keyProcessResultBuilder.state)
|
onUnknownKey(editor, processBuilder.state)
|
||||||
updateState(keyProcessResultBuilder.state)
|
updateState(processBuilder.state)
|
||||||
return KeyProcessResult.Unknown.apply {
|
return KeyProcessResult.Unknown.apply {
|
||||||
handleKeyRecursionCount-- // because onFinish will now be executed for unknown
|
handleKeyRecursionCount-- // because onFinish will now be executed for unknown
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
keyProcessResultBuilder.onFinish = { handleKeyRecursionCount-- }
|
processBuilder.onFinish = { handleKeyRecursionCount-- }
|
||||||
}
|
}
|
||||||
return keyProcessResultBuilder.build()
|
return processBuilder.build()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -239,7 +225,7 @@ class KeyHandler {
|
|||||||
val operatorArguments = OperatorArguments(command.rawCount, editorState.mode)
|
val operatorArguments = OperatorArguments(command.rawCount, editorState.mode)
|
||||||
|
|
||||||
// If we were in "operator pending" mode, reset back to normal mode.
|
// If we were in "operator pending" mode, reset back to normal mode.
|
||||||
// But opening command line should not reset operator pending mode (e.g. `d/foo`)
|
// But opening command line should not reset operator pending mode (e.g. `d/foo`
|
||||||
if (!command.flags.contains(CommandFlags.FLAG_START_EX)) {
|
if (!command.flags.contains(CommandFlags.FLAG_START_EX)) {
|
||||||
editor.resetOpPending()
|
editor.resetOpPending()
|
||||||
}
|
}
|
||||||
|
@ -1,95 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.change.change
|
|
||||||
|
|
||||||
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.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.Command
|
|
||||||
import com.maddyhome.idea.vim.command.DuplicableOperatorAction
|
|
||||||
import com.maddyhome.idea.vim.command.OperatorArguments
|
|
||||||
import com.maddyhome.idea.vim.common.TextRange
|
|
||||||
import com.maddyhome.idea.vim.handler.ChangeEditorActionHandler
|
|
||||||
|
|
||||||
@CommandOrMotion(keys = ["g?"], modes = [Mode.NORMAL])
|
|
||||||
class ChangeRot13MotionAction : ChangeEditorActionHandler.ForEachCaret(), DuplicableOperatorAction {
|
|
||||||
override val type: Command.Type = Command.Type.CHANGE
|
|
||||||
|
|
||||||
override val argumentType: Argument.Type = Argument.Type.MOTION
|
|
||||||
|
|
||||||
override val duplicateWith: Char = '?'
|
|
||||||
|
|
||||||
override fun execute(
|
|
||||||
editor: VimEditor,
|
|
||||||
caret: VimCaret,
|
|
||||||
context: ExecutionContext,
|
|
||||||
argument: Argument?,
|
|
||||||
operatorArguments: OperatorArguments,
|
|
||||||
): Boolean {
|
|
||||||
if (argument == null) return false
|
|
||||||
|
|
||||||
val range = injector.motion.getMotionRange(
|
|
||||||
editor, caret, context, argument,
|
|
||||||
operatorArguments
|
|
||||||
) ?: return false
|
|
||||||
|
|
||||||
return applyRot13(editor, caret, range)
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
/**
|
|
||||||
* Apply ROT13 encoding to the text in the given range.
|
|
||||||
* Only ASCII letters below 0x80 are converted.
|
|
||||||
*/
|
|
||||||
fun applyRot13(editor: VimEditor, caret: VimCaret, range: TextRange): Boolean {
|
|
||||||
val starts = range.startOffsets
|
|
||||||
val ends = range.endOffsets
|
|
||||||
|
|
||||||
for (i in ends.indices.reversed()) {
|
|
||||||
applyRot13ToRange(editor, caret, starts[i], ends[i])
|
|
||||||
}
|
|
||||||
|
|
||||||
caret.moveToOffset(range.startOffset)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Apply ROT13 encoding to the text between start and end offsets.
|
|
||||||
* Only ASCII letters below 0x80 are converted.
|
|
||||||
*/
|
|
||||||
private fun applyRot13ToRange(editor: VimEditor, caret: VimCaret, start: Int, end: Int) {
|
|
||||||
val (newStart, newEnd) = if (start > end) end to start else start to end
|
|
||||||
|
|
||||||
val changedText = buildString {
|
|
||||||
for (i in newStart until newEnd) {
|
|
||||||
append(rot13(editor.text()[i]))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
injector.changeGroup.replaceText(editor, caret, newStart, newEnd, changedText)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Apply ROT13 encoding to a single character.
|
|
||||||
*
|
|
||||||
* Only ASCII letters below 0x80 are converted, see https://github.com/vim/vim/blob/470317f78b110b4559cecb26039b5f93447c1bf0/src/ops.c#L1591
|
|
||||||
*/
|
|
||||||
private fun rot13(ch: Char): Char {
|
|
||||||
// Only convert ASCII letters below 0x80
|
|
||||||
return when {
|
|
||||||
ch.code < 0x80 && ch in 'a'..'z' -> 'a' + (ch - 'a' + 13) % 26
|
|
||||||
ch.code < 0x80 && ch in 'A'..'Z' -> 'A' + (ch - 'A' + 13) % 26
|
|
||||||
else -> ch
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.change.change
|
|
||||||
|
|
||||||
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.VimCaret
|
|
||||||
import com.maddyhome.idea.vim.api.VimEditor
|
|
||||||
import com.maddyhome.idea.vim.command.Command
|
|
||||||
import com.maddyhome.idea.vim.command.OperatorArguments
|
|
||||||
import com.maddyhome.idea.vim.group.visual.VimSelection
|
|
||||||
import com.maddyhome.idea.vim.handler.VisualOperatorActionHandler
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author vlan
|
|
||||||
*/
|
|
||||||
@CommandOrMotion(keys = ["g?"], modes = [Mode.VISUAL])
|
|
||||||
class ChangeRot13VisualAction : VisualOperatorActionHandler.ForEachCaret() {
|
|
||||||
override val type: Command.Type = Command.Type.CHANGE
|
|
||||||
|
|
||||||
override fun executeAction(
|
|
||||||
editor: VimEditor,
|
|
||||||
caret: VimCaret,
|
|
||||||
context: ExecutionContext,
|
|
||||||
cmd: Command,
|
|
||||||
range: VimSelection,
|
|
||||||
operatorArguments: OperatorArguments,
|
|
||||||
): Boolean {
|
|
||||||
return ChangeRot13MotionAction.applyRot13(editor, caret, range.toVimTextRange(false))
|
|
||||||
}
|
|
||||||
}
|
|
@ -70,6 +70,6 @@ class MotionDownNotLineWiseAction : MotionActionHandler.ForEachCaret() {
|
|||||||
argument: Argument?,
|
argument: Argument?,
|
||||||
operatorArguments: OperatorArguments,
|
operatorArguments: OperatorArguments,
|
||||||
): Motion {
|
): Motion {
|
||||||
return injector.motion.getVerticalMotionOffset(editor, caret, operatorArguments.count1, bufferLines = true)
|
return injector.motion.getVerticalMotionOffset(editor, caret, operatorArguments.count1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -70,6 +70,6 @@ class MotionUpNotLineWiseAction : MotionActionHandler.ForEachCaret() {
|
|||||||
argument: Argument?,
|
argument: Argument?,
|
||||||
operatorArguments: OperatorArguments,
|
operatorArguments: OperatorArguments,
|
||||||
): Motion {
|
): Motion {
|
||||||
return injector.motion.getVerticalMotionOffset(editor, caret, -operatorArguments.count1, bufferLines = true)
|
return injector.motion.getVerticalMotionOffset(editor, caret, -operatorArguments.count1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user