mirror of
https://github.com/chylex/IntelliJ-IdeaVim.git
synced 2025-08-18 10:31:44 +02:00
Compare commits
65 Commits
0.61
...
0.61.2-EAP
Author | SHA1 | Date | |
---|---|---|---|
![]() |
4926d2554e | ||
![]() |
eae135acba | ||
![]() |
8ce3801b87 | ||
![]() |
0c7c11f817 | ||
![]() |
b3a39c05d7 | ||
![]() |
7370012667 | ||
![]() |
412838fd4b | ||
![]() |
273a614389 | ||
![]() |
3944c80ae2 | ||
![]() |
726ab3f91b | ||
![]() |
ab307dd78f | ||
![]() |
e3079912ae | ||
![]() |
52da3ed0e4 | ||
![]() |
cda85169ea | ||
![]() |
978d1df598 | ||
![]() |
f90d22cc20 | ||
![]() |
bae69d92ae | ||
![]() |
b910239825 | ||
![]() |
6421a5969a | ||
![]() |
5c9faba7f4 | ||
![]() |
c1af738cc5 | ||
![]() |
23a80a9260 | ||
![]() |
d9d92f7eee | ||
![]() |
c8be6c203e | ||
![]() |
612c599d9b | ||
![]() |
1292c7d1ae | ||
![]() |
69f07967b5 | ||
![]() |
aedd427c07 | ||
![]() |
9b6c3dc511 | ||
![]() |
b4fa7f4317 | ||
![]() |
f053d305d5 | ||
![]() |
1d95b7ddf7 | ||
![]() |
01a6964d68 | ||
![]() |
d661f96a9b | ||
![]() |
c79fae8ab3 | ||
![]() |
121f130893 | ||
![]() |
da9a0a414a | ||
![]() |
e0732e041b | ||
![]() |
6fc5b3189a | ||
![]() |
2a0c9cb749 | ||
![]() |
7ad131b448 | ||
![]() |
3e7186bd60 | ||
![]() |
132f8cce53 | ||
![]() |
5c07f42afb | ||
![]() |
1f7a2594c8 | ||
![]() |
ec64d19a36 | ||
![]() |
5cb67470d5 | ||
![]() |
c03f01a96a | ||
![]() |
26b67a43ae | ||
![]() |
a93ca3a205 | ||
![]() |
dcc647ba3c | ||
![]() |
fe44f59239 | ||
![]() |
80dba0babf | ||
![]() |
34acf9a91e | ||
![]() |
cb859dbb7b | ||
![]() |
20c04b1e62 | ||
![]() |
69eaf8ed0c | ||
![]() |
62c828d722 | ||
![]() |
251e8e8ff4 | ||
![]() |
acc41ec72e | ||
![]() |
f9ebcf2ee4 | ||
![]() |
f3df231dc2 | ||
![]() |
75a1bb7cc5 | ||
![]() |
7d6a64315a | ||
![]() |
2758071d31 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -6,6 +6,8 @@
|
|||||||
!/.idea/copyright
|
!/.idea/copyright
|
||||||
!/.idea/icon.png
|
!/.idea/icon.png
|
||||||
!/.idea/inspectionProfiles
|
!/.idea/inspectionProfiles
|
||||||
|
!/.idea/fileTemplates
|
||||||
|
!/.idea/runConfigurations
|
||||||
|
|
||||||
/build/
|
/build/
|
||||||
/out/
|
/out/
|
||||||
|
1
.idea/fileTemplates/code/I18nized Concatenation.java
generated
Normal file
1
.idea/fileTemplates/code/I18nized Concatenation.java
generated
Normal file
@@ -0,0 +1 @@
|
|||||||
|
com.maddyhome.idea.vim.helper.MessageHelper.message("${PROPERTY_KEY}", ${PARAMETERS})
|
1
.idea/fileTemplates/code/I18nized Expression.java
generated
Normal file
1
.idea/fileTemplates/code/I18nized Expression.java
generated
Normal file
@@ -0,0 +1 @@
|
|||||||
|
com.maddyhome.idea.vim.helper.MessageHelper.message("${PROPERTY_KEY}")
|
26
.idea/inspectionProfiles/Project_Default.xml
generated
26
.idea/inspectionProfiles/Project_Default.xml
generated
@@ -1,9 +1,35 @@
|
|||||||
<component name="InspectionProjectProfileManager">
|
<component name="InspectionProjectProfileManager">
|
||||||
<profile version="1.0">
|
<profile version="1.0">
|
||||||
<option name="myName" value="Project Default" />
|
<option name="myName" value="Project Default" />
|
||||||
|
<inspection_tool class="HardCodedStringLiteral" enabled="false" level="WARNING" enabled_by_default="false">
|
||||||
|
<scope name="Production" level="WARNING" enabled="false">
|
||||||
|
<option name="ignoreForAssertStatements" value="true" />
|
||||||
|
<option name="ignoreForExceptionConstructors" value="true" />
|
||||||
|
<option name="ignoreForSpecifiedExceptionConstructors" value="" />
|
||||||
|
<option name="ignoreForJUnitAsserts" value="true" />
|
||||||
|
<option name="ignoreForClassReferences" value="true" />
|
||||||
|
<option name="ignoreForPropertyKeyReferences" value="true" />
|
||||||
|
<option name="ignoreForNonAlpha" value="true" />
|
||||||
|
<option name="ignoreAssignedToConstants" value="false" />
|
||||||
|
<option name="ignoreToString" value="true" />
|
||||||
|
<option name="nonNlsCommentPattern" value="NON-NLS" />
|
||||||
|
</scope>
|
||||||
|
<option name="ignoreForAssertStatements" value="true" />
|
||||||
|
<option name="ignoreForExceptionConstructors" value="true" />
|
||||||
|
<option name="ignoreForSpecifiedExceptionConstructors" value="" />
|
||||||
|
<option name="ignoreForJUnitAsserts" value="true" />
|
||||||
|
<option name="ignoreForClassReferences" value="true" />
|
||||||
|
<option name="ignoreForPropertyKeyReferences" value="true" />
|
||||||
|
<option name="ignoreForNonAlpha" value="true" />
|
||||||
|
<option name="ignoreAssignedToConstants" value="false" />
|
||||||
|
<option name="ignoreToString" value="false" />
|
||||||
|
<option name="nonNlsCommentPattern" value="NON-NLS" />
|
||||||
|
</inspection_tool>
|
||||||
<inspection_tool class="MissortedModifiers" enabled="true" level="WARNING" enabled_by_default="true">
|
<inspection_tool class="MissortedModifiers" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
<option name="m_requireAnnotationsFirst" value="true" />
|
<option name="m_requireAnnotationsFirst" value="true" />
|
||||||
</inspection_tool>
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PluginXmlI18n" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="StaticMethodOnlyUsedInOneClass" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="StaticMethodOnlyUsedInOneClass" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
|
<inspection_tool class="UnstableApiUsage" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
</profile>
|
</profile>
|
||||||
</component>
|
</component>
|
25
.idea/inspectionProfiles/Qodana.xml
generated
25
.idea/inspectionProfiles/Qodana.xml
generated
@@ -8,6 +8,30 @@
|
|||||||
<option name="REPORT_FIELDS" value="true" />
|
<option name="REPORT_FIELDS" value="true" />
|
||||||
</inspection_tool>
|
</inspection_tool>
|
||||||
<inspection_tool class="GrUnresolvedAccess" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
|
<inspection_tool class="GrUnresolvedAccess" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
|
||||||
|
<inspection_tool class="HardCodedStringLiteral" enabled="false" level="WARNING" enabled_by_default="false">
|
||||||
|
<scope name="Production" level="WARNING" enabled="false">
|
||||||
|
<option name="ignoreForAssertStatements" value="true" />
|
||||||
|
<option name="ignoreForExceptionConstructors" value="true" />
|
||||||
|
<option name="ignoreForSpecifiedExceptionConstructors" value="" />
|
||||||
|
<option name="ignoreForJUnitAsserts" value="true" />
|
||||||
|
<option name="ignoreForClassReferences" value="true" />
|
||||||
|
<option name="ignoreForPropertyKeyReferences" value="true" />
|
||||||
|
<option name="ignoreForNonAlpha" value="true" />
|
||||||
|
<option name="ignoreAssignedToConstants" value="false" />
|
||||||
|
<option name="ignoreToString" value="true" />
|
||||||
|
<option name="nonNlsCommentPattern" value="NON-NLS" />
|
||||||
|
</scope>
|
||||||
|
<option name="ignoreForAssertStatements" value="true" />
|
||||||
|
<option name="ignoreForExceptionConstructors" value="true" />
|
||||||
|
<option name="ignoreForSpecifiedExceptionConstructors" value="" />
|
||||||
|
<option name="ignoreForJUnitAsserts" value="true" />
|
||||||
|
<option name="ignoreForClassReferences" value="true" />
|
||||||
|
<option name="ignoreForPropertyKeyReferences" value="true" />
|
||||||
|
<option name="ignoreForNonAlpha" value="true" />
|
||||||
|
<option name="ignoreAssignedToConstants" value="false" />
|
||||||
|
<option name="ignoreToString" value="false" />
|
||||||
|
<option name="nonNlsCommentPattern" value="NON-NLS" />
|
||||||
|
</inspection_tool>
|
||||||
<inspection_tool class="MissortedModifiers" enabled="true" level="WARNING" enabled_by_default="true">
|
<inspection_tool class="MissortedModifiers" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
<option name="m_requireAnnotationsFirst" value="true" />
|
<option name="m_requireAnnotationsFirst" value="true" />
|
||||||
</inspection_tool>
|
</inspection_tool>
|
||||||
@@ -19,5 +43,6 @@
|
|||||||
</inspection_tool>
|
</inspection_tool>
|
||||||
<inspection_tool class="StaticMethodOnlyUsedInOneClass" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="StaticMethodOnlyUsedInOneClass" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="SuperTearDownInFinally" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="SuperTearDownInFinally" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
|
<inspection_tool class="UnstableApiUsage" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
</profile>
|
</profile>
|
||||||
</component>
|
</component>
|
@@ -323,6 +323,14 @@ Contributors:
|
|||||||
[![icon][github]](https://github.com/i-e-b)
|
[![icon][github]](https://github.com/i-e-b)
|
||||||
|
|
||||||
Iain Ballard
|
Iain Ballard
|
||||||
|
* [![icon][mail]](mailto:brandoncc@gmail.com)
|
||||||
|
[![icon][github]](https://github.com/brandoncc)
|
||||||
|
|
||||||
|
Brandon Conway
|
||||||
|
* [![icon][mail]](mailto:ga@anadoxin.org)
|
||||||
|
[![icon][github]](https://github.com/antekone)
|
||||||
|
|
||||||
|
Grzegorz Antoniak
|
||||||
|
|
||||||
If you are a contributor and your name is not listed here, feel free to
|
If you are a contributor and your name is not listed here, feel free to
|
||||||
contact the maintainers.
|
contact the maintainers.
|
||||||
|
18
CHANGES.md
18
CHANGES.md
@@ -24,7 +24,23 @@ usual beta standards.
|
|||||||
|
|
||||||
## To Be Released
|
## To Be Released
|
||||||
|
|
||||||
...
|
### Features:
|
||||||
|
|
||||||
|
* Support `unmap` and `mapclear` commands [VIM-1491](https://youtrack.jetbrains.com/issue/VIM-1491)
|
||||||
|
* Support mappings in ex panel (`cmap`) [VIM-1227](https://youtrack.jetbrains.com/issue/VIM-1227)
|
||||||
|
|
||||||
|
### Fixes:
|
||||||
|
* [VIM-2113](https://youtrack.jetbrains.com/issue/VIM-2113) Fix `cit` for empty tags
|
||||||
|
* [VIM-2114](https://youtrack.jetbrains.com/issue/VIM-2114) Unnamed register isn't changed after deleting empty tag
|
||||||
|
* [VIM-1475](https://youtrack.jetbrains.com/issue/VIM-1475) Enable block caret to be used in insert mode.
|
||||||
|
* [VIM-2170](https://youtrack.jetbrains.com/issue/VIM-2170) Fix an alternative range format for `s` command
|
||||||
|
|
||||||
|
### Merged PRs:
|
||||||
|
* [249](https://github.com/JetBrains/ideavim/pull/249) by [Jan Palus](https://github.com/jpalus): VIM-2113 Increase tag range only in visual mode
|
||||||
|
* [250](https://github.com/JetBrains/ideavim/pull/250) by [Jan Palus](https://github.com/jpalus): VIM-2114 Do not override registers when deleting empty range
|
||||||
|
* [256](https://github.com/JetBrains/ideavim/pull/256) by [Brandon Conway](https://github.com/brandoncc): Fix typo
|
||||||
|
* [254](https://github.com/JetBrains/ideavim/pull/254) by [Grzegorz Antoniak](https://github.com/antekone): VIM-1475: Add an option to use block caret in insert mode
|
||||||
|
* [225](https://github.com/JetBrains/ideavim/pull/225) by [sumoooru2](https://github.com/sumoooru2): Implement cmap
|
||||||
|
|
||||||
## 0.61, 2020-11-12
|
## 0.61, 2020-11-12
|
||||||
|
|
||||||
|
28
README.md
28
README.md
@@ -165,7 +165,7 @@ You can read your `~/.vimrc` file from `~/.ideavimrc` with this command:
|
|||||||
|
|
||||||
source ~/.vimrc
|
source ~/.vimrc
|
||||||
|
|
||||||
Please note that IdeaVim currently parses `~/.ideavimrc` & `~/.vimrc` files via simple pattern-matching.
|
> :warning: Please note that IdeaVim currently parses `~/.ideavimrc` & `~/.vimrc` files via simple pattern-matching.
|
||||||
See [VIM-669](https://youtrack.jetbrains.com/issue/VIM-669) for proper parsing
|
See [VIM-669](https://youtrack.jetbrains.com/issue/VIM-669) for proper parsing
|
||||||
of VimL files.
|
of VimL files.
|
||||||
|
|
||||||
@@ -183,10 +183,8 @@ Emulated Vim Plugins
|
|||||||
|
|
||||||
See [doc/emulated-plugins.md](doc/emulated-plugins.md)
|
See [doc/emulated-plugins.md](doc/emulated-plugins.md)
|
||||||
|
|
||||||
Changes to the IDE
|
Executing IDE Actions
|
||||||
------------------
|
---------------------
|
||||||
|
|
||||||
### Executing IDE Actions
|
|
||||||
|
|
||||||
IdeaVim adds various commands for listing and executing arbitrary IDE actions as
|
IdeaVim adds various commands for listing and executing arbitrary IDE actions as
|
||||||
Ex commands or via `:map` command mappings:
|
Ex commands or via `:map` command mappings:
|
||||||
@@ -205,7 +203,7 @@ Ex commands or via `:map` command mappings:
|
|||||||
extract the ids of executed command. This option can be found in "Search everywhere" (double `shift`).
|
extract the ids of executed command. This option can be found in "Search everywhere" (double `shift`).
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary><strong>"Track aciton Ids" Details</strong> (click to see)</summary>
|
<summary><strong>"Track action Ids" Details</strong> (click to see)</summary>
|
||||||
<img src="resources/readme/track_action_id.gif" alt="track action ids"/>
|
<img src="resources/readme/track_action_id.gif" alt="track action ids"/>
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
@@ -222,24 +220,6 @@ Examples:
|
|||||||
:map \b <Action>(ToggleLineBreakpoint)
|
:map \b <Action>(ToggleLineBreakpoint)
|
||||||
```
|
```
|
||||||
|
|
||||||
### Undo/Redo
|
|
||||||
|
|
||||||
The IdeaVim plugin uses the undo/redo functionality of the IntelliJ Platform,
|
|
||||||
so the behavior of the `u` and `<C-R>` commands may differ from the original
|
|
||||||
Vim. Vim compatibility of undo/redo may be improved in future releases.
|
|
||||||
|
|
||||||
See also [unresolved undo issues](https://youtrack.jetbrains.com/issues/VIM?q=%23Unresolved+Help+topic%3A+u).
|
|
||||||
|
|
||||||
### Escape
|
|
||||||
|
|
||||||
Using `<Esc>` in dialog windows remains problematic. For most dialog windows,
|
|
||||||
the Vim emulator is put into insert mode with `<Esc>` not working. You
|
|
||||||
should use `<C-c>` or `<C-[>` instead. In some dialog windows, the normal mode is
|
|
||||||
switched by default. The usage of the Vim emulator in dialog windows is an area for
|
|
||||||
improvement.
|
|
||||||
|
|
||||||
See also [unresolved escape issues](https://youtrack.jetbrains.com/issues/VIM?q=%23Unresolved+Help+topic%3A+i_Esc).
|
|
||||||
|
|
||||||
:gem: Contributing
|
:gem: Contributing
|
||||||
------------
|
------------
|
||||||
|
|
||||||
|
24
build.gradle
24
build.gradle
@@ -13,7 +13,7 @@ buildscript {
|
|||||||
}
|
}
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id 'org.jetbrains.intellij' version '0.6.2'
|
id 'org.jetbrains.intellij' version '0.6.5'
|
||||||
id 'io.gitlab.arturbosch.detekt' version '1.14.1'
|
id 'io.gitlab.arturbosch.detekt' version '1.14.1'
|
||||||
id "org.jetbrains.changelog" version "0.6.2"
|
id "org.jetbrains.changelog" version "0.6.2"
|
||||||
}
|
}
|
||||||
@@ -45,6 +45,8 @@ intellij {
|
|||||||
intellijRepo = "https://www.jetbrains.com/intellij-repository"
|
intellijRepo = "https://www.jetbrains.com/intellij-repository"
|
||||||
plugins = ['java']
|
plugins = ['java']
|
||||||
|
|
||||||
|
downloadRobotServerPlugin.version = "0.10.0"
|
||||||
|
|
||||||
publishPlugin {
|
publishPlugin {
|
||||||
channels publishChannels.split(',')
|
channels publishChannels.split(',')
|
||||||
username publishUsername
|
username publishUsername
|
||||||
@@ -52,6 +54,10 @@ intellij {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
runIdeForUiTests {
|
||||||
|
systemProperty "robot-server.port", "8082"
|
||||||
|
}
|
||||||
|
|
||||||
runPluginVerifier {
|
runPluginVerifier {
|
||||||
ideVersions = ["IC-2020.1.4", "IC-2020.2.3"]
|
ideVersions = ["IC-2020.1.4", "IC-2020.2.3"]
|
||||||
downloadDirectory = "${project.buildDir}/pluginVerifier/ides"
|
downloadDirectory = "${project.buildDir}/pluginVerifier/ides"
|
||||||
@@ -61,14 +67,18 @@ runPluginVerifier {
|
|||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
jcenter()
|
jcenter()
|
||||||
|
maven { url = "https://jetbrains.bintray.com/intellij-third-party-dependencies" }
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compileOnly "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlinVersion"
|
compileOnly "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlinVersion"
|
||||||
compileOnly "org.jetbrains:annotations:19.0.0"
|
compileOnly "org.jetbrains:annotations:20.1.0"
|
||||||
|
|
||||||
// https://mvnrepository.com/artifact/com.ensarsarajcic.neovim.java/neovim-api
|
// https://mvnrepository.com/artifact/com.ensarsarajcic.neovim.java/neovim-api
|
||||||
compile group: 'com.ensarsarajcic.neovim.java', name: 'neovim-api', version: '0.1.16'
|
testImplementation("com.ensarsarajcic.neovim.java:neovim-api:0.1.16")
|
||||||
|
|
||||||
|
testImplementation("com.intellij.remoterobot:remote-robot:0.10.0")
|
||||||
|
testImplementation("com.intellij.remoterobot:remote-fixtures:1.1.18")
|
||||||
}
|
}
|
||||||
|
|
||||||
compileKotlin {
|
compileKotlin {
|
||||||
@@ -113,6 +123,14 @@ changelog {
|
|||||||
// version = "0.60"
|
// version = "0.60"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
task getUnreleasedChangelog() {
|
||||||
|
group = "changelog"
|
||||||
|
doLast {
|
||||||
|
def log = changelog.getUnreleased().toHTML()
|
||||||
|
println log
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
tasks.register("slackEapNotification") {
|
tasks.register("slackEapNotification") {
|
||||||
doLast {
|
doLast {
|
||||||
if (!slackUrl) return
|
if (!slackUrl) return
|
||||||
|
@@ -25,7 +25,9 @@
|
|||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.JoinLinesHandler" names="j[oin]"/>
|
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.JoinLinesHandler" names="j[oin]"/>
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.JumpsHandler" names="ju[mps]"/>
|
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.JumpsHandler" names="ju[mps]"/>
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.LetHandler" names="let"/>
|
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.LetHandler" names="let"/>
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.MapHandler"/>
|
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.mapping.MapHandler"/>
|
||||||
|
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.mapping.UnMapHandler"/>
|
||||||
|
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.mapping.MapClearHandler"/>
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.MarkHandler" names="ma[rk],k"/>
|
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.MarkHandler" names="ma[rk],k"/>
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.MarksHandler" names="marks"/>
|
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.MarksHandler" names="marks"/>
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.MoveTextHandler" names="m[ove]"/>
|
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.MoveTextHandler" names="m[ove]"/>
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
<idea-plugin>
|
<idea-plugin>
|
||||||
<applicationListeners>
|
<applicationListeners>
|
||||||
<listener class="com.maddyhome.idea.vim.ui.ExEntryPanel$LafListener"
|
<listener class="com.maddyhome.idea.vim.ui.ex.ExEntryPanel$LafListener"
|
||||||
topic="com.intellij.ide.ui.LafManagerListener"/>
|
topic="com.intellij.ide.ui.LafManagerListener"/>
|
||||||
<listener class="com.maddyhome.idea.vim.extension.highlightedyank.HighlightColorResetter"
|
<listener class="com.maddyhome.idea.vim.extension.highlightedyank.HighlightColorResetter"
|
||||||
topic="com.intellij.ide.ui.LafManagerListener"/>
|
topic="com.intellij.ide.ui.LafManagerListener"/>
|
||||||
|
@@ -1,47 +1,64 @@
|
|||||||
<idea-plugin url="https://plugins.jetbrains.com/plugin/164" xmlns:xi="http://www.w3.org/2001/XInclude">
|
<idea-plugin url="https://plugins.jetbrains.com/plugin/164" xmlns:xi="http://www.w3.org/2001/XInclude">
|
||||||
<name>IdeaVim</name>
|
<name>IdeaVim</name>
|
||||||
<id>IdeaVIM</id>
|
<id>IdeaVIM</id>
|
||||||
<change-notes>
|
<change-notes><![CDATA[
|
||||||
<h3>Features:</h3>
|
<h3>Features:</h3>
|
||||||
<br/>
|
<ul>
|
||||||
<ul><li>Ability to map IDE actions via the <code>&lt;Action&gt;</code> keyword. E.g.
|
<li>Support <code>unmap</code> and <code>mapclear</code> commands
|
||||||
<code>map &lt;C-K&gt; &lt;Action&gt;(CommentByLineComment)</code>.
|
<a href="https://youtrack.jetbrains.com/issue/VIM-1491">VIM-1491</a>
|
||||||
Check out <code>README.md</code> for the details.</li><li><code>IdeaVim: track action
|
</li>
|
||||||
Ids</code> command to find action ids for the <code>:action</code> command.
|
<li>Support mappings in ex panel (<code>cmap</code>)
|
||||||
Enable this option in &quot;Search everywhere&quot; (double shift).</li><li>Ability to enable
|
<a href="https://youtrack.jetbrains.com/issue/VIM-1227">VIM-1227</a>
|
||||||
extensions using <code>vim-plug</code> or <code>vundle</code> syntax.<br />
|
</li>
|
||||||
E.g. to enable commentary extension you can use one of the following commands:<pre><code
|
</ul>
|
||||||
class="language-vim">set commentary
|
|
||||||
Plug 'tpope/vim-commentary'
|
|
||||||
Plug 'https://github.com/tpope/vim-commentary'
|
|
||||||
Plugin 'tpope/vim-commentary'
|
|
||||||
...
|
|
||||||
</code></pre><p>This approach is especially handy if you have <code>.vimrc</code> with
|
|
||||||
plugins registered via <code>vim-plug</code> or <code>vundle</code>.</p></li></ul>
|
|
||||||
|
|
||||||
|
<h3>Fixes:</h3>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="https://youtrack.jetbrains.com/issue/VIM-2113">VIM-2113</a>
|
||||||
|
Fix <code>cit</code> for empty tags
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="https://youtrack.jetbrains.com/issue/VIM-2114">VIM-2114</a>
|
||||||
|
Unnamed register isn't changed after deleting empty tag
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="https://youtrack.jetbrains.com/issue/VIM-1475">VIM-1475</a>
|
||||||
|
Enable block caret to be used in insert mode.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="https://youtrack.jetbrains.com/issue/VIM-2170">VIM-2170</a>
|
||||||
|
Fix an alternative range format for <code>s</code> command
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
<br/>
|
<h3>Merged PRs:</h3>
|
||||||
<h3>Changes:</h3>
|
<ul>
|
||||||
<br/>
|
<li>
|
||||||
<ul><li>Fix <code>&lt;Esc&gt;</code> for dialogs. Now <code>&lt;Esc&gt;</code>
|
<a href="https://github.com/JetBrains/ideavim/pull/249">249</a>
|
||||||
will exit insert / visual mode and close the dialog from normal mode.</li><li>Add option to disable
|
by <a href="https://github.com/jpalus">Jan Palus</a>: VIM-2113 Increase tag range only in visual mode
|
||||||
IdeaVim in dialogs / single line editors. <a href="https://youtrack.jetbrains.com/issue/VIM-765">VIM-765</a><br
|
</li>
|
||||||
/>
|
<li>
|
||||||
Use <code>set ideavimsupport=</code> to disable IdeaVim in dialog editors. </li><li>Reposition
|
<a href="https://github.com/JetBrains/ideavim/pull/250">250</a>
|
||||||
cursor when <code>scrolloff</code> changes</li></ul>
|
by <a href="https://github.com/jpalus">Jan Palus</a>: VIM-2114 Do not override registers when deleting empty range
|
||||||
|
</li>
|
||||||
<br/>
|
<li>
|
||||||
<h3>Fixes:</h3>
|
<a href="https://github.com/JetBrains/ideavim/pull/256">256</a>
|
||||||
<br/>
|
by <a href="https://github.com/brandoncc">Brandon Conway</a>: Fix typo
|
||||||
<ul><li><a href="https://youtrack.jetbrains.com/issue/VIM-2150">VIM-2150</a> <code>Shift-D</code>
|
</li>
|
||||||
should not delete an empty line</li><li><a href="https://youtrack.jetbrains.com/issue/VIM-2157">VIM-2157</a>
|
<li>
|
||||||
Fix tab with an active template</li><li><a href="https://youtrack.jetbrains.com/issue/VIM-2156">VIM-2156</a>
|
<a href="https://github.com/JetBrains/ideavim/pull/254">254</a>
|
||||||
Correct up/down motions with inlays</li><li><a href="https://youtrack.jetbrains.com/issue/VIM-2144">VIM-2144</a>
|
by <a href="https://github.com/antekone">Grzegorz Antoniak</a>: VIM-1475: Add an option to use block caret in insert
|
||||||
Correct text position after block insert with inlays</li><li><a
|
mode
|
||||||
href="https://youtrack.jetbrains.com/issue/VIM-2158">VIM-2158</a> Fix scrolling when <code>scrolloff</code>
|
</li>
|
||||||
is over half screen height, but less than full height</li></ul>
|
<li>
|
||||||
<br/>
|
<a href="https://github.com/JetBrains/ideavim/pull/225">225</a>
|
||||||
<p>See also the complete <a href="https://github.com/JetBrains/ideavim/blob/master/CHANGES.md">changelog</a>.</p>
|
by <a href="https://github.com/sumoooru2">sumoooru2</a>: Implement cmap
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<br/>
|
||||||
|
<p>See also the complete <a href="https://github.com/JetBrains/ideavim/blob/master/CHANGES.md">changelog</a>.</p>
|
||||||
|
]]>
|
||||||
</change-notes>
|
</change-notes>
|
||||||
<description><![CDATA[
|
<description><![CDATA[
|
||||||
<p>Vim emulation plugin for IntelliJ Platform-based IDEs.</p>
|
<p>Vim emulation plugin for IntelliJ Platform-based IDEs.</p>
|
||||||
@@ -60,11 +77,11 @@
|
|||||||
|
|
||||||
<!-- Please search for "[VERSION UPDATE]" in project in case you update the since-build version -->
|
<!-- Please search for "[VERSION UPDATE]" in project in case you update the since-build version -->
|
||||||
<!-- Check for [Version Update] tag in YouTrack as well -->
|
<!-- Check for [Version Update] tag in YouTrack as well -->
|
||||||
<idea-version since-build="201.5985.32"/>
|
<idea-version since-build="201.5985.41"/>
|
||||||
|
|
||||||
<!-- Mark the plugin as compatible with RubyMine and other products based on the IntelliJ platform -->
|
<!-- Mark the plugin as compatible with RubyMine and other products based on the IntelliJ platform -->
|
||||||
<depends>com.intellij.modules.lang</depends>
|
<depends>com.intellij.modules.lang</depends>
|
||||||
<resource-bundle xmlns="">messages</resource-bundle>
|
<resource-bundle>messages.IdeaVimBundle</resource-bundle>
|
||||||
|
|
||||||
<application-components>
|
<application-components>
|
||||||
<component>
|
<component>
|
||||||
@@ -111,7 +128,7 @@
|
|||||||
<xi:include href="/META-INF/includes/VimExtensions.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
<xi:include href="/META-INF/includes/VimExtensions.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||||
<xi:include href="/META-INF/includes/VimListeners.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
<xi:include href="/META-INF/includes/VimListeners.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||||
|
|
||||||
<actions>
|
<actions resource-bundle="messages.IdeaVimBundle">
|
||||||
<action id="VimPluginToggle" class="com.maddyhome.idea.vim.action.VimPluginToggleAction">
|
<action id="VimPluginToggle" class="com.maddyhome.idea.vim.action.VimPluginToggleAction">
|
||||||
<add-to-group group-id="ToolsMenu" anchor="last"/>
|
<add-to-group group-id="ToolsMenu" anchor="last"/>
|
||||||
</action>
|
</action>
|
||||||
@@ -137,8 +154,6 @@
|
|||||||
</action>
|
</action>
|
||||||
</group>
|
</group>
|
||||||
|
|
||||||
<action id="VimFindActionIdAction"
|
<action id="VimFindActionIdAction" class="com.maddyhome.idea.vim.listener.FindActionIdAction"/>
|
||||||
class="com.maddyhome.idea.vim.listener.FindActionIdAction" text="IdeaVim: Track Action Ids"
|
|
||||||
description="Starts tracking ids of executed actions"/>
|
|
||||||
</actions>
|
</actions>
|
||||||
</idea-plugin>
|
</idea-plugin>
|
||||||
|
@@ -72,8 +72,54 @@ E475=E475: Invalid argument: {0}
|
|||||||
E774=E774: 'operatorfunc' is empty
|
E774=E774: 'operatorfunc' is empty
|
||||||
|
|
||||||
action.VimPluginToggle.text=Vim Emulator
|
action.VimPluginToggle.text=Vim Emulator
|
||||||
description.VimPluginToggle.description=Toggle the vim plugin On/off
|
action.VimPluginToggle.description=Toggle the vim plugin On/Off
|
||||||
|
action.VimPluginToggle.enabled=Enabled
|
||||||
|
action.VimPluginToggle.enable=Enable
|
||||||
|
|
||||||
action.VimShortcutKeyAction.text=Shortcuts
|
action.VimShortcutKeyAction.text=Shortcuts
|
||||||
|
|
||||||
action.VimActions.text=Vim Actions
|
action.VimActions.text=Vim Actions
|
||||||
|
action.not.found.0=Action not found: {0}
|
||||||
|
|
||||||
|
action.VimFindActionIdAction.text=IdeaVim: Track Action Ids
|
||||||
|
action.VimFindActionIdAction.description=Starts tracking ids of executed actions
|
||||||
|
|
||||||
|
ex.show.all.actions.0.1=--- Actions ---{0}{1}
|
||||||
|
e471.argument.required=E471: Argument required
|
||||||
|
|
||||||
|
buffer.0.does.not.exist=Buffer {0} does not exist
|
||||||
|
no.matching.buffer.for.0=No matching buffer for {0}
|
||||||
|
no.write.since.last.change.add.to.override=No write since last change (add ! to override)
|
||||||
|
more.than.one.match.for.0=More than one match for {0}
|
||||||
|
e176.invalid.number.of.arguments=E176: Invalid number of arguments
|
||||||
|
e183.user.defined.commands.must.start.with.an.uppercase.letter=E183: User defined commands must start with an uppercase letter
|
||||||
|
e841.reserved.name.cannot.be.used.for.user.defined.command=E841: Reserved name, cannot be used for user defined command
|
||||||
|
e174.command.already.exists.add.to.replace.it=E174: Command already exists: add ! to replace it
|
||||||
|
recursion.detected.maximum.alias.depth.reached=Recursion detected, maximum alias depth reached.
|
||||||
|
show.mode.recording=recording
|
||||||
|
e184.no.such.user.defined.command.0=E184: No such user-defined command: {0}
|
||||||
|
unable.to.find.0=Unable to find {0}
|
||||||
|
more.ret.line.space.page.d.half.page.q.quit=-- MORE -- (RET: line, SPACE: page, d: half page, q: quit)
|
||||||
|
hit.enter.or.type.command.to.continue=Hit ENTER or type command to continue
|
||||||
|
ex.output.panel.more=-- MORE --
|
||||||
|
command.name.vim.macro.playback=Vim Macro Playback
|
||||||
|
action.no.changes.text=No Changes
|
||||||
|
action.reload.text=Reload
|
||||||
|
replace.with.0=Replace with {0} (y/n/a/q/l)?
|
||||||
|
error.invalid.command.argument=Error: invalid command argument
|
||||||
|
argtextobj.invalid.value.of.g.argtextobj.pairs.0=argtextobj: Invalid value of g:argtextobj_pairs -- {0}
|
||||||
|
highlightedyank.invalid.value.of.0.1=highlightedyank: Invalid value of {0} -- {1}
|
||||||
|
could.not.find.file.0=Could not find file: {0}
|
||||||
|
popup.advertisement.version=Version {0}
|
||||||
|
action.eap.choice.active.text=EAP{0, choice, 0# (Active)|1#}
|
||||||
|
action.about.eap.text=About EAP...
|
||||||
|
action.contacts.help.text=Contacts && Help
|
||||||
|
action.contact.on.twitter.text=Contact on Twitter
|
||||||
|
action.create.issue.text=Create an Issue
|
||||||
|
action.contribute.on.github.text=Contribute on GitHub
|
||||||
|
action.settings.text=Settings...
|
||||||
|
action.finish.eap.text=Finish EAP
|
||||||
|
action.subscribe.to.eap.text=Subscribe to EAP
|
||||||
|
configurable.name.vim.emulation=Vim Emulation
|
||||||
|
border.title.shortcut.conflicts.for.active.keymap=Shortcut Conflicts for Active Keymap
|
||||||
|
message.no.more.matches=No more matches
|
@@ -26,10 +26,8 @@ import com.intellij.openapi.application.ApplicationManager;
|
|||||||
import com.intellij.openapi.application.ModalityState;
|
import com.intellij.openapi.application.ModalityState;
|
||||||
import com.intellij.openapi.command.CommandProcessor;
|
import com.intellij.openapi.command.CommandProcessor;
|
||||||
import com.intellij.openapi.command.UndoConfirmationPolicy;
|
import com.intellij.openapi.command.UndoConfirmationPolicy;
|
||||||
import com.intellij.openapi.editor.Caret;
|
|
||||||
import com.intellij.openapi.editor.Editor;
|
import com.intellij.openapi.editor.Editor;
|
||||||
import com.intellij.openapi.editor.actionSystem.ActionPlan;
|
import com.intellij.openapi.editor.actionSystem.ActionPlan;
|
||||||
import com.intellij.openapi.editor.actionSystem.CaretSpecificDataContext;
|
|
||||||
import com.intellij.openapi.editor.actionSystem.DocCommandGroupId;
|
import com.intellij.openapi.editor.actionSystem.DocCommandGroupId;
|
||||||
import com.intellij.openapi.editor.actionSystem.TypedActionHandler;
|
import com.intellij.openapi.editor.actionSystem.TypedActionHandler;
|
||||||
import com.intellij.openapi.project.Project;
|
import com.intellij.openapi.project.Project;
|
||||||
@@ -40,17 +38,14 @@ import com.maddyhome.idea.vim.action.change.insert.InsertCompletedDigraphAction;
|
|||||||
import com.maddyhome.idea.vim.action.change.insert.InsertCompletedLiteralAction;
|
import com.maddyhome.idea.vim.action.change.insert.InsertCompletedLiteralAction;
|
||||||
import com.maddyhome.idea.vim.action.macro.ToggleRecordingAction;
|
import com.maddyhome.idea.vim.action.macro.ToggleRecordingAction;
|
||||||
import com.maddyhome.idea.vim.command.*;
|
import com.maddyhome.idea.vim.command.*;
|
||||||
import com.maddyhome.idea.vim.extension.VimExtensionHandler;
|
|
||||||
import com.maddyhome.idea.vim.group.ChangeGroup;
|
import com.maddyhome.idea.vim.group.ChangeGroup;
|
||||||
import com.maddyhome.idea.vim.group.RegisterGroup;
|
import com.maddyhome.idea.vim.group.RegisterGroup;
|
||||||
import com.maddyhome.idea.vim.group.visual.VimSelection;
|
|
||||||
import com.maddyhome.idea.vim.group.visual.VisualGroupKt;
|
import com.maddyhome.idea.vim.group.visual.VisualGroupKt;
|
||||||
import com.maddyhome.idea.vim.handler.EditorActionHandlerBase;
|
import com.maddyhome.idea.vim.handler.EditorActionHandlerBase;
|
||||||
import com.maddyhome.idea.vim.helper.*;
|
import com.maddyhome.idea.vim.helper.*;
|
||||||
import com.maddyhome.idea.vim.key.*;
|
import com.maddyhome.idea.vim.key.*;
|
||||||
import com.maddyhome.idea.vim.listener.SelectionVimListenerSuppressor;
|
|
||||||
import com.maddyhome.idea.vim.listener.VimListenerSuppressor;
|
|
||||||
import com.maddyhome.idea.vim.option.OptionsManager;
|
import com.maddyhome.idea.vim.option.OptionsManager;
|
||||||
|
import com.maddyhome.idea.vim.ui.ex.ExEntryPanel;
|
||||||
import com.maddyhome.idea.vim.ui.ShowCmd;
|
import com.maddyhome.idea.vim.ui.ShowCmd;
|
||||||
import org.jetbrains.annotations.Contract;
|
import org.jetbrains.annotations.Contract;
|
||||||
import org.jetbrains.annotations.NonNls;
|
import org.jetbrains.annotations.NonNls;
|
||||||
@@ -59,13 +54,12 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
import java.awt.event.InputEvent;
|
||||||
import java.awt.event.KeyEvent;
|
import java.awt.event.KeyEvent;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Function;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import static com.intellij.openapi.actionSystem.CommonDataKeys.*;
|
import static com.intellij.openapi.actionSystem.CommonDataKeys.*;
|
||||||
import static com.intellij.openapi.actionSystem.PlatformDataKeys.PROJECT_FILE_DIRECTORY;
|
import static com.intellij.openapi.actionSystem.PlatformDataKeys.PROJECT_FILE_DIRECTORY;
|
||||||
@@ -599,6 +593,22 @@ public class KeyHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
DigraphResult res = editorState.processDigraphKey(key, editor);
|
DigraphResult res = editorState.processDigraphKey(key, editor);
|
||||||
|
if (ExEntryPanel.getInstance().isActive()) {
|
||||||
|
switch (res.getResult()) {
|
||||||
|
case DigraphResult.RES_HANDLED:
|
||||||
|
setPromptCharacterEx(commandBuilder.isPuttingLiteral() ? '^' : key.getKeyChar());
|
||||||
|
break;
|
||||||
|
case DigraphResult.RES_DONE:
|
||||||
|
case DigraphResult.RES_BAD:
|
||||||
|
if (key.getKeyCode() == KeyEvent.VK_C && (key.getModifiers() & InputEvent.CTRL_DOWN_MASK) != 0) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
ExEntryPanel.getInstance().getEntry().clearCurrentAction();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch (res.getResult()) {
|
switch (res.getResult()) {
|
||||||
case DigraphResult.RES_HANDLED:
|
case DigraphResult.RES_HANDLED:
|
||||||
editorState.getCommandBuilder().addKey(key);
|
editorState.getCommandBuilder().addKey(key);
|
||||||
@@ -753,8 +763,10 @@ public class KeyHandler {
|
|||||||
// the key handler when it's complete.
|
// the key handler when it's complete.
|
||||||
if (action instanceof InsertCompletedDigraphAction) {
|
if (action instanceof InsertCompletedDigraphAction) {
|
||||||
editorState.startDigraphSequence();
|
editorState.startDigraphSequence();
|
||||||
|
setPromptCharacterEx('?');
|
||||||
} else if (action instanceof InsertCompletedLiteralAction) {
|
} else if (action instanceof InsertCompletedLiteralAction) {
|
||||||
editorState.startLiteralSequence();
|
editorState.startLiteralSequence();
|
||||||
|
setPromptCharacterEx('^');
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EX_STRING:
|
case EX_STRING:
|
||||||
@@ -777,7 +789,7 @@ public class KeyHandler {
|
|||||||
* @param name The name of the action to execute
|
* @param name The name of the action to execute
|
||||||
* @param context The context to run it in
|
* @param context The context to run it in
|
||||||
*/
|
*/
|
||||||
public static boolean executeAction(@NotNull String name, @NotNull DataContext context) {
|
public static boolean executeAction(@NotNull @NonNls String name, @NotNull DataContext context) {
|
||||||
ActionManager aMgr = ActionManager.getInstance();
|
ActionManager aMgr = ActionManager.getInstance();
|
||||||
AnAction action = aMgr.getAction(name);
|
AnAction action = aMgr.getAction(name);
|
||||||
return action != null && executeAction(action, context);
|
return action != null && executeAction(action, context);
|
||||||
@@ -849,6 +861,13 @@ public class KeyHandler {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setPromptCharacterEx(final char promptCharacter) {
|
||||||
|
final ExEntryPanel exEntryPanel = ExEntryPanel.getInstance();
|
||||||
|
if (exEntryPanel.isActive()) {
|
||||||
|
exEntryPanel.getEntry().setCurrentActionPromptCharacter(promptCharacter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// This class is copied from com.intellij.openapi.editor.actionSystem.DialogAwareDataContext.DialogAwareDataContext
|
// This class is copied from com.intellij.openapi.editor.actionSystem.DialogAwareDataContext.DialogAwareDataContext
|
||||||
private static final class DialogAwareDataContext implements DataContext {
|
private static final class DialogAwareDataContext implements DataContext {
|
||||||
@SuppressWarnings("rawtypes")
|
@SuppressWarnings("rawtypes")
|
||||||
@@ -917,7 +936,9 @@ public class KeyHandler {
|
|||||||
editorState.popModes();
|
editorState.popModes();
|
||||||
}
|
}
|
||||||
|
|
||||||
KeyHandler.getInstance().reset(editor);
|
if (editorState.getCommandBuilder().isDone()) {
|
||||||
|
KeyHandler.getInstance().reset(editor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Editor editor;
|
private final Editor editor;
|
||||||
|
@@ -24,7 +24,10 @@ import com.intellij.notification.NotificationListener;
|
|||||||
import com.intellij.openapi.Disposable;
|
import com.intellij.openapi.Disposable;
|
||||||
import com.intellij.openapi.application.Application;
|
import com.intellij.openapi.application.Application;
|
||||||
import com.intellij.openapi.application.ApplicationManager;
|
import com.intellij.openapi.application.ApplicationManager;
|
||||||
import com.intellij.openapi.components.*;
|
import com.intellij.openapi.components.PersistentStateComponent;
|
||||||
|
import com.intellij.openapi.components.ServiceManager;
|
||||||
|
import com.intellij.openapi.components.State;
|
||||||
|
import com.intellij.openapi.components.Storage;
|
||||||
import com.intellij.openapi.diagnostic.Logger;
|
import com.intellij.openapi.diagnostic.Logger;
|
||||||
import com.intellij.openapi.extensions.PluginId;
|
import com.intellij.openapi.extensions.PluginId;
|
||||||
import com.intellij.openapi.keymap.Keymap;
|
import com.intellij.openapi.keymap.Keymap;
|
||||||
@@ -50,7 +53,7 @@ import com.maddyhome.idea.vim.group.visual.VisualMotionGroup;
|
|||||||
import com.maddyhome.idea.vim.helper.MacKeyRepeat;
|
import com.maddyhome.idea.vim.helper.MacKeyRepeat;
|
||||||
import com.maddyhome.idea.vim.listener.VimListenerManager;
|
import com.maddyhome.idea.vim.listener.VimListenerManager;
|
||||||
import com.maddyhome.idea.vim.option.OptionsManager;
|
import com.maddyhome.idea.vim.option.OptionsManager;
|
||||||
import com.maddyhome.idea.vim.ui.ExEntryPanel;
|
import com.maddyhome.idea.vim.ui.ex.ExEntryPanel;
|
||||||
import com.maddyhome.idea.vim.ui.StatusBarIconFactory;
|
import com.maddyhome.idea.vim.ui.StatusBarIconFactory;
|
||||||
import com.maddyhome.idea.vim.ui.VimEmulationConfigurable;
|
import com.maddyhome.idea.vim.ui.VimEmulationConfigurable;
|
||||||
import com.maddyhome.idea.vim.ui.VimRcFileState;
|
import com.maddyhome.idea.vim.ui.VimRcFileState;
|
||||||
@@ -324,7 +327,7 @@ public class VimPlugin implements PersistentStateComponent<Element>, Disposable
|
|||||||
showMessage(msg);
|
showMessage(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void showMessage(@Nls @Nullable String msg) {
|
public static void showMessage(@Nls(capitalization = Nls.Capitalization.Sentence) @Nullable String msg) {
|
||||||
if (ApplicationManager.getApplication().isUnitTestMode()) {
|
if (ApplicationManager.getApplication().isUnitTestMode()) {
|
||||||
getInstance().message = msg;
|
getInstance().message = msg;
|
||||||
}
|
}
|
||||||
|
@@ -21,6 +21,7 @@ package com.maddyhome.idea.vim.action
|
|||||||
import com.intellij.openapi.actionSystem.AnActionEvent
|
import com.intellij.openapi.actionSystem.AnActionEvent
|
||||||
import com.intellij.openapi.project.DumbAwareToggleAction
|
import com.intellij.openapi.project.DumbAwareToggleAction
|
||||||
import com.maddyhome.idea.vim.VimPlugin
|
import com.maddyhome.idea.vim.VimPlugin
|
||||||
|
import com.maddyhome.idea.vim.helper.MessageHelper
|
||||||
import com.maddyhome.idea.vim.ui.VimActions
|
import com.maddyhome.idea.vim.ui.VimActions
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -38,7 +39,7 @@ class VimPluginToggleAction : DumbAwareToggleAction() {
|
|||||||
super.update(e)
|
super.update(e)
|
||||||
|
|
||||||
e.presentation.text = if (VimActions.actionPlace == e.place) {
|
e.presentation.text = if (VimActions.actionPlace == e.place) {
|
||||||
if (VimPlugin.isEnabled()) "Enabled" else "Enable"
|
if (VimPlugin.isEnabled()) MessageHelper.message("action.VimPluginToggle.enabled") else MessageHelper.message("action.VimPluginToggle.enable")
|
||||||
} else "Vim Emulator"
|
} else MessageHelper.message("action.VimPluginToggle.text")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -26,6 +26,7 @@ import com.intellij.openapi.actionSystem.DataContext
|
|||||||
import com.intellij.openapi.editor.Editor
|
import com.intellij.openapi.editor.Editor
|
||||||
import com.intellij.openapi.editor.VisualPosition
|
import com.intellij.openapi.editor.VisualPosition
|
||||||
import com.maddyhome.idea.vim.helper.EditorHelper
|
import com.maddyhome.idea.vim.helper.EditorHelper
|
||||||
|
import com.maddyhome.idea.vim.helper.VimNlsSafe
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.math.max
|
import kotlin.math.max
|
||||||
|
|
||||||
@@ -43,7 +44,10 @@ class AddInlineInlaysAction : AnAction() {
|
|||||||
val lineLength = EditorHelper.getLineLength(editor, EditorHelper.visualLineToLogicalLine(editor, currentVisualLine))
|
val lineLength = EditorHelper.getLineLength(editor, EditorHelper.visualLineToLogicalLine(editor, currentVisualLine))
|
||||||
while (i < lineLength) {
|
while (i < lineLength) {
|
||||||
val relatesToPrecedingText = random.nextInt(10) > 7
|
val relatesToPrecedingText = random.nextInt(10) > 7
|
||||||
|
|
||||||
|
@VimNlsSafe
|
||||||
val text = "a".repeat(max(1, random.nextInt(7)))
|
val text = "a".repeat(max(1, random.nextInt(7)))
|
||||||
|
|
||||||
val offset = EditorHelper.visualPositionToOffset(editor, VisualPosition(currentVisualLine, i))
|
val offset = EditorHelper.visualPositionToOffset(editor, VisualPosition(currentVisualLine, i))
|
||||||
// We don't need a custom renderer, just use the standard parameter hint renderer
|
// We don't need a custom renderer, just use the standard parameter hint renderer
|
||||||
inlayModel.addInlineElement(offset, relatesToPrecedingText, HintRenderer(if (relatesToPrecedingText) ":$text" else "$text:"))
|
inlayModel.addInlineElement(offset, relatesToPrecedingText, HintRenderer(if (relatesToPrecedingText) ":$text" else "$text:"))
|
||||||
|
@@ -23,10 +23,10 @@ import com.intellij.openapi.editor.Editor
|
|||||||
import com.maddyhome.idea.vim.VimPlugin
|
import com.maddyhome.idea.vim.VimPlugin
|
||||||
import com.maddyhome.idea.vim.command.Command
|
import com.maddyhome.idea.vim.command.Command
|
||||||
import com.maddyhome.idea.vim.command.CommandState
|
import com.maddyhome.idea.vim.command.CommandState
|
||||||
import com.maddyhome.idea.vim.helper.moveToInlayAwareOffset
|
|
||||||
import com.maddyhome.idea.vim.group.visual.vimSetSystemSelectionSilently
|
import com.maddyhome.idea.vim.group.visual.vimSetSystemSelectionSilently
|
||||||
import com.maddyhome.idea.vim.handler.VimActionHandler
|
import com.maddyhome.idea.vim.handler.VimActionHandler
|
||||||
import com.maddyhome.idea.vim.helper.EditorHelper
|
import com.maddyhome.idea.vim.helper.EditorHelper
|
||||||
|
import com.maddyhome.idea.vim.helper.moveToInlayAwareOffset
|
||||||
import com.maddyhome.idea.vim.helper.vimLastColumn
|
import com.maddyhome.idea.vim.helper.vimLastColumn
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -23,10 +23,10 @@ import com.intellij.openapi.editor.Editor
|
|||||||
import com.maddyhome.idea.vim.VimPlugin
|
import com.maddyhome.idea.vim.VimPlugin
|
||||||
import com.maddyhome.idea.vim.command.Command
|
import com.maddyhome.idea.vim.command.Command
|
||||||
import com.maddyhome.idea.vim.command.CommandState
|
import com.maddyhome.idea.vim.command.CommandState
|
||||||
import com.maddyhome.idea.vim.helper.moveToInlayAwareOffset
|
|
||||||
import com.maddyhome.idea.vim.group.visual.vimSetSystemSelectionSilently
|
import com.maddyhome.idea.vim.group.visual.vimSetSystemSelectionSilently
|
||||||
import com.maddyhome.idea.vim.handler.VimActionHandler
|
import com.maddyhome.idea.vim.handler.VimActionHandler
|
||||||
import com.maddyhome.idea.vim.helper.EditorHelper
|
import com.maddyhome.idea.vim.helper.EditorHelper
|
||||||
|
import com.maddyhome.idea.vim.helper.moveToInlayAwareOffset
|
||||||
import com.maddyhome.idea.vim.helper.vimLastColumn
|
import com.maddyhome.idea.vim.helper.vimLastColumn
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -23,10 +23,10 @@ import com.intellij.openapi.editor.Editor
|
|||||||
import com.maddyhome.idea.vim.VimPlugin
|
import com.maddyhome.idea.vim.VimPlugin
|
||||||
import com.maddyhome.idea.vim.command.Command
|
import com.maddyhome.idea.vim.command.Command
|
||||||
import com.maddyhome.idea.vim.command.CommandState
|
import com.maddyhome.idea.vim.command.CommandState
|
||||||
import com.maddyhome.idea.vim.helper.moveToInlayAwareOffset
|
|
||||||
import com.maddyhome.idea.vim.group.visual.updateCaretState
|
import com.maddyhome.idea.vim.group.visual.updateCaretState
|
||||||
import com.maddyhome.idea.vim.handler.VimActionHandler
|
import com.maddyhome.idea.vim.handler.VimActionHandler
|
||||||
import com.maddyhome.idea.vim.helper.commandState
|
import com.maddyhome.idea.vim.helper.commandState
|
||||||
|
import com.maddyhome.idea.vim.helper.moveToInlayAwareOffset
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Alex Plate
|
* @author Alex Plate
|
||||||
|
@@ -1,6 +1,9 @@
|
|||||||
package com.maddyhome.idea.vim.command
|
package com.maddyhome.idea.vim.command
|
||||||
|
|
||||||
import com.maddyhome.idea.vim.action.DuplicableOperatorAction
|
import com.maddyhome.idea.vim.action.DuplicableOperatorAction
|
||||||
|
import com.maddyhome.idea.vim.action.ResetModeAction
|
||||||
|
import com.maddyhome.idea.vim.action.change.insert.InsertCompletedDigraphAction
|
||||||
|
import com.maddyhome.idea.vim.action.change.insert.InsertCompletedLiteralAction
|
||||||
import com.maddyhome.idea.vim.handler.EditorActionHandlerBase
|
import com.maddyhome.idea.vim.handler.EditorActionHandlerBase
|
||||||
import com.maddyhome.idea.vim.key.CommandPartNode
|
import com.maddyhome.idea.vim.key.CommandPartNode
|
||||||
import com.maddyhome.idea.vim.key.Node
|
import com.maddyhome.idea.vim.key.Node
|
||||||
@@ -24,6 +27,9 @@ class CommandBuilder(private var currentCommandPartNode: CommandPartNode) {
|
|||||||
var expectedArgumentType: Argument.Type? = null
|
var expectedArgumentType: Argument.Type? = null
|
||||||
private set
|
private set
|
||||||
|
|
||||||
|
var prevExpectedArgumentType: Argument.Type? = null
|
||||||
|
private set
|
||||||
|
|
||||||
val isReady get() = commandState == CurrentCommandState.READY
|
val isReady get() = commandState == CurrentCommandState.READY
|
||||||
val isBad get() = commandState == CurrentCommandState.BAD_COMMAND
|
val isBad get() = commandState == CurrentCommandState.BAD_COMMAND
|
||||||
val isEmpty get() = commandParts.isEmpty()
|
val isEmpty get() = commandParts.isEmpty()
|
||||||
@@ -38,6 +44,7 @@ class CommandBuilder(private var currentCommandPartNode: CommandPartNode) {
|
|||||||
|
|
||||||
fun pushCommandPart(action: EditorActionHandlerBase) {
|
fun pushCommandPart(action: EditorActionHandlerBase) {
|
||||||
commandParts.add(Command(count, action, action.type, action.flags))
|
commandParts.add(Command(count, action, action.type, action.flags))
|
||||||
|
prevExpectedArgumentType = expectedArgumentType
|
||||||
expectedArgumentType = action.argumentType
|
expectedArgumentType = action.argumentType
|
||||||
count = 0
|
count = 0
|
||||||
}
|
}
|
||||||
@@ -106,6 +113,14 @@ class CommandBuilder(private var currentCommandPartNode: CommandPartNode) {
|
|||||||
return currentCommandPartNode !is RootNode
|
return currentCommandPartNode !is RootNode
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun isPuttingLiteral(): Boolean {
|
||||||
|
return !commandParts.isEmpty() && commandParts.last.action is InsertCompletedLiteralAction
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isDone(): Boolean {
|
||||||
|
return commandParts.isEmpty()
|
||||||
|
}
|
||||||
|
|
||||||
fun completeCommandPart(argument: Argument) {
|
fun completeCommandPart(argument: Argument) {
|
||||||
commandParts.peekLast().argument = argument
|
commandParts.peekLast().argument = argument
|
||||||
commandState = CurrentCommandState.READY
|
commandState = CurrentCommandState.READY
|
||||||
@@ -121,6 +136,11 @@ class CommandBuilder(private var currentCommandPartNode: CommandPartNode) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun buildCommand(): Command {
|
fun buildCommand(): Command {
|
||||||
|
if (commandParts.last.action is InsertCompletedDigraphAction || commandParts.last.action is ResetModeAction) {
|
||||||
|
expectedArgumentType = prevExpectedArgumentType
|
||||||
|
prevExpectedArgumentType = null
|
||||||
|
return commandParts.removeLast()
|
||||||
|
}
|
||||||
|
|
||||||
var command: Command = commandParts.removeFirst()
|
var command: Command = commandParts.removeFirst()
|
||||||
while (commandParts.size > 0) {
|
while (commandParts.size > 0) {
|
||||||
@@ -147,6 +167,7 @@ class CommandBuilder(private var currentCommandPartNode: CommandPartNode) {
|
|||||||
commandParts.clear()
|
commandParts.clear()
|
||||||
keyList.clear()
|
keyList.clear()
|
||||||
expectedArgumentType = null
|
expectedArgumentType = null
|
||||||
|
prevExpectedArgumentType = null
|
||||||
}
|
}
|
||||||
|
|
||||||
fun resetInProgressCommandPart(commandPartNode: CommandPartNode) {
|
fun resetInProgressCommandPart(commandPartNode: CommandPartNode) {
|
||||||
|
@@ -23,6 +23,8 @@ import com.intellij.openapi.editor.Editor
|
|||||||
import com.maddyhome.idea.vim.VimPlugin
|
import com.maddyhome.idea.vim.VimPlugin
|
||||||
import com.maddyhome.idea.vim.helper.DigraphResult
|
import com.maddyhome.idea.vim.helper.DigraphResult
|
||||||
import com.maddyhome.idea.vim.helper.DigraphSequence
|
import com.maddyhome.idea.vim.helper.DigraphSequence
|
||||||
|
import com.maddyhome.idea.vim.helper.MessageHelper
|
||||||
|
import com.maddyhome.idea.vim.helper.VimNlsSafe
|
||||||
import com.maddyhome.idea.vim.helper.noneOfEnum
|
import com.maddyhome.idea.vim.helper.noneOfEnum
|
||||||
import com.maddyhome.idea.vim.helper.vimCommandState
|
import com.maddyhome.idea.vim.helper.vimCommandState
|
||||||
import com.maddyhome.idea.vim.key.CommandPartNode
|
import com.maddyhome.idea.vim.key.CommandPartNode
|
||||||
@@ -232,6 +234,7 @@ class CommandState private constructor() {
|
|||||||
* be added. It's better not to compare the whole string but only
|
* be added. It's better not to compare the whole string but only
|
||||||
* the leading character(s).
|
* the leading character(s).
|
||||||
*/
|
*/
|
||||||
|
@VimNlsSafe
|
||||||
fun toVimNotation(): String {
|
fun toVimNotation(): String {
|
||||||
return when (mode) {
|
return when (mode) {
|
||||||
Mode.COMMAND -> "n"
|
Mode.COMMAND -> "n"
|
||||||
@@ -266,7 +269,7 @@ class CommandState private constructor() {
|
|||||||
if (msg.isNotEmpty()) {
|
if (msg.isNotEmpty()) {
|
||||||
msg.append(" - ")
|
msg.append(" - ")
|
||||||
}
|
}
|
||||||
msg.append("recording")
|
msg.append(MessageHelper.message("show.mode.recording"))
|
||||||
}
|
}
|
||||||
VimPlugin.showMode(msg.toString())
|
VimPlugin.showMode(msg.toString())
|
||||||
}
|
}
|
||||||
|
@@ -19,6 +19,8 @@
|
|||||||
package com.maddyhome.idea.vim.common
|
package com.maddyhome.idea.vim.common
|
||||||
|
|
||||||
import com.maddyhome.idea.vim.VimPlugin
|
import com.maddyhome.idea.vim.VimPlugin
|
||||||
|
import com.maddyhome.idea.vim.helper.MessageHelper
|
||||||
|
import org.jetbrains.annotations.NonNls
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Elliot Courant
|
* @author Elliot Courant
|
||||||
@@ -39,10 +41,10 @@ class Alias(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private companion object {
|
private companion object {
|
||||||
const val LessThan = "<lt>"
|
@NonNls const val LessThan = "<lt>"
|
||||||
const val Count = "<count>"
|
@NonNls const val Count = "<count>"
|
||||||
const val Arguments = "<args>"
|
@NonNls const val Arguments = "<args>"
|
||||||
const val QuotedArguments = "<q-args>"
|
@NonNls const val QuotedArguments = "<q-args>"
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getCommand(input: String, count: Int): String {
|
fun getCommand(input: String, count: Int): String {
|
||||||
@@ -52,7 +54,7 @@ class Alias(
|
|||||||
var compiledCommand = this.command
|
var compiledCommand = this.command
|
||||||
val cleanedInput = input.trim().removePrefix(name).trim()
|
val cleanedInput = input.trim().removePrefix(name).trim()
|
||||||
if (minimumNumberOfArguments > 0 && cleanedInput.isEmpty()) {
|
if (minimumNumberOfArguments > 0 && cleanedInput.isEmpty()) {
|
||||||
VimPlugin.showMessage("E471: Argument required")
|
VimPlugin.showMessage(MessageHelper.message("e471.argument.required"))
|
||||||
VimPlugin.indicateError()
|
VimPlugin.indicateError()
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
@@ -22,6 +22,7 @@ import com.intellij.ide.bookmarks.Bookmark
|
|||||||
import com.intellij.ide.bookmarks.BookmarkManager
|
import com.intellij.ide.bookmarks.BookmarkManager
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.maddyhome.idea.vim.group.MarkGroup
|
import com.maddyhome.idea.vim.group.MarkGroup
|
||||||
|
import org.jetbrains.annotations.NonNls
|
||||||
import java.lang.ref.WeakReference
|
import java.lang.ref.WeakReference
|
||||||
|
|
||||||
interface Mark {
|
interface Mark {
|
||||||
@@ -35,7 +36,7 @@ interface Mark {
|
|||||||
fun clear()
|
fun clear()
|
||||||
|
|
||||||
object KeySorter : Comparator<Mark> {
|
object KeySorter : Comparator<Mark> {
|
||||||
private const val ORDER = "'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\"[]^.<>"
|
@NonNls private const val ORDER = "'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\"[]^.<>"
|
||||||
|
|
||||||
override fun compare(o1: Mark, o2: Mark): Int {
|
override fun compare(o1: Mark, o2: Mark): Int {
|
||||||
return ORDER.indexOf(o1.key) - ORDER.indexOf(o2.key)
|
return ORDER.indexOf(o1.key) - ORDER.indexOf(o2.key)
|
||||||
|
@@ -20,8 +20,8 @@ package com.maddyhome.idea.vim.common
|
|||||||
import com.intellij.codeInsight.editorActions.TextBlockTransferableData
|
import com.intellij.codeInsight.editorActions.TextBlockTransferableData
|
||||||
import com.maddyhome.idea.vim.command.SelectionType
|
import com.maddyhome.idea.vim.command.SelectionType
|
||||||
import com.maddyhome.idea.vim.helper.StringHelper
|
import com.maddyhome.idea.vim.helper.StringHelper
|
||||||
|
import org.jetbrains.annotations.NonNls
|
||||||
import java.awt.event.KeyEvent
|
import java.awt.event.KeyEvent
|
||||||
import java.util.*
|
|
||||||
import javax.swing.KeyStroke
|
import javax.swing.KeyStroke
|
||||||
|
|
||||||
class Register {
|
class Register {
|
||||||
@@ -81,7 +81,7 @@ class Register {
|
|||||||
}
|
}
|
||||||
|
|
||||||
object KeySorter : Comparator<Register> {
|
object KeySorter : Comparator<Register> {
|
||||||
private const val ORDER = "\"0123456789abcdefghijklmnopqrstuvwxyz-*+.:%#/="
|
@NonNls private const val ORDER = "\"0123456789abcdefghijklmnopqrstuvwxyz-*+.:%#/="
|
||||||
|
|
||||||
override fun compare(o1: Register, o2: Register): Int {
|
override fun compare(o1: Register, o2: Register): Int {
|
||||||
return ORDER.indexOf(o1.name.toLowerCase()) - ORDER.indexOf(o2.name.toLowerCase())
|
return ORDER.indexOf(o1.name.toLowerCase()) - ORDER.indexOf(o2.name.toLowerCase())
|
||||||
|
@@ -18,6 +18,7 @@
|
|||||||
package com.maddyhome.idea.vim.common
|
package com.maddyhome.idea.vim.common
|
||||||
|
|
||||||
import org.jetbrains.annotations.Contract
|
import org.jetbrains.annotations.Contract
|
||||||
|
import org.jetbrains.annotations.NonNls
|
||||||
import kotlin.math.max
|
import kotlin.math.max
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
|
|
||||||
@@ -85,7 +86,7 @@ class TextRange(val startOffsets: IntArray, val endOffsets: IntArray) {
|
|||||||
operator fun contains(offset: Int): Boolean = if (isMultiple) false else offset in startOffset until endOffset
|
operator fun contains(offset: Int): Boolean = if (isMultiple) false else offset in startOffset until endOffset
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
val sb = StringBuilder()
|
@NonNls val sb = StringBuilder()
|
||||||
sb.append("TextRange")
|
sb.append("TextRange")
|
||||||
sb.append("{starts=")
|
sb.append("{starts=")
|
||||||
|
|
||||||
|
@@ -60,7 +60,7 @@ class MigrationComponents(
|
|||||||
@Service
|
@Service
|
||||||
class ApplicationConfigurationMigrator(migrationComponents: MigrationComponents) {
|
class ApplicationConfigurationMigrator(migrationComponents: MigrationComponents) {
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused", "HardCodedStringLiteral")
|
||||||
constructor() : this(productionMigrationComponents)
|
constructor() : this(productionMigrationComponents)
|
||||||
|
|
||||||
private val migrators = migrationComponents.groupedMigrators
|
private val migrators = migrationComponents.groupedMigrators
|
||||||
|
@@ -21,6 +21,7 @@
|
|||||||
package com.maddyhome.idea.vim.config.migration
|
package com.maddyhome.idea.vim.config.migration
|
||||||
|
|
||||||
import com.intellij.openapi.application.PathManager
|
import com.intellij.openapi.application.PathManager
|
||||||
|
import org.jetbrains.annotations.NonNls
|
||||||
|
|
||||||
interface VersionDetector {
|
interface VersionDetector {
|
||||||
fun extractVersion(): Int?
|
fun extractVersion(): Int?
|
||||||
@@ -28,7 +29,7 @@ interface VersionDetector {
|
|||||||
|
|
||||||
object `Detect versions 3, 4, 5, 6` : VersionDetector {
|
object `Detect versions 3, 4, 5, 6` : VersionDetector {
|
||||||
|
|
||||||
val pattern = "state version=\"(.)\"".toRegex()
|
@NonNls val pattern = "state version=\"(.)\"".toRegex()
|
||||||
|
|
||||||
override fun extractVersion(): Int? {
|
override fun extractVersion(): Int? {
|
||||||
val configFile = PathManager.getOptionsFile("vim_settings")
|
val configFile = PathManager.getOptionsFile("vim_settings")
|
||||||
|
@@ -18,8 +18,6 @@
|
|||||||
|
|
||||||
package com.maddyhome.idea.vim.ex
|
package com.maddyhome.idea.vim.ex
|
||||||
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
class CommandNode(command: ExBeanClass? = null) {
|
class CommandNode(command: ExBeanClass? = null) {
|
||||||
|
|
||||||
var commandHandler: ExBeanClass? = command
|
var commandHandler: ExBeanClass? = command
|
||||||
|
@@ -150,7 +150,7 @@ public class CommandParser {
|
|||||||
}
|
}
|
||||||
processCommand(editor, context, commandAlias, count, aliasCountdown - 1);
|
processCommand(editor, context, commandAlias, count, aliasCountdown - 1);
|
||||||
} else {
|
} else {
|
||||||
VimPlugin.showMessage("Recursion detected, maximum alias depth reached.");
|
VimPlugin.showMessage(MessageHelper.message("recursion.detected.maximum.alias.depth.reached"));
|
||||||
VimPlugin.indicateError();
|
VimPlugin.indicateError();
|
||||||
logger.warn("Recursion detected, maximum alias depth reached. ");
|
logger.warn("Recursion detected, maximum alias depth reached. ");
|
||||||
}
|
}
|
||||||
@@ -307,6 +307,10 @@ public class CommandParser {
|
|||||||
state = State.RANGE_SHORT_PATTERN;
|
state = State.RANGE_SHORT_PATTERN;
|
||||||
reprocess = false;
|
reprocess = false;
|
||||||
}
|
}
|
||||||
|
else if (ch == ',') {
|
||||||
|
location.append('.');
|
||||||
|
state = State.RANGE_MAYBE_DONE;
|
||||||
|
}
|
||||||
else if (ch == '/' || ch == '?') {
|
else if (ch == '/' || ch == '?') {
|
||||||
location.append(ch);
|
location.append(ch);
|
||||||
patternType = ch;
|
patternType = ch;
|
||||||
|
@@ -33,6 +33,7 @@ import com.maddyhome.idea.vim.ex.CommandHandler.RangeFlag.RANGE_OPTIONAL
|
|||||||
import com.maddyhome.idea.vim.ex.CommandHandlerFlags
|
import com.maddyhome.idea.vim.ex.CommandHandlerFlags
|
||||||
import com.maddyhome.idea.vim.ex.ExCommand
|
import com.maddyhome.idea.vim.ex.ExCommand
|
||||||
import com.maddyhome.idea.vim.ex.flags
|
import com.maddyhome.idea.vim.ex.flags
|
||||||
|
import com.maddyhome.idea.vim.helper.MessageHelper
|
||||||
import com.maddyhome.idea.vim.helper.runAfterGotFocus
|
import com.maddyhome.idea.vim.helper.runAfterGotFocus
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -45,7 +46,7 @@ class ActionHandler : CommandHandler.SingleExecution() {
|
|||||||
override fun execute(editor: Editor, context: DataContext, cmd: ExCommand): Boolean {
|
override fun execute(editor: Editor, context: DataContext, cmd: ExCommand): Boolean {
|
||||||
val actionName = cmd.argument.trim()
|
val actionName = cmd.argument.trim()
|
||||||
val action = ActionManager.getInstance().getAction(actionName) ?: run {
|
val action = ActionManager.getInstance().getAction(actionName) ?: run {
|
||||||
VimPlugin.showMessage("Action not found: $actionName")
|
VimPlugin.showMessage(MessageHelper.message("action.not.found.0", actionName))
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
val application = ApplicationManager.getApplication()
|
val application = ApplicationManager.getApplication()
|
||||||
|
@@ -30,6 +30,7 @@ import com.maddyhome.idea.vim.ex.CommandHandlerFlags
|
|||||||
import com.maddyhome.idea.vim.ex.ExCommand
|
import com.maddyhome.idea.vim.ex.ExCommand
|
||||||
import com.maddyhome.idea.vim.ex.ExOutputModel
|
import com.maddyhome.idea.vim.ex.ExOutputModel
|
||||||
import com.maddyhome.idea.vim.ex.flags
|
import com.maddyhome.idea.vim.ex.flags
|
||||||
|
import com.maddyhome.idea.vim.helper.MessageHelper
|
||||||
import com.maddyhome.idea.vim.helper.StringHelper
|
import com.maddyhome.idea.vim.helper.StringHelper
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -55,7 +56,7 @@ class ActionListHandler : CommandHandler.SingleExecution() {
|
|||||||
.joinToString(lineSeparator)
|
.joinToString(lineSeparator)
|
||||||
|
|
||||||
|
|
||||||
ExOutputModel.getInstance(editor).output("--- Actions ---$lineSeparator$actions")
|
ExOutputModel.getInstance(editor).output(MessageHelper.message("ex.show.all.actions.0.1", lineSeparator, actions))
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -27,6 +27,7 @@ import com.maddyhome.idea.vim.ex.CommandHandler
|
|||||||
import com.maddyhome.idea.vim.ex.ExCommand
|
import com.maddyhome.idea.vim.ex.ExCommand
|
||||||
import com.maddyhome.idea.vim.ex.flags
|
import com.maddyhome.idea.vim.ex.flags
|
||||||
import com.maddyhome.idea.vim.helper.EditorHelper
|
import com.maddyhome.idea.vim.helper.EditorHelper
|
||||||
|
import com.maddyhome.idea.vim.helper.MessageHelper
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles buffer, buf, bu, b.
|
* Handles buffer, buf, bu, b.
|
||||||
@@ -47,7 +48,7 @@ class BufferHandler : CommandHandler.SingleExecution() {
|
|||||||
val bufNum = buffer.toInt() - 1
|
val bufNum = buffer.toInt() - 1
|
||||||
|
|
||||||
if (!VimPlugin.getFile().selectFile(bufNum, context)) {
|
if (!VimPlugin.getFile().selectFile(bufNum, context)) {
|
||||||
VimPlugin.showMessage("Buffer $bufNum does not exist")
|
VimPlugin.showMessage(MessageHelper.message("buffer.0.does.not.exist", bufNum))
|
||||||
result = false
|
result = false
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -55,12 +56,12 @@ class BufferHandler : CommandHandler.SingleExecution() {
|
|||||||
|
|
||||||
when(editors.size) {
|
when(editors.size) {
|
||||||
0 -> {
|
0 -> {
|
||||||
VimPlugin.showMessage("No matching buffer for $buffer")
|
VimPlugin.showMessage(MessageHelper.message("no.matching.buffer.for.0", buffer))
|
||||||
result = false
|
result = false
|
||||||
}
|
}
|
||||||
1 -> {
|
1 -> {
|
||||||
if (EditorHelper.hasUnsavedChanges(editor) && !overrideModified) {
|
if (EditorHelper.hasUnsavedChanges(editor) && !overrideModified) {
|
||||||
VimPlugin.showMessage("No write since last change (add ! to override)")
|
VimPlugin.showMessage(MessageHelper.message("no.write.since.last.change.add.to.override"))
|
||||||
result = false
|
result = false
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -68,7 +69,7 @@ class BufferHandler : CommandHandler.SingleExecution() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
VimPlugin.showMessage("More than one match for $buffer")
|
VimPlugin.showMessage(MessageHelper.message("more.than.one.match.for.0", buffer))
|
||||||
result = false
|
result = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -31,6 +31,7 @@ import com.maddyhome.idea.vim.ex.ExCommand
|
|||||||
import com.maddyhome.idea.vim.ex.ExOutputModel
|
import com.maddyhome.idea.vim.ex.ExOutputModel
|
||||||
import com.maddyhome.idea.vim.ex.flags
|
import com.maddyhome.idea.vim.ex.flags
|
||||||
import com.maddyhome.idea.vim.helper.EditorHelper
|
import com.maddyhome.idea.vim.helper.EditorHelper
|
||||||
|
import org.jetbrains.annotations.NonNls
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -115,7 +116,7 @@ class BufferListHandler : CommandHandler.SingleExecution() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun getBufferStatus(editor: Editor, file: VirtualFile, currentFile: VirtualFile, previousFile: VirtualFile?): String {
|
private fun getBufferStatus(editor: Editor, file: VirtualFile, currentFile: VirtualFile, previousFile: VirtualFile?): String {
|
||||||
val bufStatus = StringBuilder()
|
@NonNls val bufStatus = StringBuilder()
|
||||||
|
|
||||||
when(file) {
|
when(file) {
|
||||||
currentFile -> bufStatus.append("%a ")
|
currentFile -> bufStatus.append("%a ")
|
||||||
|
@@ -32,6 +32,8 @@ import com.maddyhome.idea.vim.ex.ExOutputModel
|
|||||||
import com.maddyhome.idea.vim.ex.flags
|
import com.maddyhome.idea.vim.ex.flags
|
||||||
import com.maddyhome.idea.vim.ex.vimscript.VimScriptCommandHandler
|
import com.maddyhome.idea.vim.ex.vimscript.VimScriptCommandHandler
|
||||||
import com.maddyhome.idea.vim.group.CommandGroup.Companion.BLACKLISTED_ALIASES
|
import com.maddyhome.idea.vim.group.CommandGroup.Companion.BLACKLISTED_ALIASES
|
||||||
|
import com.maddyhome.idea.vim.helper.MessageHelper
|
||||||
|
import org.jetbrains.annotations.NonNls
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Elliot Courant
|
* @author Elliot Courant
|
||||||
@@ -42,16 +44,13 @@ class CmdHandler : CommandHandler.SingleExecution(), VimScriptCommandHandler {
|
|||||||
// Static definitions needed for aliases.
|
// Static definitions needed for aliases.
|
||||||
private companion object {
|
private companion object {
|
||||||
const val overridePrefix = "!"
|
const val overridePrefix = "!"
|
||||||
const val argsPrefix = "-nargs"
|
|
||||||
|
// [VERSION UPDATE] 203+ Annotation should be replaced with @NlsSafe
|
||||||
|
@NonNls const val argsPrefix = "-nargs"
|
||||||
|
|
||||||
const val anyNumberOfArguments = "*"
|
const val anyNumberOfArguments = "*"
|
||||||
const val zeroOrOneArguments = "?"
|
const val zeroOrOneArguments = "?"
|
||||||
const val moreThanZeroArguments = "+"
|
const val moreThanZeroArguments = "+"
|
||||||
|
|
||||||
const val errorInvalidNumberOfArguments = "E176: Invalid number of arguments"
|
|
||||||
const val errorCannotStartWithLowercase = "E183: User defined commands must start with an uppercase letter"
|
|
||||||
const val errorReservedName = "E841: Reserved name, cannot be used for user defined command"
|
|
||||||
const val errorCommandAlreadyExists = "E174: Command already exists: add ! to replace it"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun execute(cmd: ExCommand) {
|
override fun execute(cmd: ExCommand) {
|
||||||
@@ -95,7 +94,7 @@ class CmdHandler : CommandHandler.SingleExecution(), VimScriptCommandHandler {
|
|||||||
// in the actual alias being created, and we don't want to parse that one.
|
// in the actual alias being created, and we don't want to parse that one.
|
||||||
val trimmedInput = argument.takeWhile { it != ' ' }
|
val trimmedInput = argument.takeWhile { it != ' ' }
|
||||||
val pattern = Regex("(?>-nargs=((|[-])\\d+|[?]|[+]|[*]))").find(trimmedInput) ?: run {
|
val pattern = Regex("(?>-nargs=((|[-])\\d+|[?]|[+]|[*]))").find(trimmedInput) ?: run {
|
||||||
VimPlugin.showMessage(errorInvalidNumberOfArguments)
|
VimPlugin.showMessage(MessageHelper.message("e176.invalid.number.of.arguments"))
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
val nargForTrim = pattern.groupValues[0]
|
val nargForTrim = pattern.groupValues[0]
|
||||||
@@ -118,7 +117,7 @@ class CmdHandler : CommandHandler.SingleExecution(), VimScriptCommandHandler {
|
|||||||
// I missed something, since the regex limits the value to be ? + * or
|
// I missed something, since the regex limits the value to be ? + * or
|
||||||
// a valid number, its not possible (as far as I know) to have another value
|
// a valid number, its not possible (as far as I know) to have another value
|
||||||
// that regex would accept that is not valid.
|
// that regex would accept that is not valid.
|
||||||
VimPlugin.showMessage(errorInvalidNumberOfArguments)
|
VimPlugin.showMessage(MessageHelper.message("e176.invalid.number.of.arguments"))
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -126,7 +125,7 @@ class CmdHandler : CommandHandler.SingleExecution(), VimScriptCommandHandler {
|
|||||||
// Not sure why this isn't documented, but if you try to create a command in vim
|
// Not sure why this isn't documented, but if you try to create a command in vim
|
||||||
// with an explicit number of arguments greater than 1 it returns this error.
|
// with an explicit number of arguments greater than 1 it returns this error.
|
||||||
if (argNum > 1 || argNum < 0) {
|
if (argNum > 1 || argNum < 0) {
|
||||||
VimPlugin.showMessage(errorInvalidNumberOfArguments)
|
VimPlugin.showMessage(MessageHelper.message("e176.invalid.number.of.arguments"))
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
minNumberOfArgs = argNum
|
minNumberOfArgs = argNum
|
||||||
@@ -148,12 +147,12 @@ class CmdHandler : CommandHandler.SingleExecution(), VimScriptCommandHandler {
|
|||||||
|
|
||||||
// User-aliases need to begin with an uppercase character.
|
// User-aliases need to begin with an uppercase character.
|
||||||
if (!alias[0].isUpperCase()) {
|
if (!alias[0].isUpperCase()) {
|
||||||
VimPlugin.showMessage(errorCannotStartWithLowercase)
|
VimPlugin.showMessage(MessageHelper.message("e183.user.defined.commands.must.start.with.an.uppercase.letter"))
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if (alias in BLACKLISTED_ALIASES) {
|
if (alias in BLACKLISTED_ALIASES) {
|
||||||
VimPlugin.showMessage(errorReservedName)
|
VimPlugin.showMessage(MessageHelper.message("e841.reserved.name.cannot.be.used.for.user.defined.command"))
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,7 +168,7 @@ class CmdHandler : CommandHandler.SingleExecution(), VimScriptCommandHandler {
|
|||||||
// If we are not over-writing existing aliases, and an alias with the same command
|
// If we are not over-writing existing aliases, and an alias with the same command
|
||||||
// already exists then we want to do nothing.
|
// already exists then we want to do nothing.
|
||||||
if (!overrideAlias && VimPlugin.getCommand().hasAlias(alias)) {
|
if (!overrideAlias && VimPlugin.getCommand().hasAlias(alias)) {
|
||||||
VimPlugin.showMessage(errorCommandAlreadyExists)
|
VimPlugin.showMessage(MessageHelper.message("e174.command.already.exists.add.to.replace.it"))
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -24,12 +24,13 @@ import com.maddyhome.idea.vim.VimPlugin
|
|||||||
import com.maddyhome.idea.vim.ex.CommandHandler
|
import com.maddyhome.idea.vim.ex.CommandHandler
|
||||||
import com.maddyhome.idea.vim.ex.ExCommand
|
import com.maddyhome.idea.vim.ex.ExCommand
|
||||||
import com.maddyhome.idea.vim.ex.flags
|
import com.maddyhome.idea.vim.ex.flags
|
||||||
|
import com.maddyhome.idea.vim.helper.MessageHelper
|
||||||
|
|
||||||
class DelCmdHandler : CommandHandler.SingleExecution() {
|
class DelCmdHandler : CommandHandler.SingleExecution() {
|
||||||
override val argFlags = flags(RangeFlag.RANGE_FORBIDDEN, ArgumentFlag.ARGUMENT_REQUIRED, Access.READ_ONLY)
|
override val argFlags = flags(RangeFlag.RANGE_FORBIDDEN, ArgumentFlag.ARGUMENT_REQUIRED, Access.READ_ONLY)
|
||||||
override fun execute(editor: Editor, context: DataContext, cmd: ExCommand): Boolean {
|
override fun execute(editor: Editor, context: DataContext, cmd: ExCommand): Boolean {
|
||||||
if (!VimPlugin.getCommand().hasAlias(cmd.argument)) {
|
if (!VimPlugin.getCommand().hasAlias(cmd.argument)) {
|
||||||
VimPlugin.showMessage("E184: No such user-defined command: ${cmd.argument}")
|
VimPlugin.showMessage(MessageHelper.message("e184.no.such.user.defined.command.0", cmd.argument))
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -24,6 +24,7 @@ import com.intellij.openapi.editor.Editor
|
|||||||
import com.maddyhome.idea.vim.ex.CommandHandler
|
import com.maddyhome.idea.vim.ex.CommandHandler
|
||||||
import com.maddyhome.idea.vim.ex.ExCommand
|
import com.maddyhome.idea.vim.ex.ExCommand
|
||||||
import com.maddyhome.idea.vim.ex.flags
|
import com.maddyhome.idea.vim.ex.flags
|
||||||
|
import org.jetbrains.annotations.NonNls
|
||||||
import java.io.UnsupportedEncodingException
|
import java.io.UnsupportedEncodingException
|
||||||
import java.net.URLEncoder
|
import java.net.URLEncoder
|
||||||
|
|
||||||
@@ -37,6 +38,7 @@ class HelpHandler : CommandHandler.SingleExecution() {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNls
|
||||||
private fun helpTopicUrl(topic: String): String {
|
private fun helpTopicUrl(topic: String): String {
|
||||||
if (topic.isBlank()) return HELP_ROOT_URL
|
if (topic.isBlank()) return HELP_ROOT_URL
|
||||||
|
|
||||||
|
@@ -36,7 +36,6 @@ import com.maddyhome.idea.vim.helper.EditorHelper
|
|||||||
import com.maddyhome.idea.vim.helper.MessageHelper
|
import com.maddyhome.idea.vim.helper.MessageHelper
|
||||||
import com.maddyhome.idea.vim.helper.Msg
|
import com.maddyhome.idea.vim.helper.Msg
|
||||||
import com.maddyhome.idea.vim.helper.fileSize
|
import com.maddyhome.idea.vim.helper.fileSize
|
||||||
import java.util.*
|
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
|
|
||||||
class MoveTextHandler : CommandHandler.SingleExecution() {
|
class MoveTextHandler : CommandHandler.SingleExecution() {
|
||||||
|
@@ -28,9 +28,8 @@ import com.maddyhome.idea.vim.ex.ExCommand
|
|||||||
import com.maddyhome.idea.vim.ex.ExException
|
import com.maddyhome.idea.vim.ex.ExException
|
||||||
import com.maddyhome.idea.vim.ex.flags
|
import com.maddyhome.idea.vim.ex.flags
|
||||||
import com.maddyhome.idea.vim.ex.ranges.LineRange
|
import com.maddyhome.idea.vim.ex.ranges.LineRange
|
||||||
import com.maddyhome.idea.vim.helper.moveToInlayAwareOffset
|
|
||||||
import com.maddyhome.idea.vim.helper.inBlockSubMode
|
import com.maddyhome.idea.vim.helper.inBlockSubMode
|
||||||
import java.util.*
|
import com.maddyhome.idea.vim.helper.moveToInlayAwareOffset
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Alex Selesse
|
* @author Alex Selesse
|
||||||
|
@@ -24,11 +24,14 @@ import com.maddyhome.idea.vim.VimPlugin
|
|||||||
import com.maddyhome.idea.vim.ex.CommandHandler
|
import com.maddyhome.idea.vim.ex.CommandHandler
|
||||||
import com.maddyhome.idea.vim.ex.ExCommand
|
import com.maddyhome.idea.vim.ex.ExCommand
|
||||||
import com.maddyhome.idea.vim.ex.flags
|
import com.maddyhome.idea.vim.ex.flags
|
||||||
|
import org.jetbrains.annotations.NonNls
|
||||||
|
|
||||||
class SplitHandler : CommandHandler.SingleExecution() {
|
class SplitHandler : CommandHandler.SingleExecution() {
|
||||||
override val argFlags = flags(RangeFlag.RANGE_FORBIDDEN, ArgumentFlag.ARGUMENT_OPTIONAL, Access.READ_ONLY)
|
override val argFlags = flags(RangeFlag.RANGE_FORBIDDEN, ArgumentFlag.ARGUMENT_OPTIONAL, Access.READ_ONLY)
|
||||||
|
@NonNls private val visualSplitPrefix = "v"
|
||||||
|
|
||||||
override fun execute(editor: Editor, context: DataContext, cmd: ExCommand): Boolean {
|
override fun execute(editor: Editor, context: DataContext, cmd: ExCommand): Boolean {
|
||||||
if (cmd.command.startsWith("v")) {
|
if (cmd.command.startsWith(visualSplitPrefix)) {
|
||||||
VimPlugin.getWindow().splitWindowVertical(context, cmd.argument)
|
VimPlugin.getWindow().splitWindowVertical(context, cmd.argument)
|
||||||
} else {
|
} else {
|
||||||
VimPlugin.getWindow().splitWindowHorizontal(context, cmd.argument)
|
VimPlugin.getWindow().splitWindowHorizontal(context, cmd.argument)
|
||||||
|
@@ -26,6 +26,7 @@ import com.maddyhome.idea.vim.VimPlugin
|
|||||||
import com.maddyhome.idea.vim.ex.CommandHandler
|
import com.maddyhome.idea.vim.ex.CommandHandler
|
||||||
import com.maddyhome.idea.vim.ex.ExCommand
|
import com.maddyhome.idea.vim.ex.ExCommand
|
||||||
import com.maddyhome.idea.vim.ex.flags
|
import com.maddyhome.idea.vim.ex.flags
|
||||||
|
import com.maddyhome.idea.vim.helper.MessageHelper
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Rieon Ke
|
* @author Rieon Ke
|
||||||
@@ -51,7 +52,7 @@ class TabCloseHandler : CommandHandler.SingleExecution() {
|
|||||||
val select = if (index == current) index + 1 else current
|
val select = if (index == current) index + 1 else current
|
||||||
tabbedPane.removeTabAt(index, select)
|
tabbedPane.removeTabAt(index, select)
|
||||||
} else {
|
} else {
|
||||||
VimPlugin.showMessage("Error: invalid command argument")
|
VimPlugin.showMessage(MessageHelper.message("error.invalid.command.argument"))
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
|
31
src/com/maddyhome/idea/vim/ex/handler/mapping/CommandInfo.kt
Normal file
31
src/com/maddyhome/idea/vim/ex/handler/mapping/CommandInfo.kt
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||||
|
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.maddyhome.idea.vim.ex.handler.mapping
|
||||||
|
|
||||||
|
import com.maddyhome.idea.vim.command.MappingMode
|
||||||
|
import org.jetbrains.annotations.NonNls
|
||||||
|
|
||||||
|
internal class CommandInfo(
|
||||||
|
@NonNls val prefix: String,
|
||||||
|
@NonNls suffix: String,
|
||||||
|
val mappingModes: Set<MappingMode>,
|
||||||
|
val isRecursive: Boolean
|
||||||
|
) {
|
||||||
|
val command = if (suffix.isBlank()) prefix else "$prefix[$suffix]"
|
||||||
|
}
|
@@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||||
|
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.maddyhome.idea.vim.ex.handler.mapping
|
||||||
|
|
||||||
|
import com.intellij.openapi.actionSystem.DataContext
|
||||||
|
import com.intellij.openapi.editor.Editor
|
||||||
|
import com.maddyhome.idea.vim.VimPlugin
|
||||||
|
import com.maddyhome.idea.vim.command.MappingMode
|
||||||
|
import com.maddyhome.idea.vim.ex.CommandHandler
|
||||||
|
import com.maddyhome.idea.vim.ex.CommandHandler.Access.READ_ONLY
|
||||||
|
import com.maddyhome.idea.vim.ex.CommandHandler.ArgumentFlag.ARGUMENT_FORBIDDEN
|
||||||
|
import com.maddyhome.idea.vim.ex.CommandHandler.RangeFlag.RANGE_FORBIDDEN
|
||||||
|
import com.maddyhome.idea.vim.ex.CommandHandlerFlags
|
||||||
|
import com.maddyhome.idea.vim.ex.CommandName
|
||||||
|
import com.maddyhome.idea.vim.ex.ComplicatedNameExCommand
|
||||||
|
import com.maddyhome.idea.vim.ex.ExCommand
|
||||||
|
import com.maddyhome.idea.vim.ex.commands
|
||||||
|
import com.maddyhome.idea.vim.ex.flags
|
||||||
|
import com.maddyhome.idea.vim.ex.vimscript.VimScriptCommandHandler
|
||||||
|
|
||||||
|
class MapClearHandler : CommandHandler.SingleExecution(), VimScriptCommandHandler, ComplicatedNameExCommand {
|
||||||
|
override val argFlags: CommandHandlerFlags = flags(RANGE_FORBIDDEN, ARGUMENT_FORBIDDEN, READ_ONLY)
|
||||||
|
override val names: Array<CommandName> = COMMAND_NAMES
|
||||||
|
|
||||||
|
override fun execute(editor: Editor, context: DataContext, cmd: ExCommand): Boolean = executeCommand(cmd)
|
||||||
|
|
||||||
|
override fun execute(cmd: ExCommand) {
|
||||||
|
executeCommand(cmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun executeCommand(cmd: ExCommand): Boolean {
|
||||||
|
val commandInfo = COMMAND_INFOS.find { cmd.command.startsWith(it.prefix) } ?: return false
|
||||||
|
|
||||||
|
VimPlugin.getKey().removeKeyMapping(commandInfo.mappingModes)
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val COMMAND_INFOS = arrayOf(
|
||||||
|
CommandInfo("mapc", "lear", MappingMode.NVO, false),
|
||||||
|
CommandInfo("nmapc", "lear", MappingMode.N, false),
|
||||||
|
CommandInfo("vmapc", "lear", MappingMode.V, false),
|
||||||
|
CommandInfo("xmapc", "lear", MappingMode.X, false),
|
||||||
|
CommandInfo("smapc", "lear", MappingMode.S, false),
|
||||||
|
CommandInfo("omapc", "lear", MappingMode.O, false),
|
||||||
|
CommandInfo("imapc", "lear", MappingMode.I, false),
|
||||||
|
CommandInfo("cmapc", "lear", MappingMode.C, false)
|
||||||
|
)
|
||||||
|
|
||||||
|
val COMMAND_NAMES = commands(*COMMAND_INFOS.map { it.command }.toTypedArray())
|
||||||
|
}
|
||||||
|
}
|
@@ -16,7 +16,7 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.maddyhome.idea.vim.ex.handler
|
package com.maddyhome.idea.vim.ex.handler.mapping
|
||||||
|
|
||||||
import com.intellij.openapi.actionSystem.DataContext
|
import com.intellij.openapi.actionSystem.DataContext
|
||||||
import com.intellij.openapi.editor.Editor
|
import com.intellij.openapi.editor.Editor
|
||||||
@@ -30,11 +30,12 @@ import com.maddyhome.idea.vim.ex.ExCommand
|
|||||||
import com.maddyhome.idea.vim.ex.ExException
|
import com.maddyhome.idea.vim.ex.ExException
|
||||||
import com.maddyhome.idea.vim.ex.commands
|
import com.maddyhome.idea.vim.ex.commands
|
||||||
import com.maddyhome.idea.vim.ex.flags
|
import com.maddyhome.idea.vim.ex.flags
|
||||||
import com.maddyhome.idea.vim.ex.handler.MapHandler.SpecialArgument.EXPR
|
import com.maddyhome.idea.vim.ex.handler.mapping.MapHandler.SpecialArgument.EXPR
|
||||||
import com.maddyhome.idea.vim.ex.handler.MapHandler.SpecialArgument.SCRIPT
|
import com.maddyhome.idea.vim.ex.handler.mapping.MapHandler.SpecialArgument.SCRIPT
|
||||||
import com.maddyhome.idea.vim.ex.vimscript.VimScriptCommandHandler
|
import com.maddyhome.idea.vim.ex.vimscript.VimScriptCommandHandler
|
||||||
import com.maddyhome.idea.vim.helper.StringHelper.parseKeys
|
import com.maddyhome.idea.vim.helper.StringHelper.parseKeys
|
||||||
import com.maddyhome.idea.vim.key.MappingOwner
|
import com.maddyhome.idea.vim.key.MappingOwner
|
||||||
|
import org.jetbrains.annotations.NonNls
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import javax.swing.KeyStroke
|
import javax.swing.KeyStroke
|
||||||
|
|
||||||
@@ -57,34 +58,32 @@ class MapHandler : CommandHandler.SingleExecution(), VimScriptCommandHandler, Co
|
|||||||
|
|
||||||
@Throws(ExException::class)
|
@Throws(ExException::class)
|
||||||
private fun executeCommand(cmd: ExCommand, editor: Editor?): Boolean {
|
private fun executeCommand(cmd: ExCommand, editor: Editor?): Boolean {
|
||||||
val commandInfo = COMMAND_INFOS.find { cmd.command.startsWith(it.prefix) }
|
val commandInfo = COMMAND_INFOS.find { cmd.command.startsWith(it.prefix) } ?: return false
|
||||||
if (commandInfo != null) {
|
val argument = cmd.argument
|
||||||
val argument = cmd.argument
|
val modes = commandInfo.mappingModes
|
||||||
val modes = commandInfo.mappingModes
|
|
||||||
if (argument.isEmpty()) {
|
|
||||||
return editor != null && VimPlugin.getKey().showKeyMappings(modes, editor)
|
|
||||||
} else {
|
|
||||||
val arguments = try {
|
|
||||||
parseCommandArguments(argument)
|
|
||||||
} catch (ignored: IllegalArgumentException) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
if (arguments != null) {
|
if (argument.isEmpty()) return editor != null && VimPlugin.getKey().showKeyMappings(modes, editor)
|
||||||
for (unsupportedArgument in UNSUPPORTED_SPECIAL_ARGUMENTS) {
|
|
||||||
if (unsupportedArgument in arguments.specialArguments) {
|
val arguments = try {
|
||||||
throw ExException("Unsupported map argument: $unsupportedArgument")
|
parseCommandArguments(argument) ?: return false
|
||||||
}
|
} catch (ignored: IllegalArgumentException) {
|
||||||
}
|
return false
|
||||||
VimPlugin.getKey().putKeyMapping(modes, arguments.fromKeys, MappingOwner.IdeaVim, arguments.toKeys, commandInfo.isRecursive)
|
}
|
||||||
return true
|
|
||||||
}
|
for (unsupportedArgument in UNSUPPORTED_SPECIAL_ARGUMENTS) {
|
||||||
|
if (unsupportedArgument in arguments.specialArguments) {
|
||||||
|
throw ExException("Unsupported map argument: $unsupportedArgument")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false
|
|
||||||
|
VimPlugin.getKey()
|
||||||
|
.putKeyMapping(modes, arguments.fromKeys, MappingOwner.IdeaVim, arguments.toKeys, commandInfo.isRecursive)
|
||||||
|
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
|
@NonNls
|
||||||
private enum class SpecialArgument(val myName: String) {
|
private enum class SpecialArgument(val myName: String) {
|
||||||
BUFFER("<buffer>"),
|
BUFFER("<buffer>"),
|
||||||
NOWAIT("<nowait>"),
|
NOWAIT("<nowait>"),
|
||||||
@@ -113,10 +112,6 @@ class MapHandler : CommandHandler.SingleExecution(), VimScriptCommandHandler, Co
|
|||||||
private class CommandArguments(val specialArguments: Set<SpecialArgument>, val fromKeys: List<KeyStroke>,
|
private class CommandArguments(val specialArguments: Set<SpecialArgument>, val fromKeys: List<KeyStroke>,
|
||||||
val toKeys: List<KeyStroke>)
|
val toKeys: List<KeyStroke>)
|
||||||
|
|
||||||
private class CommandInfo(val prefix: String, suffix: String, val mappingModes: Set<MappingMode>, val isRecursive: Boolean) {
|
|
||||||
val command = if (suffix.isBlank()) prefix else "$prefix[$suffix]"
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val CTRL_V = '\u0016'
|
private const val CTRL_V = '\u0016'
|
||||||
private val COMMAND_INFOS = arrayOf(
|
private val COMMAND_INFOS = arrayOf(
|
@@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||||
|
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.maddyhome.idea.vim.ex.handler.mapping
|
||||||
|
|
||||||
|
import com.intellij.openapi.actionSystem.DataContext
|
||||||
|
import com.intellij.openapi.editor.Editor
|
||||||
|
import com.maddyhome.idea.vim.VimPlugin
|
||||||
|
import com.maddyhome.idea.vim.command.MappingMode
|
||||||
|
import com.maddyhome.idea.vim.ex.CommandHandler
|
||||||
|
import com.maddyhome.idea.vim.ex.CommandHandler.Access.READ_ONLY
|
||||||
|
import com.maddyhome.idea.vim.ex.CommandHandler.ArgumentFlag.ARGUMENT_REQUIRED
|
||||||
|
import com.maddyhome.idea.vim.ex.CommandHandler.RangeFlag.RANGE_FORBIDDEN
|
||||||
|
import com.maddyhome.idea.vim.ex.CommandHandlerFlags
|
||||||
|
import com.maddyhome.idea.vim.ex.CommandName
|
||||||
|
import com.maddyhome.idea.vim.ex.ComplicatedNameExCommand
|
||||||
|
import com.maddyhome.idea.vim.ex.ExCommand
|
||||||
|
import com.maddyhome.idea.vim.ex.commands
|
||||||
|
import com.maddyhome.idea.vim.ex.flags
|
||||||
|
import com.maddyhome.idea.vim.ex.vimscript.VimScriptCommandHandler
|
||||||
|
import com.maddyhome.idea.vim.helper.StringHelper.parseKeys
|
||||||
|
|
||||||
|
class UnMapHandler : CommandHandler.SingleExecution(), VimScriptCommandHandler, ComplicatedNameExCommand {
|
||||||
|
override val argFlags: CommandHandlerFlags = flags(RANGE_FORBIDDEN, ARGUMENT_REQUIRED, READ_ONLY)
|
||||||
|
override val names: Array<CommandName> = COMMAND_NAMES
|
||||||
|
|
||||||
|
override fun execute(editor: Editor, context: DataContext, cmd: ExCommand): Boolean = executeCommand(cmd)
|
||||||
|
|
||||||
|
override fun execute(cmd: ExCommand) {
|
||||||
|
executeCommand(cmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun executeCommand(cmd: ExCommand): Boolean {
|
||||||
|
val commandInfo = COMMAND_INFOS.find { cmd.command.startsWith(it.prefix) } ?: return false
|
||||||
|
val argument = cmd.argument
|
||||||
|
|
||||||
|
if (argument.isEmpty()) return false
|
||||||
|
|
||||||
|
val parsedKeys = parseKeys(argument.trimStart())
|
||||||
|
|
||||||
|
VimPlugin.getKey().removeKeyMapping(commandInfo.mappingModes, parsedKeys)
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val COMMAND_INFOS = arrayOf(
|
||||||
|
CommandInfo("unm", "ap", MappingMode.NVO, false),
|
||||||
|
CommandInfo("nun", "map", MappingMode.N, false),
|
||||||
|
CommandInfo("vu", "nmap", MappingMode.V, false),
|
||||||
|
CommandInfo("xu", "nmap", MappingMode.X, false),
|
||||||
|
CommandInfo("sunm", "ap", MappingMode.S, false),
|
||||||
|
CommandInfo("ou", "nmap", MappingMode.O, false),
|
||||||
|
CommandInfo("iu", "nmap", MappingMode.I, false),
|
||||||
|
CommandInfo("cu", "nmap", MappingMode.C, false)
|
||||||
|
)
|
||||||
|
|
||||||
|
val COMMAND_NAMES = commands(*COMMAND_INFOS.map { it.command }.toTypedArray())
|
||||||
|
}
|
||||||
|
}
|
@@ -24,6 +24,7 @@ import com.maddyhome.idea.vim.common.TextRange
|
|||||||
import com.maddyhome.idea.vim.group.MotionGroup
|
import com.maddyhome.idea.vim.group.MotionGroup
|
||||||
import com.maddyhome.idea.vim.helper.EditorHelper
|
import com.maddyhome.idea.vim.helper.EditorHelper
|
||||||
import com.maddyhome.idea.vim.helper.fileSize
|
import com.maddyhome.idea.vim.helper.fileSize
|
||||||
|
import org.jetbrains.annotations.NonNls
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -179,6 +180,7 @@ class Ranges {
|
|||||||
count = 0
|
count = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNls
|
||||||
override fun toString(): String = "Ranges[ranges=$ranges]"
|
override fun toString(): String = "Ranges[ranges=$ranges]"
|
||||||
|
|
||||||
private var startLine = 0
|
private var startLine = 0
|
||||||
|
@@ -20,6 +20,7 @@ package com.maddyhome.idea.vim.ex.vimscript
|
|||||||
import com.maddyhome.idea.vim.ex.CommandParser
|
import com.maddyhome.idea.vim.ex.CommandParser
|
||||||
import com.maddyhome.idea.vim.ex.ExException
|
import com.maddyhome.idea.vim.ex.ExException
|
||||||
import com.maddyhome.idea.vim.ui.VimRcFileState
|
import com.maddyhome.idea.vim.ui.VimRcFileState
|
||||||
|
import org.jetbrains.annotations.NonNls
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.nio.file.Paths
|
import java.nio.file.Paths
|
||||||
@@ -30,8 +31,14 @@ import java.util.regex.Pattern
|
|||||||
* @author vlan
|
* @author vlan
|
||||||
*/
|
*/
|
||||||
object VimScriptParser {
|
object VimScriptParser {
|
||||||
|
// [VERSION UPDATE] 203+ Annotation should be replaced with @NlsSafe
|
||||||
|
@NonNls
|
||||||
private const val VIMRC_FILE_NAME = "ideavimrc"
|
private const val VIMRC_FILE_NAME = "ideavimrc"
|
||||||
|
// [VERSION UPDATE] 203+ Annotation should be replaced with @NlsSafe
|
||||||
|
@NonNls
|
||||||
private val HOME_VIMRC_PATHS = arrayOf(".$VIMRC_FILE_NAME", "_$VIMRC_FILE_NAME")
|
private val HOME_VIMRC_PATHS = arrayOf(".$VIMRC_FILE_NAME", "_$VIMRC_FILE_NAME")
|
||||||
|
// [VERSION UPDATE] 203+ Annotation should be replaced with @NlsSafe
|
||||||
|
@NonNls
|
||||||
private val XDG_VIMRC_PATH = "ideavim" + File.separator + VIMRC_FILE_NAME
|
private val XDG_VIMRC_PATH = "ideavim" + File.separator + VIMRC_FILE_NAME
|
||||||
private val DOUBLE_QUOTED_STRING = Pattern.compile("\"([^\"]*)\"")
|
private val DOUBLE_QUOTED_STRING = Pattern.compile("\"([^\"]*)\"")
|
||||||
private val SINGLE_QUOTED_STRING = Pattern.compile("'([^']*)'")
|
private val SINGLE_QUOTED_STRING = Pattern.compile("'([^']*)'")
|
||||||
|
@@ -21,7 +21,6 @@ package com.maddyhome.idea.vim.extension
|
|||||||
import com.intellij.openapi.application.ApplicationManager
|
import com.intellij.openapi.application.ApplicationManager
|
||||||
import com.intellij.openapi.extensions.AbstractExtensionPointBean
|
import com.intellij.openapi.extensions.AbstractExtensionPointBean
|
||||||
import com.intellij.util.xmlb.annotations.Attribute
|
import com.intellij.util.xmlb.annotations.Attribute
|
||||||
import com.intellij.util.xmlb.annotations.CollectionBean
|
|
||||||
import com.intellij.util.xmlb.annotations.Tag
|
import com.intellij.util.xmlb.annotations.Tag
|
||||||
import com.intellij.util.xmlb.annotations.XCollection
|
import com.intellij.util.xmlb.annotations.XCollection
|
||||||
import java.util.concurrent.atomic.AtomicBoolean
|
import java.util.concurrent.atomic.AtomicBoolean
|
||||||
|
@@ -20,6 +20,7 @@ package com.maddyhome.idea.vim.extension;
|
|||||||
|
|
||||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||||
import com.maddyhome.idea.vim.VimPlugin;
|
import com.maddyhome.idea.vim.VimPlugin;
|
||||||
|
import com.maddyhome.idea.vim.helper.VimNlsSafe;
|
||||||
import com.maddyhome.idea.vim.key.MappingOwner;
|
import com.maddyhome.idea.vim.key.MappingOwner;
|
||||||
import org.jetbrains.annotations.ApiStatus;
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@@ -36,6 +37,7 @@ public interface VimExtension {
|
|||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
@ApiStatus.ScheduledForRemoval(inVersion = "0.65")
|
@ApiStatus.ScheduledForRemoval(inVersion = "0.65")
|
||||||
|
@VimNlsSafe
|
||||||
@NotNull String getName();
|
@NotNull String getName();
|
||||||
|
|
||||||
default MappingOwner getOwner() {
|
default MappingOwner getOwner() {
|
||||||
|
@@ -30,7 +30,7 @@ import com.maddyhome.idea.vim.helper.TestInputModel
|
|||||||
import com.maddyhome.idea.vim.helper.commandState
|
import com.maddyhome.idea.vim.helper.commandState
|
||||||
import com.maddyhome.idea.vim.key.MappingOwner
|
import com.maddyhome.idea.vim.key.MappingOwner
|
||||||
import com.maddyhome.idea.vim.key.OperatorFunction
|
import com.maddyhome.idea.vim.key.OperatorFunction
|
||||||
import com.maddyhome.idea.vim.ui.ExEntryPanel
|
import com.maddyhome.idea.vim.ui.ex.ExEntryPanel
|
||||||
import com.maddyhome.idea.vim.ui.ModalEntry
|
import com.maddyhome.idea.vim.ui.ModalEntry
|
||||||
import java.awt.event.KeyEvent
|
import java.awt.event.KeyEvent
|
||||||
import javax.swing.KeyStroke
|
import javax.swing.KeyStroke
|
||||||
|
@@ -12,12 +12,16 @@ import com.maddyhome.idea.vim.extension.VimExtension;
|
|||||||
import com.maddyhome.idea.vim.extension.VimExtensionHandler;
|
import com.maddyhome.idea.vim.extension.VimExtensionHandler;
|
||||||
import com.maddyhome.idea.vim.handler.TextObjectActionHandler;
|
import com.maddyhome.idea.vim.handler.TextObjectActionHandler;
|
||||||
import com.maddyhome.idea.vim.helper.InlayHelperKt;
|
import com.maddyhome.idea.vim.helper.InlayHelperKt;
|
||||||
|
import com.maddyhome.idea.vim.helper.MessageHelper;
|
||||||
import com.maddyhome.idea.vim.listener.SelectionVimListenerSuppressor;
|
import com.maddyhome.idea.vim.listener.SelectionVimListenerSuppressor;
|
||||||
import com.maddyhome.idea.vim.listener.VimListenerSuppressor;
|
import com.maddyhome.idea.vim.listener.VimListenerSuppressor;
|
||||||
|
import org.jetbrains.annotations.Nls;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.ArrayDeque;
|
||||||
|
import java.util.Deque;
|
||||||
|
import java.util.EnumSet;
|
||||||
|
|
||||||
import static com.maddyhome.idea.vim.extension.VimExtensionFacade.putExtensionHandlerMapping;
|
import static com.maddyhome.idea.vim.extension.VimExtensionFacade.putExtensionHandlerMapping;
|
||||||
import static com.maddyhome.idea.vim.extension.VimExtensionFacade.putKeyMapping;
|
import static com.maddyhome.idea.vim.extension.VimExtensionFacade.putKeyMapping;
|
||||||
@@ -183,7 +187,8 @@ public class VimArgTextObjExtension implements VimExtension {
|
|||||||
try {
|
try {
|
||||||
bracketPairs = BracketPairs.fromBracketPairList(bracketPairsVar);
|
bracketPairs = BracketPairs.fromBracketPairList(bracketPairsVar);
|
||||||
} catch (BracketPairs.ParseException parseException) {
|
} catch (BracketPairs.ParseException parseException) {
|
||||||
VimPlugin.showMessage("argtextobj: Invalid value of g:argtextobj_pairs -- " + parseException.getMessage());
|
VimPlugin.showMessage(
|
||||||
|
MessageHelper.message("argtextobj.invalid.value.of.g.argtextobj.pairs.0", parseException.getMessage()));
|
||||||
VimPlugin.indicateError();
|
VimPlugin.indicateError();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -259,7 +264,7 @@ public class VimArgTextObjExtension implements VimExtension {
|
|||||||
private int rightBound = Integer.MIN_VALUE;
|
private int rightBound = Integer.MIN_VALUE;
|
||||||
private int leftBracket;
|
private int leftBracket;
|
||||||
private int rightBracket;
|
private int rightBracket;
|
||||||
private String error = null;
|
private @Nls String error = null;
|
||||||
private static final String QUOTES = "\"'";
|
private static final String QUOTES = "\"'";
|
||||||
|
|
||||||
private static final int MAX_SEARCH_LINES = 10;
|
private static final int MAX_SEARCH_LINES = 10;
|
||||||
|
@@ -51,6 +51,7 @@ import com.maddyhome.idea.vim.helper.moveToInlayAwareLogicalPosition
|
|||||||
import com.maddyhome.idea.vim.helper.moveToInlayAwareOffset
|
import com.maddyhome.idea.vim.helper.moveToInlayAwareOffset
|
||||||
import com.maddyhome.idea.vim.helper.subMode
|
import com.maddyhome.idea.vim.helper.subMode
|
||||||
import com.maddyhome.idea.vim.key.OperatorFunction
|
import com.maddyhome.idea.vim.key.OperatorFunction
|
||||||
|
import org.jetbrains.annotations.NonNls
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This emulation misses:
|
* This emulation misses:
|
||||||
@@ -80,8 +81,11 @@ class VimExchangeExtension : VimExtension {
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
@NonNls
|
||||||
const val EXCHANGE_CMD = "<Plug>(Exchange)"
|
const val EXCHANGE_CMD = "<Plug>(Exchange)"
|
||||||
|
@NonNls
|
||||||
const val EXCHANGE_CLEAR_CMD = "<Plug>(ExchangeClear)"
|
const val EXCHANGE_CLEAR_CMD = "<Plug>(ExchangeClear)"
|
||||||
|
@NonNls
|
||||||
const val EXCHANGE_LINE_CMD = "<Plug>(ExchangeLine)"
|
const val EXCHANGE_LINE_CMD = "<Plug>(ExchangeLine)"
|
||||||
|
|
||||||
val EXCHANGE_KEY = Key<Exchange>("exchange")
|
val EXCHANGE_KEY = Key<Exchange>("exchange")
|
||||||
|
@@ -35,16 +35,21 @@ import com.maddyhome.idea.vim.VimProjectService
|
|||||||
import com.maddyhome.idea.vim.common.TextRange
|
import com.maddyhome.idea.vim.common.TextRange
|
||||||
import com.maddyhome.idea.vim.ex.vimscript.VimScriptGlobalEnvironment
|
import com.maddyhome.idea.vim.ex.vimscript.VimScriptGlobalEnvironment
|
||||||
import com.maddyhome.idea.vim.extension.VimExtension
|
import com.maddyhome.idea.vim.extension.VimExtension
|
||||||
|
import com.maddyhome.idea.vim.helper.MessageHelper
|
||||||
import com.maddyhome.idea.vim.listener.VimInsertListener
|
import com.maddyhome.idea.vim.listener.VimInsertListener
|
||||||
import com.maddyhome.idea.vim.listener.VimYankListener
|
import com.maddyhome.idea.vim.listener.VimYankListener
|
||||||
import com.maddyhome.idea.vim.option.StrictMode
|
import com.maddyhome.idea.vim.option.StrictMode
|
||||||
|
import org.jetbrains.annotations.NonNls
|
||||||
import java.awt.Color
|
import java.awt.Color
|
||||||
import java.awt.Font
|
import java.awt.Font
|
||||||
import java.util.concurrent.Executors
|
import java.util.concurrent.Executors
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
const val DEFAULT_HIGHLIGHT_DURATION: Long = 300
|
const val DEFAULT_HIGHLIGHT_DURATION: Long = 300
|
||||||
|
|
||||||
|
@NonNls
|
||||||
private const val HIGHLIGHT_DURATION_VARIABLE_NAME = "g:highlightedyank_highlight_duration"
|
private const val HIGHLIGHT_DURATION_VARIABLE_NAME = "g:highlightedyank_highlight_duration"
|
||||||
|
@NonNls
|
||||||
private const val HIGHLIGHT_COLOR_VARIABLE_NAME = "g:highlightedyank_highlight_color"
|
private const val HIGHLIGHT_COLOR_VARIABLE_NAME = "g:highlightedyank_highlight_color"
|
||||||
private var defaultHighlightTextColor: Color? = null
|
private var defaultHighlightTextColor: Color? = null
|
||||||
|
|
||||||
@@ -197,7 +202,13 @@ class VimHighlightedYank: VimExtension, VimYankListener, VimInsertListener {
|
|||||||
extractFun(value)
|
extractFun(value)
|
||||||
}
|
}
|
||||||
catch (e: Exception){
|
catch (e: Exception){
|
||||||
VimPlugin.showMessage("highlightedyank: Invalid value of $variableName -- ${e.message}")
|
VimPlugin.showMessage(
|
||||||
|
MessageHelper.message(
|
||||||
|
"highlightedyank.invalid.value.of.0.1",
|
||||||
|
variableName,
|
||||||
|
e.message ?: ""
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
default
|
default
|
||||||
}
|
}
|
||||||
|
@@ -34,21 +34,34 @@ import com.maddyhome.idea.vim.extension.VimExtensionHandler
|
|||||||
import com.maddyhome.idea.vim.group.MotionGroup
|
import com.maddyhome.idea.vim.group.MotionGroup
|
||||||
import com.maddyhome.idea.vim.group.visual.vimSetSelection
|
import com.maddyhome.idea.vim.group.visual.vimSetSelection
|
||||||
import com.maddyhome.idea.vim.helper.EditorHelper
|
import com.maddyhome.idea.vim.helper.EditorHelper
|
||||||
|
import com.maddyhome.idea.vim.helper.MessageHelper
|
||||||
import com.maddyhome.idea.vim.helper.SearchHelper.findWordUnderCursor
|
import com.maddyhome.idea.vim.helper.SearchHelper.findWordUnderCursor
|
||||||
import com.maddyhome.idea.vim.helper.StringHelper.parseKeys
|
import com.maddyhome.idea.vim.helper.StringHelper.parseKeys
|
||||||
import com.maddyhome.idea.vim.helper.endOffsetInclusive
|
import com.maddyhome.idea.vim.helper.endOffsetInclusive
|
||||||
import com.maddyhome.idea.vim.helper.exitVisualMode
|
import com.maddyhome.idea.vim.helper.exitVisualMode
|
||||||
import com.maddyhome.idea.vim.helper.inVisualMode
|
import com.maddyhome.idea.vim.helper.inVisualMode
|
||||||
import com.maddyhome.idea.vim.option.OptionsManager
|
import com.maddyhome.idea.vim.option.OptionsManager
|
||||||
|
import org.jetbrains.annotations.NonNls
|
||||||
import java.lang.Integer.min
|
import java.lang.Integer.min
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.Comparator
|
|
||||||
|
|
||||||
|
// [VERSION UPDATE] 203+ Annotation should be replaced with @NlsSafe
|
||||||
|
@NonNls
|
||||||
private const val NEXT_WHOLE_OCCURRENCE = "<Plug>NextWholeOccurrence"
|
private const val NEXT_WHOLE_OCCURRENCE = "<Plug>NextWholeOccurrence"
|
||||||
|
// [VERSION UPDATE] 203+ Annotation should be replaced with @NlsSafe
|
||||||
|
@NonNls
|
||||||
private const val NEXT_OCCURRENCE = "<Plug>NextOccurrence"
|
private const val NEXT_OCCURRENCE = "<Plug>NextOccurrence"
|
||||||
|
// [VERSION UPDATE] 203+ Annotation should be replaced with @NlsSafe
|
||||||
|
@NonNls
|
||||||
private const val SKIP_OCCURRENCE = "<Plug>SkipOccurrence"
|
private const val SKIP_OCCURRENCE = "<Plug>SkipOccurrence"
|
||||||
|
// [VERSION UPDATE] 203+ Annotation should be replaced with @NlsSafe
|
||||||
|
@NonNls
|
||||||
private const val REMOVE_OCCURRENCE = "<Plug>RemoveOccurrence"
|
private const val REMOVE_OCCURRENCE = "<Plug>RemoveOccurrence"
|
||||||
|
// [VERSION UPDATE] 203+ Annotation should be replaced with @NlsSafe
|
||||||
|
@NonNls
|
||||||
private const val ALL_WHOLE_OCCURRENCES = "<Plug>AllWholeOccurrences"
|
private const val ALL_WHOLE_OCCURRENCES = "<Plug>AllWholeOccurrences"
|
||||||
|
// [VERSION UPDATE] 203+ Annotation should be replaced with @NlsSafe
|
||||||
|
@NonNls
|
||||||
private const val ALL_OCCURRENCES = "<Plug>AllOccurrences"
|
private const val ALL_OCCURRENCES = "<Plug>AllOccurrences"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -97,7 +110,7 @@ class VimMultipleCursorsExtension : VimExtension {
|
|||||||
if (range.startOffset > caret.offset) return
|
if (range.startOffset > caret.offset) return
|
||||||
|
|
||||||
val nextOffset = findNextOccurrence(editor, caret, range, whole)
|
val nextOffset = findNextOccurrence(editor, caret, range, whole)
|
||||||
if (nextOffset == caret.selectionStart) VimPlugin.showMessage("No more matches")
|
if (nextOffset == caret.selectionStart) VimPlugin.showMessage(MessageHelper.message("message.no.more.matches"))
|
||||||
} else {
|
} else {
|
||||||
val newPositions = arrayListOf<VisualPosition>()
|
val newPositions = arrayListOf<VisualPosition>()
|
||||||
val patterns = sortedSetOf(patternComparator)
|
val patterns = sortedSetOf(patternComparator)
|
||||||
@@ -140,7 +153,7 @@ class VimMultipleCursorsExtension : VimExtension {
|
|||||||
|
|
||||||
caretModel.allCarets.forEach {
|
caretModel.allCarets.forEach {
|
||||||
if (it.selectionStart == nextOffset) {
|
if (it.selectionStart == nextOffset) {
|
||||||
VimPlugin.showMessage("No more matches")
|
VimPlugin.showMessage(MessageHelper.message("message.no.more.matches"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -194,7 +207,7 @@ class VimMultipleCursorsExtension : VimExtension {
|
|||||||
|
|
||||||
editor.caretModel.allCarets.forEach {
|
editor.caretModel.allCarets.forEach {
|
||||||
if (it.selectionStart == nextOffset) {
|
if (it.selectionStart == nextOffset) {
|
||||||
VimPlugin.showMessage("No more matches")
|
VimPlugin.showMessage(MessageHelper.message("message.no.more.matches"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -42,6 +42,7 @@ import com.maddyhome.idea.vim.helper.exitVisualMode
|
|||||||
import com.maddyhome.idea.vim.helper.subMode
|
import com.maddyhome.idea.vim.helper.subMode
|
||||||
import com.maddyhome.idea.vim.helper.vimForEachCaret
|
import com.maddyhome.idea.vim.helper.vimForEachCaret
|
||||||
import com.maddyhome.idea.vim.key.OperatorFunction
|
import com.maddyhome.idea.vim.key.OperatorFunction
|
||||||
|
import org.jetbrains.annotations.NonNls
|
||||||
|
|
||||||
|
|
||||||
class ReplaceWithRegister : VimExtension {
|
class ReplaceWithRegister : VimExtension {
|
||||||
@@ -123,8 +124,11 @@ class ReplaceWithRegister : VimExtension {
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
@NonNls
|
||||||
private const val RWR_OPERATOR = "<Plug>ReplaceWithRegisterOperator"
|
private const val RWR_OPERATOR = "<Plug>ReplaceWithRegisterOperator"
|
||||||
|
@NonNls
|
||||||
private const val RWR_LINE = "<Plug>ReplaceWithRegisterLine"
|
private const val RWR_LINE = "<Plug>ReplaceWithRegisterLine"
|
||||||
|
@NonNls
|
||||||
private const val RWR_VISUAL = "<Plug>ReplaceWithRegisterVisual"
|
private const val RWR_VISUAL = "<Plug>ReplaceWithRegisterVisual"
|
||||||
|
|
||||||
private fun doReplace(editor: Editor, visualSelection: PutData.VisualSelection) {
|
private fun doReplace(editor: Editor, visualSelection: PutData.VisualSelection) {
|
||||||
|
@@ -69,6 +69,7 @@ import com.maddyhome.idea.vim.option.BoundListOption;
|
|||||||
import com.maddyhome.idea.vim.option.OptionsManager;
|
import com.maddyhome.idea.vim.option.OptionsManager;
|
||||||
import kotlin.Pair;
|
import kotlin.Pair;
|
||||||
import kotlin.text.StringsKt;
|
import kotlin.text.StringsKt;
|
||||||
|
import org.jetbrains.annotations.NonNls;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
@@ -93,6 +94,9 @@ public class ChangeGroup {
|
|||||||
private static final ImmutableSet<String> wordMotions =
|
private static final ImmutableSet<String> wordMotions =
|
||||||
ImmutableSet.of(VIM_MOTION_WORD_RIGHT, VIM_MOTION_BIG_WORD_RIGHT, VIM_MOTION_CAMEL_RIGHT);
|
ImmutableSet.of(VIM_MOTION_WORD_RIGHT, VIM_MOTION_BIG_WORD_RIGHT, VIM_MOTION_CAMEL_RIGHT);
|
||||||
|
|
||||||
|
@NonNls private static final String HEX_START = "0x";
|
||||||
|
@NonNls private static final String MAX_HEX_INTEGER = "ffffffffffffffff";
|
||||||
|
|
||||||
private @Nullable Command lastInsert;
|
private @Nullable Command lastInsert;
|
||||||
|
|
||||||
private List<VimInsertListener> insertListeners = ContainerUtil.createLockFreeCopyOnWriteList();
|
private List<VimInsertListener> insertListeners = ContainerUtil.createLockFreeCopyOnWriteList();
|
||||||
@@ -1940,7 +1944,7 @@ public class ChangeGroup {
|
|||||||
|
|
||||||
char ch = text.charAt(0);
|
char ch = text.charAt(0);
|
||||||
if (hex && SearchHelper.NumberType.HEX.equals(numberType)) {
|
if (hex && SearchHelper.NumberType.HEX.equals(numberType)) {
|
||||||
if (!text.toLowerCase().startsWith("0x")) throw new RuntimeException("Hex number should start with 0x: " + text);
|
if (!text.toLowerCase().startsWith(HEX_START)) throw new RuntimeException("Hex number should start with 0x: " + text);
|
||||||
for (int i = text.length() - 1; i >= 2; i--) {
|
for (int i = text.length() - 1; i >= 2; i--) {
|
||||||
int index = "abcdefABCDEF".indexOf(text.charAt(i));
|
int index = "abcdefABCDEF".indexOf(text.charAt(i));
|
||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
@@ -1952,7 +1956,7 @@ public class ChangeGroup {
|
|||||||
BigInteger num = new BigInteger(text.substring(2), 16);
|
BigInteger num = new BigInteger(text.substring(2), 16);
|
||||||
num = num.add(BigInteger.valueOf(count));
|
num = num.add(BigInteger.valueOf(count));
|
||||||
if (num.compareTo(BigInteger.ZERO) < 0) {
|
if (num.compareTo(BigInteger.ZERO) < 0) {
|
||||||
num = new BigInteger("ffffffffffffffff", 16).add(BigInteger.ONE).add(num);
|
num = new BigInteger(MAX_HEX_INTEGER, 16).add(BigInteger.ONE).add(num);
|
||||||
}
|
}
|
||||||
number = num.toString(16);
|
number = num.toString(16);
|
||||||
number = StringsKt.padStart(number, text.length() - 2, '0');
|
number = StringsKt.padStart(number, text.length() - 2, '0');
|
||||||
|
@@ -19,13 +19,14 @@
|
|||||||
package com.maddyhome.idea.vim.group
|
package com.maddyhome.idea.vim.group
|
||||||
|
|
||||||
import com.maddyhome.idea.vim.common.Alias
|
import com.maddyhome.idea.vim.common.Alias
|
||||||
|
import org.jetbrains.annotations.NonNls
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Elliot Courant
|
* @author Elliot Courant
|
||||||
*/
|
*/
|
||||||
class CommandGroup {
|
class CommandGroup {
|
||||||
companion object {
|
companion object {
|
||||||
val BLACKLISTED_ALIASES = arrayOf("X", "Next", "Print")
|
@NonNls val BLACKLISTED_ALIASES = arrayOf("X", "Next", "Print")
|
||||||
private const val overridePrefix = "!"
|
private const val overridePrefix = "!"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -35,6 +35,7 @@ import com.maddyhome.idea.vim.option.OptionChangeListener;
|
|||||||
import com.maddyhome.idea.vim.option.OptionsManager;
|
import com.maddyhome.idea.vim.option.OptionsManager;
|
||||||
import org.jdom.Element;
|
import org.jdom.Element;
|
||||||
import org.jetbrains.annotations.Contract;
|
import org.jetbrains.annotations.Contract;
|
||||||
|
import org.jetbrains.annotations.NonNls;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
@@ -44,7 +45,7 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
@State(name = "VimEditorSettings", storages = {@Storage(value = "$APP_CONFIG$/vim_settings.xml")})
|
@State(name = "VimEditorSettings", storages = {@Storage(value = "$APP_CONFIG$/vim_settings.xml")})
|
||||||
public class EditorGroup implements PersistentStateComponent<Element> {
|
public class EditorGroup implements PersistentStateComponent<Element> {
|
||||||
private static final boolean REFRAIN_FROM_SCROLLING_VIM_VALUE = true;
|
private static final boolean REFRAIN_FROM_SCROLLING_VIM_VALUE = true;
|
||||||
public static final String EDITOR_STORE_ELEMENT = "editor";
|
public static final @NonNls String EDITOR_STORE_ELEMENT = "editor";
|
||||||
|
|
||||||
private boolean isBlockCursor = false;
|
private boolean isBlockCursor = false;
|
||||||
private boolean isRefrainFromScrolling = false;
|
private boolean isRefrainFromScrolling = false;
|
||||||
|
@@ -44,6 +44,7 @@ import com.maddyhome.idea.vim.command.CommandState;
|
|||||||
import com.maddyhome.idea.vim.common.TextRange;
|
import com.maddyhome.idea.vim.common.TextRange;
|
||||||
import com.maddyhome.idea.vim.helper.EditorHelper;
|
import com.maddyhome.idea.vim.helper.EditorHelper;
|
||||||
import com.maddyhome.idea.vim.helper.EditorHelperRt;
|
import com.maddyhome.idea.vim.helper.EditorHelperRt;
|
||||||
|
import com.maddyhome.idea.vim.helper.MessageHelper;
|
||||||
import com.maddyhome.idea.vim.helper.SearchHelper;
|
import com.maddyhome.idea.vim.helper.SearchHelper;
|
||||||
import com.maddyhome.idea.vim.option.IdeaWriteData;
|
import com.maddyhome.idea.vim.option.IdeaWriteData;
|
||||||
import com.maddyhome.idea.vim.option.OptionsManager;
|
import com.maddyhome.idea.vim.option.OptionsManager;
|
||||||
@@ -85,7 +86,7 @@ public class FileGroup {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
VimPlugin.showMessage("Unable to find " + filename);
|
VimPlugin.showMessage(MessageHelper.message("unable.to.find.0", filename));
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@@ -27,6 +27,7 @@ import com.maddyhome.idea.vim.helper.StringHelper;
|
|||||||
import com.maddyhome.idea.vim.option.NumberOption;
|
import com.maddyhome.idea.vim.option.NumberOption;
|
||||||
import com.maddyhome.idea.vim.option.OptionsManager;
|
import com.maddyhome.idea.vim.option.OptionsManager;
|
||||||
import org.jdom.Element;
|
import org.jdom.Element;
|
||||||
|
import org.jetbrains.annotations.NonNls;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
@@ -39,10 +40,10 @@ import java.util.Map;
|
|||||||
@Storage(value = "$APP_CONFIG$/vim_settings_local.xml", roamingType = RoamingType.DISABLED)
|
@Storage(value = "$APP_CONFIG$/vim_settings_local.xml", roamingType = RoamingType.DISABLED)
|
||||||
})
|
})
|
||||||
public class HistoryGroup implements PersistentStateComponent<Element> {
|
public class HistoryGroup implements PersistentStateComponent<Element> {
|
||||||
public static final String SEARCH = "search";
|
public static final @NonNls String SEARCH = "search";
|
||||||
public static final String COMMAND = "cmd";
|
public static final @NonNls String COMMAND = "cmd";
|
||||||
public static final String EXPRESSION = "expr";
|
public static final @NonNls String EXPRESSION = "expr";
|
||||||
public static final String INPUT = "input";
|
public static final @NonNls String INPUT = "input";
|
||||||
|
|
||||||
public void addEntry(String key, @NotNull String text) {
|
public void addEntry(String key, @NotNull String text) {
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
|
@@ -47,6 +47,7 @@ import com.maddyhome.idea.vim.key.*;
|
|||||||
import kotlin.Pair;
|
import kotlin.Pair;
|
||||||
import kotlin.text.StringsKt;
|
import kotlin.text.StringsKt;
|
||||||
import org.jdom.Element;
|
import org.jdom.Element;
|
||||||
|
import org.jetbrains.annotations.NonNls;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
@@ -65,9 +66,9 @@ import static java.util.stream.Collectors.toList;
|
|||||||
*/
|
*/
|
||||||
@State(name = "VimKeySettings", storages = {@Storage(value = "$APP_CONFIG$/vim_settings.xml")})
|
@State(name = "VimKeySettings", storages = {@Storage(value = "$APP_CONFIG$/vim_settings.xml")})
|
||||||
public class KeyGroup implements PersistentStateComponent<Element> {
|
public class KeyGroup implements PersistentStateComponent<Element> {
|
||||||
public static final String SHORTCUT_CONFLICTS_ELEMENT = "shortcut-conflicts";
|
public static final @NonNls String SHORTCUT_CONFLICTS_ELEMENT = "shortcut-conflicts";
|
||||||
private static final String SHORTCUT_CONFLICT_ELEMENT = "shortcut-conflict";
|
private static final @NonNls String SHORTCUT_CONFLICT_ELEMENT = "shortcut-conflict";
|
||||||
private static final String OWNER_ATTRIBUTE = "owner";
|
private static final @NonNls String OWNER_ATTRIBUTE = "owner";
|
||||||
private static final String TEXT_ELEMENT = "text";
|
private static final String TEXT_ELEMENT = "text";
|
||||||
|
|
||||||
private static final Logger logger = Logger.getInstance(KeyGroup.class);
|
private static final Logger logger = Logger.getInstance(KeyGroup.class);
|
||||||
@@ -117,6 +118,14 @@ public class KeyGroup implements PersistentStateComponent<Element> {
|
|||||||
unregisterKeyMapping(owner);
|
unregisterKeyMapping(owner);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void removeKeyMapping(@NotNull Set<MappingMode> modes, @NotNull List<KeyStroke> keys) {
|
||||||
|
modes.stream().map(this::getKeyMapping).forEach(o -> o.delete(keys));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeKeyMapping(@NotNull Set<MappingMode> modes) {
|
||||||
|
modes.stream().map(this::getKeyMapping).forEach(KeyMapping::delete);
|
||||||
|
}
|
||||||
|
|
||||||
public void putKeyMapping(@NotNull Set<MappingMode> modes,
|
public void putKeyMapping(@NotNull Set<MappingMode> modes,
|
||||||
@NotNull List<KeyStroke> fromKeys,
|
@NotNull List<KeyStroke> fromKeys,
|
||||||
@NotNull MappingOwner owner,
|
@NotNull MappingOwner owner,
|
||||||
@@ -467,7 +476,7 @@ public class KeyGroup implements PersistentStateComponent<Element> {
|
|||||||
return rows;
|
return rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static @NotNull String getModesStringCode(@NotNull Set<MappingMode> modes) {
|
private static @NotNull @NonNls String getModesStringCode(@NotNull Set<MappingMode> modes) {
|
||||||
if (modes.equals(MappingMode.NVO)) {
|
if (modes.equals(MappingMode.NVO)) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
@@ -525,7 +534,7 @@ public class KeyGroup implements PersistentStateComponent<Element> {
|
|||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public Element getState() {
|
public Element getState() {
|
||||||
Element element = new Element("key");
|
@NonNls Element element = new Element("key");
|
||||||
saveData(element);
|
saveData(element);
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
@@ -27,6 +27,7 @@ import com.intellij.openapi.project.Project;
|
|||||||
import com.maddyhome.idea.vim.KeyHandler;
|
import com.maddyhome.idea.vim.KeyHandler;
|
||||||
import com.maddyhome.idea.vim.VimPlugin;
|
import com.maddyhome.idea.vim.VimPlugin;
|
||||||
import com.maddyhome.idea.vim.common.Register;
|
import com.maddyhome.idea.vim.common.Register;
|
||||||
|
import com.maddyhome.idea.vim.helper.MessageHelper;
|
||||||
import com.maddyhome.idea.vim.helper.StringHelper;
|
import com.maddyhome.idea.vim.helper.StringHelper;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
@@ -130,7 +131,8 @@ public class MacroGroup {
|
|||||||
};
|
};
|
||||||
|
|
||||||
ApplicationManager.getApplication().invokeLater(
|
ApplicationManager.getApplication().invokeLater(
|
||||||
() -> CommandProcessor.getInstance().executeCommand(project, run, "Vim Macro Playback", keys.get(pos)));
|
() -> CommandProcessor.getInstance()
|
||||||
|
.executeCommand(project, run, MessageHelper.message("command.name.vim.macro.playback"), keys.get(pos)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void postKey(@NotNull KeyStroke stroke, @NotNull Editor editor) {
|
public void postKey(@NotNull KeyStroke stroke, @NotNull Editor editor) {
|
||||||
|
@@ -48,6 +48,7 @@ import com.maddyhome.idea.vim.helper.SearchHelper;
|
|||||||
import com.maddyhome.idea.vim.option.OptionsManager;
|
import com.maddyhome.idea.vim.option.OptionsManager;
|
||||||
import org.jdom.Element;
|
import org.jdom.Element;
|
||||||
import org.jetbrains.annotations.Contract;
|
import org.jetbrains.annotations.Contract;
|
||||||
|
import org.jetbrains.annotations.NonNls;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
@@ -811,7 +812,7 @@ public class MarkGroup implements PersistentStateComponent<Element> {
|
|||||||
private static final int SAVE_JUMP_COUNT = 100;
|
private static final int SAVE_JUMP_COUNT = 100;
|
||||||
|
|
||||||
public static final String WR_GLOBAL_MARKS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
public static final String WR_GLOBAL_MARKS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||||
public static final String WR_REGULAR_FILE_MARKS = "abcdefghijklmnopqrstuvwxyz";
|
public static final @NonNls String WR_REGULAR_FILE_MARKS = "abcdefghijklmnopqrstuvwxyz";
|
||||||
/** Marks: abcdefghijklmnopqrstuvwxyz' */
|
/** Marks: abcdefghijklmnopqrstuvwxyz' */
|
||||||
private static final String WR_FILE_MARKS = WR_REGULAR_FILE_MARKS + "'";
|
private static final String WR_FILE_MARKS = WR_REGULAR_FILE_MARKS + "'";
|
||||||
|
|
||||||
|
@@ -41,10 +41,11 @@ import com.maddyhome.idea.vim.group.visual.VisualGroupKt;
|
|||||||
import com.maddyhome.idea.vim.handler.MotionActionHandler;
|
import com.maddyhome.idea.vim.handler.MotionActionHandler;
|
||||||
import com.maddyhome.idea.vim.handler.TextObjectActionHandler;
|
import com.maddyhome.idea.vim.handler.TextObjectActionHandler;
|
||||||
import com.maddyhome.idea.vim.helper.*;
|
import com.maddyhome.idea.vim.helper.*;
|
||||||
|
import com.maddyhome.idea.vim.listener.IdeaSpecifics;
|
||||||
import com.maddyhome.idea.vim.option.NumberOption;
|
import com.maddyhome.idea.vim.option.NumberOption;
|
||||||
import com.maddyhome.idea.vim.option.OptionChangeListener;
|
import com.maddyhome.idea.vim.option.OptionChangeListener;
|
||||||
import com.maddyhome.idea.vim.option.OptionsManager;
|
import com.maddyhome.idea.vim.option.OptionsManager;
|
||||||
import com.maddyhome.idea.vim.ui.ExEntryPanel;
|
import com.maddyhome.idea.vim.ui.ex.ExEntryPanel;
|
||||||
import kotlin.Pair;
|
import kotlin.Pair;
|
||||||
import kotlin.ranges.IntProgression;
|
import kotlin.ranges.IntProgression;
|
||||||
import org.jetbrains.annotations.Contract;
|
import org.jetbrains.annotations.Contract;
|
||||||
@@ -318,6 +319,8 @@ public class MotionGroup {
|
|||||||
else {
|
else {
|
||||||
ModeHelper.exitVisualMode(editor);
|
ModeHelper.exitVisualMode(editor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IdeaSpecifics.AppCodeTemplates.onMovement(editor, caret, oldOffset < offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
private @Nullable Editor selectEditor(@NotNull Editor editor, @NotNull Mark mark) {
|
private @Nullable Editor selectEditor(@NotNull Editor editor, @NotNull Mark mark) {
|
||||||
|
@@ -31,7 +31,7 @@ import com.maddyhome.idea.vim.common.TextRange;
|
|||||||
import com.maddyhome.idea.vim.ex.CommandParser;
|
import com.maddyhome.idea.vim.ex.CommandParser;
|
||||||
import com.maddyhome.idea.vim.ex.ExException;
|
import com.maddyhome.idea.vim.ex.ExException;
|
||||||
import com.maddyhome.idea.vim.helper.UiHelper;
|
import com.maddyhome.idea.vim.helper.UiHelper;
|
||||||
import com.maddyhome.idea.vim.ui.ExEntryPanel;
|
import com.maddyhome.idea.vim.ui.ex.ExEntryPanel;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
@@ -62,6 +62,7 @@ import com.maddyhome.idea.vim.option.OptionsManager;
|
|||||||
import com.maddyhome.idea.vim.ui.ClipboardHandler;
|
import com.maddyhome.idea.vim.ui.ClipboardHandler;
|
||||||
import kotlin.Pair;
|
import kotlin.Pair;
|
||||||
import org.jdom.Element;
|
import org.jdom.Element;
|
||||||
|
import org.jetbrains.annotations.NonNls;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
@@ -80,9 +81,9 @@ import java.util.stream.Collectors;
|
|||||||
@Storage(value = "$APP_CONFIG$/vim_settings_local.xml", roamingType = RoamingType.DISABLED)
|
@Storage(value = "$APP_CONFIG$/vim_settings_local.xml", roamingType = RoamingType.DISABLED)
|
||||||
})
|
})
|
||||||
public class RegisterGroup implements PersistentStateComponent<Element> {
|
public class RegisterGroup implements PersistentStateComponent<Element> {
|
||||||
private static final String WRITABLE_REGISTERS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-*+_/\"";
|
private static final @NonNls String WRITABLE_REGISTERS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-*+_/\"";
|
||||||
private static final String READONLY_REGISTERS = ":.%#=/";
|
private static final String READONLY_REGISTERS = ":.%#=/";
|
||||||
private static final String RECORDABLE_REGISTER = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
private static final @NonNls String RECORDABLE_REGISTER = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||||
private static final String PLAYBACK_REGISTER = RECORDABLE_REGISTER + "\".*+";
|
private static final String PLAYBACK_REGISTER = RECORDABLE_REGISTER + "\".*+";
|
||||||
private static final String VALID_REGISTERS = WRITABLE_REGISTERS + READONLY_REGISTERS;
|
private static final String VALID_REGISTERS = WRITABLE_REGISTERS + READONLY_REGISTERS;
|
||||||
private static final List<Character> CLIPBOARD_REGISTERS = ImmutableList.of('*', '+');
|
private static final List<Character> CLIPBOARD_REGISTERS = ImmutableList.of('*', '+');
|
||||||
@@ -179,6 +180,11 @@ public class RegisterGroup implements PersistentStateComponent<Element> {
|
|||||||
|
|
||||||
int start = range.getStartOffset();
|
int start = range.getStartOffset();
|
||||||
int end = range.getEndOffset();
|
int end = range.getEndOffset();
|
||||||
|
|
||||||
|
if (isDelete && start == end) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Normalize the start and end
|
// Normalize the start and end
|
||||||
if (start > end) {
|
if (start > end) {
|
||||||
int t = start;
|
int t = start;
|
||||||
|
@@ -49,11 +49,12 @@ import com.maddyhome.idea.vim.option.OptionsManager;
|
|||||||
import com.maddyhome.idea.vim.regexp.CharPointer;
|
import com.maddyhome.idea.vim.regexp.CharPointer;
|
||||||
import com.maddyhome.idea.vim.regexp.CharacterClasses;
|
import com.maddyhome.idea.vim.regexp.CharacterClasses;
|
||||||
import com.maddyhome.idea.vim.regexp.RegExp;
|
import com.maddyhome.idea.vim.regexp.RegExp;
|
||||||
import com.maddyhome.idea.vim.ui.ExEntryPanel;
|
import com.maddyhome.idea.vim.ui.ex.ExEntryPanel;
|
||||||
import com.maddyhome.idea.vim.ui.ModalEntry;
|
import com.maddyhome.idea.vim.ui.ModalEntry;
|
||||||
import kotlin.jvm.functions.Function1;
|
import kotlin.jvm.functions.Function1;
|
||||||
import org.jdom.Element;
|
import org.jdom.Element;
|
||||||
import org.jetbrains.annotations.Contract;
|
import org.jetbrains.annotations.Contract;
|
||||||
|
import org.jetbrains.annotations.NonNls;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
@@ -209,7 +210,7 @@ public class SearchGroup implements PersistentStateComponent<Element> {
|
|||||||
else {
|
else {
|
||||||
// XXX: The Ex entry panel is used only for UI here, its logic might be inappropriate for this method
|
// XXX: The Ex entry panel is used only for UI here, its logic might be inappropriate for this method
|
||||||
final ExEntryPanel exEntryPanel = ExEntryPanel.getInstanceWithoutShortcuts();
|
final ExEntryPanel exEntryPanel = ExEntryPanel.getInstanceWithoutShortcuts();
|
||||||
exEntryPanel.activate(editor, new EditorDataContext(editor, null), "Replace with " + match + " (y/n/a/q/l)?", "", 1);
|
exEntryPanel.activate(editor, new EditorDataContext(editor, null), MessageHelper.message("replace.with.0", match), "", 1);
|
||||||
MotionGroup.moveCaret(editor, caret, startoff);
|
MotionGroup.moveCaret(editor, caret, startoff);
|
||||||
ModalEntry.INSTANCE.activate(keyStrokeProcessor);
|
ModalEntry.INSTANCE.activate(keyStrokeProcessor);
|
||||||
exEntryPanel.deactivate(true, false);
|
exEntryPanel.deactivate(true, false);
|
||||||
@@ -983,7 +984,7 @@ public class SearchGroup implements PersistentStateComponent<Element> {
|
|||||||
|
|
||||||
@RWLockLabel.SelfSynchronized
|
@RWLockLabel.SelfSynchronized
|
||||||
public boolean searchAndReplace(@NotNull Editor editor, @NotNull Caret caret, @NotNull LineRange range,
|
public boolean searchAndReplace(@NotNull Editor editor, @NotNull Caret caret, @NotNull LineRange range,
|
||||||
@NotNull String excmd, String exarg) {
|
@NotNull @NonNls String excmd, @NonNls String exarg) {
|
||||||
// Explicitly exit visual mode here, so that visual mode marks don't change when we move the cursor to a match.
|
// Explicitly exit visual mode here, so that visual mode marks don't change when we move the cursor to a match.
|
||||||
if (CommandStateHelper.inVisualMode(editor)) {
|
if (CommandStateHelper.inVisualMode(editor)) {
|
||||||
ModeHelper.exitVisualMode(editor);
|
ModeHelper.exitVisualMode(editor);
|
||||||
|
@@ -26,6 +26,7 @@ import com.intellij.openapi.fileEditor.impl.EditorWithProviderComposite;
|
|||||||
import com.intellij.openapi.project.Project;
|
import com.intellij.openapi.project.Project;
|
||||||
import com.intellij.openapi.vfs.VirtualFile;
|
import com.intellij.openapi.vfs.VirtualFile;
|
||||||
import com.maddyhome.idea.vim.VimPlugin;
|
import com.maddyhome.idea.vim.VimPlugin;
|
||||||
|
import com.maddyhome.idea.vim.helper.MessageHelper;
|
||||||
import com.maddyhome.idea.vim.helper.RWLockLabel;
|
import com.maddyhome.idea.vim.helper.RWLockLabel;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
@@ -158,7 +159,7 @@ public class WindowGroup {
|
|||||||
if (filename.length() > 0) {
|
if (filename.length() > 0) {
|
||||||
virtualFile = VimPlugin.getFile().findFile(filename, project);
|
virtualFile = VimPlugin.getFile().findFile(filename, project);
|
||||||
if (virtualFile == null) {
|
if (virtualFile == null) {
|
||||||
VimPlugin.showMessage("Could not find file: " + filename);
|
VimPlugin.showMessage(MessageHelper.message("could.not.find.file.0", filename));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -46,9 +46,9 @@ import com.maddyhome.idea.vim.common.TextRange
|
|||||||
import com.maddyhome.idea.vim.group.MarkGroup
|
import com.maddyhome.idea.vim.group.MarkGroup
|
||||||
import com.maddyhome.idea.vim.group.MotionGroup
|
import com.maddyhome.idea.vim.group.MotionGroup
|
||||||
import com.maddyhome.idea.vim.group.visual.VimSelection
|
import com.maddyhome.idea.vim.group.visual.VimSelection
|
||||||
import com.maddyhome.idea.vim.helper.moveToInlayAwareOffset
|
|
||||||
import com.maddyhome.idea.vim.helper.EditorHelper
|
import com.maddyhome.idea.vim.helper.EditorHelper
|
||||||
import com.maddyhome.idea.vim.helper.fileSize
|
import com.maddyhome.idea.vim.helper.fileSize
|
||||||
|
import com.maddyhome.idea.vim.helper.moveToInlayAwareOffset
|
||||||
import com.maddyhome.idea.vim.option.ClipboardOptionsData
|
import com.maddyhome.idea.vim.option.ClipboardOptionsData
|
||||||
import com.maddyhome.idea.vim.option.OptionsManager
|
import com.maddyhome.idea.vim.option.OptionsManager
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
@@ -32,7 +32,6 @@ import com.maddyhome.idea.vim.helper.EditorHelper
|
|||||||
import com.maddyhome.idea.vim.helper.fileSize
|
import com.maddyhome.idea.vim.helper.fileSize
|
||||||
import com.maddyhome.idea.vim.listener.VimYankListener
|
import com.maddyhome.idea.vim.listener.VimYankListener
|
||||||
import org.jetbrains.annotations.Contract
|
import org.jetbrains.annotations.Contract
|
||||||
import java.util.*
|
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
|
|
||||||
class YankGroup {
|
class YankGroup {
|
||||||
|
@@ -27,6 +27,7 @@ import com.maddyhome.idea.vim.command.SelectionType.CHARACTER_WISE
|
|||||||
import com.maddyhome.idea.vim.command.SelectionType.LINE_WISE
|
import com.maddyhome.idea.vim.command.SelectionType.LINE_WISE
|
||||||
import com.maddyhome.idea.vim.common.TextRange
|
import com.maddyhome.idea.vim.common.TextRange
|
||||||
import com.maddyhome.idea.vim.helper.EditorHelper
|
import com.maddyhome.idea.vim.helper.EditorHelper
|
||||||
|
import org.jetbrains.annotations.NonNls
|
||||||
import kotlin.math.max
|
import kotlin.math.max
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
|
|
||||||
@@ -68,6 +69,7 @@ sealed class VimSelection {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNls
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
val startLogPosition = editor.offsetToLogicalPosition(vimStart)
|
val startLogPosition = editor.offsetToLogicalPosition(vimStart)
|
||||||
val endLogPosition = editor.offsetToLogicalPosition(vimEnd)
|
val endLogPosition = editor.offsetToLogicalPosition(vimEnd)
|
||||||
|
@@ -32,6 +32,7 @@ import com.maddyhome.idea.vim.helper.StringHelper
|
|||||||
import com.maddyhome.idea.vim.helper.commandState
|
import com.maddyhome.idea.vim.helper.commandState
|
||||||
import com.maddyhome.idea.vim.helper.getTopLevelEditor
|
import com.maddyhome.idea.vim.helper.getTopLevelEditor
|
||||||
import com.maddyhome.idea.vim.helper.noneOfEnum
|
import com.maddyhome.idea.vim.helper.noneOfEnum
|
||||||
|
import org.jetbrains.annotations.NonNls
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import javax.swing.KeyStroke
|
import javax.swing.KeyStroke
|
||||||
|
|
||||||
@@ -103,14 +104,17 @@ abstract class EditorActionHandlerBase(private val myRunForEachCaret: Boolean) {
|
|||||||
fun parseKeysSet(keyStrings: List<String>) = keyStrings.map { StringHelper.parseKeys(it) }.toSet()
|
fun parseKeysSet(keyStrings: List<String>) = keyStrings.map { StringHelper.parseKeys(it) }.toSet()
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun parseKeysSet(vararg keyStrings: String): Set<List<KeyStroke>> = List(keyStrings.size) {
|
fun parseKeysSet(@NonNls vararg keyStrings: String): Set<List<KeyStroke>> = List(keyStrings.size) {
|
||||||
StringHelper.parseKeys(keyStrings[it])
|
StringHelper.parseKeys(keyStrings[it])
|
||||||
}.toSet()
|
}.toSet()
|
||||||
|
|
||||||
|
@NonNls private const val VimActionPrefix = "Vim"
|
||||||
|
|
||||||
|
@NonNls
|
||||||
fun getActionId(classFullName: String): String {
|
fun getActionId(classFullName: String): String {
|
||||||
return classFullName
|
return classFullName
|
||||||
.takeLastWhile { it != '.' }
|
.takeLastWhile { it != '.' }
|
||||||
.let { if (it.startsWith("Vim", true)) it else "Vim$it" }
|
.let { if (it.startsWith(VimActionPrefix, true)) it else "$VimActionPrefix$it" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -50,6 +50,8 @@ object CharacterHelper {
|
|||||||
CharacterType.KATAKANA
|
CharacterType.KATAKANA
|
||||||
} else if (isHalfWidthKatakanaLetter(ch)) {
|
} else if (isHalfWidthKatakanaLetter(ch)) {
|
||||||
CharacterType.HALF_WIDTH_KATAKANA
|
CharacterType.HALF_WIDTH_KATAKANA
|
||||||
|
} else if (block == UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS) {
|
||||||
|
CharacterType.CJK_UNIFIED_IDEOGRAPHS
|
||||||
} else if (punctuationAsLetters || iskeyword.isKeyword(ch)) {
|
} else if (punctuationAsLetters || iskeyword.isKeyword(ch)) {
|
||||||
CharacterType.KEYWORD
|
CharacterType.KEYWORD
|
||||||
} else {
|
} else {
|
||||||
@@ -89,6 +91,6 @@ object CharacterHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum class CharacterType {
|
enum class CharacterType {
|
||||||
KEYWORD, HIRAGANA, KATAKANA, HALF_WIDTH_KATAKANA, PUNCTUATION, WHITESPACE
|
KEYWORD, HIRAGANA, KATAKANA, HALF_WIDTH_KATAKANA, CJK_UNIFIED_IDEOGRAPHS, PUNCTUATION, WHITESPACE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -24,6 +24,7 @@ import com.intellij.openapi.editor.Editor
|
|||||||
import com.maddyhome.idea.vim.command.CommandState
|
import com.maddyhome.idea.vim.command.CommandState
|
||||||
import com.maddyhome.idea.vim.option.OptionsManager
|
import com.maddyhome.idea.vim.option.OptionsManager
|
||||||
|
|
||||||
|
@get:VimNlsSafe
|
||||||
val usesVirtualSpace
|
val usesVirtualSpace
|
||||||
get() = OptionsManager.virtualedit.value == "onemore"
|
get() = OptionsManager.virtualedit.value == "onemore"
|
||||||
|
|
||||||
|
@@ -27,7 +27,7 @@ import com.intellij.openapi.vfs.VirtualFile;
|
|||||||
import com.intellij.testFramework.LightVirtualFile;
|
import com.intellij.testFramework.LightVirtualFile;
|
||||||
import com.maddyhome.idea.vim.common.IndentConfig;
|
import com.maddyhome.idea.vim.common.IndentConfig;
|
||||||
import com.maddyhome.idea.vim.common.TextRange;
|
import com.maddyhome.idea.vim.common.TextRange;
|
||||||
import com.maddyhome.idea.vim.ui.ExEntryPanel;
|
import com.maddyhome.idea.vim.ui.ex.ExEntryPanel;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
@@ -19,6 +19,7 @@
|
|||||||
package com.maddyhome.idea.vim.helper;
|
package com.maddyhome.idea.vim.helper;
|
||||||
|
|
||||||
import com.google.common.io.CharStreams;
|
import com.google.common.io.CharStreams;
|
||||||
|
import org.jetbrains.annotations.NonNls;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
@@ -30,15 +31,19 @@ import java.io.InputStreamReader;
|
|||||||
* @author vlan
|
* @author vlan
|
||||||
*/
|
*/
|
||||||
public class MacKeyRepeat {
|
public class MacKeyRepeat {
|
||||||
public static final String FMT = "defaults %s -globalDomain ApplePressAndHoldEnabled";
|
@VimNlsSafe public static final String FMT = "defaults %s -globalDomain ApplePressAndHoldEnabled";
|
||||||
private static final @NotNull MacKeyRepeat INSTANCE = new MacKeyRepeat();
|
@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() {
|
public static @NotNull MacKeyRepeat getInstance() {
|
||||||
return INSTANCE;
|
return INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public @Nullable Boolean isEnabled() {
|
public @Nullable Boolean isEnabled() {
|
||||||
final String command = String.format(FMT, "read");
|
final String command = String.format(FMT, read);
|
||||||
try {
|
try {
|
||||||
final Process process = Runtime.getRuntime().exec(command);
|
final Process process = Runtime.getRuntime().exec(command);
|
||||||
final String data = read(process.getInputStream()).trim();
|
final String data = read(process.getInputStream()).trim();
|
||||||
@@ -56,17 +61,17 @@ public class MacKeyRepeat {
|
|||||||
public void setEnabled(@Nullable Boolean value) {
|
public void setEnabled(@Nullable Boolean value) {
|
||||||
final String command;
|
final String command;
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
command = String.format(FMT, "delete");
|
command = String.format(FMT, delete);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
final String arg = value ? "0" : "1";
|
final String arg = value ? "0" : "1";
|
||||||
command = String.format(FMT, "write") + " " + arg;
|
command = String.format(FMT, write) + " " + arg;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
final Runtime runtime = Runtime.getRuntime();
|
final Runtime runtime = Runtime.getRuntime();
|
||||||
final Process defaults = runtime.exec(command);
|
final Process defaults = runtime.exec(command);
|
||||||
defaults.waitFor();
|
defaults.waitFor();
|
||||||
final Process restartSystemUI = runtime.exec("launchctl stop com.apple.SystemUIServer.agent");
|
final Process restartSystemUI = runtime.exec(EXEC_COMMAND);
|
||||||
restartSystemUI.waitFor();
|
restartSystemUI.waitFor();
|
||||||
}
|
}
|
||||||
catch (IOException | InterruptedException ignored) {
|
catch (IOException | InterruptedException ignored) {
|
||||||
|
@@ -1,61 +0,0 @@
|
|||||||
/*
|
|
||||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
|
||||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.maddyhome.idea.vim.helper;
|
|
||||||
|
|
||||||
import com.intellij.CommonBundle;
|
|
||||||
import com.intellij.reference.SoftReference;
|
|
||||||
import org.jetbrains.annotations.NonNls;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import org.jetbrains.annotations.PropertyKey;
|
|
||||||
|
|
||||||
import java.lang.ref.Reference;
|
|
||||||
import java.util.ResourceBundle;
|
|
||||||
|
|
||||||
|
|
||||||
public class MessageHelper {
|
|
||||||
private static @Nullable Reference<ResourceBundle> ourBundle;
|
|
||||||
|
|
||||||
@NonNls
|
|
||||||
private static final String BUNDLE = "messages";
|
|
||||||
|
|
||||||
private MessageHelper() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public static @NotNull String message(@NotNull @PropertyKey(resourceBundle = BUNDLE)String key, Object... params) {
|
|
||||||
return CommonBundle.message(getBundle(), key, params);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This method added for jruby access
|
|
||||||
*/
|
|
||||||
public static @NotNull String message(@NotNull @PropertyKey(resourceBundle = BUNDLE)String key) {
|
|
||||||
return CommonBundle.message(getBundle(), key);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static @NotNull ResourceBundle getBundle() {
|
|
||||||
ResourceBundle bundle = null;
|
|
||||||
if (ourBundle != null) bundle = ourBundle.get();
|
|
||||||
if (bundle == null) {
|
|
||||||
bundle = ResourceBundle.getBundle(BUNDLE);
|
|
||||||
ourBundle = new SoftReference<>(bundle);
|
|
||||||
}
|
|
||||||
return bundle;
|
|
||||||
}
|
|
||||||
}
|
|
35
src/com/maddyhome/idea/vim/helper/MessageHelper.kt
Normal file
35
src/com/maddyhome/idea/vim/helper/MessageHelper.kt
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||||
|
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.maddyhome.idea.vim.helper
|
||||||
|
|
||||||
|
import com.intellij.AbstractBundle
|
||||||
|
import org.jetbrains.annotations.NonNls
|
||||||
|
import org.jetbrains.annotations.PropertyKey
|
||||||
|
|
||||||
|
@NonNls
|
||||||
|
private const val BUNDLE = "messages.IdeaVimBundle"
|
||||||
|
|
||||||
|
object MessageHelper : AbstractBundle(BUNDLE) {
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun message(@PropertyKey(resourceBundle = BUNDLE) key: String, vararg params: Any) = getMessage(key, *params)
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun message(@PropertyKey(resourceBundle = BUNDLE) key: String) = getMessage(key)
|
||||||
|
}
|
@@ -29,6 +29,7 @@ import com.intellij.psi.PsiComment;
|
|||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
import com.intellij.psi.PsiFile;
|
import com.intellij.psi.PsiFile;
|
||||||
import com.intellij.psi.util.PsiTreeUtil;
|
import com.intellij.psi.util.PsiTreeUtil;
|
||||||
|
import com.maddyhome.idea.vim.command.CommandState;
|
||||||
import com.maddyhome.idea.vim.common.TextRange;
|
import com.maddyhome.idea.vim.common.TextRange;
|
||||||
import com.maddyhome.idea.vim.option.ListOption;
|
import com.maddyhome.idea.vim.option.ListOption;
|
||||||
import com.maddyhome.idea.vim.option.OptionsManager;
|
import com.maddyhome.idea.vim.option.OptionsManager;
|
||||||
@@ -541,16 +542,19 @@ public class SearchHelper {
|
|||||||
selectionEndWithoutNewline++;
|
selectionEndWithoutNewline++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (closingTagTextRange.getStartOffset() == selectionEndWithoutNewline &&
|
final CommandState.Mode mode = CommandState.getInstance(editor).getMode();
|
||||||
|
if (mode == CommandState.Mode.VISUAL) {
|
||||||
|
if (closingTagTextRange.getStartOffset() == selectionEndWithoutNewline &&
|
||||||
openingTag.getEndOffset() == selectionStart) {
|
openingTag.getEndOffset() == selectionStart) {
|
||||||
// Special case: if the inner tag is already selected we should like isOuter is active
|
// Special case: if the inner tag is already selected we should like isOuter is active
|
||||||
// Note that we need to ignore newlines, because their selection is lost between multiple "it" invocations
|
// Note that we need to ignore newlines, because their selection is lost between multiple "it" invocations
|
||||||
isOuter = true;
|
isOuter = true;
|
||||||
}
|
}
|
||||||
else if (openingTag.getEndOffset() == closingTagTextRange.getStartOffset() &&
|
else if (openingTag.getEndOffset() == closingTagTextRange.getStartOffset() &&
|
||||||
selectionStart == openingTag.getEndOffset()) {
|
selectionStart == openingTag.getEndOffset()) {
|
||||||
// Special case: for an empty tag pair (e.g. <a></a>) the whole tag is selected if the caret is in the middle.
|
// Special case: for an empty tag pair (e.g. <a></a>) the whole tag is selected if the caret is in the middle.
|
||||||
isOuter = true;
|
isOuter = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isOuter) {
|
if (isOuter) {
|
||||||
|
@@ -22,6 +22,7 @@ import com.intellij.openapi.util.text.StringUtil;
|
|||||||
import com.maddyhome.idea.vim.ex.vimscript.VimScriptGlobalEnvironment;
|
import com.maddyhome.idea.vim.ex.vimscript.VimScriptGlobalEnvironment;
|
||||||
import org.apache.commons.codec.binary.Base64;
|
import org.apache.commons.codec.binary.Base64;
|
||||||
import org.jdom.Element;
|
import org.jdom.Element;
|
||||||
|
import org.jetbrains.annotations.NonNls;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
@@ -59,7 +60,7 @@ public class StringHelper {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static @NotNull List<KeyStroke> stringToKeys(@NotNull String s) {
|
public static @NotNull List<KeyStroke> stringToKeys(@NotNull @NonNls String s) {
|
||||||
// The following if is a dirty hack to finally support `let mapleader = "\<space>"`
|
// The following if is a dirty hack to finally support `let mapleader = "\<space>"`
|
||||||
if ("\\<SPACE>".equalsIgnoreCase(s)) return Collections.singletonList(getKeyStroke(' '));
|
if ("\\<SPACE>".equalsIgnoreCase(s)) return Collections.singletonList(getKeyStroke(' '));
|
||||||
final List<KeyStroke> res = new ArrayList<>();
|
final List<KeyStroke> res = new ArrayList<>();
|
||||||
@@ -83,7 +84,7 @@ public class StringHelper {
|
|||||||
* @throws java.lang.IllegalArgumentException if the mapping doesn't make sense for Vim emulation
|
* @throws java.lang.IllegalArgumentException if the mapping doesn't make sense for Vim emulation
|
||||||
* @see :help <>
|
* @see :help <>
|
||||||
*/
|
*/
|
||||||
public static @NotNull List<KeyStroke> parseKeys(@NotNull String... strings) {
|
public static @NotNull List<KeyStroke> parseKeys(@NotNull @NonNls String... strings) {
|
||||||
final List<KeyStroke> result = new ArrayList<>();
|
final List<KeyStroke> result = new ArrayList<>();
|
||||||
for (String s : strings) {
|
for (String s : strings) {
|
||||||
KeyParserState state = KeyParserState.INIT;
|
KeyParserState state = KeyParserState.INIT;
|
||||||
@@ -404,7 +405,7 @@ public class StringHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Integer getVimKeyName(String lower) {
|
private static Integer getVimKeyName(@NonNls String lower) {
|
||||||
switch (lower) {
|
switch (lower) {
|
||||||
case "cr":
|
case "cr":
|
||||||
case "enter":
|
case "enter":
|
||||||
@@ -472,7 +473,7 @@ public class StringHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getVimKeyValue(int c) {
|
private static @NonNls String getVimKeyValue(int c) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case VK_ENTER:
|
case VK_ENTER:
|
||||||
return "cr";
|
return "cr";
|
||||||
|
25
src/com/maddyhome/idea/vim/helper/VimNlsSafe.kt
Normal file
25
src/com/maddyhome/idea/vim/helper/VimNlsSafe.kt
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||||
|
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.maddyhome.idea.vim.helper
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NonNls
|
||||||
|
|
||||||
|
// [VERSION UPDATE] 203+ replace this annotation with @VimNlsSafe
|
||||||
|
@NonNls
|
||||||
|
annotation class VimNlsSafe
|
@@ -108,14 +108,28 @@ public class KeyMapping implements Iterable<List<KeyStroke>> {
|
|||||||
myKeys.entrySet().stream().filter(o -> o.getValue().getOwner().equals(owner)).collect(Collectors.toList());
|
myKeys.entrySet().stream().filter(o -> o.getValue().getOwner().equals(owner)).collect(Collectors.toList());
|
||||||
|
|
||||||
toRemove.forEach(o -> myKeys.remove(o.getKey(), o.getValue()));
|
toRemove.forEach(o -> myKeys.remove(o.getKey(), o.getValue()));
|
||||||
toRemove.stream().map(Map.Entry::getKey).forEach(keys -> {
|
toRemove.stream().map(Map.Entry::getKey).forEach(this::removePrefixes);
|
||||||
List<KeyStroke> prefix = new ArrayList<>();
|
}
|
||||||
final int prefixLength = keys.size() - 1;
|
|
||||||
for (int i = 0; i < prefixLength; i++) {
|
public void delete(@NotNull List<KeyStroke> keys) {
|
||||||
prefix.add(keys.get(i));
|
MappingInfo removed = myKeys.remove(keys);
|
||||||
myPrefixes.remove(prefix);
|
if (removed == null) return;
|
||||||
}
|
|
||||||
});
|
removePrefixes(keys);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void delete() {
|
||||||
|
myKeys.clear();
|
||||||
|
myPrefixes.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removePrefixes(@NotNull List<KeyStroke> keys) {
|
||||||
|
List<KeyStroke> prefix = new ArrayList<>();
|
||||||
|
final int prefixLength = keys.size() - 1;
|
||||||
|
for (int i = 0; i < prefixLength; i++) {
|
||||||
|
prefix.add(keys.get(i));
|
||||||
|
myPrefixes.remove(prefix);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Pair<List<KeyStroke>, MappingInfo>> getByOwner(@NotNull MappingOwner owner) {
|
public List<Pair<List<KeyStroke>, MappingInfo>> getByOwner(@NotNull MappingOwner owner) {
|
||||||
|
@@ -36,11 +36,11 @@ import com.maddyhome.idea.vim.group.visual.VimSelection
|
|||||||
import com.maddyhome.idea.vim.group.visual.VimSelection.Companion.create
|
import com.maddyhome.idea.vim.group.visual.VimSelection.Companion.create
|
||||||
import com.maddyhome.idea.vim.helper.EditorDataContext
|
import com.maddyhome.idea.vim.helper.EditorDataContext
|
||||||
import com.maddyhome.idea.vim.helper.StringHelper.toKeyNotation
|
import com.maddyhome.idea.vim.helper.StringHelper.toKeyNotation
|
||||||
|
import com.maddyhome.idea.vim.helper.VimNlsSafe
|
||||||
import com.maddyhome.idea.vim.helper.subMode
|
import com.maddyhome.idea.vim.helper.subMode
|
||||||
import com.maddyhome.idea.vim.helper.vimSelectionStart
|
import com.maddyhome.idea.vim.helper.vimSelectionStart
|
||||||
import com.maddyhome.idea.vim.listener.SelectionVimListenerSuppressor
|
import com.maddyhome.idea.vim.listener.SelectionVimListenerSuppressor
|
||||||
import java.awt.event.KeyEvent
|
import java.awt.event.KeyEvent
|
||||||
import java.util.*
|
|
||||||
import javax.swing.KeyStroke
|
import javax.swing.KeyStroke
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
|
|
||||||
@@ -49,6 +49,7 @@ import kotlin.math.min
|
|||||||
*/
|
*/
|
||||||
sealed class MappingInfo(val fromKeys: List<KeyStroke>, val isRecursive: Boolean, val owner: MappingOwner) : Comparable<MappingInfo> {
|
sealed class MappingInfo(val fromKeys: List<KeyStroke>, val isRecursive: Boolean, val owner: MappingOwner) : Comparable<MappingInfo> {
|
||||||
|
|
||||||
|
@VimNlsSafe
|
||||||
abstract fun getPresentableString(): String
|
abstract fun getPresentableString(): String
|
||||||
|
|
||||||
abstract fun execute(editor: Editor, context: DataContext)
|
abstract fun execute(editor: Editor, context: DataContext)
|
||||||
|
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
package com.maddyhome.idea.vim.key;
|
package com.maddyhome.idea.vim.key;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NonNls;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -25,13 +26,13 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
*/
|
*/
|
||||||
public enum ShortcutOwner {
|
public enum ShortcutOwner {
|
||||||
UNDEFINED("undefined", "Undefined"),
|
UNDEFINED("undefined", "Undefined"),
|
||||||
IDE("ide", "IDE"),
|
IDE(Constants.IDE_STRING, "IDE"),
|
||||||
VIM("vim", "Vim");
|
VIM(Constants.VIM_STRING, "Vim");
|
||||||
|
|
||||||
private final @NotNull String name;
|
private final @NotNull @NonNls String name;
|
||||||
private final @NotNull String title;
|
private final @NotNull @NonNls String title;
|
||||||
|
|
||||||
ShortcutOwner(@NotNull String name, @NotNull String title) {
|
ShortcutOwner(@NotNull @NonNls String name, @NotNull @NonNls String title) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.title = title;
|
this.title = title;
|
||||||
}
|
}
|
||||||
@@ -46,12 +47,17 @@ public enum ShortcutOwner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static @NotNull ShortcutOwner fromString(@NotNull String s) {
|
public static @NotNull ShortcutOwner fromString(@NotNull String s) {
|
||||||
if ("ide".equals(s)) {
|
if (Constants.IDE_STRING.equals(s)) {
|
||||||
return IDE;
|
return IDE;
|
||||||
}
|
}
|
||||||
else if ("vim".equals(s)) {
|
else if (Constants.VIM_STRING.equals(s)) {
|
||||||
return VIM;
|
return VIM;
|
||||||
}
|
}
|
||||||
return UNDEFINED;
|
return UNDEFINED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class Constants {
|
||||||
|
@NonNls private static final String IDE_STRING = "ide";
|
||||||
|
@NonNls private static final String VIM_STRING = "vim";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -32,12 +32,14 @@ import com.intellij.openapi.actionSystem.CommonDataKeys
|
|||||||
import com.intellij.openapi.actionSystem.DataContext
|
import com.intellij.openapi.actionSystem.DataContext
|
||||||
import com.intellij.openapi.actionSystem.IdeActions
|
import com.intellij.openapi.actionSystem.IdeActions
|
||||||
import com.intellij.openapi.actionSystem.ex.AnActionListener
|
import com.intellij.openapi.actionSystem.ex.AnActionListener
|
||||||
|
import com.intellij.openapi.editor.Caret
|
||||||
import com.intellij.openapi.editor.Editor
|
import com.intellij.openapi.editor.Editor
|
||||||
import com.intellij.openapi.editor.actionSystem.EditorActionManager
|
import com.intellij.openapi.editor.actionSystem.EditorActionManager
|
||||||
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.intellij.openapi.project.DumbAwareToggleAction
|
import com.intellij.openapi.project.DumbAwareToggleAction
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.openapi.util.Key
|
||||||
import com.intellij.util.PlatformUtils
|
import com.intellij.util.PlatformUtils
|
||||||
import com.maddyhome.idea.vim.EventFacade
|
import com.maddyhome.idea.vim.EventFacade
|
||||||
import com.maddyhome.idea.vim.KeyHandler
|
import com.maddyhome.idea.vim.KeyHandler
|
||||||
@@ -47,9 +49,12 @@ 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.EditorDataContext
|
import com.maddyhome.idea.vim.helper.EditorDataContext
|
||||||
import com.maddyhome.idea.vim.helper.commandState
|
import com.maddyhome.idea.vim.helper.commandState
|
||||||
|
import com.maddyhome.idea.vim.helper.fileSize
|
||||||
import com.maddyhome.idea.vim.helper.getTopLevelEditor
|
import com.maddyhome.idea.vim.helper.getTopLevelEditor
|
||||||
import com.maddyhome.idea.vim.helper.inNormalMode
|
import com.maddyhome.idea.vim.helper.inNormalMode
|
||||||
import com.maddyhome.idea.vim.option.IdeaRefactorMode
|
import com.maddyhome.idea.vim.option.IdeaRefactorMode
|
||||||
|
import org.jetbrains.annotations.NonNls
|
||||||
|
import org.jetbrains.annotations.NotNull
|
||||||
import java.beans.PropertyChangeEvent
|
import java.beans.PropertyChangeEvent
|
||||||
import java.beans.PropertyChangeListener
|
import java.beans.PropertyChangeListener
|
||||||
|
|
||||||
@@ -66,6 +71,7 @@ object IdeaSpecifics {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class VimActionListener : AnActionListener {
|
class VimActionListener : AnActionListener {
|
||||||
|
@NonNls
|
||||||
private val surrounderItems = listOf("if", "if / else", "for")
|
private val surrounderItems = listOf("if", "if / else", "for")
|
||||||
private val surrounderAction = "com.intellij.codeInsight.generation.surroundWith.SurroundWithHandler\$InvokeSurrounderAction"
|
private val surrounderAction = "com.intellij.codeInsight.generation.surroundWith.SurroundWithHandler\$InvokeSurrounderAction"
|
||||||
private var editor: Editor? = null
|
private var editor: Editor? = null
|
||||||
@@ -189,6 +195,87 @@ object IdeaSpecifics {
|
|||||||
.javaClass.name.startsWith("org.acejump.")
|
.javaClass.name.startsWith("org.acejump.")
|
||||||
}
|
}
|
||||||
//endregion
|
//endregion
|
||||||
|
|
||||||
|
//region AppCode templates
|
||||||
|
/**
|
||||||
|
* A collection of hacks to improve the interaction with fancy AppCode templates
|
||||||
|
*/
|
||||||
|
object AppCodeTemplates {
|
||||||
|
private val facedAppCodeTemplate = Key.create<IntRange>("FacedAppCodeTemplate")
|
||||||
|
|
||||||
|
private const val TEMPLATE_START = "<#T##"
|
||||||
|
private const val TEMPLATE_END = "#>"
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun onMovement(
|
||||||
|
editor: @NotNull Editor,
|
||||||
|
caret: @NotNull Caret,
|
||||||
|
toRight: Boolean
|
||||||
|
) {
|
||||||
|
if (!PlatformUtils.isAppCode()) return
|
||||||
|
|
||||||
|
val offset = caret.offset
|
||||||
|
val offsetRightEnd = offset + TEMPLATE_START.length
|
||||||
|
val offsetLeftEnd = offset - 1
|
||||||
|
val templateRange = caret.getUserData(facedAppCodeTemplate)
|
||||||
|
if (templateRange == null) {
|
||||||
|
if (offsetRightEnd < editor.fileSize
|
||||||
|
&& editor.document.charsSequence.subSequence(offset, offsetRightEnd).toString() == TEMPLATE_START) {
|
||||||
|
caret.shake()
|
||||||
|
|
||||||
|
val templateEnd = editor.findTemplateEnd(offset) ?: return
|
||||||
|
|
||||||
|
caret.putUserData(facedAppCodeTemplate, offset..templateEnd)
|
||||||
|
}
|
||||||
|
if (offsetLeftEnd >= 0
|
||||||
|
&& editor.document.charsSequence.subSequence(offsetLeftEnd, offset + 1).toString() == TEMPLATE_END) {
|
||||||
|
caret.shake()
|
||||||
|
|
||||||
|
val templateStart = editor.findTemplateStart(offsetLeftEnd) ?: return
|
||||||
|
|
||||||
|
caret.putUserData(facedAppCodeTemplate, templateStart..offset)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (offset in templateRange) {
|
||||||
|
if (toRight) {
|
||||||
|
caret.moveToOffset(templateRange.last + 1)
|
||||||
|
} else {
|
||||||
|
caret.moveToOffset(templateRange.first)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
caret.putUserData(facedAppCodeTemplate, null)
|
||||||
|
caret.shake()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Caret.shake() {
|
||||||
|
moveCaretRelatively(1, 0, false, false)
|
||||||
|
moveCaretRelatively(-1, 0, false, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Editor.findTemplateEnd(start: Int): Int? {
|
||||||
|
val charSequence = this.document.charsSequence
|
||||||
|
val length = charSequence.length
|
||||||
|
for (i in start until length - 1) {
|
||||||
|
if (charSequence[i] == TEMPLATE_END[0] && charSequence[i+1] == TEMPLATE_END[1]) {
|
||||||
|
return i + 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Editor.findTemplateStart(start: Int): Int? {
|
||||||
|
val charSequence = this.document.charsSequence
|
||||||
|
val templateLastIndex = TEMPLATE_START.length
|
||||||
|
for (i in start downTo templateLastIndex) {
|
||||||
|
if (charSequence.subSequence(i - templateLastIndex, i + 1).toString() == TEMPLATE_START) {
|
||||||
|
return i - templateLastIndex
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
//region Find action ID
|
//region Find action ID
|
||||||
|
@@ -68,7 +68,7 @@ import com.maddyhome.idea.vim.listener.VimListenerManager.EditorListeners.add
|
|||||||
import com.maddyhome.idea.vim.listener.VimListenerManager.EditorListeners.remove
|
import com.maddyhome.idea.vim.listener.VimListenerManager.EditorListeners.remove
|
||||||
import com.maddyhome.idea.vim.option.OptionsManager
|
import com.maddyhome.idea.vim.option.OptionsManager
|
||||||
import com.maddyhome.idea.vim.option.StrictMode
|
import com.maddyhome.idea.vim.option.StrictMode
|
||||||
import com.maddyhome.idea.vim.ui.ExEntryPanel
|
import com.maddyhome.idea.vim.ui.ex.ExEntryPanel
|
||||||
import com.maddyhome.idea.vim.ui.ShowCmdOptionChangeListener
|
import com.maddyhome.idea.vim.ui.ShowCmdOptionChangeListener
|
||||||
import java.awt.event.MouseAdapter
|
import java.awt.event.MouseAdapter
|
||||||
import java.awt.event.MouseEvent
|
import java.awt.event.MouseEvent
|
||||||
|
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
package com.maddyhome.idea.vim.option;
|
package com.maddyhome.idea.vim.option;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NonNls;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -26,7 +27,7 @@ import java.util.List;
|
|||||||
|
|
||||||
|
|
||||||
public class BoundListOption extends ListOption {
|
public class BoundListOption extends ListOption {
|
||||||
BoundListOption(String name, String abbrev, String[] dflt, String[] values) {
|
BoundListOption(@NonNls String name, @NonNls String abbrev, @NonNls String[] dflt, @NonNls String[] values) {
|
||||||
super(name, abbrev, dflt, null);
|
super(name, abbrev, dflt, null);
|
||||||
|
|
||||||
this.values = new ArrayList<>(Arrays.asList(values));
|
this.values = new ArrayList<>(Arrays.asList(values));
|
||||||
|
@@ -18,10 +18,11 @@
|
|||||||
|
|
||||||
package com.maddyhome.idea.vim.option;
|
package com.maddyhome.idea.vim.option;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NonNls;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
public class BoundStringOption extends StringOption {
|
public class BoundStringOption extends StringOption {
|
||||||
BoundStringOption(String name, String abbrev, String dflt, String[] values) {
|
BoundStringOption(@NonNls String name, @NonNls String abbrev, @NonNls String dflt, String[] values) {
|
||||||
super(name, abbrev, dflt);
|
super(name, abbrev, dflt);
|
||||||
|
|
||||||
this.values = values;
|
this.values = values;
|
||||||
|
@@ -19,6 +19,7 @@
|
|||||||
package com.maddyhome.idea.vim.option;
|
package com.maddyhome.idea.vim.option;
|
||||||
|
|
||||||
import org.apache.commons.lang.math.NumberUtils;
|
import org.apache.commons.lang.math.NumberUtils;
|
||||||
|
import org.jetbrains.annotations.NonNls;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
@@ -30,12 +31,13 @@ import java.util.regex.Pattern;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public final class KeywordOption extends ListOption {
|
public final class KeywordOption extends ListOption {
|
||||||
|
@NonNls private static final String allLettersRegex = "\\p{L}";
|
||||||
private final @NotNull Pattern validationPattern;
|
private final @NotNull Pattern validationPattern;
|
||||||
|
|
||||||
// KeywordSpecs are the option values in reverse order
|
// KeywordSpecs are the option values in reverse order
|
||||||
private @NotNull List<KeywordSpec> keywordSpecs = new ArrayList<>();
|
private @NotNull List<KeywordSpec> keywordSpecs = new ArrayList<>();
|
||||||
|
|
||||||
public KeywordOption(@NotNull String name, @NotNull String abbrev, @NotNull String[] defaultValue) {
|
public KeywordOption(@NotNull @NonNls String name, @NotNull @NonNls String abbrev, @NotNull String[] defaultValue) {
|
||||||
super(name, abbrev, defaultValue,
|
super(name, abbrev, defaultValue,
|
||||||
"(\\^?(([^0-9^]|[0-9]{1,3})-([^0-9]|[0-9]{1,3})|([^0-9^]|[0-9]{1,3})),)*\\^?(([^0-9^]|[0-9]{1,3})-([^0-9]|[0-9]{1,3})|([^0-9]|[0-9]{1,3})),?$");
|
"(\\^?(([^0-9^]|[0-9]{1,3})-([^0-9]|[0-9]{1,3})|([^0-9^]|[0-9]{1,3})),)*\\^?(([^0-9^]|[0-9]{1,3})-([^0-9]|[0-9]{1,3})|([^0-9]|[0-9]{1,3})),?$");
|
||||||
validationPattern = Pattern.compile(pattern);
|
validationPattern = Pattern.compile(pattern);
|
||||||
@@ -209,7 +211,7 @@ public final class KeywordOption extends ListOption {
|
|||||||
public List<String> toRegex() {
|
public List<String> toRegex() {
|
||||||
return keywordSpecs.stream().map(spec -> {
|
return keywordSpecs.stream().map(spec -> {
|
||||||
if (spec.isAllLetters) {
|
if (spec.isAllLetters) {
|
||||||
return "\\p{L}";
|
return allLettersRegex;
|
||||||
} else if (spec.isRange) {
|
} else if (spec.isRange) {
|
||||||
return "[" + (char)spec.rangeLow.intValue() + "-" + (char)spec.rangeHigh.intValue() + "]";
|
return "[" + (char)spec.rangeLow.intValue() + "-" + (char)spec.rangeHigh.intValue() + "]";
|
||||||
} else {
|
} else {
|
||||||
|
@@ -19,6 +19,8 @@
|
|||||||
package com.maddyhome.idea.vim.option;
|
package com.maddyhome.idea.vim.option;
|
||||||
|
|
||||||
import com.intellij.util.ArrayUtil;
|
import com.intellij.util.ArrayUtil;
|
||||||
|
import com.maddyhome.idea.vim.helper.VimNlsSafe;
|
||||||
|
import org.jetbrains.annotations.NonNls;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
@@ -69,7 +71,7 @@ public class ListOption extends TextOption {
|
|||||||
* @param val A comma separated list of values to look for
|
* @param val A comma separated list of values to look for
|
||||||
* @return True if all the supplied values are set in this option, false if not
|
* @return True if all the supplied values are set in this option, false if not
|
||||||
*/
|
*/
|
||||||
public boolean contains(String val) {
|
public boolean contains(@NonNls String val) {
|
||||||
final List<String> vals = parseVals(val);
|
final List<String> vals = parseVals(val);
|
||||||
return vals != null && value.containsAll(vals);
|
return vals != null && value.containsAll(vals);
|
||||||
}
|
}
|
||||||
@@ -178,7 +180,7 @@ public class ListOption extends TextOption {
|
|||||||
* @param dflt The option's default values
|
* @param dflt The option's default values
|
||||||
* @param pattern A regular expression that is used to validate new values. null if no check needed
|
* @param pattern A regular expression that is used to validate new values. null if no check needed
|
||||||
*/
|
*/
|
||||||
ListOption(String name, String abbrev, String[] dflt, String pattern) {
|
ListOption(@VimNlsSafe String name, @VimNlsSafe String abbrev, @VimNlsSafe String[] dflt, @VimNlsSafe String pattern) {
|
||||||
super(name, abbrev);
|
super(name, abbrev);
|
||||||
|
|
||||||
this.dflt = new ArrayList<>(Arrays.asList(dflt));
|
this.dflt = new ArrayList<>(Arrays.asList(dflt));
|
||||||
|
@@ -18,6 +18,8 @@
|
|||||||
|
|
||||||
package com.maddyhome.idea.vim.option;
|
package com.maddyhome.idea.vim.option;
|
||||||
|
|
||||||
|
import com.maddyhome.idea.vim.helper.VimNlsSafe;
|
||||||
|
import org.jetbrains.annotations.NonNls;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
@@ -32,7 +34,7 @@ public class NumberOption extends TextOption {
|
|||||||
* @param abbrev The short name
|
* @param abbrev The short name
|
||||||
* @param dflt The default value
|
* @param dflt The default value
|
||||||
*/
|
*/
|
||||||
NumberOption(String name, String abbrev, int dflt) {
|
NumberOption(@NonNls String name, @NonNls String abbrev, int dflt) {
|
||||||
this(name, abbrev, dflt, 0, Integer.MAX_VALUE);
|
this(name, abbrev, dflt, 0, Integer.MAX_VALUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,7 +47,7 @@ public class NumberOption extends TextOption {
|
|||||||
* @param min The option's minimum value
|
* @param min The option's minimum value
|
||||||
* @param max The option's maximum value
|
* @param max The option's maximum value
|
||||||
*/
|
*/
|
||||||
NumberOption(String name, String abbrev, int dflt, int min, int max) {
|
NumberOption(@VimNlsSafe String name, @VimNlsSafe String abbrev, int dflt, int min, int max) {
|
||||||
super(name, abbrev);
|
super(name, abbrev);
|
||||||
this.dflt = dflt;
|
this.dflt = dflt;
|
||||||
this.value = dflt;
|
this.value = dflt;
|
||||||
|
@@ -36,8 +36,8 @@ import com.maddyhome.idea.vim.helper.isBlockCaret
|
|||||||
import com.maddyhome.idea.vim.helper.mode
|
import com.maddyhome.idea.vim.helper.mode
|
||||||
import com.maddyhome.idea.vim.helper.subMode
|
import com.maddyhome.idea.vim.helper.subMode
|
||||||
import com.maddyhome.idea.vim.listener.SelectionVimListenerSuppressor
|
import com.maddyhome.idea.vim.listener.SelectionVimListenerSuppressor
|
||||||
import org.jetbrains.annotations.ApiStatus
|
|
||||||
import org.jetbrains.annotations.Contract
|
import org.jetbrains.annotations.Contract
|
||||||
|
import org.jetbrains.annotations.NonNls
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.math.ceil
|
import kotlin.math.ceil
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
@@ -366,6 +366,7 @@ object OptionsManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNls
|
||||||
object KeyModelOptionData {
|
object KeyModelOptionData {
|
||||||
const val name = "keymodel"
|
const val name = "keymodel"
|
||||||
private const val abbr = "km"
|
private const val abbr = "km"
|
||||||
@@ -382,6 +383,7 @@ object KeyModelOptionData {
|
|||||||
val option = BoundListOption(name, abbr, default, options)
|
val option = BoundListOption(name, abbr, default, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNls
|
||||||
object SelectModeOptionData {
|
object SelectModeOptionData {
|
||||||
const val name = "selectmode"
|
const val name = "selectmode"
|
||||||
private const val abbr = "slm"
|
private const val abbr = "slm"
|
||||||
@@ -402,6 +404,7 @@ object SelectModeOptionData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNls
|
||||||
object ClipboardOptionsData {
|
object ClipboardOptionsData {
|
||||||
const val name = "clipboard"
|
const val name = "clipboard"
|
||||||
const val abbr = "cb"
|
const val abbr = "cb"
|
||||||
@@ -431,6 +434,7 @@ object ClipboardOptionsData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNls
|
||||||
object IdeaJoinOptionsData {
|
object IdeaJoinOptionsData {
|
||||||
const val name = "ideajoin"
|
const val name = "ideajoin"
|
||||||
private const val defaultValue = false
|
private const val defaultValue = false
|
||||||
@@ -438,6 +442,7 @@ object IdeaJoinOptionsData {
|
|||||||
val option = ToggleOption(name, name, defaultValue)
|
val option = ToggleOption(name, name, defaultValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNls
|
||||||
object IdeaMarkskOptionsData {
|
object IdeaMarkskOptionsData {
|
||||||
const val name = "ideamarks"
|
const val name = "ideamarks"
|
||||||
private const val defaultValue = true
|
private const val defaultValue = true
|
||||||
@@ -445,16 +450,19 @@ object IdeaMarkskOptionsData {
|
|||||||
val option = ToggleOption(name, name, defaultValue)
|
val option = ToggleOption(name, name, defaultValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNls
|
||||||
object SmartCaseOptionsData {
|
object SmartCaseOptionsData {
|
||||||
const val name = "smartcase"
|
const val name = "smartcase"
|
||||||
const val abbr = "scs"
|
const val abbr = "scs"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNls
|
||||||
object IgnoreCaseOptionsData {
|
object IgnoreCaseOptionsData {
|
||||||
const val name = "ignorecase"
|
const val name = "ignorecase"
|
||||||
const val abbr = "ic"
|
const val abbr = "ic"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNls
|
||||||
object IdeaRefactorMode {
|
object IdeaRefactorMode {
|
||||||
const val name = "idearefactormode"
|
const val name = "idearefactormode"
|
||||||
|
|
||||||
@@ -513,6 +521,7 @@ object IdeaRefactorMode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNls
|
||||||
object LookupKeysData {
|
object LookupKeysData {
|
||||||
const val name = "lookupkeys"
|
const val name = "lookupkeys"
|
||||||
val defaultValues = arrayOf(
|
val defaultValues = arrayOf(
|
||||||
@@ -527,6 +536,7 @@ object LookupKeysData {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNls
|
||||||
object IdeaStatusIcon {
|
object IdeaStatusIcon {
|
||||||
const val enabled = "enabled"
|
const val enabled = "enabled"
|
||||||
const val gray = "gray"
|
const val gray = "gray"
|
||||||
@@ -536,10 +546,12 @@ object IdeaStatusIcon {
|
|||||||
val allValues = arrayOf(enabled, gray, disabled)
|
val allValues = arrayOf(enabled, gray, disabled)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNls
|
||||||
object ScrollOffData {
|
object ScrollOffData {
|
||||||
const val name = "scrolloff"
|
const val name = "scrolloff"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNls
|
||||||
object ScrollJumpData {
|
object ScrollJumpData {
|
||||||
const val name = "scrolljump"
|
const val name = "scrolljump"
|
||||||
}
|
}
|
||||||
@@ -548,11 +560,13 @@ object StrictMode {
|
|||||||
val on: Boolean
|
val on: Boolean
|
||||||
get() = OptionsManager.ideastrictmode.isSet
|
get() = OptionsManager.ideastrictmode.isSet
|
||||||
|
|
||||||
fun fail(message: String) {
|
@NonNls
|
||||||
|
fun fail(message: @NonNls String) {
|
||||||
if (on) error(message)
|
if (on) error(message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNls
|
||||||
object VirtualEditData {
|
object VirtualEditData {
|
||||||
const val name = "virtualedit"
|
const val name = "virtualedit"
|
||||||
|
|
||||||
@@ -560,6 +574,7 @@ object VirtualEditData {
|
|||||||
val allValues = arrayOf("block", "insert", "all", onemore)
|
val allValues = arrayOf("block", "insert", "all", onemore)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNls
|
||||||
object IdeaWriteData {
|
object IdeaWriteData {
|
||||||
const val all = "all"
|
const val all = "all"
|
||||||
|
|
||||||
|
@@ -18,12 +18,17 @@
|
|||||||
|
|
||||||
package com.maddyhome.idea.vim.option;
|
package com.maddyhome.idea.vim.option;
|
||||||
|
|
||||||
|
import com.maddyhome.idea.vim.helper.VimNlsSafe;
|
||||||
|
import org.jetbrains.annotations.NonNls;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a boolean option
|
* Represents a boolean option
|
||||||
*/
|
*/
|
||||||
public class ToggleOption extends Option<Boolean> {
|
public class ToggleOption extends Option<Boolean> {
|
||||||
|
|
||||||
|
private static final @NonNls String NO_PREFIX = "no";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the option
|
* Creates the option
|
||||||
*
|
*
|
||||||
@@ -31,7 +36,7 @@ public class ToggleOption extends Option<Boolean> {
|
|||||||
* @param abbrev The short name
|
* @param abbrev The short name
|
||||||
* @param dflt The default value
|
* @param dflt The default value
|
||||||
*/
|
*/
|
||||||
public ToggleOption(String name, String abbrev, boolean dflt) {
|
public ToggleOption(@VimNlsSafe String name, @VimNlsSafe String abbrev, boolean dflt) {
|
||||||
super(name, abbrev);
|
super(name, abbrev);
|
||||||
|
|
||||||
this.dflt = dflt;
|
this.dflt = dflt;
|
||||||
@@ -89,7 +94,7 @@ public class ToggleOption extends Option<Boolean> {
|
|||||||
public @NotNull String toString() {
|
public @NotNull String toString() {
|
||||||
StringBuilder res = new StringBuilder();
|
StringBuilder res = new StringBuilder();
|
||||||
if (!value) {
|
if (!value) {
|
||||||
res.append("no");
|
res.append(NO_PREFIX);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
res.append(" ");
|
res.append(" ");
|
||||||
|
@@ -612,20 +612,20 @@
|
|||||||
*
|
*
|
||||||
* |c_CTRL-A| TO BE IMPLEMENTED
|
* |c_CTRL-A| TO BE IMPLEMENTED
|
||||||
* |c_CTRL-B| {@link javax.swing.text.DefaultEditorKit#beginLineAction}
|
* |c_CTRL-B| {@link javax.swing.text.DefaultEditorKit#beginLineAction}
|
||||||
* |c_CTRL-C| {@link com.maddyhome.idea.vim.ui.ExEditorKit.CancelEntryAction}
|
* |c_CTRL-C| {@link com.maddyhome.idea.vim.ui.ex.CancelEntryAction}
|
||||||
* |c_CTRL-D| TO BE IMPLEMENTED
|
* |c_CTRL-D| TO BE IMPLEMENTED
|
||||||
* |c_CTRL-E| {@link javax.swing.text.DefaultEditorKit#endLineAction}
|
* |c_CTRL-E| {@link javax.swing.text.DefaultEditorKit#endLineAction}
|
||||||
* |c_CTRL-G| TO BE IMPLEMENTED
|
* |c_CTRL-G| TO BE IMPLEMENTED
|
||||||
* |c_CTRL-H| {@link com.maddyhome.idea.vim.ui.ExEditorKit.DeletePreviousCharAction}
|
* |c_CTRL-H| {@link com.maddyhome.idea.vim.ui.ex.DeletePreviousCharAction}
|
||||||
* |c_CTRL-I| TO BE IMPLEMENTED
|
* |c_CTRL-I| TO BE IMPLEMENTED
|
||||||
* |c_CTRL-J| {@link com.maddyhome.idea.vim.ui.ExEditorKit.CompleteEntryAction}
|
* |c_CTRL-J| {@link com.maddyhome.idea.vim.ui.ex.CompleteEntryAction}
|
||||||
* |c_CTRL-K| {@link com.maddyhome.idea.vim.ui.ExEditorKit.StartDigraphAction}
|
* |c_CTRL-K| Handled by KeyHandler
|
||||||
* |c_CTRL-L| TO BE IMPLEMENTED
|
* |c_CTRL-L| TO BE IMPLEMENTED
|
||||||
* |c_CTRL-M| {@link com.maddyhome.idea.vim.action.ex.ProcessExEntryAction}
|
* |c_CTRL-M| {@link com.maddyhome.idea.vim.action.ex.ProcessExEntryAction}
|
||||||
* |c_CTRL-N| {@link com.maddyhome.idea.vim.ui.ExEditorKit.HistoryDownAction}
|
* |c_CTRL-N| {@link com.maddyhome.idea.vim.ui.ex.HistoryDownAction}
|
||||||
* |c_CTRL-P| {@link com.maddyhome.idea.vim.ui.ExEditorKit.HistoryUpAction}
|
* |c_CTRL-P| {@link com.maddyhome.idea.vim.ui.ex.HistoryUpAction}
|
||||||
* |c_CTRL-Q| {@link com.maddyhome.idea.vim.ui.ExEditorKit.StartDigraphAction}
|
* |c_CTRL-Q| Handled by KeyHandler
|
||||||
* |c_CTRL-R| {@link com.maddyhome.idea.vim.ui.ExEditorKit.InsertRegisterAction}
|
* |c_CTRL-R| {@link com.maddyhome.idea.vim.ui.ex.InsertRegisterAction}
|
||||||
* |c_CTRL-R_CTRL-A| TO BE IMPLEMENTED
|
* |c_CTRL-R_CTRL-A| TO BE IMPLEMENTED
|
||||||
* |c_CTRL-R_CTRL-F| TO BE IMPLEMENTED
|
* |c_CTRL-R_CTRL-F| TO BE IMPLEMENTED
|
||||||
* |c_CTRL-R_CTRL-L| TO BE IMPLEMENTED
|
* |c_CTRL-R_CTRL-L| TO BE IMPLEMENTED
|
||||||
@@ -634,9 +634,9 @@
|
|||||||
* |c_CTRL-R_CTRL-R| TO BE IMPLEMENTED
|
* |c_CTRL-R_CTRL-R| TO BE IMPLEMENTED
|
||||||
* |c_CTRL-R_CTRL-W| TO BE IMPLEMENTED
|
* |c_CTRL-R_CTRL-W| TO BE IMPLEMENTED
|
||||||
* |c_CTRL-T| TO BE IMPLEMENTED
|
* |c_CTRL-T| TO BE IMPLEMENTED
|
||||||
* |c_CTRL-U| {@link com.maddyhome.idea.vim.ui.ExEditorKit.DeleteToCursorAction}
|
* |c_CTRL-U| {@link com.maddyhome.idea.vim.ui.ex.DeleteToCursorAction}
|
||||||
* |c_CTRL-V| {@link com.maddyhome.idea.vim.ui.ExEditorKit.StartDigraphAction}
|
* |c_CTRL-V| Handled by KeyHandler
|
||||||
* |c_CTRL-W| {@link com.maddyhome.idea.vim.ui.ExEditorKit.DeletePreviousWordAction}
|
* |c_CTRL-W| {@link com.maddyhome.idea.vim.ui.ex.DeletePreviousWordAction}
|
||||||
* |c_CTRL-Y| TO BE IMPLEMENTED
|
* |c_CTRL-Y| TO BE IMPLEMENTED
|
||||||
* |c_CTRL-\_e| TO BE IMPLEMENTED
|
* |c_CTRL-\_e| TO BE IMPLEMENTED
|
||||||
* |c_CTRL-\_CTRL-G| TO BE IMPLEMENTED
|
* |c_CTRL-\_CTRL-G| TO BE IMPLEMENTED
|
||||||
@@ -644,32 +644,32 @@
|
|||||||
* |c_CTRL-_| not applicable
|
* |c_CTRL-_| not applicable
|
||||||
* |c_CTRL-^| not applicable
|
* |c_CTRL-^| not applicable
|
||||||
* |c_CTRL-]| TO BE IMPLEMENTED
|
* |c_CTRL-]| TO BE IMPLEMENTED
|
||||||
* |c_CTRL-[| {@link com.maddyhome.idea.vim.ui.ExEditorKit.EscapeCharAction}
|
* |c_CTRL-[| {@link com.maddyhome.idea.vim.ui.ex.EscapeCharAction}
|
||||||
* |c_<BS>| {@link com.maddyhome.idea.vim.ui.ExEditorKit.DeletePreviousCharAction}
|
* |c_<BS>| {@link com.maddyhome.idea.vim.ui.ex.DeletePreviousCharAction}
|
||||||
* |c_<CR>| {@link com.maddyhome.idea.vim.ui.ExEditorKit.CompleteEntryAction}
|
* |c_<CR>| {@link com.maddyhome.idea.vim.ui.ex.CompleteEntryAction}
|
||||||
* |c_<C-Left>| {@link javax.swing.text.DefaultEditorKit#previousWordAction}
|
* |c_<C-Left>| {@link javax.swing.text.DefaultEditorKit#previousWordAction}
|
||||||
* |c_<C-Right>| {@link javax.swing.text.DefaultEditorKit#nextWordAction}
|
* |c_<C-Right>| {@link javax.swing.text.DefaultEditorKit#nextWordAction}
|
||||||
* |c_<Del>| {@link javax.swing.text.DefaultEditorKit#deleteNextCharAction}
|
* |c_<Del>| {@link javax.swing.text.DefaultEditorKit#deleteNextCharAction}
|
||||||
* |c_<Down>| {@link com.maddyhome.idea.vim.ui.ExEditorKit.HistoryDownFilterAction}
|
* |c_<Down>| {@link com.maddyhome.idea.vim.ui.ex.HistoryDownFilterAction}
|
||||||
* |c_<End>| {@link javax.swing.text.DefaultEditorKit#endLineAction}
|
* |c_<End>| {@link javax.swing.text.DefaultEditorKit#endLineAction}
|
||||||
* |c_<Esc>| {@link com.maddyhome.idea.vim.ui.ExEditorKit.EscapeCharAction}
|
* |c_<Esc>| {@link com.maddyhome.idea.vim.ui.ex.EscapeCharAction}
|
||||||
* |c_<Home>| {@link javax.swing.text.DefaultEditorKit#beginLineAction}
|
* |c_<Home>| {@link javax.swing.text.DefaultEditorKit#beginLineAction}
|
||||||
* |c_<Insert>| {@link com.maddyhome.idea.vim.ui.ExEditorKit.ToggleInsertReplaceAction}
|
* |c_<Insert>| {@link com.maddyhome.idea.vim.ui.ex.ToggleInsertReplaceAction}
|
||||||
* |c_<Left>| {@link javax.swing.text.DefaultEditorKit#backwardAction}
|
* |c_<Left>| {@link javax.swing.text.DefaultEditorKit#backwardAction}
|
||||||
* |c_<LeftMouse>| not applicable
|
* |c_<LeftMouse>| not applicable
|
||||||
* |c_<MiddleMouse>| TO BE IMPLEMENTED
|
* |c_<MiddleMouse>| TO BE IMPLEMENTED
|
||||||
* |c_<NL>| {@link com.maddyhome.idea.vim.ui.ExEditorKit.CompleteEntryAction}
|
* |c_<NL>| {@link com.maddyhome.idea.vim.ui.ex.CompleteEntryAction}
|
||||||
* |c_<PageUp>| {@link com.maddyhome.idea.vim.ui.ExEditorKit.HistoryUpAction}
|
* |c_<PageUp>| {@link com.maddyhome.idea.vim.ui.ex.HistoryUpAction}
|
||||||
* |c_<PageDown>| {@link com.maddyhome.idea.vim.ui.ExEditorKit.HistoryDownAction}
|
* |c_<PageDown>| {@link com.maddyhome.idea.vim.ui.ex.HistoryDownAction}
|
||||||
* |c_<Right>| {@link javax.swing.text.DefaultEditorKit#forwardAction}
|
* |c_<Right>| {@link javax.swing.text.DefaultEditorKit#forwardAction}
|
||||||
* |c_<S-Down>| {@link com.maddyhome.idea.vim.ui.ExEditorKit.HistoryDownAction}
|
* |c_<S-Down>| {@link com.maddyhome.idea.vim.ui.ex.HistoryDownAction}
|
||||||
* |c_<S-Left>| {@link javax.swing.text.DefaultEditorKit#previousWordAction}
|
* |c_<S-Left>| {@link javax.swing.text.DefaultEditorKit#previousWordAction}
|
||||||
* |c_<S-Right>| {@link javax.swing.text.DefaultEditorKit#nextWordAction}
|
* |c_<S-Right>| {@link javax.swing.text.DefaultEditorKit#nextWordAction}
|
||||||
* |c_<S-Tab>| TO BE IMPLEMENTED
|
* |c_<S-Tab>| TO BE IMPLEMENTED
|
||||||
* |c_<S-Up>| {@link com.maddyhome.idea.vim.ui.ExEditorKit.HistoryUpAction}
|
* |c_<S-Up>| {@link com.maddyhome.idea.vim.ui.ex.HistoryUpAction}
|
||||||
* |c_<Tab>| TO BE IMPLEMENTED
|
* |c_<Tab>| TO BE IMPLEMENTED
|
||||||
* |c_<Up>| {@link com.maddyhome.idea.vim.ui.ExEditorKit.HistoryUpFilterAction}
|
* |c_<Up>| {@link com.maddyhome.idea.vim.ui.ex.HistoryUpFilterAction}
|
||||||
* |c_digraph| {char1} <BS> {char2} {@link com.maddyhome.idea.vim.ui.ExEditorKit.StartDigraphAction}
|
* |c_digraph| {char1} <BS> {char2} {@link com.maddyhome.idea.vim.ui.ex.StartDigraphAction}
|
||||||
* |c_wildchar| TO BE IMPLEMENTED
|
* |c_wildchar| TO BE IMPLEMENTED
|
||||||
* |'cedit'| TO BE IMPLEMENTED
|
* |'cedit'| TO BE IMPLEMENTED
|
||||||
*
|
*
|
||||||
@@ -679,7 +679,7 @@
|
|||||||
* tag handler
|
* tag handler
|
||||||
* -------------------------------------------------------------------------------------------------------------------
|
* -------------------------------------------------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* |:map| {@link com.maddyhome.idea.vim.ex.handler.MapHandler}
|
* |:map| {@link com.maddyhome.idea.vim.ex.handler.mapping.MapHandler}
|
||||||
* |:nmap| ...
|
* |:nmap| ...
|
||||||
* |:vmap| ...
|
* |:vmap| ...
|
||||||
* |:omap| ...
|
* |:omap| ...
|
||||||
|
@@ -18,11 +18,13 @@
|
|||||||
|
|
||||||
package com.maddyhome.idea.vim.regexp;
|
package com.maddyhome.idea.vim.regexp;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NonNls;
|
||||||
|
|
||||||
public final class CharacterClasses {
|
public final class CharacterClasses {
|
||||||
private CharacterClasses() {
|
private CharacterClasses() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final String[] CLASS_NAMES = new String[]{
|
public static final String @NonNls [] CLASS_NAMES = new String[]{
|
||||||
"alnum:]",
|
"alnum:]",
|
||||||
"alpha:]",
|
"alpha:]",
|
||||||
"blank:]",
|
"blank:]",
|
||||||
|
@@ -25,6 +25,7 @@ import com.maddyhome.idea.vim.VimPlugin;
|
|||||||
import com.maddyhome.idea.vim.helper.EditorHelper;
|
import com.maddyhome.idea.vim.helper.EditorHelper;
|
||||||
import com.maddyhome.idea.vim.helper.MessageHelper;
|
import com.maddyhome.idea.vim.helper.MessageHelper;
|
||||||
import com.maddyhome.idea.vim.helper.Msg;
|
import com.maddyhome.idea.vim.helper.Msg;
|
||||||
|
import org.jetbrains.annotations.NonNls;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
@@ -4273,8 +4274,8 @@ public class RegExp {
|
|||||||
/*
|
/*
|
||||||
* regprop - printable representation of opcode
|
* regprop - printable representation of opcode
|
||||||
*/
|
*/
|
||||||
private @NotNull String regprop(@NotNull CharPointer op) {
|
private @NotNull @NonNls String regprop(@NotNull CharPointer op) {
|
||||||
String p;
|
@NonNls String p;
|
||||||
StringBuilder buf = new StringBuilder();
|
StringBuilder buf = new StringBuilder();
|
||||||
|
|
||||||
buf.append(':');
|
buf.append(':');
|
||||||
|
@@ -1,565 +0,0 @@
|
|||||||
/*
|
|
||||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
|
||||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.maddyhome.idea.vim.ui;
|
|
||||||
|
|
||||||
import com.intellij.openapi.diagnostic.Logger;
|
|
||||||
import com.maddyhome.idea.vim.KeyHandler;
|
|
||||||
import com.maddyhome.idea.vim.VimPlugin;
|
|
||||||
import com.maddyhome.idea.vim.common.Register;
|
|
||||||
import com.maddyhome.idea.vim.helper.DigraphResult;
|
|
||||||
import com.maddyhome.idea.vim.helper.DigraphSequence;
|
|
||||||
import com.maddyhome.idea.vim.helper.SearchHelper;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import javax.swing.*;
|
|
||||||
import javax.swing.text.*;
|
|
||||||
import java.awt.event.ActionEvent;
|
|
||||||
import java.awt.event.KeyEvent;
|
|
||||||
|
|
||||||
|
|
||||||
public class ExEditorKit extends DefaultEditorKit {
|
|
||||||
public static ExEditorKit getInstance() {
|
|
||||||
if (instance == null) {
|
|
||||||
instance = new ExEditorKit();
|
|
||||||
}
|
|
||||||
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the MIME type of the data that this
|
|
||||||
* kit represents support for.
|
|
||||||
*
|
|
||||||
* @return the type
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public @NotNull String getContentType() {
|
|
||||||
return "text/ideavim";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fetches the set of commands that can be used
|
|
||||||
* on a text component that is using a model and
|
|
||||||
* view produced by this kit.
|
|
||||||
*
|
|
||||||
* @return the set of actions
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public Action[] getActions() {
|
|
||||||
Action[] res = TextAction.augmentList(super.getActions(), this.exActions);
|
|
||||||
if (logger.isDebugEnabled()) logger.debug("res.length=" + res.length);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates an uninitialized text storage model
|
|
||||||
* that is appropriate for this type of editor.
|
|
||||||
*
|
|
||||||
* @return the model
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public @NotNull Document createDefaultDocument() {
|
|
||||||
return new ExDocument();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static @Nullable KeyStroke convert(@NotNull ActionEvent event) {
|
|
||||||
String cmd = event.getActionCommand();
|
|
||||||
int mods = event.getModifiers();
|
|
||||||
if (cmd != null && cmd.length() > 0) {
|
|
||||||
char ch = cmd.charAt(0);
|
|
||||||
if (ch < ' ') {
|
|
||||||
if ((mods & ActionEvent.CTRL_MASK) != 0) {
|
|
||||||
return KeyStroke.getKeyStroke(KeyEvent.VK_A + ch - 1, mods);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return KeyStroke.getKeyStroke(Character.valueOf(ch), mods);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
static final String CancelEntry = "cancel-entry";
|
|
||||||
static final String CompleteEntry = "complete-entry";
|
|
||||||
static final String EscapeChar = "escape";
|
|
||||||
static final String DeleteToCursor = "delete-to-cursor";
|
|
||||||
static final String ToggleInsertReplace = "toggle-insert";
|
|
||||||
static final String InsertRegister = "insert-register";
|
|
||||||
static final String HistoryUp = "history-up";
|
|
||||||
static final String HistoryDown = "history-down";
|
|
||||||
static final String HistoryUpFilter = "history-up-filter";
|
|
||||||
static final String HistoryDownFilter = "history-down-filter";
|
|
||||||
static final String StartDigraph = "start-digraph";
|
|
||||||
static final String StartLiteral = "start-literal";
|
|
||||||
|
|
||||||
private final @NotNull Action[] exActions = new Action[]{
|
|
||||||
new CancelEntryAction(),
|
|
||||||
new CompleteEntryAction(),
|
|
||||||
new EscapeCharAction(),
|
|
||||||
new DeleteNextCharAction(),
|
|
||||||
new DeletePreviousCharAction(),
|
|
||||||
new DeletePreviousWordAction(),
|
|
||||||
new DeleteToCursorAction(),
|
|
||||||
new HistoryUpAction(),
|
|
||||||
new HistoryDownAction(),
|
|
||||||
new HistoryUpFilterAction(),
|
|
||||||
new HistoryDownFilterAction(),
|
|
||||||
new ToggleInsertReplaceAction(),
|
|
||||||
new StartDigraphAction(),
|
|
||||||
new StartLiteralAction(),
|
|
||||||
new InsertRegisterAction(),
|
|
||||||
};
|
|
||||||
|
|
||||||
public static class DefaultExKeyHandler extends DefaultKeyTypedAction {
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(@NotNull ActionEvent e) {
|
|
||||||
ExTextField target = (ExTextField)getTextComponent(e);
|
|
||||||
final Action currentAction = target.getCurrentAction();
|
|
||||||
if (currentAction != null) {
|
|
||||||
currentAction.actionPerformed(e);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
KeyStroke key = convert(e);
|
|
||||||
if (key != null) {
|
|
||||||
final char c = key.getKeyChar();
|
|
||||||
if (c > 0) {
|
|
||||||
ActionEvent event = new ActionEvent(e.getSource(), e.getID(), String.valueOf(c), e.getWhen(), e.getModifiers());
|
|
||||||
super.actionPerformed(event);
|
|
||||||
target.saveLastEntry();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
super.actionPerformed(e);
|
|
||||||
|
|
||||||
target.saveLastEntry();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface MultiStepAction extends Action {
|
|
||||||
void reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class HistoryUpAction extends TextAction {
|
|
||||||
HistoryUpAction() {
|
|
||||||
super(HistoryUp);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionEvent actionEvent) {
|
|
||||||
ExTextField target = (ExTextField)getTextComponent(actionEvent);
|
|
||||||
target.selectHistory(true, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class HistoryDownAction extends TextAction {
|
|
||||||
HistoryDownAction() {
|
|
||||||
super(HistoryDown);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionEvent actionEvent) {
|
|
||||||
ExTextField target = (ExTextField)getTextComponent(actionEvent);
|
|
||||||
target.selectHistory(false, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class HistoryUpFilterAction extends TextAction {
|
|
||||||
HistoryUpFilterAction() {
|
|
||||||
super(HistoryUpFilter);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionEvent actionEvent) {
|
|
||||||
ExTextField target = (ExTextField)getTextComponent(actionEvent);
|
|
||||||
target.selectHistory(true, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class HistoryDownFilterAction extends TextAction {
|
|
||||||
HistoryDownFilterAction() {
|
|
||||||
super(HistoryDownFilter);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionEvent actionEvent) {
|
|
||||||
ExTextField target = (ExTextField)getTextComponent(actionEvent);
|
|
||||||
target.selectHistory(false, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class InsertRegisterAction extends TextAction implements MultiStepAction {
|
|
||||||
private enum State {
|
|
||||||
SKIP_CTRL_R,
|
|
||||||
WAIT_REGISTER,
|
|
||||||
}
|
|
||||||
|
|
||||||
private @NotNull State state = State.SKIP_CTRL_R;
|
|
||||||
|
|
||||||
InsertRegisterAction() {
|
|
||||||
super(InsertRegister);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(@NotNull ActionEvent e) {
|
|
||||||
final ExTextField target = (ExTextField)getTextComponent(e);
|
|
||||||
final KeyStroke key = convert(e);
|
|
||||||
if (key != null) {
|
|
||||||
switch (state) {
|
|
||||||
case SKIP_CTRL_R:
|
|
||||||
state = State.WAIT_REGISTER;
|
|
||||||
target.setCurrentAction(this, '\"');
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WAIT_REGISTER:
|
|
||||||
state = State.SKIP_CTRL_R;
|
|
||||||
target.clearCurrentAction();
|
|
||||||
final char c = key.getKeyChar();
|
|
||||||
if (c != KeyEvent.CHAR_UNDEFINED) {
|
|
||||||
final Register register = VimPlugin.getRegister().getRegister(c);
|
|
||||||
if (register != null) {
|
|
||||||
final String oldText = target.getActualText();
|
|
||||||
final String text = register.getText();
|
|
||||||
if (text != null) {
|
|
||||||
final int offset = target.getCaretPosition();
|
|
||||||
target.setText(oldText.substring(0, offset) + text + oldText.substring(offset));
|
|
||||||
target.setCaretPosition(offset + text.length());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if ((key.getModifiers() & KeyEvent.CTRL_DOWN_MASK) != 0 && key.getKeyCode() == KeyEvent.VK_C) {
|
|
||||||
// Eat any unused keys, unless it's <C-C>, in which case forward on and cancel entry
|
|
||||||
target.handleKey(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reset() {
|
|
||||||
state = State.SKIP_CTRL_R;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class CompleteEntryAction extends TextAction {
|
|
||||||
CompleteEntryAction() {
|
|
||||||
super(CompleteEntry);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionEvent actionEvent) {
|
|
||||||
logger.debug("complete entry");
|
|
||||||
KeyStroke stroke = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);
|
|
||||||
|
|
||||||
// We send the <Enter> keystroke through the key handler rather than calling ProcessGroup#processExEntry directly.
|
|
||||||
// We do this for a couple of reasons:
|
|
||||||
// * The C mode mapping for ProcessExEntryAction handles the actual entry, and most importantly, it does so as a
|
|
||||||
// write action
|
|
||||||
// * The key handler routines get the chance to clean up and reset state
|
|
||||||
final ExTextField entry = ExEntryPanel.getInstance().getEntry();
|
|
||||||
KeyHandler.getInstance().handleKey(entry.getEditor(), stroke, entry.getContext());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class CancelEntryAction extends TextAction {
|
|
||||||
CancelEntryAction() {
|
|
||||||
super(CancelEntry);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionEvent e) {
|
|
||||||
ExTextField target = (ExTextField)getTextComponent(e);
|
|
||||||
target.cancel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class EscapeCharAction extends TextAction {
|
|
||||||
EscapeCharAction() {
|
|
||||||
super(EscapeChar);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionEvent e) {
|
|
||||||
ExTextField target = (ExTextField)getTextComponent(e);
|
|
||||||
target.escape();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
|
|
||||||
private abstract static class DeleteCharAction extends TextAction {
|
|
||||||
|
|
||||||
DeleteCharAction(String name) {
|
|
||||||
super(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean deleteSelection(Document doc, int dot, int mark) throws BadLocationException {
|
|
||||||
if (dot != mark) {
|
|
||||||
doc.remove(Math.min(dot, mark), Math.abs(dot - mark));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean deleteNextChar(Document doc, int dot) throws BadLocationException {
|
|
||||||
if (dot < doc.getLength()) {
|
|
||||||
int delChars = 1;
|
|
||||||
|
|
||||||
if (dot < doc.getLength() - 1) {
|
|
||||||
final String dotChars = doc.getText(dot, 2);
|
|
||||||
final char c0 = dotChars.charAt(0);
|
|
||||||
final char c1 = dotChars.charAt(1);
|
|
||||||
|
|
||||||
if (c0 >= '\uD800' && c0 <= '\uDBFF' &&
|
|
||||||
c1 >= '\uDC00' && c1 <= '\uDFFF') {
|
|
||||||
delChars = 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
doc.remove(dot, delChars);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean deletePrevChar(Document doc, int dot) throws BadLocationException {
|
|
||||||
if (dot > 0) {
|
|
||||||
int delChars = 1;
|
|
||||||
|
|
||||||
if (dot > 1) {
|
|
||||||
final String dotChars = doc.getText(dot - 2, 2);
|
|
||||||
final char c0 = dotChars.charAt(0);
|
|
||||||
final char c1 = dotChars.charAt(1);
|
|
||||||
|
|
||||||
if (c0 >= '\uD800' && c0 <= '\uDBFF' &&
|
|
||||||
c1 >= '\uDC00' && c1 <= '\uDFFF') {
|
|
||||||
delChars = 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
doc.remove(dot - delChars, delChars);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class DeleteNextCharAction extends DeleteCharAction {
|
|
||||||
DeleteNextCharAction() {
|
|
||||||
super(deleteNextCharAction);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionEvent e) {
|
|
||||||
final ExTextField target = (ExTextField)getTextComponent(e);
|
|
||||||
target.saveLastEntry();
|
|
||||||
|
|
||||||
try {
|
|
||||||
final Document doc = target.getDocument();
|
|
||||||
final Caret caret = target.getCaret();
|
|
||||||
final int dot = caret.getDot();
|
|
||||||
final int mark = caret.getMark();
|
|
||||||
if (!deleteSelection(doc, dot, mark) && !deleteNextChar(doc, dot) && !deletePrevChar(doc, dot)) {
|
|
||||||
target.cancel();
|
|
||||||
}
|
|
||||||
} catch (BadLocationException ex) {
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class DeletePreviousCharAction extends DeleteCharAction {
|
|
||||||
DeletePreviousCharAction() {
|
|
||||||
super(deletePrevCharAction);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionEvent e) {
|
|
||||||
ExTextField target = (ExTextField)getTextComponent(e);
|
|
||||||
target.saveLastEntry();
|
|
||||||
|
|
||||||
try {
|
|
||||||
Document doc = target.getDocument();
|
|
||||||
Caret caret = target.getCaret();
|
|
||||||
int dot = caret.getDot();
|
|
||||||
int mark = caret.getMark();
|
|
||||||
if (!deleteSelection(doc, dot, mark) && !deletePrevChar(doc, dot)) {
|
|
||||||
if (dot == 0 && doc.getLength() == 0) {
|
|
||||||
target.cancel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (BadLocationException bl) {
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class DeletePreviousWordAction extends TextAction {
|
|
||||||
DeletePreviousWordAction() {
|
|
||||||
super(deletePrevWordAction);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Invoked when an action occurs.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionEvent e) {
|
|
||||||
ExTextField target = (ExTextField)getTextComponent(e);
|
|
||||||
target.saveLastEntry();
|
|
||||||
|
|
||||||
Document doc = target.getDocument();
|
|
||||||
Caret caret = target.getCaret();
|
|
||||||
int offset = SearchHelper.findNextWord(target.getActualText(), caret.getDot(), target.getActualText().length(),
|
|
||||||
-1, false, false);
|
|
||||||
if (logger.isDebugEnabled()) logger.debug("offset=" + offset);
|
|
||||||
try {
|
|
||||||
int pos = caret.getDot();
|
|
||||||
doc.remove(offset, pos - offset);
|
|
||||||
}
|
|
||||||
catch (BadLocationException ex) {
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class DeleteToCursorAction extends TextAction {
|
|
||||||
DeleteToCursorAction() {
|
|
||||||
super(DeleteToCursor);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Invoked when an action occurs.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionEvent e) {
|
|
||||||
ExTextField target = (ExTextField)getTextComponent(e);
|
|
||||||
target.saveLastEntry();
|
|
||||||
|
|
||||||
Document doc = target.getDocument();
|
|
||||||
Caret caret = target.getCaret();
|
|
||||||
try {
|
|
||||||
doc.remove(0, caret.getDot());
|
|
||||||
}
|
|
||||||
catch (BadLocationException ex) {
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class ToggleInsertReplaceAction extends TextAction {
|
|
||||||
ToggleInsertReplaceAction() {
|
|
||||||
super(ToggleInsertReplace);
|
|
||||||
|
|
||||||
logger.debug("ToggleInsertReplaceAction()");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Invoked when an action occurs.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionEvent e) {
|
|
||||||
logger.debug("actionPerformed");
|
|
||||||
ExTextField target = (ExTextField)getTextComponent(e);
|
|
||||||
target.toggleInsertReplace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private abstract static class StartDigraphLiteralActionBase extends TextAction implements MultiStepAction {
|
|
||||||
private @Nullable DigraphSequence digraphSequence;
|
|
||||||
|
|
||||||
public StartDigraphLiteralActionBase(String name) {
|
|
||||||
super(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionEvent e) {
|
|
||||||
final ExTextField target = (ExTextField)getTextComponent(e);
|
|
||||||
final KeyStroke key = convert(e);
|
|
||||||
if (key != null && digraphSequence != null) {
|
|
||||||
DigraphResult res = digraphSequence.processKey(key, target.getEditor());
|
|
||||||
switch (res.getResult()) {
|
|
||||||
case DigraphResult.RES_HANDLED:
|
|
||||||
target.setCurrentActionPromptCharacter(res.getPromptCharacter());
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DigraphResult.RES_BAD:
|
|
||||||
target.clearCurrentAction();
|
|
||||||
// Eat the character, unless it's <C-C>, in which case, forward on and cancel entry. Note that at some point
|
|
||||||
// we should support input of control characters
|
|
||||||
if ((key.getModifiers() & KeyEvent.CTRL_DOWN_MASK) != 0 && key.getKeyCode() == KeyEvent.VK_C) {
|
|
||||||
target.handleKey(key);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DigraphResult.RES_DONE:
|
|
||||||
final KeyStroke digraph = res.getStroke();
|
|
||||||
digraphSequence = null;
|
|
||||||
target.clearCurrentAction();
|
|
||||||
if (digraph != null) {
|
|
||||||
target.handleKey(digraph);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (key != null) {
|
|
||||||
digraphSequence = new DigraphSequence();
|
|
||||||
DigraphResult res = start(digraphSequence);
|
|
||||||
target.setCurrentAction(this, res.getPromptCharacter());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract DigraphResult start(@NotNull DigraphSequence digraphSequence);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reset() {
|
|
||||||
digraphSequence = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class StartDigraphAction extends StartDigraphLiteralActionBase {
|
|
||||||
StartDigraphAction() {
|
|
||||||
super(StartDigraph);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected DigraphResult start(@NotNull DigraphSequence digraphSequence) {
|
|
||||||
return digraphSequence.startDigraphSequence();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class StartLiteralAction extends StartDigraphLiteralActionBase {
|
|
||||||
StartLiteralAction() {
|
|
||||||
super(StartLiteral);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected DigraphResult start(@NotNull DigraphSequence digraphSequence) {
|
|
||||||
return digraphSequence.startLiteralSequence();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static ExEditorKit instance;
|
|
||||||
|
|
||||||
private static final Logger logger = Logger.getInstance(ExEditorKit.class.getName());
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user