mirror of
https://github.com/chylex/IntelliJ-IdeaVim.git
synced 2025-08-17 16:31:45 +02:00
Compare commits
71 Commits
0.60.2-EAP
...
0.61
Author | SHA1 | Date | |
---|---|---|---|
![]() |
3881b905be | ||
![]() |
073c62f868 | ||
![]() |
d8e0f26bea | ||
![]() |
04c24ab5d0 | ||
![]() |
bfb0ba1ab9 | ||
![]() |
fb7d48af1f | ||
![]() |
559989ce4b | ||
![]() |
81f59e3c18 | ||
![]() |
b6adf9f7a9 | ||
![]() |
b972a01cf0 | ||
![]() |
0296cae712 | ||
![]() |
c38b18e16b | ||
![]() |
8d65c3ed26 | ||
![]() |
995bb966ad | ||
![]() |
dbda1a76ca | ||
![]() |
ed6f990d9a | ||
![]() |
4f86d9cc77 | ||
![]() |
d55774abab | ||
![]() |
d5591ba08d | ||
![]() |
f67d483c4e | ||
![]() |
f26ddd4a27 | ||
![]() |
dbbea642bc | ||
![]() |
0539e39977 | ||
![]() |
65235d32a1 | ||
![]() |
ecfcdf5a8c | ||
![]() |
cf127ba7f9 | ||
![]() |
1fba77d925 | ||
![]() |
5752b116f6 | ||
![]() |
cdf7fd8ce6 | ||
![]() |
8fe07e7b20 | ||
![]() |
b800237606 | ||
![]() |
fed02e5b8a | ||
![]() |
2d4d3e9410 | ||
![]() |
880d4c6888 | ||
![]() |
6a3d606032 | ||
![]() |
612a86c4d9 | ||
![]() |
14abc25c01 | ||
![]() |
52673d1a02 | ||
![]() |
b7caee119e | ||
![]() |
a148446912 | ||
![]() |
1ee9075976 | ||
![]() |
b03627a110 | ||
![]() |
04ac0ab743 | ||
![]() |
e7aa985ad5 | ||
![]() |
4177f4e4f3 | ||
![]() |
c1e415b76a | ||
![]() |
8ae656dee3 | ||
![]() |
d48576f48a | ||
![]() |
c0c5075072 | ||
![]() |
59d106b8c4 | ||
![]() |
d96c313ecb | ||
![]() |
212c708150 | ||
![]() |
3739eb173e | ||
![]() |
0d3ecce8a2 | ||
![]() |
164d7a4200 | ||
![]() |
1258e602e6 | ||
![]() |
8a5ad713ea | ||
![]() |
12be65fa09 | ||
![]() |
0720431c91 | ||
![]() |
6f1ac1de97 | ||
![]() |
99d2d4b594 | ||
![]() |
2bf9b97e49 | ||
![]() |
c6600f3348 | ||
![]() |
e29ab54b0e | ||
![]() |
197565d4cb | ||
![]() |
3d570d2020 | ||
![]() |
fe364dc6dc | ||
![]() |
5d0e82781f | ||
![]() |
24f005a340 | ||
![]() |
1743c08091 | ||
![]() |
81b095c899 |
@@ -1,23 +1,18 @@
|
|||||||
<?xml version="1.0" ?>
|
<?xml version="1.0" ?>
|
||||||
<SmellBaseline>
|
<SmellBaseline>
|
||||||
<ManuallySuppressedIssues></ManuallySuppressedIssues>
|
<ManuallySuppressedIssues>
|
||||||
<CurrentIssues>
|
|
||||||
<ID>ComplexMethod:CmdHandler.kt$CmdHandler$private fun addAlias(cmd: ExCommand, editor: Editor?): Boolean</ID>
|
<ID>ComplexMethod:CmdHandler.kt$CmdHandler$private fun addAlias(cmd: ExCommand, editor: Editor?): Boolean</ID>
|
||||||
<ID>ComplexMethod:CommandHandler.kt$CommandHandler$ @Throws(ExException::class) fun process(editor: Editor, context: DataContext, cmd: ExCommand, count: Int): Boolean</ID>
|
|
||||||
<ID>ComplexMethod:CommandState.kt$CommandState$ fun toVimNotation(): String</ID>
|
<ID>ComplexMethod:CommandState.kt$CommandState$ fun toVimNotation(): String</ID>
|
||||||
<ID>ComplexMethod:CommandState.kt$CommandState$private fun getStatusString(pos: Int): String</ID>
|
</ManuallySuppressedIssues>
|
||||||
|
<CurrentIssues>
|
||||||
<ID>ComplexMethod:HistoryHandler.kt$HistoryHandler$override fun execute(editor: Editor, context: DataContext, cmd: ExCommand): Boolean</ID>
|
<ID>ComplexMethod:HistoryHandler.kt$HistoryHandler$override fun execute(editor: Editor, context: DataContext, cmd: ExCommand): Boolean</ID>
|
||||||
<ID>ComplexMethod:OptionsManager.kt$OptionsManager$ fun parseOptionLine(editor: Editor?, args: String, failOnBad: Boolean): Boolean</ID>
|
<ID>ComplexMethod:OptionsManager.kt$OptionsManager$ fun parseOptionLine(editor: Editor?, args: String, failOnBad: Boolean): Boolean</ID>
|
||||||
<ID>ComplexMethod:OptionsManager.kt$OptionsManager$ private fun showOptions(editor: Editor?, opts: Collection<Option<*>>, showIntro: Boolean)</ID>
|
|
||||||
<ID>ComplexMethod:PutGroup.kt$PutGroup$private fun moveCaretToEndPosition( editor: Editor, caret: Caret, startOffset: Int, endOffset: Int, typeInRegister: SelectionType, modeInEditor: CommandState.SubMode, caretAfterInsertedText: Boolean )</ID>
|
|
||||||
<ID>ComplexMethod:PutGroup.kt$PutGroup$private fun prepareDocumentAndGetStartOffsets(editor: Editor, caret: Caret, typeInRegister: SelectionType, data: PutData, additionalData: Map<String, Any>): List<Int></ID>
|
<ID>ComplexMethod:PutGroup.kt$PutGroup$private fun prepareDocumentAndGetStartOffsets(editor: Editor, caret: Caret, typeInRegister: SelectionType, data: PutData, additionalData: Map<String, Any>): List<Int></ID>
|
||||||
<ID>ComplexMethod:SearchHelperKt.kt$// bounds are considered inside corresponding quotes fun checkInString(chars: CharSequence, currentPos: Int, str: Boolean): Boolean</ID>
|
<ID>ComplexMethod:SearchHelperKt.kt$// bounds are considered inside corresponding quotes fun checkInString(chars: CharSequence, currentPos: Int, str: Boolean): Boolean</ID>
|
||||||
<ID>ComplexMethod:TabCloseHandler.kt$TabCloseHandler$ private fun getTabIndexToClose(arg: String, current: Int, last: Int): Int?</ID>
|
<ID>ComplexMethod:TabCloseHandler.kt$TabCloseHandler$ private fun getTabIndexToClose(arg: String, current: Int, last: Int): Int?</ID>
|
||||||
<ID>ComplexMethod:VimExchangeExtension.kt$VimExchangeExtension.Operator$private fun compareExchanges(x: Exchange, y: Exchange): ExchangeCompareResult</ID>
|
<ID>ComplexMethod:VimExchangeExtension.kt$VimExchangeExtension.Operator$private fun compareExchanges(x: Exchange, y: Exchange): ExchangeCompareResult</ID>
|
||||||
<ID>ComplexMethod:VimExtensionFacade.kt$VimExtensionFacade$ @JvmStatic fun inputString(editor: Editor, prompt: String, finishOn: Char?): String</ID>
|
|
||||||
<ID>ComplexMethod:VimMultipleCursorsExtension.kt$VimMultipleCursorsExtension.NextOccurrenceHandler$override fun executeInWriteAction(editor: Editor, context: DataContext)</ID>
|
<ID>ComplexMethod:VimMultipleCursorsExtension.kt$VimMultipleCursorsExtension.NextOccurrenceHandler$override fun executeInWriteAction(editor: Editor, context: DataContext)</ID>
|
||||||
<ID>ComplexMethod:VimShortcutKeyAction.kt$VimShortcutKeyAction$private fun isEnabled(e: AnActionEvent): Boolean</ID>
|
<ID>ComplexMethod:VimShortcutKeyAction.kt$VimShortcutKeyAction$private fun isEnabled(e: AnActionEvent): Boolean</ID>
|
||||||
<ID>ComplexMethod:VisualGroup.kt$private fun setVisualSelection(selectionStart: Int, selectionEnd: Int, caret: Caret)</ID>
|
|
||||||
<ID>LongMethod:CmdHandler.kt$CmdHandler$private fun addAlias(cmd: ExCommand, editor: Editor?): Boolean</ID>
|
<ID>LongMethod:CmdHandler.kt$CmdHandler$private fun addAlias(cmd: ExCommand, editor: Editor?): Boolean</ID>
|
||||||
<ID>LongMethod:HistoryHandler.kt$HistoryHandler$override fun execute(editor: Editor, context: DataContext, cmd: ExCommand): Boolean</ID>
|
<ID>LongMethod:HistoryHandler.kt$HistoryHandler$override fun execute(editor: Editor, context: DataContext, cmd: ExCommand): Boolean</ID>
|
||||||
<ID>LongMethod:OptionsManager.kt$OptionsManager$ fun parseOptionLine(editor: Editor?, args: String, failOnBad: Boolean): Boolean</ID>
|
<ID>LongMethod:OptionsManager.kt$OptionsManager$ fun parseOptionLine(editor: Editor?, args: String, failOnBad: Boolean): Boolean</ID>
|
||||||
@@ -140,7 +135,7 @@
|
|||||||
<ID>ReturnCount:VisualMotionGroup.kt$VisualMotionGroup$private fun seemsLikeBlockMode(editor: Editor): Boolean</ID>
|
<ID>ReturnCount:VisualMotionGroup.kt$VisualMotionGroup$private fun seemsLikeBlockMode(editor: Editor): Boolean</ID>
|
||||||
<ID>ReturnCount:VisualOperatorActionHandler.kt$VisualOperatorActionHandler$final override fun baseExecute(editor: Editor, caret: Caret, context: DataContext, cmd: Command): Boolean</ID>
|
<ID>ReturnCount:VisualOperatorActionHandler.kt$VisualOperatorActionHandler$final override fun baseExecute(editor: Editor, caret: Caret, context: DataContext, cmd: Command): Boolean</ID>
|
||||||
<ID>ReturnCount:YankGroup.kt$YankGroup$ fun yankMotion(editor: Editor, context: DataContext, count: Int, rawCount: Int, argument: Argument): Boolean</ID>
|
<ID>ReturnCount:YankGroup.kt$YankGroup$ fun yankMotion(editor: Editor, context: DataContext, count: Int, rawCount: Int, argument: Argument): Boolean</ID>
|
||||||
<ID>ThrowsCount:CommandHandler.kt$CommandHandler$ @Throws(ExException::class) fun process(editor: Editor, context: DataContext, cmd: ExCommand, count: Int): Boolean</ID>
|
<ID>ThrowsCount:CommandHandler.kt$CommandHandler$private fun checkArgs(cmd: ExCommand)</ID>
|
||||||
<ID>TooManyFunctions:CommandBuilder.kt$CommandBuilder</ID>
|
<ID>TooManyFunctions:CommandBuilder.kt$CommandBuilder</ID>
|
||||||
<ID>TooManyFunctions:CommandState.kt$CommandState</ID>
|
<ID>TooManyFunctions:CommandState.kt$CommandState</ID>
|
||||||
<ID>TooManyFunctions:PutGroup.kt$PutGroup</ID>
|
<ID>TooManyFunctions:PutGroup.kt$PutGroup</ID>
|
@@ -11,6 +11,8 @@ complexity:
|
|||||||
threshold: 6
|
threshold: 6
|
||||||
ComplexCondition:
|
ComplexCondition:
|
||||||
threshold: 6
|
threshold: 6
|
||||||
|
ComplexMethod:
|
||||||
|
threshold: 20
|
||||||
exceptions:
|
exceptions:
|
||||||
TooGenericExceptionCaught:
|
TooGenericExceptionCaught:
|
||||||
active: false
|
active: false
|
||||||
@@ -25,3 +27,5 @@ style:
|
|||||||
active: false
|
active: false
|
||||||
MaxLineLength:
|
MaxLineLength:
|
||||||
maxLineLength: 160
|
maxLineLength: 160
|
||||||
|
ReturnCount:
|
||||||
|
max: 5
|
1
.gitignore
vendored
1
.gitignore
vendored
@@ -5,6 +5,7 @@
|
|||||||
!/.idea/scopes
|
!/.idea/scopes
|
||||||
!/.idea/copyright
|
!/.idea/copyright
|
||||||
!/.idea/icon.png
|
!/.idea/icon.png
|
||||||
|
!/.idea/inspectionProfiles
|
||||||
|
|
||||||
/build/
|
/build/
|
||||||
/out/
|
/out/
|
||||||
|
9
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
9
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<profile version="1.0">
|
||||||
|
<option name="myName" value="Project Default" />
|
||||||
|
<inspection_tool class="MissortedModifiers" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<option name="m_requireAnnotationsFirst" value="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="StaticMethodOnlyUsedInOneClass" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
|
</profile>
|
||||||
|
</component>
|
23
.idea/inspectionProfiles/Qodana.xml
generated
Normal file
23
.idea/inspectionProfiles/Qodana.xml
generated
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<profile version="1.0">
|
||||||
|
<description>Inspections profile for Qodana</description>
|
||||||
|
<option name="myName" value="Qodana" />
|
||||||
|
<inspection_tool class="CanBeFinal" enabled="false" level="WARNING" enabled_by_default="false">
|
||||||
|
<option name="REPORT_CLASSES" value="false" />
|
||||||
|
<option name="REPORT_METHODS" value="false" />
|
||||||
|
<option name="REPORT_FIELDS" value="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="GrUnresolvedAccess" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
|
||||||
|
<inspection_tool class="MissortedModifiers" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<option name="m_requireAnnotationsFirst" value="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="SameReturnValue" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
|
<inspection_tool class="SpellCheckingInspection" enabled="false" level="TYPO" enabled_by_default="false">
|
||||||
|
<option name="processCode" value="true" />
|
||||||
|
<option name="processLiterals" value="true" />
|
||||||
|
<option name="processComments" value="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="StaticMethodOnlyUsedInOneClass" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
|
<inspection_tool class="SuperTearDownInFinally" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
|
</profile>
|
||||||
|
</component>
|
24
.run/IdeaVim full verification.run.xml
Normal file
24
.run/IdeaVim full verification.run.xml
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<component name="ProjectRunConfigurationManager">
|
||||||
|
<configuration default="false" name="IdeaVim full verification" type="GradleRunConfiguration" factoryName="Gradle">
|
||||||
|
<ExternalSystemSettings>
|
||||||
|
<option name="executionName" />
|
||||||
|
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||||
|
<option name="externalSystemIdString" value="GRADLE" />
|
||||||
|
<option name="scriptParameters" value="" />
|
||||||
|
<option name="taskDescriptions">
|
||||||
|
<list />
|
||||||
|
</option>
|
||||||
|
<option name="taskNames">
|
||||||
|
<list>
|
||||||
|
<option value="check" />
|
||||||
|
<option value="runPluginVerifier" />
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
<option name="vmOptions" value="" />
|
||||||
|
</ExternalSystemSettings>
|
||||||
|
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||||
|
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||||
|
<DebugAllEnabled>false</DebugAllEnabled>
|
||||||
|
<method v="2" />
|
||||||
|
</configuration>
|
||||||
|
</component>
|
23
.run/IdeaVim tests.run.xml
Normal file
23
.run/IdeaVim tests.run.xml
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
<component name="ProjectRunConfigurationManager">
|
||||||
|
<configuration default="false" name="IdeaVim tests" type="GradleRunConfiguration" factoryName="Gradle">
|
||||||
|
<ExternalSystemSettings>
|
||||||
|
<option name="executionName" />
|
||||||
|
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||||
|
<option name="externalSystemIdString" value="GRADLE" />
|
||||||
|
<option name="scriptParameters" value="" />
|
||||||
|
<option name="taskDescriptions">
|
||||||
|
<list />
|
||||||
|
</option>
|
||||||
|
<option name="taskNames">
|
||||||
|
<list>
|
||||||
|
<option value="test" />
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
<option name="vmOptions" value="" />
|
||||||
|
</ExternalSystemSettings>
|
||||||
|
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||||
|
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||||
|
<DebugAllEnabled>false</DebugAllEnabled>
|
||||||
|
<method v="2" />
|
||||||
|
</configuration>
|
||||||
|
</component>
|
23
.run/Run IJ with IdeaVim.run.xml
Normal file
23
.run/Run IJ with IdeaVim.run.xml
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
<component name="ProjectRunConfigurationManager">
|
||||||
|
<configuration default="false" name="Start IJ with IdeaVim" type="GradleRunConfiguration" factoryName="Gradle">
|
||||||
|
<ExternalSystemSettings>
|
||||||
|
<option name="executionName" />
|
||||||
|
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||||
|
<option name="externalSystemIdString" value="GRADLE" />
|
||||||
|
<option name="scriptParameters" value="" />
|
||||||
|
<option name="taskDescriptions">
|
||||||
|
<list />
|
||||||
|
</option>
|
||||||
|
<option name="taskNames">
|
||||||
|
<list>
|
||||||
|
<option value="runIde" />
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
<option name="vmOptions" value="" />
|
||||||
|
</ExternalSystemSettings>
|
||||||
|
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||||
|
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||||
|
<DebugAllEnabled>false</DebugAllEnabled>
|
||||||
|
<method v="2" />
|
||||||
|
</configuration>
|
||||||
|
</component>
|
136
.teamcity/_Self/Project.kt
vendored
136
.teamcity/_Self/Project.kt
vendored
@@ -1,70 +1,86 @@
|
|||||||
package _Self
|
package _Self
|
||||||
|
|
||||||
import _Self.buildTypes.*
|
import _Self.buildTypes.GitHubPullRequests
|
||||||
import _Self.vcsRoots.*
|
import _Self.buildTypes.Nvim
|
||||||
|
import _Self.buildTypes.PluginVerifier
|
||||||
|
import _Self.buildTypes.Release
|
||||||
|
import _Self.buildTypes.ReleaseEap
|
||||||
|
import _Self.buildTypes.TestsForIntelliJ20181
|
||||||
|
import _Self.buildTypes.TestsForIntelliJ20182
|
||||||
|
import _Self.buildTypes.TestsForIntelliJ20183
|
||||||
|
import _Self.buildTypes.TestsForIntelliJ20191
|
||||||
|
import _Self.buildTypes.TestsForIntelliJ20192
|
||||||
|
import _Self.buildTypes.TestsForIntelliJ20193
|
||||||
|
import _Self.buildTypes.TestsForIntelliJ20201
|
||||||
|
import _Self.buildTypes.TestsForIntelliJ20202
|
||||||
|
import _Self.buildTypes.TestsForIntelliJEAP
|
||||||
|
import _Self.vcsRoots.Branch_181
|
||||||
|
import _Self.vcsRoots.Branch_183
|
||||||
|
import _Self.vcsRoots.Branch_191_193
|
||||||
|
import _Self.vcsRoots.GitHubPullRequest
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.Project
|
import jetbrains.buildServer.configs.kotlin.v2019_2.Project
|
||||||
|
|
||||||
object Project : Project({
|
object Project : Project({
|
||||||
description = "Vim emulation plugin for the IntelliJ platform products"
|
description = "Vim emulation plugin for the IntelliJ platform products"
|
||||||
|
|
||||||
vcsRoot(Branch_183)
|
vcsRoot(Branch_183)
|
||||||
vcsRoot(Branch_181)
|
vcsRoot(Branch_181)
|
||||||
vcsRoot(GitHubPullRequest)
|
vcsRoot(GitHubPullRequest)
|
||||||
vcsRoot(Branch_191_193)
|
vcsRoot(Branch_191_193)
|
||||||
vcsRoot(Branch_Nvim)
|
|
||||||
|
|
||||||
buildType(GitHubPullRequests)
|
buildType(GitHubPullRequests)
|
||||||
buildType(Release)
|
buildType(Release)
|
||||||
buildType(TestsForIntelliJ20201)
|
buildType(TestsForIntelliJ20201)
|
||||||
buildType(TestsForIntelliJ20191)
|
buildType(TestsForIntelliJ20191)
|
||||||
buildType(TestsForIntelliJ20181)
|
buildType(TestsForIntelliJ20181)
|
||||||
buildType(TestsForIntelliJ20192)
|
buildType(TestsForIntelliJ20192)
|
||||||
buildType(TestsForIntelliJ20182)
|
buildType(TestsForIntelliJ20182)
|
||||||
buildType(TestsForIntelliJ20193)
|
buildType(TestsForIntelliJ20193)
|
||||||
buildType(TestsForIntelliJ20183)
|
buildType(TestsForIntelliJ20183)
|
||||||
// buildType(Nvim)
|
buildType(Nvim)
|
||||||
buildType(ReleaseEap)
|
buildType(ReleaseEap)
|
||||||
buildType(TestsForIntelliJ20202)
|
buildType(TestsForIntelliJ20202)
|
||||||
buildType(TestsForIntelliJEAP)
|
buildType(TestsForIntelliJEAP)
|
||||||
|
buildType(PluginVerifier)
|
||||||
|
|
||||||
features {
|
features {
|
||||||
feature {
|
feature {
|
||||||
id = "PROJECT_EXT_768"
|
id = "PROJECT_EXT_768"
|
||||||
type = "CloudImage"
|
type = "CloudImage"
|
||||||
param("use-spot-instances", "true")
|
param("use-spot-instances", "true")
|
||||||
param("user-tags", "project=idea-vim")
|
param("user-tags", "project=idea-vim")
|
||||||
param("agent_pool_id", "41")
|
param("agent_pool_id", "41")
|
||||||
param("image-instances-limit", "")
|
param("image-instances-limit", "")
|
||||||
param("subnet-id", "subnet-58839511")
|
param("subnet-id", "subnet-58839511")
|
||||||
param("ebs-optimized", "false")
|
param("ebs-optimized", "false")
|
||||||
param("instance-type", "c5d.large")
|
param("instance-type", "c5d.large")
|
||||||
param("amazon-id", "ami-0d1a6a32faa92923e")
|
param("amazon-id", "ami-0d1a6a32faa92923e")
|
||||||
param("spot-instance-price", "0.1")
|
param("spot-instance-price", "0.1")
|
||||||
param("source-id", "BuildAgentsIdeaVim")
|
param("source-id", "BuildAgentsIdeaVim")
|
||||||
param("image-name-prefix", "BuildAgentsIdeaVim")
|
param("image-name-prefix", "BuildAgentsIdeaVim")
|
||||||
param("key-pair-name", "teamcity-prod-pub")
|
param("key-pair-name", "teamcity-prod-pub")
|
||||||
param("security-group-ids", "sg-eda08696,sg-7332cf0f,")
|
param("security-group-ids", "sg-eda08696,sg-7332cf0f,")
|
||||||
param("profileId", "amazon-48")
|
param("profileId", "amazon-48")
|
||||||
}
|
|
||||||
feature {
|
|
||||||
id = "amazon-48"
|
|
||||||
type = "CloudProfile"
|
|
||||||
param("profileServerUrl", "")
|
|
||||||
param("secure:access-id", "credentialsJSON:dbcdb2a2-de5f-4bc9-9421-292b19e83947")
|
|
||||||
param("system.cloud.profile_id", "amazon-48")
|
|
||||||
param("total-work-time", "")
|
|
||||||
param("description", "")
|
|
||||||
param("cloud-code", "amazon")
|
|
||||||
param("enabled", "true")
|
|
||||||
param("max-running-instances", "10")
|
|
||||||
param("agentPushPreset", "")
|
|
||||||
param("profileId", "amazon-48")
|
|
||||||
param("name", "Cloud Agents")
|
|
||||||
param("next-hour", "")
|
|
||||||
param("secure:secret-key", "credentialsJSON:65a87fe7-0977-4af9-96f1-344f2b82d269")
|
|
||||||
param("region", "eu-west-1")
|
|
||||||
param("terminate-idle-time", "15")
|
|
||||||
param("not-checked", "")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
feature {
|
||||||
|
id = "amazon-48"
|
||||||
|
type = "CloudProfile"
|
||||||
|
param("profileServerUrl", "")
|
||||||
|
param("secure:access-id", "credentialsJSON:dbcdb2a2-de5f-4bc9-9421-292b19e83947")
|
||||||
|
param("system.cloud.profile_id", "amazon-48")
|
||||||
|
param("total-work-time", "")
|
||||||
|
param("description", "")
|
||||||
|
param("cloud-code", "amazon")
|
||||||
|
param("enabled", "true")
|
||||||
|
param("max-running-instances", "10")
|
||||||
|
param("agentPushPreset", "")
|
||||||
|
param("profileId", "amazon-48")
|
||||||
|
param("name", "Cloud Agents")
|
||||||
|
param("next-hour", "")
|
||||||
|
param("secure:secret-key", "credentialsJSON:65a87fe7-0977-4af9-96f1-344f2b82d269")
|
||||||
|
param("region", "eu-west-1")
|
||||||
|
param("terminate-idle-time", "15")
|
||||||
|
param("not-checked", "")
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
95
.teamcity/_Self/buildTypes/GitHubPullRequests.kt
vendored
95
.teamcity/_Self/buildTypes/GitHubPullRequests.kt
vendored
@@ -1,7 +1,8 @@
|
|||||||
package _Self.buildTypes
|
package _Self.buildTypes
|
||||||
|
|
||||||
import _Self.vcsRoots.GitHubPullRequest
|
import _Self.vcsRoots.GitHubPullRequest
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.*
|
import jetbrains.buildServer.configs.kotlin.v2019_2.BuildType
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.CheckoutMode
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.buildFeatures.PullRequests
|
import jetbrains.buildServer.configs.kotlin.v2019_2.buildFeatures.PullRequests
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.buildFeatures.commitStatusPublisher
|
import jetbrains.buildServer.configs.kotlin.v2019_2.buildFeatures.commitStatusPublisher
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.buildFeatures.pullRequests
|
import jetbrains.buildServer.configs.kotlin.v2019_2.buildFeatures.pullRequests
|
||||||
@@ -10,64 +11,64 @@ import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.VcsTrigger
|
|||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.vcs
|
import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.vcs
|
||||||
|
|
||||||
object GitHubPullRequests : BuildType({
|
object GitHubPullRequests : BuildType({
|
||||||
name = "GitHub Pull Requests"
|
name = "GitHub Pull Requests"
|
||||||
description = "Test GitHub pull requests"
|
description = "Test GitHub pull requests"
|
||||||
|
|
||||||
params {
|
params {
|
||||||
param("env.ORG_GRADLE_PROJECT_downloadIdeaSources", "false")
|
param("env.ORG_GRADLE_PROJECT_downloadIdeaSources", "false")
|
||||||
param("env.ORG_GRADLE_PROJECT_ideaVersion", "2020.1")
|
param("env.ORG_GRADLE_PROJECT_ideaVersion", "2020.1")
|
||||||
param("env.ORG_GRADLE_PROJECT_instrumentPluginCode", "false")
|
param("env.ORG_GRADLE_PROJECT_instrumentPluginCode", "false")
|
||||||
}
|
}
|
||||||
|
|
||||||
vcs {
|
vcs {
|
||||||
root(_Self.vcsRoots.GitHubPullRequest)
|
root(_Self.vcsRoots.GitHubPullRequest)
|
||||||
|
|
||||||
checkoutMode = CheckoutMode.ON_SERVER
|
checkoutMode = CheckoutMode.ON_SERVER
|
||||||
branchFilter = """
|
branchFilter = """
|
||||||
+:*
|
+:*
|
||||||
-:<default>
|
-:<default>
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
}
|
}
|
||||||
|
|
||||||
steps {
|
steps {
|
||||||
gradle {
|
gradle {
|
||||||
tasks = "clean test"
|
tasks = "clean test"
|
||||||
buildFile = ""
|
buildFile = ""
|
||||||
enableStacktrace = true
|
enableStacktrace = true
|
||||||
param("org.jfrog.artifactory.selectedDeployableServer.defaultModuleVersionConfiguration", "GLOBAL")
|
param("org.jfrog.artifactory.selectedDeployableServer.defaultModuleVersionConfiguration", "GLOBAL")
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
triggers {
|
triggers {
|
||||||
vcs {
|
vcs {
|
||||||
quietPeriodMode = VcsTrigger.QuietPeriodMode.USE_DEFAULT
|
quietPeriodMode = VcsTrigger.QuietPeriodMode.USE_DEFAULT
|
||||||
branchFilter = ""
|
branchFilter = ""
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
features {
|
features {
|
||||||
pullRequests {
|
pullRequests {
|
||||||
provider = github {
|
provider = github {
|
||||||
authType = token {
|
authType = token {
|
||||||
token = "credentialsJSON:43afd6e5-6ad5-4d12-a218-cf1547717a7f"
|
token = "credentialsJSON:43afd6e5-6ad5-4d12-a218-cf1547717a7f"
|
||||||
}
|
|
||||||
filterTargetBranch = "refs/heads/master"
|
|
||||||
filterAuthorRole = PullRequests.GitHubRoleFilter.EVERYBODY
|
|
||||||
}
|
|
||||||
}
|
|
||||||
commitStatusPublisher {
|
|
||||||
vcsRootExtId = "${GitHubPullRequest.id}"
|
|
||||||
publisher = github {
|
|
||||||
githubUrl = "https://api.github.com"
|
|
||||||
authType = personalToken {
|
|
||||||
token = "credentialsJSON:43afd6e5-6ad5-4d12-a218-cf1547717a7f"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
param("github_oauth_user", "AlexPl292")
|
|
||||||
}
|
}
|
||||||
|
filterTargetBranch = "refs/heads/master"
|
||||||
|
filterAuthorRole = PullRequests.GitHubRoleFilter.EVERYBODY
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
commitStatusPublisher {
|
||||||
|
vcsRootExtId = "${GitHubPullRequest.id}"
|
||||||
|
publisher = github {
|
||||||
|
githubUrl = "https://api.github.com"
|
||||||
|
authType = personalToken {
|
||||||
|
token = "credentialsJSON:43afd6e5-6ad5-4d12-a218-cf1547717a7f"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
param("github_oauth_user", "AlexPl292")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
requirements {
|
requirements {
|
||||||
noLessThanVer("teamcity.agent.jvm.version", "1.8")
|
noLessThanVer("teamcity.agent.jvm.version", "1.8")
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
72
.teamcity/_Self/buildTypes/Nvim.kt
vendored
72
.teamcity/_Self/buildTypes/Nvim.kt
vendored
@@ -2,49 +2,53 @@ package _Self.buildTypes
|
|||||||
|
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.BuildType
|
import jetbrains.buildServer.configs.kotlin.v2019_2.BuildType
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.CheckoutMode
|
import jetbrains.buildServer.configs.kotlin.v2019_2.CheckoutMode
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.DslContext
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.gradle
|
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.gradle
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.script
|
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.script
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.vcs
|
import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.vcs
|
||||||
|
|
||||||
object Nvim : BuildType({
|
object Nvim : BuildType({
|
||||||
name = "NVIM"
|
name = "Tests with nvim"
|
||||||
description = "branch EAP"
|
description = "Running tests with nvim integration"
|
||||||
|
|
||||||
params {
|
params {
|
||||||
param("env.ORG_GRADLE_PROJECT_downloadIdeaSources", "false")
|
param("env.ORG_GRADLE_PROJECT_downloadIdeaSources", "false")
|
||||||
param("env.ORG_GRADLE_PROJECT_ideaVersion", "LATEST-EAP-SNAPSHOT")
|
param("env.ORG_GRADLE_PROJECT_ideaVersion", "LATEST-EAP-SNAPSHOT")
|
||||||
param("env.ORG_GRADLE_PROJECT_instrumentPluginCode", "false")
|
param("env.ORG_GRADLE_PROJECT_instrumentPluginCode", "false")
|
||||||
|
param("env.ideavim.nvim.path", "./nvim-linux64/bin/nvim")
|
||||||
|
}
|
||||||
|
|
||||||
|
vcs {
|
||||||
|
root(DslContext.settingsRoot)
|
||||||
|
|
||||||
|
checkoutMode = CheckoutMode.ON_SERVER
|
||||||
|
}
|
||||||
|
|
||||||
|
steps {
|
||||||
|
script {
|
||||||
|
name = "Set up NeoVim"
|
||||||
|
scriptContent = """
|
||||||
|
wget https://github.com/neovim/neovim/releases/download/v0.4.4/nvim-linux64.tar.gz
|
||||||
|
tar xzf nvim-linux64.tar.gz
|
||||||
|
cd nvim-linux64/bin
|
||||||
|
chmod +x nvim
|
||||||
|
""".trimIndent()
|
||||||
}
|
}
|
||||||
|
gradle {
|
||||||
|
tasks = "clean testWithNeovim"
|
||||||
|
buildFile = ""
|
||||||
|
enableStacktrace = true
|
||||||
|
param("org.jfrog.artifactory.selectedDeployableServer.defaultModuleVersionConfiguration", "GLOBAL")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
triggers {
|
||||||
vcs {
|
vcs {
|
||||||
root(_Self.vcsRoots.Branch_Nvim)
|
branchFilter = ""
|
||||||
|
|
||||||
checkoutMode = CheckoutMode.ON_SERVER
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
steps {
|
requirements {
|
||||||
script {
|
noLessThanVer("teamcity.agent.jvm.version", "1.8")
|
||||||
scriptContent = "apt-get install neovim"
|
}
|
||||||
}
|
|
||||||
gradle {
|
|
||||||
tasks = "--version"
|
|
||||||
param("org.jfrog.artifactory.selectedDeployableServer.defaultModuleVersionConfiguration", "GLOBAL")
|
|
||||||
}
|
|
||||||
gradle {
|
|
||||||
tasks = "clean test"
|
|
||||||
buildFile = ""
|
|
||||||
enableStacktrace = true
|
|
||||||
param("org.jfrog.artifactory.selectedDeployableServer.defaultModuleVersionConfiguration", "GLOBAL")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
triggers {
|
|
||||||
vcs {
|
|
||||||
branchFilter = ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
requirements {
|
|
||||||
noLessThanVer("teamcity.agent.jvm.version", "1.8")
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
40
.teamcity/_Self/buildTypes/PluginVerifier.kt
vendored
Normal file
40
.teamcity/_Self/buildTypes/PluginVerifier.kt
vendored
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
package _Self.buildTypes
|
||||||
|
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.BuildType
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.CheckoutMode
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.DslContext
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.gradle
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.vcs
|
||||||
|
|
||||||
|
object PluginVerifier : BuildType({
|
||||||
|
name = "Plugin verification"
|
||||||
|
params {
|
||||||
|
param("env.ORG_GRADLE_PROJECT_downloadIdeaSources", "false")
|
||||||
|
param("env.ORG_GRADLE_PROJECT_instrumentPluginCode", "false")
|
||||||
|
}
|
||||||
|
|
||||||
|
vcs {
|
||||||
|
root(DslContext.settingsRoot)
|
||||||
|
|
||||||
|
checkoutMode = CheckoutMode.ON_SERVER
|
||||||
|
}
|
||||||
|
|
||||||
|
steps {
|
||||||
|
gradle {
|
||||||
|
tasks = "clean runPluginVerifier"
|
||||||
|
buildFile = ""
|
||||||
|
enableStacktrace = true
|
||||||
|
param("org.jfrog.artifactory.selectedDeployableServer.defaultModuleVersionConfiguration", "GLOBAL")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
triggers {
|
||||||
|
vcs {
|
||||||
|
branchFilter = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
requirements {
|
||||||
|
noLessThanVer("teamcity.agent.jvm.version", "1.8")
|
||||||
|
}
|
||||||
|
})
|
60
.teamcity/_Self/buildTypes/Release.kt
vendored
60
.teamcity/_Self/buildTypes/Release.kt
vendored
@@ -1,36 +1,42 @@
|
|||||||
package _Self.buildTypes
|
package _Self.buildTypes
|
||||||
|
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.*
|
import jetbrains.buildServer.configs.kotlin.v2019_2.BuildType
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.CheckoutMode
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.DslContext
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.gradle
|
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.gradle
|
||||||
|
|
||||||
object Release : BuildType({
|
object Release : BuildType({
|
||||||
name = "Publish Release"
|
name = "Publish Release"
|
||||||
description = "Build and publish IdeaVim plugin"
|
description = "Build and publish IdeaVim plugin"
|
||||||
|
|
||||||
artifactRules = "build/distributions/*"
|
artifactRules = "build/distributions/*"
|
||||||
buildNumberPattern = "0.60"
|
buildNumberPattern = "0.61"
|
||||||
|
|
||||||
params {
|
params {
|
||||||
param("env.ORG_GRADLE_PROJECT_ideaVersion", "2020.2")
|
param("env.ORG_GRADLE_PROJECT_ideaVersion", "2020.2")
|
||||||
password("env.ORG_GRADLE_PROJECT_publishToken", "credentialsJSON:ec1dc748-e289-47e1-88b6-f193d7999bf4", label = "Password")
|
password(
|
||||||
param("env.ORG_GRADLE_PROJECT_publishUsername", "vlan")
|
"env.ORG_GRADLE_PROJECT_publishToken",
|
||||||
param("env.ORG_GRADLE_PROJECT_version", "%build.number%")
|
"credentialsJSON:ec1dc748-e289-47e1-88b6-f193d7999bf4",
|
||||||
param("env.ORG_GRADLE_PROJECT_downloadIdeaSources", "false")
|
label = "Password"
|
||||||
param("env.ORG_GRADLE_PROJECT_publishChannels", "default,eap")
|
)
|
||||||
}
|
param("env.ORG_GRADLE_PROJECT_publishUsername", "vlan")
|
||||||
|
param("env.ORG_GRADLE_PROJECT_version", "%build.number%")
|
||||||
vcs {
|
param("env.ORG_GRADLE_PROJECT_downloadIdeaSources", "false")
|
||||||
root(DslContext.settingsRoot)
|
param("env.ORG_GRADLE_PROJECT_publishChannels", "default,eap")
|
||||||
|
}
|
||||||
checkoutMode = CheckoutMode.ON_SERVER
|
|
||||||
}
|
vcs {
|
||||||
|
root(DslContext.settingsRoot)
|
||||||
steps {
|
|
||||||
gradle {
|
checkoutMode = CheckoutMode.ON_SERVER
|
||||||
tasks = "clean publishPlugin"
|
}
|
||||||
buildFile = ""
|
|
||||||
enableStacktrace = true
|
steps {
|
||||||
param("org.jfrog.artifactory.selectedDeployableServer.defaultModuleVersionConfiguration", "GLOBAL")
|
gradle {
|
||||||
}
|
tasks = "clean publishPlugin"
|
||||||
|
buildFile = ""
|
||||||
|
enableStacktrace = true
|
||||||
|
param("org.jfrog.artifactory.selectedDeployableServer.defaultModuleVersionConfiguration", "GLOBAL")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
104
.teamcity/_Self/buildTypes/ReleaseEap.kt
vendored
104
.teamcity/_Self/buildTypes/ReleaseEap.kt
vendored
@@ -9,59 +9,67 @@ import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.ScheduleTrigger
|
|||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.schedule
|
import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.schedule
|
||||||
|
|
||||||
object ReleaseEap : BuildType({
|
object ReleaseEap : BuildType({
|
||||||
name = "Publish EAP Build"
|
name = "Publish EAP Build"
|
||||||
description = "Build and publish EAP of IdeaVim plugin"
|
description = "Build and publish EAP of IdeaVim plugin"
|
||||||
|
|
||||||
artifactRules = "build/distributions/*"
|
artifactRules = "build/distributions/*"
|
||||||
buildNumberPattern = "0.60.%build.counter%"
|
buildNumberPattern = "0.61.%build.counter%"
|
||||||
|
|
||||||
params {
|
params {
|
||||||
param("env.ORG_GRADLE_PROJECT_ideaVersion", "2020.2")
|
param("env.ORG_GRADLE_PROJECT_ideaVersion", "2020.2")
|
||||||
password("env.ORG_GRADLE_PROJECT_publishToken", "credentialsJSON:ec1dc748-e289-47e1-88b6-f193d7999bf4", label = "Token")
|
password(
|
||||||
param("env.ORG_GRADLE_PROJECT_publishUsername", "vlan")
|
"env.ORG_GRADLE_PROJECT_publishToken",
|
||||||
param("env.ORG_GRADLE_PROJECT_version", "%build.number%")
|
"credentialsJSON:ec1dc748-e289-47e1-88b6-f193d7999bf4",
|
||||||
param("env.ORG_GRADLE_PROJECT_downloadIdeaSources", "false")
|
label = "Token"
|
||||||
param("env.ORG_GRADLE_PROJECT_publishChannels", "eap")
|
)
|
||||||
password("env.ORG_GRADLE_PROJECT_slackUrl", "credentialsJSON:a8ab8150-e6f8-4eaf-987c-bcd65eac50b5", label = "Slack Token")
|
param("env.ORG_GRADLE_PROJECT_publishUsername", "vlan")
|
||||||
|
param("env.ORG_GRADLE_PROJECT_version", "%build.number%")
|
||||||
|
param("env.ORG_GRADLE_PROJECT_downloadIdeaSources", "false")
|
||||||
|
param("env.ORG_GRADLE_PROJECT_publishChannels", "eap")
|
||||||
|
password(
|
||||||
|
"env.ORG_GRADLE_PROJECT_slackUrl",
|
||||||
|
"credentialsJSON:a8ab8150-e6f8-4eaf-987c-bcd65eac50b5",
|
||||||
|
label = "Slack Token"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
vcs {
|
||||||
|
root(DslContext.settingsRoot)
|
||||||
|
|
||||||
|
checkoutMode = CheckoutMode.ON_SERVER
|
||||||
|
}
|
||||||
|
|
||||||
|
steps {
|
||||||
|
gradle {
|
||||||
|
tasks = "clean publishPlugin slackEapNotification"
|
||||||
|
buildFile = ""
|
||||||
|
enableStacktrace = true
|
||||||
|
param("org.jfrog.artifactory.selectedDeployableServer.defaultModuleVersionConfiguration", "GLOBAL")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
vcs {
|
triggers {
|
||||||
root(DslContext.settingsRoot)
|
schedule {
|
||||||
|
enabled = false
|
||||||
checkoutMode = CheckoutMode.ON_SERVER
|
schedulingPolicy = daily {
|
||||||
|
hour = 22
|
||||||
|
}
|
||||||
|
branchFilter = ""
|
||||||
|
triggerBuild = onWatchedBuildChange {
|
||||||
|
buildType = "IdeaVim_TestsForIntelliJBranch146"
|
||||||
|
watchedBuildRule = ScheduleTrigger.WatchedBuildRule.LAST_SUCCESSFUL
|
||||||
|
watchedBuildBranchFilter = "<default>"
|
||||||
|
promoteWatchedBuild = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
steps {
|
features {
|
||||||
gradle {
|
vcsLabeling {
|
||||||
tasks = "clean publishPlugin slackEapNotification"
|
vcsRootId = "${DslContext.settingsRoot.id}"
|
||||||
buildFile = ""
|
labelingPattern = "%system.build.number%-EAP"
|
||||||
enableStacktrace = true
|
successfulOnly = true
|
||||||
param("org.jfrog.artifactory.selectedDeployableServer.defaultModuleVersionConfiguration", "GLOBAL")
|
branchFilter = ""
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
triggers {
|
|
||||||
schedule {
|
|
||||||
enabled = false
|
|
||||||
schedulingPolicy = daily {
|
|
||||||
hour = 22
|
|
||||||
}
|
|
||||||
branchFilter = ""
|
|
||||||
triggerBuild = onWatchedBuildChange {
|
|
||||||
buildType = "IdeaVim_TestsForIntelliJBranch146"
|
|
||||||
watchedBuildRule = ScheduleTrigger.WatchedBuildRule.LAST_SUCCESSFUL
|
|
||||||
watchedBuildBranchFilter = "<default>"
|
|
||||||
promoteWatchedBuild = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
features {
|
|
||||||
vcsLabeling {
|
|
||||||
vcsRootId = "${DslContext.settingsRoot.id}"
|
|
||||||
labelingPattern = "%system.build.number%-EAP"
|
|
||||||
successfulOnly = true
|
|
||||||
branchFilter = ""
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
@@ -1,42 +0,0 @@
|
|||||||
package _Self.buildTypes
|
|
||||||
|
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.*
|
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.gradle
|
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.vcs
|
|
||||||
|
|
||||||
object TestsForIntelliJ20181 : BuildType({
|
|
||||||
name = "Tests for IntelliJ 2018.1"
|
|
||||||
description = "branch 181"
|
|
||||||
|
|
||||||
params {
|
|
||||||
param("env.ORG_GRADLE_PROJECT_downloadIdeaSources", "false")
|
|
||||||
param("env.ORG_GRADLE_PROJECT_ideaVersion", "IC-2018.1")
|
|
||||||
param("env.ORG_GRADLE_PROJECT_instrumentPluginCode", "false")
|
|
||||||
param("env.ORG_GRADLE_PROJECT_javaVersion", "1.8")
|
|
||||||
}
|
|
||||||
|
|
||||||
vcs {
|
|
||||||
root(_Self.vcsRoots.Branch_181)
|
|
||||||
|
|
||||||
checkoutMode = CheckoutMode.ON_SERVER
|
|
||||||
}
|
|
||||||
|
|
||||||
steps {
|
|
||||||
gradle {
|
|
||||||
tasks = "clean test"
|
|
||||||
buildFile = ""
|
|
||||||
enableStacktrace = true
|
|
||||||
param("org.jfrog.artifactory.selectedDeployableServer.defaultModuleVersionConfiguration", "GLOBAL")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
triggers {
|
|
||||||
vcs {
|
|
||||||
branchFilter = ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
requirements {
|
|
||||||
noLessThanVer("teamcity.agent.jvm.version", "1.8")
|
|
||||||
}
|
|
||||||
})
|
|
@@ -1,42 +0,0 @@
|
|||||||
package _Self.buildTypes
|
|
||||||
|
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.*
|
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.gradle
|
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.vcs
|
|
||||||
|
|
||||||
object TestsForIntelliJ20182 : BuildType({
|
|
||||||
name = "Tests for IntelliJ 2018.2"
|
|
||||||
description = "branch 182"
|
|
||||||
|
|
||||||
params {
|
|
||||||
param("env.ORG_GRADLE_PROJECT_downloadIdeaSources", "false")
|
|
||||||
param("env.ORG_GRADLE_PROJECT_ideaVersion", "IC-2018.2")
|
|
||||||
param("env.ORG_GRADLE_PROJECT_instrumentPluginCode", "false")
|
|
||||||
param("env.ORG_GRADLE_PROJECT_javaVersion", "1.8")
|
|
||||||
}
|
|
||||||
|
|
||||||
vcs {
|
|
||||||
root(_Self.vcsRoots.Branch_181)
|
|
||||||
|
|
||||||
checkoutMode = CheckoutMode.ON_SERVER
|
|
||||||
}
|
|
||||||
|
|
||||||
steps {
|
|
||||||
gradle {
|
|
||||||
tasks = "clean test"
|
|
||||||
buildFile = ""
|
|
||||||
enableStacktrace = true
|
|
||||||
param("org.jfrog.artifactory.selectedDeployableServer.defaultModuleVersionConfiguration", "GLOBAL")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
triggers {
|
|
||||||
vcs {
|
|
||||||
branchFilter = ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
requirements {
|
|
||||||
noLessThanVer("teamcity.agent.jvm.version", "1.8")
|
|
||||||
}
|
|
||||||
})
|
|
@@ -1,43 +1,44 @@
|
|||||||
package _Self.buildTypes
|
package _Self.buildTypes
|
||||||
|
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.*
|
import jetbrains.buildServer.configs.kotlin.v2019_2.BuildType
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.CheckoutMode
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.gradle
|
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.gradle
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.vcs
|
import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.vcs
|
||||||
|
|
||||||
object TestsForIntelliJ20183 : BuildType({
|
object TestsForIntelliJ20183 : BuildType({
|
||||||
name = "Tests for IntelliJ 2018.3"
|
name = "Tests for IntelliJ 2018.3"
|
||||||
description = "branch 183"
|
description = "branch 183"
|
||||||
|
|
||||||
params {
|
params {
|
||||||
param("env.ORG_GRADLE_PROJECT_downloadIdeaSources", "false")
|
param("env.ORG_GRADLE_PROJECT_downloadIdeaSources", "false")
|
||||||
param("env.ORG_GRADLE_PROJECT_legacyNoJavaPlugin", "true")
|
param("env.ORG_GRADLE_PROJECT_legacyNoJavaPlugin", "true")
|
||||||
param("env.ORG_GRADLE_PROJECT_ideaVersion", "IC-2018.3")
|
param("env.ORG_GRADLE_PROJECT_ideaVersion", "IC-2018.3")
|
||||||
param("env.ORG_GRADLE_PROJECT_instrumentPluginCode", "false")
|
param("env.ORG_GRADLE_PROJECT_instrumentPluginCode", "false")
|
||||||
param("env.ORG_GRADLE_PROJECT_javaVersion", "1.8")
|
param("env.ORG_GRADLE_PROJECT_javaVersion", "1.8")
|
||||||
|
}
|
||||||
|
|
||||||
|
vcs {
|
||||||
|
root(_Self.vcsRoots.Branch_183)
|
||||||
|
|
||||||
|
checkoutMode = CheckoutMode.ON_SERVER
|
||||||
|
}
|
||||||
|
|
||||||
|
steps {
|
||||||
|
gradle {
|
||||||
|
tasks = "clean test"
|
||||||
|
buildFile = ""
|
||||||
|
enableStacktrace = true
|
||||||
|
param("org.jfrog.artifactory.selectedDeployableServer.defaultModuleVersionConfiguration", "GLOBAL")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
triggers {
|
||||||
vcs {
|
vcs {
|
||||||
root(_Self.vcsRoots.Branch_183)
|
branchFilter = ""
|
||||||
|
|
||||||
checkoutMode = CheckoutMode.ON_SERVER
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
steps {
|
requirements {
|
||||||
gradle {
|
noLessThanVer("teamcity.agent.jvm.version", "1.8")
|
||||||
tasks = "clean test"
|
}
|
||||||
buildFile = ""
|
|
||||||
enableStacktrace = true
|
|
||||||
param("org.jfrog.artifactory.selectedDeployableServer.defaultModuleVersionConfiguration", "GLOBAL")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
triggers {
|
|
||||||
vcs {
|
|
||||||
branchFilter = ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
requirements {
|
|
||||||
noLessThanVer("teamcity.agent.jvm.version", "1.8")
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
@@ -1,43 +0,0 @@
|
|||||||
package _Self.buildTypes
|
|
||||||
|
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.*
|
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.gradle
|
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.vcs
|
|
||||||
|
|
||||||
object TestsForIntelliJ20191 : BuildType({
|
|
||||||
name = "Tests for IntelliJ 2019.1"
|
|
||||||
description = "branch 191"
|
|
||||||
|
|
||||||
params {
|
|
||||||
param("env.ORG_GRADLE_PROJECT_downloadIdeaSources", "false")
|
|
||||||
param("env.ORG_GRADLE_PROJECT_legacyNoJavaPlugin", "true")
|
|
||||||
param("env.ORG_GRADLE_PROJECT_ideaVersion", "IC-2019.1")
|
|
||||||
param("env.ORG_GRADLE_PROJECT_instrumentPluginCode", "false")
|
|
||||||
param("env.ORG_GRADLE_PROJECT_javaVersion", "1.8")
|
|
||||||
}
|
|
||||||
|
|
||||||
vcs {
|
|
||||||
root(_Self.vcsRoots.Branch_191_193)
|
|
||||||
|
|
||||||
checkoutMode = CheckoutMode.ON_SERVER
|
|
||||||
}
|
|
||||||
|
|
||||||
steps {
|
|
||||||
gradle {
|
|
||||||
tasks = "clean test"
|
|
||||||
buildFile = ""
|
|
||||||
enableStacktrace = true
|
|
||||||
param("org.jfrog.artifactory.selectedDeployableServer.defaultModuleVersionConfiguration", "GLOBAL")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
triggers {
|
|
||||||
vcs {
|
|
||||||
branchFilter = ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
requirements {
|
|
||||||
noLessThanVer("teamcity.agent.jvm.version", "1.8")
|
|
||||||
}
|
|
||||||
})
|
|
@@ -1,43 +0,0 @@
|
|||||||
package _Self.buildTypes
|
|
||||||
|
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.*
|
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.gradle
|
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.vcs
|
|
||||||
|
|
||||||
object TestsForIntelliJ20192 : BuildType({
|
|
||||||
name = "Tests for IntelliJ 2019.2"
|
|
||||||
description = "branch 192"
|
|
||||||
|
|
||||||
params {
|
|
||||||
param("env.ORG_GRADLE_PROJECT_downloadIdeaSources", "false")
|
|
||||||
param("env.ORG_GRADLE_PROJECT_legacyNoJavaPlugin", "false")
|
|
||||||
param("env.ORG_GRADLE_PROJECT_ideaVersion", "IC-2019.2")
|
|
||||||
param("env.ORG_GRADLE_PROJECT_instrumentPluginCode", "false")
|
|
||||||
param("env.ORG_GRADLE_PROJECT_javaVersion", "1.8")
|
|
||||||
}
|
|
||||||
|
|
||||||
vcs {
|
|
||||||
root(_Self.vcsRoots.Branch_191_193)
|
|
||||||
|
|
||||||
checkoutMode = CheckoutMode.ON_SERVER
|
|
||||||
}
|
|
||||||
|
|
||||||
steps {
|
|
||||||
gradle {
|
|
||||||
tasks = "clean test"
|
|
||||||
buildFile = ""
|
|
||||||
enableStacktrace = true
|
|
||||||
param("org.jfrog.artifactory.selectedDeployableServer.defaultModuleVersionConfiguration", "GLOBAL")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
triggers {
|
|
||||||
vcs {
|
|
||||||
branchFilter = ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
requirements {
|
|
||||||
noLessThanVer("teamcity.agent.jvm.version", "1.8")
|
|
||||||
}
|
|
||||||
})
|
|
@@ -1,43 +0,0 @@
|
|||||||
package _Self.buildTypes
|
|
||||||
|
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.*
|
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.gradle
|
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.vcs
|
|
||||||
|
|
||||||
object TestsForIntelliJ20193 : BuildType({
|
|
||||||
name = "Tests for IntelliJ 2019.3"
|
|
||||||
description = "branch 193"
|
|
||||||
|
|
||||||
params {
|
|
||||||
param("env.ORG_GRADLE_PROJECT_downloadIdeaSources", "false")
|
|
||||||
param("env.ORG_GRADLE_PROJECT_legacyNoJavaPlugin", "false")
|
|
||||||
param("env.ORG_GRADLE_PROJECT_ideaVersion", "2019.3")
|
|
||||||
param("env.ORG_GRADLE_PROJECT_instrumentPluginCode", "false")
|
|
||||||
param("env.ORG_GRADLE_PROJECT_javaVersion", "1.8")
|
|
||||||
}
|
|
||||||
|
|
||||||
vcs {
|
|
||||||
root(_Self.vcsRoots.Branch_191_193)
|
|
||||||
|
|
||||||
checkoutMode = CheckoutMode.ON_SERVER
|
|
||||||
}
|
|
||||||
|
|
||||||
steps {
|
|
||||||
gradle {
|
|
||||||
tasks = "clean test"
|
|
||||||
buildFile = ""
|
|
||||||
enableStacktrace = true
|
|
||||||
param("org.jfrog.artifactory.selectedDeployableServer.defaultModuleVersionConfiguration", "GLOBAL")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
triggers {
|
|
||||||
vcs {
|
|
||||||
branchFilter = ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
requirements {
|
|
||||||
noLessThanVer("teamcity.agent.jvm.version", "1.8")
|
|
||||||
}
|
|
||||||
})
|
|
47
.teamcity/_Self/buildTypes/TestsForIntelliJ_181-182.kt
vendored
Normal file
47
.teamcity/_Self/buildTypes/TestsForIntelliJ_181-182.kt
vendored
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
@file:Suppress("ClassName")
|
||||||
|
|
||||||
|
package _Self.buildTypes
|
||||||
|
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.BuildType
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.CheckoutMode
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.gradle
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.vcs
|
||||||
|
|
||||||
|
sealed class TestsForIntelliJ_181_branch(private val version: String) : BuildType({
|
||||||
|
name = "Tests for IntelliJ $version"
|
||||||
|
|
||||||
|
params {
|
||||||
|
param("env.ORG_GRADLE_PROJECT_downloadIdeaSources", "false")
|
||||||
|
param("env.ORG_GRADLE_PROJECT_ideaVersion", "IC-$version")
|
||||||
|
param("env.ORG_GRADLE_PROJECT_instrumentPluginCode", "false")
|
||||||
|
param("env.ORG_GRADLE_PROJECT_javaVersion", "1.8")
|
||||||
|
}
|
||||||
|
|
||||||
|
vcs {
|
||||||
|
root(_Self.vcsRoots.Branch_181)
|
||||||
|
|
||||||
|
checkoutMode = CheckoutMode.ON_SERVER
|
||||||
|
}
|
||||||
|
|
||||||
|
steps {
|
||||||
|
gradle {
|
||||||
|
tasks = "clean test"
|
||||||
|
buildFile = ""
|
||||||
|
enableStacktrace = true
|
||||||
|
param("org.jfrog.artifactory.selectedDeployableServer.defaultModuleVersionConfiguration", "GLOBAL")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
triggers {
|
||||||
|
vcs {
|
||||||
|
branchFilter = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
requirements {
|
||||||
|
noLessThanVer("teamcity.agent.jvm.version", "1.8")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
object TestsForIntelliJ20181 : TestsForIntelliJ_181_branch("2018.1")
|
||||||
|
object TestsForIntelliJ20182 : TestsForIntelliJ_181_branch("2018.2")
|
49
.teamcity/_Self/buildTypes/TestsForIntelliJ_191-193.kt
vendored
Normal file
49
.teamcity/_Self/buildTypes/TestsForIntelliJ_191-193.kt
vendored
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
@file:Suppress("ClassName")
|
||||||
|
|
||||||
|
package _Self.buildTypes
|
||||||
|
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.BuildType
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.CheckoutMode
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.gradle
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.vcs
|
||||||
|
|
||||||
|
sealed class TestsForIntelliJ_191_193_branch(private val version: String) : BuildType({
|
||||||
|
name = "Tests for IntelliJ $version"
|
||||||
|
|
||||||
|
params {
|
||||||
|
param("env.ORG_GRADLE_PROJECT_downloadIdeaSources", "false")
|
||||||
|
param("env.ORG_GRADLE_PROJECT_legacyNoJavaPlugin", "true")
|
||||||
|
param("env.ORG_GRADLE_PROJECT_ideaVersion", "IC-$version")
|
||||||
|
param("env.ORG_GRADLE_PROJECT_instrumentPluginCode", "false")
|
||||||
|
param("env.ORG_GRADLE_PROJECT_javaVersion", "1.8")
|
||||||
|
}
|
||||||
|
|
||||||
|
vcs {
|
||||||
|
root(_Self.vcsRoots.Branch_191_193)
|
||||||
|
|
||||||
|
checkoutMode = CheckoutMode.ON_SERVER
|
||||||
|
}
|
||||||
|
|
||||||
|
steps {
|
||||||
|
gradle {
|
||||||
|
tasks = "clean test"
|
||||||
|
buildFile = ""
|
||||||
|
enableStacktrace = true
|
||||||
|
param("org.jfrog.artifactory.selectedDeployableServer.defaultModuleVersionConfiguration", "GLOBAL")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
triggers {
|
||||||
|
vcs {
|
||||||
|
branchFilter = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
requirements {
|
||||||
|
noLessThanVer("teamcity.agent.jvm.version", "1.8")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
object TestsForIntelliJ20191 : TestsForIntelliJ_191_193_branch("2019.1")
|
||||||
|
object TestsForIntelliJ20192 : TestsForIntelliJ_191_193_branch("2019.2")
|
||||||
|
object TestsForIntelliJ20193 : TestsForIntelliJ_191_193_branch("2019.3")
|
8
.teamcity/_Self/vcsRoots/Branch_181.kt
vendored
8
.teamcity/_Self/vcsRoots/Branch_181.kt
vendored
@@ -5,8 +5,8 @@ package _Self.vcsRoots
|
|||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.vcs.GitVcsRoot
|
import jetbrains.buildServer.configs.kotlin.v2019_2.vcs.GitVcsRoot
|
||||||
|
|
||||||
object Branch_181 : GitVcsRoot({
|
object Branch_181 : GitVcsRoot({
|
||||||
name = "https://github.com/JetBrains/ideavim (branch 181)"
|
name = "https://github.com/JetBrains/ideavim (branch 181)"
|
||||||
url = "https://github.com/JetBrains/ideavim.git"
|
url = "https://github.com/JetBrains/ideavim.git"
|
||||||
branch = "181"
|
branch = "181"
|
||||||
useMirrors = false
|
useMirrors = false
|
||||||
})
|
})
|
||||||
|
8
.teamcity/_Self/vcsRoots/Branch_183.kt
vendored
8
.teamcity/_Self/vcsRoots/Branch_183.kt
vendored
@@ -5,8 +5,8 @@ package _Self.vcsRoots
|
|||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.vcs.GitVcsRoot
|
import jetbrains.buildServer.configs.kotlin.v2019_2.vcs.GitVcsRoot
|
||||||
|
|
||||||
object Branch_183 : GitVcsRoot({
|
object Branch_183 : GitVcsRoot({
|
||||||
name = "https://github.com/JetBrains/ideavim (branch 183)"
|
name = "https://github.com/JetBrains/ideavim (branch 183)"
|
||||||
url = "https://github.com/JetBrains/ideavim.git"
|
url = "https://github.com/JetBrains/ideavim.git"
|
||||||
branch = "183"
|
branch = "183"
|
||||||
useMirrors = false
|
useMirrors = false
|
||||||
})
|
})
|
||||||
|
8
.teamcity/_Self/vcsRoots/Branch_191_193.kt
vendored
8
.teamcity/_Self/vcsRoots/Branch_191_193.kt
vendored
@@ -5,8 +5,8 @@ package _Self.vcsRoots
|
|||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.vcs.GitVcsRoot
|
import jetbrains.buildServer.configs.kotlin.v2019_2.vcs.GitVcsRoot
|
||||||
|
|
||||||
object Branch_191_193 : GitVcsRoot({
|
object Branch_191_193 : GitVcsRoot({
|
||||||
name = "https://github.com/JetBrains/ideavim (branch 191-193)"
|
name = "https://github.com/JetBrains/ideavim (branch 191-193)"
|
||||||
url = "https://github.com/JetBrains/ideavim.git"
|
url = "https://github.com/JetBrains/ideavim.git"
|
||||||
branch = "191-193"
|
branch = "191-193"
|
||||||
useMirrors = false
|
useMirrors = false
|
||||||
})
|
})
|
||||||
|
11
.teamcity/_Self/vcsRoots/Branch_Nvim.kt
vendored
11
.teamcity/_Self/vcsRoots/Branch_Nvim.kt
vendored
@@ -1,11 +0,0 @@
|
|||||||
@file:Suppress("ClassName")
|
|
||||||
|
|
||||||
package _Self.vcsRoots
|
|
||||||
|
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.vcs.GitVcsRoot
|
|
||||||
|
|
||||||
object Branch_Nvim : GitVcsRoot({
|
|
||||||
name = "https://github.com/JetBrains/ideavim (branch nvim)"
|
|
||||||
url = "https://github.com/JetBrains/ideavim.git"
|
|
||||||
branch = "neovim"
|
|
||||||
})
|
|
12
.teamcity/_Self/vcsRoots/GitHubPullRequest.kt
vendored
12
.teamcity/_Self/vcsRoots/GitHubPullRequest.kt
vendored
@@ -3,10 +3,10 @@ package _Self.vcsRoots
|
|||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.vcs.GitVcsRoot
|
import jetbrains.buildServer.configs.kotlin.v2019_2.vcs.GitVcsRoot
|
||||||
|
|
||||||
object GitHubPullRequest : GitVcsRoot({
|
object GitHubPullRequest : GitVcsRoot({
|
||||||
name = "IdeaVim Pull Requests"
|
name = "IdeaVim Pull Requests"
|
||||||
url = "git@github.com:JetBrains/ideavim.git"
|
url = "git@github.com:JetBrains/ideavim.git"
|
||||||
branchSpec = "+:refs/(pull/*)/head"
|
branchSpec = "+:refs/(pull/*)/head"
|
||||||
authMethod = uploadedKey {
|
authMethod = uploadedKey {
|
||||||
uploadedKey = "Alex Plate TeamCity key"
|
uploadedKey = "Alex Plate TeamCity key"
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
26
CHANGES.md
26
CHANGES.md
@@ -24,24 +24,42 @@ usual beta standards.
|
|||||||
|
|
||||||
## To Be Released
|
## To Be Released
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
## 0.61, 2020-11-12
|
||||||
|
|
||||||
### Features:
|
### Features:
|
||||||
* Ability to map IDE actions via the `<Action>` keyword. E.g. `map <C-K> <Action>(CommentByLineComment)`.
|
* Ability to map IDE actions via the `<Action>` keyword. E.g. `map <C-K> <Action>(CommentByLineComment)`.
|
||||||
Check out `README.md` for the details.
|
Check out `README.md` for the details.
|
||||||
* `IdeaVim: track action Ids` command to find action ids for the `:action` command.
|
* `IdeaVim: track action Ids` command to find action ids for the `:action` command.
|
||||||
Enable this option in "Search everywhere" (double shift).
|
Enable this option in "Search everywhere" (double shift).
|
||||||
|
* Ability to enable extensions using `vim-plug` or `vundle` syntax.
|
||||||
|
E.g. to enable commentary extension you can use one of the following commands:
|
||||||
|
```vim
|
||||||
|
set commentary
|
||||||
|
Plug 'tpope/vim-commentary'
|
||||||
|
Plug 'https://github.com/tpope/vim-commentary'
|
||||||
|
Plugin 'tpope/vim-commentary'
|
||||||
|
...
|
||||||
|
```
|
||||||
|
This approach is especially handy if you have `.vimrc` with plugins registered via `vim-plug` or `vundle`.
|
||||||
|
|
||||||
|
|
||||||
### Changes:
|
### Changes:
|
||||||
* Fix `<Esc>` for dialogs. Now `<Esc>` will exit insert / visual mode and close the dialog from normal mode.
|
* Fix `<Esc>` for dialogs. Now `<Esc>` will exit insert / visual mode and close the dialog from normal mode.
|
||||||
* Add option to disable IdeaVim
|
* Add option to disable IdeaVim in dialogs / single line editors. [VIM-765](https://youtrack.jetbrains.com/issue/VIM-765)
|
||||||
in dialogs / single line editors. [VIM-765](https://youtrack.jetbrains.com/issue/VIM-765)
|
Use `set ideavimsupport=` to disable IdeaVim in dialog editors.
|
||||||
Use `set ideaenabledbufs=` to disable IdeaVim in dialog editors.
|
* Reposition cursor when `scrolloff` changes
|
||||||
_Note for EAP users: the option name can be changed for the stable release_
|
|
||||||
|
|
||||||
### Fixes:
|
### Fixes:
|
||||||
* [VIM-2150](https://youtrack.jetbrains.com/issue/VIM-2150) `Shift-D` should not delete an empty line
|
* [VIM-2150](https://youtrack.jetbrains.com/issue/VIM-2150) `Shift-D` should not delete an empty line
|
||||||
* [VIM-2157](https://youtrack.jetbrains.com/issue/VIM-2157) Fix tab with an active template
|
* [VIM-2157](https://youtrack.jetbrains.com/issue/VIM-2157) Fix tab with an active template
|
||||||
* [VIM-2156](https://youtrack.jetbrains.com/issue/VIM-2156) Correct up/down motions with inlays
|
* [VIM-2156](https://youtrack.jetbrains.com/issue/VIM-2156) Correct up/down motions with inlays
|
||||||
* [VIM-2144](https://youtrack.jetbrains.com/issue/VIM-2144) Correct text position after block insert with inlays
|
* [VIM-2144](https://youtrack.jetbrains.com/issue/VIM-2144) Correct text position after block insert with inlays
|
||||||
|
* [VIM-2158](https://youtrack.jetbrains.com/issue/VIM-2158) Fix scrolling when `scrolloff` is over half screen height, but less than full height
|
||||||
|
|
||||||
|
### Merged PRs:
|
||||||
|
* [255](https://github.com/JetBrains/ideavim/pull/255) by [Matt Ellis](https://github.com/citizenmatt): Fix various scrolling issues
|
||||||
|
|
||||||
## 0.60, 2020-10-09
|
## 0.60, 2020-10-09
|
||||||
|
|
||||||
|
@@ -26,7 +26,12 @@ OK, ready to do some coding?
|
|||||||
* Fork the repository and clone it to the local machine.
|
* Fork the repository and clone it to the local machine.
|
||||||
* Open the project with IntelliJ IDEA.
|
* Open the project with IntelliJ IDEA.
|
||||||
|
|
||||||
Yoo hoo! You’re all set to begin contributing. Here are some useful gradle commands:
|
Yoo hoo! You’re all set to begin contributing.
|
||||||
|
We've prepared some useful configurations for you:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
And here are useful gradle commands:
|
||||||
|
|
||||||
* `./gradlew runIde` — start the dev version of IntelliJ IDEA with IdeaVim installed.
|
* `./gradlew runIde` — start the dev version of IntelliJ IDEA with IdeaVim installed.
|
||||||
* `./gradlew test` — run tests.
|
* `./gradlew test` — run tests.
|
||||||
@@ -136,5 +141,5 @@ This is just terrible. [You know what to do](https://github.com/JetBrains/ideavi
|
|||||||
* [Changelog](CHANGES.md)
|
* [Changelog](CHANGES.md)
|
||||||
* [Contributors listing](AUTHORS.md)
|
* [Contributors listing](AUTHORS.md)
|
||||||
|
|
||||||
[teamcity-build-status]: https://teamcity.jetbrains.com/viewType.html?buildTypeId=IdeaVim_TestsForIntelliJ20201&guest=1
|
[teamcity-build-status]: https://teamcity.jetbrains.com/viewType.html?buildTypeId=IdeaVim_TestsForIntelliJEAP&guest=1
|
||||||
[teamcity-build-status-svg]: https://teamcity.jetbrains.com/app/rest/builds/buildType:(id:IdeaVim_TestsForIntelliJ20201)/statusIcon.svg?guest=1
|
[teamcity-build-status-svg]: https://teamcity.jetbrains.com/app/rest/builds/buildType:(id:IdeaVim_TestsForIntelliJEAP)/statusIcon.svg?guest=1
|
||||||
|
42
README.md
42
README.md
@@ -11,7 +11,7 @@ IdeaVim
|
|||||||
[![Gitter][gitter-svg]][gitter]
|
[![Gitter][gitter-svg]][gitter]
|
||||||
[![Twitter][twitter-svg]][twitter]
|
[![Twitter][twitter-svg]][twitter]
|
||||||
|
|
||||||
IdeaVim is a Vim emulation plugin for IDEs based on the IntelliJ Platform.
|
IdeaVim is a Vim emulation plugin for IntelliJ Platform-based IDEs.
|
||||||
|
|
||||||
##### Contact maintainers:
|
##### Contact maintainers:
|
||||||
* [Bug tracker](https://youtrack.jetbrains.com/issues/VIM)
|
* [Bug tracker](https://youtrack.jetbrains.com/issues/VIM)
|
||||||
@@ -188,42 +188,38 @@ Changes to the IDE
|
|||||||
|
|
||||||
### Executing IDE Actions
|
### Executing IDE Actions
|
||||||
|
|
||||||
IdeaVim adds two 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:
|
||||||
|
|
||||||
|
**Executing actions:**
|
||||||
|
* `:action {action_id}`
|
||||||
|
* Execute an action by id. Works from Ex command line.
|
||||||
|
* `<Action>(*action_id*)`
|
||||||
|
* For the mappings you can use a special `<Action>` keyword. Don't forget the parentheses.
|
||||||
|
|
||||||
|
**Finding actions:**
|
||||||
* `:actionlist [pattern]`
|
* `:actionlist [pattern]`
|
||||||
* Find IDE actions by name or keymap pattern (E.g. `:actionlist extract`, `:actionlist <C-D`)
|
* Find IDE actions by id or keymap pattern (E.g. `:actionlist extract`, `:actionlist <C-D`)
|
||||||
* `:action {name}`
|
|
||||||
* Execute an action named `NAME`
|
|
||||||
|
|
||||||
In addition to `:actionlist` command, IdeaVim provides `IdeaVim: track action Ids` option to
|
* In addition to `:actionlist` command, IdeaVim provides `IdeaVim: track action Ids` option to
|
||||||
extract the ids of executed command. This option can be found in "Search everywhere" (double `shift`). **[To Be Released]**
|
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 aciton Ids" Details</strong> (click to see)</summary>
|
||||||
<img src="resources/readme/track_action_id.gif" alt="track actioin ids"/>
|
<img src="resources/readme/track_action_id.gif" alt="track action ids"/>
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
For the mappings you can use a special `<Action>` keyword. Use `<Action>(*action_id*)` to map keys to some action. Don't
|
|
||||||
forget the parentheses. This keyword works for insert mode as well. **[To Be Released]**
|
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
|
|
||||||
```vim
|
```vim
|
||||||
" Map \r to the Reformat Code action
|
" Map \r to the Reformat Code action
|
||||||
:map \r :action ReformatCode<CR>
|
:map \r <Action>(ReformatCode)
|
||||||
" or
|
|
||||||
:map \r <Action>(ReformatCode) " [To Be Released]
|
|
||||||
|
|
||||||
" Map <leader>d to start debug
|
" Map <leader>d to start debug
|
||||||
:map <leader>d :action Debug<CR>
|
:map <leader>d <Action>(Debug)
|
||||||
" or
|
|
||||||
:map <leader>d <Action>(Debug) " [To Be Released]
|
|
||||||
|
|
||||||
" Map \b to toggle the breakpoint on the current line
|
" Map \b to toggle the breakpoint on the current line
|
||||||
:map \b :action ToggleLineBreakpoint<CR>
|
:map \b <Action>(ToggleLineBreakpoint)
|
||||||
" or
|
|
||||||
:map \b <Action>(ToggleLineBreakpoint) " [To Be Released]
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Undo/Redo
|
### Undo/Redo
|
||||||
|
18
build.gradle
18
build.gradle
@@ -8,12 +8,12 @@ buildscript {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
|
||||||
classpath "com.github.AlexPl292:mark-down-to-slack:1.0.1"
|
classpath "com.github.AlexPl292:mark-down-to-slack:1.1.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id 'org.jetbrains.intellij' version '0.5.0'
|
id 'org.jetbrains.intellij' version '0.6.2'
|
||||||
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"
|
||||||
}
|
}
|
||||||
@@ -52,6 +52,12 @@ intellij {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
runPluginVerifier {
|
||||||
|
ideVersions = ["IC-2020.1.4", "IC-2020.2.3"]
|
||||||
|
downloadDirectory = "${project.buildDir}/pluginVerifier/ides"
|
||||||
|
teamCityOutputFormat = true
|
||||||
|
}
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
jcenter()
|
jcenter()
|
||||||
@@ -77,8 +83,8 @@ compileTestKotlin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
detekt {
|
detekt {
|
||||||
config = files("./detekt/config.yaml")
|
config = files("${rootProject.projectDir}/.detekt/config.yaml")
|
||||||
baseline = file("${rootProject.projectDir}/detekt/baseline.xml")
|
baseline = file("${rootProject.projectDir}/.detekt/baseline.xml")
|
||||||
input = files("src")
|
input = files("src")
|
||||||
|
|
||||||
buildUponDefaultConfig = true
|
buildUponDefaultConfig = true
|
||||||
@@ -94,7 +100,7 @@ tasks.detekt.jvmTarget = javaVersion
|
|||||||
|
|
||||||
task testWithNeovim(type: Test) {
|
task testWithNeovim(type: Test) {
|
||||||
group = "verification"
|
group = "verification"
|
||||||
systemProperty "ideavim.neovim.test", 'true'
|
systemProperty "ideavim.nvim.test", 'true'
|
||||||
}
|
}
|
||||||
|
|
||||||
changelog {
|
changelog {
|
||||||
@@ -112,7 +118,7 @@ tasks.register("slackEapNotification") {
|
|||||||
if (!slackUrl) return
|
if (!slackUrl) return
|
||||||
def post = new URL(slackUrl).openConnection()
|
def post = new URL(slackUrl).openConnection()
|
||||||
def changeLog = changelog.getUnreleased().toText()
|
def changeLog = changelog.getUnreleased().toText()
|
||||||
def slackDown = new DownParser(changeLog).toSlack().toString()
|
def slackDown = new DownParser(changeLog, true).toSlack().toString()
|
||||||
def message = """
|
def message = """
|
||||||
{
|
{
|
||||||
"text": "New version of IdeaVim",
|
"text": "New version of IdeaVim",
|
||||||
|
@@ -4,7 +4,15 @@ Emulated Vim Plugins
|
|||||||
IdeaVim extensions emulate plugins of the original Vim. In order to use
|
IdeaVim extensions emulate plugins of the original Vim. In order to use
|
||||||
IdeaVim extensions, you have to enable them via this command in your `~/.ideavimrc`:
|
IdeaVim extensions, you have to enable them via this command in your `~/.ideavimrc`:
|
||||||
|
|
||||||
set <extension-name>
|
```
|
||||||
|
set <extension-name>
|
||||||
|
```
|
||||||
|
|
||||||
|
If you reuse your existing `.vimrc` file using `source ~/.vimrc`, IdeaVim can parse and enable plugins that are defined
|
||||||
|
using [vim-plug](https://github.com/junegunn/vim-plug) or [vundle](https://github.com/VundleVim/Vundle.vim).
|
||||||
|
No additional set commands in `~/.ideavimrc` are required.
|
||||||
|
If you'd like to disable some plugin that's enabled in `.vimrc`, you can use `set no<extension-name>`
|
||||||
|
in `~/.ideavimrc`.
|
||||||
|
|
||||||
Available extensions:
|
Available extensions:
|
||||||
|
|
||||||
@@ -20,18 +28,52 @@ Available extensions:
|
|||||||
## surround
|
## surround
|
||||||
|
|
||||||
* Setup: `set surround`
|
* Setup: `set surround`
|
||||||
|
* <details>
|
||||||
|
<summary>Alternative vim-plug / vundle syntax</summary>
|
||||||
|
<code>Plug 'https://github.com/tpope/vim-surround'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'tpope/vim-surround'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'vim-surround'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'https://www.vim.org/scripts/script.php?script_id=1697'</code>
|
||||||
|
</details>
|
||||||
* Emulates [vim-surround](https://github.com/tpope/vim-surround)
|
* Emulates [vim-surround](https://github.com/tpope/vim-surround)
|
||||||
* Commands: `ys`, `cs`, `ds`, `S`
|
* Commands: `ys`, `cs`, `ds`, `S`
|
||||||
|
|
||||||
## multiple-cursors
|
## multiple-cursors
|
||||||
|
|
||||||
* Setup: `set multiple-cursors`
|
* Setup: `set multiple-cursors`
|
||||||
|
* <details>
|
||||||
|
<summary>Alternative vim-plug / vundle syntax</summary>
|
||||||
|
<code>Plug 'https://github.com/terryma/vim-multiple-cursors'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'terryma/vim-multiple-cursors'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'vim-multiple-cursors'</code>
|
||||||
|
</details>
|
||||||
* Emulates [vim-multiple-cursors](https://github.com/terryma/vim-multiple-cursors)
|
* Emulates [vim-multiple-cursors](https://github.com/terryma/vim-multiple-cursors)
|
||||||
* Commands: `<A-n>`, `<A-x>`, `<A-p>`, `g<A-n>`
|
* Commands: `<A-n>`, `<A-x>`, `<A-p>`, `g<A-n>`
|
||||||
|
|
||||||
## commentary
|
## commentary
|
||||||
|
|
||||||
* Setup: `set commentary`
|
* Setup: `set commentary`
|
||||||
|
* <details>
|
||||||
|
<summary>Alternative vim-plug / vundle syntax</summary>
|
||||||
|
<code>Plug 'https://github.com/tpope/vim-commentary'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'tpope/vim-commentary'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'vim-commentary'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'https://www.vim.org/scripts/script.php?script_id=3695'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'tomtom/tcomment_vim'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'tcomment_vim'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'https://www.vim.org/scripts/script.php?script_id=1173'</code>
|
||||||
|
</details>
|
||||||
* Emulates [commentary.vim](https://github.com/tpope/vim-commentary)
|
* Emulates [commentary.vim](https://github.com/tpope/vim-commentary)
|
||||||
* Commands: `gcc`, `gc + motion`, `v_gc`
|
* Commands: `gcc`, `gc + motion`, `v_gc`
|
||||||
* By [Daniel Leong](https://github.com/dhleong)
|
* By [Daniel Leong](https://github.com/dhleong)
|
||||||
@@ -39,6 +81,22 @@ Available extensions:
|
|||||||
## ReplaceWithRegister
|
## ReplaceWithRegister
|
||||||
|
|
||||||
* Setup: `set ReplaceWithRegister`
|
* Setup: `set ReplaceWithRegister`
|
||||||
|
* <details>
|
||||||
|
<summary>Alternative vim-plug / vundle syntax</summary>
|
||||||
|
<code>Plug 'https://github.com/vim-scripts/ReplaceWithRegister'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'vim-scripts/ReplaceWithRegister'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'ReplaceWithRegister'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'https://github.com/inkarkat/vim-ReplaceWithRegister'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'inkarkat/vim-ReplaceWithRegister'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'vim-ReplaceWithRegister'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'https://www.vim.org/scripts/script.php?script_id=2703'</code>
|
||||||
|
</details>
|
||||||
* Emulates [ReplaceWithRegister](https://github.com/vim-scripts/ReplaceWithRegister)
|
* Emulates [ReplaceWithRegister](https://github.com/vim-scripts/ReplaceWithRegister)
|
||||||
* Commands: `gr`, `grr`
|
* Commands: `gr`, `grr`
|
||||||
* By [igrekster](https://github.com/igrekster)
|
* By [igrekster](https://github.com/igrekster)
|
||||||
@@ -47,6 +105,16 @@ Available extensions:
|
|||||||
|
|
||||||
* Setup:
|
* Setup:
|
||||||
* `set argtextobj`
|
* `set argtextobj`
|
||||||
|
* <details>
|
||||||
|
<summary>Alternative vim-plug / vundle syntax</summary>
|
||||||
|
<code>Plug 'https://github.com/vim-scripts/argtextobj.vim'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'vim-scripts/argtextobj.vim'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'argtextobj.vim'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'https://www.vim.org/scripts/script.php?script_id=2699'</code>
|
||||||
|
</details>
|
||||||
* By default, only the arguments inside parenthesis are considered. To extend the functionality
|
* By default, only the arguments inside parenthesis are considered. To extend the functionality
|
||||||
to other types of brackets, set `g:argtextobj_pairs` variable to a comma-separated
|
to other types of brackets, set `g:argtextobj_pairs` variable to a comma-separated
|
||||||
list of colon-separated pairs (same as VIM's `matchpairs` option), like
|
list of colon-separated pairs (same as VIM's `matchpairs` option), like
|
||||||
@@ -59,6 +127,14 @@ Available extensions:
|
|||||||
## exchange
|
## exchange
|
||||||
|
|
||||||
* Setup: `set exchange`
|
* Setup: `set exchange`
|
||||||
|
* <details>
|
||||||
|
<summary>Alternative vim-plug / vundle syntax</summary>
|
||||||
|
<code>Plug 'https://github.com/tommcdo/vim-exchange'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'tommcdo/vim-exchange'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'vim-exchange'</code>
|
||||||
|
</details>
|
||||||
* Emulates [vim-exchange](https://github.com/tommcdo/vim-exchange)
|
* Emulates [vim-exchange](https://github.com/tommcdo/vim-exchange)
|
||||||
* Commands: `cx`, `cxx`, `X`, `cxc`
|
* Commands: `cx`, `cxx`, `X`, `cxc`
|
||||||
* By [fan-tom](https://github.com/fan-tom)
|
* By [fan-tom](https://github.com/fan-tom)
|
||||||
@@ -66,6 +142,16 @@ Available extensions:
|
|||||||
## textobj-entire
|
## textobj-entire
|
||||||
|
|
||||||
* Setup: `set textobj-entire`
|
* Setup: `set textobj-entire`
|
||||||
|
* <details>
|
||||||
|
<summary>Alternative vim-plug / vundle syntax</summary>
|
||||||
|
<code>Plug 'https://github.com/kana/vim-textobj-entire'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'kana/vim-textobj-entire'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'vim-textobj-entire'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'https://www.vim.org/scripts/script.php?script_id=2610'</code>
|
||||||
|
</details>
|
||||||
* Emulates [vim-textobj-entire](https://github.com/kana/vim-textobj-entire)
|
* Emulates [vim-textobj-entire](https://github.com/kana/vim-textobj-entire)
|
||||||
* Additional text objects: `ae`, `ie`
|
* Additional text objects: `ae`, `ie`
|
||||||
* By [Alexandre Grison](https://github.com/agrison)
|
* By [Alexandre Grison](https://github.com/agrison)
|
||||||
@@ -74,6 +160,14 @@ Available extensions:
|
|||||||
|
|
||||||
* Setup:
|
* Setup:
|
||||||
* `set highlightedyank`
|
* `set highlightedyank`
|
||||||
|
* <details>
|
||||||
|
<summary>Alternative vim-plug / vundle syntax</summary>
|
||||||
|
<code>Plug 'https://github.com/machakann/vim-highlightedyank'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'machakann/vim-highlightedyank'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'vim-highlightedyank'</code>
|
||||||
|
</details>
|
||||||
* if you want to optimize highlight duration, assign a time in milliseconds:
|
* if you want to optimize highlight duration, assign a time in milliseconds:
|
||||||
`let g:highlightedyank_highlight_duration = "1000"`
|
`let g:highlightedyank_highlight_duration = "1000"`
|
||||||
A negative number makes the highlight persistent.
|
A negative number makes the highlight persistent.
|
||||||
|
@@ -125,7 +125,7 @@ The following `:set` commands can appear in `~/.ideavimrc` or be set manually in
|
|||||||
"<C-Down>", "<C-Up>", "<PageUp>", "<PageDown>",
|
"<C-Down>", "<C-Up>", "<PageUp>", "<PageDown>",
|
||||||
"<C-J>", "<C-Q>"
|
"<C-J>", "<C-Q>"
|
||||||
|
|
||||||
`ideaenabledbufs` `ideaenabledbufs` List of strings (default "dialog") [To Be Released]
|
`ideavimsupport` `ideavimsupport` List of strings (default "dialog")
|
||||||
|
|
||||||
Define the list of additional buffers where IdeaVim is enabled.
|
Define the list of additional buffers where IdeaVim is enabled.
|
||||||
|
|
||||||
|
@@ -64,5 +64,6 @@
|
|||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.TabCloseHandler" names="tabc[lose]"/>
|
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.TabCloseHandler" names="tabc[lose]"/>
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.BufferListHandler" names="buffers,ls,files"/>
|
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.BufferListHandler" names="buffers,ls,files"/>
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.BufferHandler" names="b[uffer]"/>
|
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.BufferHandler" names="b[uffer]"/>
|
||||||
|
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.PlugHandler" names="Plug[in]"/>
|
||||||
</extensions>
|
</extensions>
|
||||||
</idea-plugin>
|
</idea-plugin>
|
||||||
|
@@ -1,12 +1,84 @@
|
|||||||
<idea-plugin>
|
<idea-plugin>
|
||||||
<extensions defaultExtensionNs="IdeaVIM">
|
<extensions defaultExtensionNs="IdeaVIM">
|
||||||
<vimExtension implementation="com.maddyhome.idea.vim.extension.surround.VimSurroundExtension"/>
|
<vimExtension implementation="com.maddyhome.idea.vim.extension.surround.VimSurroundExtension" name="surround">
|
||||||
<vimExtension implementation="com.maddyhome.idea.vim.extension.multiplecursors.VimMultipleCursorsExtension"/>
|
<aliases>
|
||||||
<vimExtension implementation="com.maddyhome.idea.vim.extension.commentary.CommentaryExtension"/>
|
<alias name="https://github.com/tpope/vim-surround"/>
|
||||||
<vimExtension implementation="com.maddyhome.idea.vim.extension.textobjentire.VimTextObjEntireExtension"/>
|
<alias name="tpope/vim-surround"/>
|
||||||
<vimExtension implementation="com.maddyhome.idea.vim.extension.argtextobj.VimArgTextObjExtension"/>
|
<alias name="vim-surround"/>
|
||||||
<vimExtension implementation="com.maddyhome.idea.vim.extension.replacewithregister.ReplaceWithRegister"/>
|
<alias name="https://www.vim.org/scripts/script.php?script_id=1697"/>
|
||||||
<vimExtension implementation="com.maddyhome.idea.vim.extension.exchange.VimExchangeExtension"/>
|
</aliases>
|
||||||
<vimExtension implementation="com.maddyhome.idea.vim.extension.highlightedyank.VimHighlightedYank"/>
|
</vimExtension>
|
||||||
|
|
||||||
|
<vimExtension implementation="com.maddyhome.idea.vim.extension.multiplecursors.VimMultipleCursorsExtension"
|
||||||
|
name="multiple-cursors">
|
||||||
|
<aliases>
|
||||||
|
<alias name="https://github.com/terryma/vim-multiple-cursors"/>
|
||||||
|
<alias name="terryma/vim-multiple-cursors"/>
|
||||||
|
<alias name="vim-multiple-cursors"/>
|
||||||
|
</aliases>
|
||||||
|
</vimExtension>
|
||||||
|
|
||||||
|
<vimExtension implementation="com.maddyhome.idea.vim.extension.commentary.CommentaryExtension" name="commentary">
|
||||||
|
<aliases>
|
||||||
|
<alias name="https://github.com/tpope/vim-commentary"/>
|
||||||
|
<alias name="tpope/vim-commentary"/>
|
||||||
|
<alias name="vim-commentary"/>
|
||||||
|
<alias name="https://www.vim.org/scripts/script.php?script_id=3695"/>
|
||||||
|
<alias name="https://github.com/tomtom/tcomment_vim"/>
|
||||||
|
<alias name="tomtom/tcomment_vim"/>
|
||||||
|
<alias name="tcomment_vim"/>
|
||||||
|
<alias name="https://www.vim.org/scripts/script.php?script_id=1173"/>
|
||||||
|
</aliases>
|
||||||
|
</vimExtension>
|
||||||
|
|
||||||
|
<vimExtension implementation="com.maddyhome.idea.vim.extension.textobjentire.VimTextObjEntireExtension"
|
||||||
|
name="textobj-entire">
|
||||||
|
<aliases>
|
||||||
|
<alias name="https://github.com/kana/vim-textobj-entire"/>
|
||||||
|
<alias name="kana/vim-textobj-entire"/>
|
||||||
|
<alias name="vim-textobj-entire"/>
|
||||||
|
<alias name="https://www.vim.org/scripts/script.php?script_id=2610"/>
|
||||||
|
</aliases>
|
||||||
|
</vimExtension>
|
||||||
|
|
||||||
|
<vimExtension implementation="com.maddyhome.idea.vim.extension.argtextobj.VimArgTextObjExtension"
|
||||||
|
name="argtextobj">
|
||||||
|
<aliases>
|
||||||
|
<alias name="https://github.com/vim-scripts/argtextobj.vim"/>
|
||||||
|
<alias name="vim-scripts/argtextobj.vim"/>
|
||||||
|
<alias name="argtextobj.vim"/>
|
||||||
|
<alias name="https://www.vim.org/scripts/script.php?script_id=2699"/>
|
||||||
|
</aliases>
|
||||||
|
</vimExtension>
|
||||||
|
|
||||||
|
<vimExtension implementation="com.maddyhome.idea.vim.extension.replacewithregister.ReplaceWithRegister"
|
||||||
|
name="ReplaceWithRegister">
|
||||||
|
<aliases>
|
||||||
|
<alias name="https://github.com/vim-scripts/ReplaceWithRegister"/>
|
||||||
|
<alias name="vim-scripts/ReplaceWithRegister"/>
|
||||||
|
<alias name="ReplaceWithRegister"/>
|
||||||
|
<alias name="https://github.com/inkarkat/vim-ReplaceWithRegister"/>
|
||||||
|
<alias name="inkarkat/vim-ReplaceWithRegister"/>
|
||||||
|
<alias name="vim-ReplaceWithRegister"/>
|
||||||
|
<alias name="https://www.vim.org/scripts/script.php?script_id=2703"/>
|
||||||
|
</aliases>
|
||||||
|
</vimExtension>
|
||||||
|
|
||||||
|
<vimExtension implementation="com.maddyhome.idea.vim.extension.exchange.VimExchangeExtension" name="exchange">
|
||||||
|
<aliases>
|
||||||
|
<alias name="https://github.com/tommcdo/vim-exchange"/>
|
||||||
|
<alias name="tommcdo/vim-exchange"/>
|
||||||
|
<alias name="vim-exchange"/>
|
||||||
|
</aliases>
|
||||||
|
</vimExtension>
|
||||||
|
|
||||||
|
<vimExtension implementation="com.maddyhome.idea.vim.extension.highlightedyank.VimHighlightedYank"
|
||||||
|
name="highlightedyank">
|
||||||
|
<aliases>
|
||||||
|
<alias name="https://github.com/machakann/vim-highlightedyank"/>
|
||||||
|
<alias name="machakann/vim-highlightedyank"/>
|
||||||
|
<alias name="vim-highlightedyank"/>
|
||||||
|
</aliases>
|
||||||
|
</vimExtension>
|
||||||
</extensions>
|
</extensions>
|
||||||
</idea-plugin>
|
</idea-plugin>
|
||||||
|
@@ -2,6 +2,8 @@
|
|||||||
<applicationListeners>
|
<applicationListeners>
|
||||||
<listener class="com.maddyhome.idea.vim.ui.ExEntryPanel$LafListener"
|
<listener class="com.maddyhome.idea.vim.ui.ExEntryPanel$LafListener"
|
||||||
topic="com.intellij.ide.ui.LafManagerListener"/>
|
topic="com.intellij.ide.ui.LafManagerListener"/>
|
||||||
|
<listener class="com.maddyhome.idea.vim.extension.highlightedyank.HighlightColorResetter"
|
||||||
|
topic="com.intellij.ide.ui.LafManagerListener"/>
|
||||||
</applicationListeners>
|
</applicationListeners>
|
||||||
<projectListeners>
|
<projectListeners>
|
||||||
<listener class="com.maddyhome.idea.vim.ui.ExOutputPanel$LafListener"
|
<listener class="com.maddyhome.idea.vim.ui.ExOutputPanel$LafListener"
|
||||||
|
@@ -1,19 +1,54 @@
|
|||||||
<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><![CDATA[
|
<change-notes>
|
||||||
<ul>
|
<h3>Features:</h3>
|
||||||
<li>Fix ESC in dialogs</li>
|
<br/>
|
||||||
<li>Add option to disable IdeaVim in dialogs and single line editors</li>
|
<ul><li>Ability to map IDE actions via the <code>&lt;Action&gt;</code> keyword. E.g.
|
||||||
<li>Ability to map IDE actions via the <Action> keyword.</li>
|
<code>map &lt;C-K&gt; &lt;Action&gt;(CommentByLineComment)</code>.
|
||||||
<li>"IdeaVim: track action Ids" command to find action ids for the :action command.
|
Check out <code>README.md</code> for the details.</li><li><code>IdeaVim: track action
|
||||||
Enable this option in "Search everywhere" (double shift).</li>
|
Ids</code> command to find action ids for the <code>:action</code> command.
|
||||||
</ul>
|
Enable this option in &quot;Search everywhere&quot; (double shift).</li><li>Ability to enable
|
||||||
<p>See also the complete <a href="https://github.com/JetBrains/ideavim/blob/master/CHANGES.md">changelog</a>.</p>
|
extensions using <code>vim-plug</code> or <code>vundle</code> syntax.<br />
|
||||||
]]></change-notes>
|
E.g. to enable commentary extension you can use one of the following commands:<pre><code
|
||||||
|
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>
|
||||||
|
|
||||||
|
|
||||||
|
<br/>
|
||||||
|
<h3>Changes:</h3>
|
||||||
|
<br/>
|
||||||
|
<ul><li>Fix <code>&lt;Esc&gt;</code> for dialogs. Now <code>&lt;Esc&gt;</code>
|
||||||
|
will exit insert / visual mode and close the dialog from normal mode.</li><li>Add option to disable
|
||||||
|
IdeaVim in dialogs / single line editors. <a href="https://youtrack.jetbrains.com/issue/VIM-765">VIM-765</a><br
|
||||||
|
/>
|
||||||
|
Use <code>set ideavimsupport=</code> to disable IdeaVim in dialog editors. </li><li>Reposition
|
||||||
|
cursor when <code>scrolloff</code> changes</li></ul>
|
||||||
|
|
||||||
|
<br/>
|
||||||
|
<h3>Fixes:</h3>
|
||||||
|
<br/>
|
||||||
|
<ul><li><a href="https://youtrack.jetbrains.com/issue/VIM-2150">VIM-2150</a> <code>Shift-D</code>
|
||||||
|
should not delete an empty line</li><li><a href="https://youtrack.jetbrains.com/issue/VIM-2157">VIM-2157</a>
|
||||||
|
Fix tab with an active template</li><li><a href="https://youtrack.jetbrains.com/issue/VIM-2156">VIM-2156</a>
|
||||||
|
Correct up/down motions with inlays</li><li><a href="https://youtrack.jetbrains.com/issue/VIM-2144">VIM-2144</a>
|
||||||
|
Correct text position after block insert with inlays</li><li><a
|
||||||
|
href="https://youtrack.jetbrains.com/issue/VIM-2158">VIM-2158</a> Fix scrolling when <code>scrolloff</code>
|
||||||
|
is over half screen height, but less than full height</li></ul>
|
||||||
|
<br/>
|
||||||
|
<p>See also the complete <a href="https://github.com/JetBrains/ideavim/blob/master/CHANGES.md">changelog</a>.</p>
|
||||||
|
</change-notes>
|
||||||
<description><![CDATA[
|
<description><![CDATA[
|
||||||
<p>Vim emulation plug-in for IDEs based on the IntelliJ platform.</p>
|
<p>Vim emulation plugin for IntelliJ Platform-based IDEs.</p>
|
||||||
<p>IdeaVim supports many Vim features including normal/insert/visual modes, motion keys, deletion/changing, marks, registers, some Ex commands, Vim regexps, configuration via ~/.ideavimrc, macros, window commands, etc.</p>
|
<br/>
|
||||||
|
<p>IdeaVim supports many Vim features including normal/insert/visual modes, motion keys, deletion/changing,
|
||||||
|
marks, registers, some Ex commands, Vim regexps, configuration via ~/.ideavimrc, macros, Vim plugins, etc.</p>
|
||||||
|
<br/>
|
||||||
<p>See also:</p>
|
<p>See also:</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="https://github.com/JetBrains/ideavim">GitHub repository</a>: documentation and contributing</li>
|
<li><a href="https://github.com/JetBrains/ideavim">GitHub repository</a>: documentation and contributing</li>
|
||||||
@@ -38,7 +73,10 @@
|
|||||||
</application-components>
|
</application-components>
|
||||||
|
|
||||||
<extensionPoints>
|
<extensionPoints>
|
||||||
<extensionPoint name="vimExtension" interface="com.maddyhome.idea.vim.extension.VimExtension" dynamic="true"/>
|
<extensionPoint name="vimExtension" beanClass="com.maddyhome.idea.vim.extension.ExtensionBeanClass" dynamic="true">
|
||||||
|
<with attribute="implementation" implements="com.maddyhome.idea.vim.extension.VimExtension"/>
|
||||||
|
|
||||||
|
</extensionPoint>
|
||||||
|
|
||||||
<!-- For internal use only -->
|
<!-- For internal use only -->
|
||||||
<extensionPoint name="vimExCommand" beanClass="com.maddyhome.idea.vim.ex.ExBeanClass" dynamic="true">
|
<extensionPoint name="vimExCommand" beanClass="com.maddyhome.idea.vim.ex.ExBeanClass" dynamic="true">
|
||||||
|
BIN
resources/contributing/configurations.png
Normal file
BIN
resources/contributing/configurations.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 22 KiB |
@@ -24,10 +24,7 @@ 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.PersistentStateComponent;
|
import com.intellij.openapi.components.*;
|
||||||
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;
|
||||||
|
@@ -20,15 +20,29 @@ package com.maddyhome.idea.vim.action
|
|||||||
import com.intellij.openapi.actionSystem.DataContext
|
import com.intellij.openapi.actionSystem.DataContext
|
||||||
import com.intellij.openapi.editor.Editor
|
import com.intellij.openapi.editor.Editor
|
||||||
import com.maddyhome.idea.vim.KeyHandler
|
import com.maddyhome.idea.vim.KeyHandler
|
||||||
|
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.group.MotionGroup
|
||||||
import com.maddyhome.idea.vim.handler.VimActionHandler
|
import com.maddyhome.idea.vim.handler.VimActionHandler
|
||||||
import com.maddyhome.idea.vim.helper.getTopLevelEditor
|
import com.maddyhome.idea.vim.helper.getTopLevelEditor
|
||||||
|
import com.maddyhome.idea.vim.helper.mode
|
||||||
|
import com.maddyhome.idea.vim.helper.vimForEachCaret
|
||||||
|
|
||||||
class ResetModeAction : VimActionHandler.SingleExecution() {
|
class ResetModeAction : VimActionHandler.SingleExecution() {
|
||||||
override val type: Command.Type = Command.Type.OTHER_WRITABLE
|
override val type: Command.Type = Command.Type.OTHER_WRITABLE
|
||||||
|
|
||||||
override fun execute(editor: Editor, context: DataContext, cmd: Command): Boolean {
|
override fun execute(editor: Editor, context: DataContext, cmd: Command): Boolean {
|
||||||
|
val modeBeforeReset = editor.mode
|
||||||
KeyHandler.getInstance().fullReset(editor.getTopLevelEditor())
|
KeyHandler.getInstance().fullReset(editor.getTopLevelEditor())
|
||||||
|
|
||||||
|
if (modeBeforeReset == CommandState.Mode.INSERT) {
|
||||||
|
editor.vimForEachCaret { caret ->
|
||||||
|
val position = VimPlugin.getMotion().getOffsetOfHorizontalMotion(editor, caret, -1, false)
|
||||||
|
MotionGroup.moveCaret(editor, caret, position)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -128,7 +128,7 @@ class VimShortcutKeyAction : AnAction(), DumbAware {
|
|||||||
private fun isEnabledForEscape(editor: Editor): Boolean {
|
private fun isEnabledForEscape(editor: Editor): Boolean {
|
||||||
return editor.isPrimaryEditor()
|
return editor.isPrimaryEditor()
|
||||||
|| EditorHelper.isFileEditor(editor) && !editor.inNormalMode
|
|| EditorHelper.isFileEditor(editor) && !editor.inNormalMode
|
||||||
|| OptionsManager.ideaenabledbufs.contains("dialog") && !editor.inNormalMode
|
|| OptionsManager.ideavimsupport.contains("dialog") && !editor.inNormalMode
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isShortcutConflict(keyStroke: KeyStroke): Boolean {
|
private fun isShortcutConflict(keyStroke: KeyStroke): Boolean {
|
||||||
|
@@ -28,7 +28,7 @@ import com.maddyhome.idea.vim.handler.VisualOperatorActionHandler
|
|||||||
import com.maddyhome.idea.vim.helper.enumSetOf
|
import com.maddyhome.idea.vim.helper.enumSetOf
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
sealed class IncNumber(val inc: Int, val avalanche: Boolean) : VisualOperatorActionHandler.ForEachCaret() {
|
sealed class IncNumber(val inc: Int, private val avalanche: Boolean) : VisualOperatorActionHandler.ForEachCaret() {
|
||||||
override val type: Command.Type = Command.Type.CHANGE
|
override val type: Command.Type = Command.Type.CHANGE
|
||||||
override val flags: EnumSet<CommandFlags> = enumSetOf(CommandFlags.FLAG_EXIT_VISUAL)
|
override val flags: EnumSet<CommandFlags> = enumSetOf(CommandFlags.FLAG_EXIT_VISUAL)
|
||||||
|
|
||||||
|
@@ -10,7 +10,7 @@ import javax.swing.KeyStroke
|
|||||||
|
|
||||||
class InsertCompletedDigraphAction : VimActionHandler.SingleExecution() {
|
class InsertCompletedDigraphAction : VimActionHandler.SingleExecution() {
|
||||||
override val type: Command.Type = Command.Type.INSERT
|
override val type: Command.Type = Command.Type.INSERT
|
||||||
override val argumentType: Argument.Type? = Argument.Type.DIGRAPH
|
override val argumentType: Argument.Type = Argument.Type.DIGRAPH
|
||||||
|
|
||||||
override fun execute(editor: Editor, context: DataContext, cmd: Command): Boolean {
|
override fun execute(editor: Editor, context: DataContext, cmd: Command): Boolean {
|
||||||
// The converted digraph character has been captured as an argument, push it back through key handler
|
// The converted digraph character has been captured as an argument, push it back through key handler
|
||||||
|
@@ -10,7 +10,7 @@ import javax.swing.KeyStroke
|
|||||||
|
|
||||||
class InsertCompletedLiteralAction : VimActionHandler.SingleExecution() {
|
class InsertCompletedLiteralAction : VimActionHandler.SingleExecution() {
|
||||||
override val type: Command.Type = Command.Type.INSERT
|
override val type: Command.Type = Command.Type.INSERT
|
||||||
override val argumentType: Argument.Type? = Argument.Type.DIGRAPH
|
override val argumentType: Argument.Type = Argument.Type.DIGRAPH
|
||||||
|
|
||||||
override fun execute(editor: Editor, context: DataContext, cmd: Command): Boolean {
|
override fun execute(editor: Editor, context: DataContext, cmd: Command): Boolean {
|
||||||
// The converted literal character has been captured as an argument, push it back through key handler
|
// The converted literal character has been captured as an argument, push it back through key handler
|
||||||
|
@@ -37,7 +37,7 @@ class MotionInnerSentenceAction : TextObjectActionHandler() {
|
|||||||
|
|
||||||
override val visualType: TextObjectVisualType = TextObjectVisualType.CHARACTER_WISE
|
override val visualType: TextObjectVisualType = TextObjectVisualType.CHARACTER_WISE
|
||||||
|
|
||||||
override fun getRange(editor: Editor, caret: Caret, context: DataContext, count: Int, rawCount: Int, argument: Argument?): TextRange? {
|
override fun getRange(editor: Editor, caret: Caret, context: DataContext, count: Int, rawCount: Int, argument: Argument?): TextRange {
|
||||||
return VimPlugin.getMotion().getSentenceRange(editor, caret, count, false)
|
return VimPlugin.getMotion().getSentenceRange(editor, caret, count, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -31,7 +31,7 @@ class MotionInnerWordAction : TextObjectActionHandler() {
|
|||||||
|
|
||||||
override val visualType: TextObjectVisualType = TextObjectVisualType.CHARACTER_WISE
|
override val visualType: TextObjectVisualType = TextObjectVisualType.CHARACTER_WISE
|
||||||
|
|
||||||
override fun getRange(editor: Editor, caret: Caret, context: DataContext, count: Int, rawCount: Int, argument: Argument?): TextRange? {
|
override fun getRange(editor: Editor, caret: Caret, context: DataContext, count: Int, rawCount: Int, argument: Argument?): TextRange {
|
||||||
return VimPlugin.getMotion().getWordRange(editor, caret, count, false, false)
|
return VimPlugin.getMotion().getWordRange(editor, caret, count, false, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -32,7 +32,7 @@ class MotionOuterBigWordAction : TextObjectActionHandler() {
|
|||||||
|
|
||||||
override val visualType: TextObjectVisualType = TextObjectVisualType.CHARACTER_WISE
|
override val visualType: TextObjectVisualType = TextObjectVisualType.CHARACTER_WISE
|
||||||
|
|
||||||
override fun getRange(editor: Editor, caret: Caret, context: DataContext, count: Int, rawCount: Int, argument: Argument?): TextRange? {
|
override fun getRange(editor: Editor, caret: Caret, context: DataContext, count: Int, rawCount: Int, argument: Argument?): TextRange {
|
||||||
return VimPlugin.getMotion().getWordRange(editor, caret, count, true, true)
|
return VimPlugin.getMotion().getWordRange(editor, caret, count, true, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -37,7 +37,7 @@ class MotionOuterSentenceAction : TextObjectActionHandler() {
|
|||||||
|
|
||||||
override val visualType: TextObjectVisualType = TextObjectVisualType.CHARACTER_WISE
|
override val visualType: TextObjectVisualType = TextObjectVisualType.CHARACTER_WISE
|
||||||
|
|
||||||
override fun getRange(editor: Editor, caret: Caret, context: DataContext, count: Int, rawCount: Int, argument: Argument?): TextRange? {
|
override fun getRange(editor: Editor, caret: Caret, context: DataContext, count: Int, rawCount: Int, argument: Argument?): TextRange {
|
||||||
return VimPlugin.getMotion().getSentenceRange(editor, caret, count, true)
|
return VimPlugin.getMotion().getSentenceRange(editor, caret, count, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -32,7 +32,7 @@ class MotionOuterWordAction : TextObjectActionHandler() {
|
|||||||
|
|
||||||
override val visualType: TextObjectVisualType = TextObjectVisualType.CHARACTER_WISE
|
override val visualType: TextObjectVisualType = TextObjectVisualType.CHARACTER_WISE
|
||||||
|
|
||||||
override fun getRange(editor: Editor, caret: Caret, context: DataContext, count: Int, rawCount: Int, argument: Argument?): TextRange? {
|
override fun getRange(editor: Editor, caret: Caret, context: DataContext, count: Int, rawCount: Int, argument: Argument?): TextRange {
|
||||||
return VimPlugin.getMotion().getWordRange(editor, caret, count, true, false)
|
return VimPlugin.getMotion().getWordRange(editor, caret, count, true, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -42,12 +42,12 @@ class SelectMotionLeftAction : MotionActionHandler.ForEachCaret() {
|
|||||||
override fun getOffset(editor: Editor, caret: Caret, context: DataContext, count: Int, rawCount: Int, argument: Argument?): Int {
|
override fun getOffset(editor: Editor, caret: Caret, context: DataContext, count: Int, rawCount: Int, argument: Argument?): Int {
|
||||||
val keymodel = OptionsManager.keymodel
|
val keymodel = OptionsManager.keymodel
|
||||||
if (KeyModelOptionData.stopsel in keymodel || KeyModelOptionData.stopselect in keymodel) {
|
if (KeyModelOptionData.stopsel in keymodel || KeyModelOptionData.stopselect in keymodel) {
|
||||||
logger.info("Keymodel option has stopselect. Exiting select mode")
|
logger.debug("Keymodel option has stopselect. Exiting select mode")
|
||||||
val startSelection = caret.selectionStart
|
val startSelection = caret.selectionStart
|
||||||
val endSelection = caret.selectionEnd
|
val endSelection = caret.selectionEnd
|
||||||
editor.exitSelectMode(false)
|
editor.exitSelectMode(false)
|
||||||
if (editor.isTemplateActive()) {
|
if (editor.isTemplateActive()) {
|
||||||
logger.info("Template is active. Activate insert mode")
|
logger.debug("Template is active. Activate insert mode")
|
||||||
VimPlugin.getChange().insertBeforeCursor(editor, context)
|
VimPlugin.getChange().insertBeforeCursor(editor, context)
|
||||||
if (caret.offset in startSelection..endSelection) {
|
if (caret.offset in startSelection..endSelection) {
|
||||||
return startSelection
|
return startSelection
|
||||||
|
@@ -42,12 +42,12 @@ class SelectMotionRightAction : MotionActionHandler.ForEachCaret() {
|
|||||||
override fun getOffset(editor: Editor, caret: Caret, context: DataContext, count: Int, rawCount: Int, argument: Argument?): Int {
|
override fun getOffset(editor: Editor, caret: Caret, context: DataContext, count: Int, rawCount: Int, argument: Argument?): Int {
|
||||||
val keymodel = OptionsManager.keymodel
|
val keymodel = OptionsManager.keymodel
|
||||||
if (KeyModelOptionData.stopsel in keymodel || KeyModelOptionData.stopselect in keymodel) {
|
if (KeyModelOptionData.stopsel in keymodel || KeyModelOptionData.stopselect in keymodel) {
|
||||||
logger.info("Keymodel option has stopselect. Exiting select mode")
|
logger.debug("Keymodel option has stopselect. Exiting select mode")
|
||||||
val startSelection = caret.selectionStart
|
val startSelection = caret.selectionStart
|
||||||
val endSelection = caret.selectionEnd
|
val endSelection = caret.selectionEnd
|
||||||
editor.exitSelectMode(false)
|
editor.exitSelectMode(false)
|
||||||
if (editor.isTemplateActive()) {
|
if (editor.isTemplateActive()) {
|
||||||
logger.info("Template is active. Activate insert mode")
|
logger.debug("Template is active. Activate insert mode")
|
||||||
VimPlugin.getChange().insertBeforeCursor(editor, context)
|
VimPlugin.getChange().insertBeforeCursor(editor, context)
|
||||||
if (caret.offset in startSelection..endSelection) {
|
if (caret.offset in startSelection..endSelection) {
|
||||||
return endSelection
|
return endSelection
|
||||||
|
@@ -19,10 +19,14 @@ package com.maddyhome.idea.vim.action.motion.visual
|
|||||||
|
|
||||||
import com.intellij.openapi.actionSystem.DataContext
|
import com.intellij.openapi.actionSystem.DataContext
|
||||||
import com.intellij.openapi.editor.Editor
|
import com.intellij.openapi.editor.Editor
|
||||||
|
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.group.MotionGroup
|
||||||
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.exitVisualMode
|
import com.maddyhome.idea.vim.helper.exitVisualMode
|
||||||
import com.maddyhome.idea.vim.helper.getTopLevelEditor
|
import com.maddyhome.idea.vim.helper.getTopLevelEditor
|
||||||
|
import com.maddyhome.idea.vim.helper.vimForEachCaret
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author vlan
|
* @author vlan
|
||||||
@@ -32,6 +36,16 @@ class VisualExitModeAction : VimActionHandler.SingleExecution() {
|
|||||||
|
|
||||||
override fun execute(editor: Editor, context: DataContext, cmd: Command): Boolean {
|
override fun execute(editor: Editor, context: DataContext, cmd: Command): Boolean {
|
||||||
editor.getTopLevelEditor().exitVisualMode()
|
editor.getTopLevelEditor().exitVisualMode()
|
||||||
|
|
||||||
|
// Should it be in [exitVisualMode]?
|
||||||
|
editor.vimForEachCaret { caret ->
|
||||||
|
val lineEnd = EditorHelper.getLineEndForOffset(editor, caret.offset)
|
||||||
|
if (lineEnd == caret.offset) {
|
||||||
|
val position = VimPlugin.getMotion().getOffsetOfHorizontalMotion(editor, caret, -1, false)
|
||||||
|
MotionGroup.moveCaret(editor, caret, position)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -75,7 +75,7 @@ class CommandState private constructor() {
|
|||||||
|
|
||||||
fun pushModes(mode: Mode, submode: SubMode) {
|
fun pushModes(mode: Mode, submode: SubMode) {
|
||||||
val newModeState = ModeState(mode, submode)
|
val newModeState = ModeState(mode, submode)
|
||||||
logger.info("Push new mode state: ${newModeState.toSimpleString()}")
|
logger.debug("Push new mode state: ${newModeState.toSimpleString()}")
|
||||||
logger.debug { "Stack of mode states before push: ${toSimpleString()}" }
|
logger.debug { "Stack of mode states before push: ${toSimpleString()}" }
|
||||||
modeStates.push(newModeState)
|
modeStates.push(newModeState)
|
||||||
setMappingMode()
|
setMappingMode()
|
||||||
@@ -86,7 +86,7 @@ class CommandState private constructor() {
|
|||||||
val popped = modeStates.pop()
|
val popped = modeStates.pop()
|
||||||
setMappingMode()
|
setMappingMode()
|
||||||
updateStatus()
|
updateStatus()
|
||||||
logger.info("Popped mode state: ${popped.toSimpleString()}")
|
logger.debug("Popped mode state: ${popped.toSimpleString()}")
|
||||||
logger.debug { "Stack of mode states after pop: ${toSimpleString()}" }
|
logger.debug { "Stack of mode states after pop: ${toSimpleString()}" }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -178,7 +178,7 @@ class CommandState private constructor() {
|
|||||||
executingCommand = null
|
executingCommand = null
|
||||||
resetModes()
|
resetModes()
|
||||||
commandBuilder.resetInProgressCommandPart(getKeyRootNode(mappingState.mappingMode))
|
commandBuilder.resetInProgressCommandPart(getKeyRootNode(mappingState.mappingMode))
|
||||||
startDigraphSequence()
|
digraphSequence.reset()
|
||||||
updateStatus()
|
updateStatus()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -121,31 +121,8 @@ sealed class CommandHandler {
|
|||||||
@Throws(ExException::class)
|
@Throws(ExException::class)
|
||||||
fun process(editor: Editor, context: DataContext, cmd: ExCommand, count: Int): Boolean {
|
fun process(editor: Editor, context: DataContext, cmd: ExCommand, count: Int): Boolean {
|
||||||
|
|
||||||
// No range allowed
|
checkArgs(cmd)
|
||||||
if (RangeFlag.RANGE_FORBIDDEN == argFlags.rangeFlag && cmd.ranges.size() != 0) {
|
|
||||||
VimPlugin.showMessage(MessageHelper.message(Msg.e_norange))
|
|
||||||
throw NoRangeAllowedException()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (RangeFlag.RANGE_REQUIRED == argFlags.rangeFlag && cmd.ranges.size() == 0) {
|
|
||||||
VimPlugin.showMessage(MessageHelper.message(Msg.e_rangereq))
|
|
||||||
throw MissingRangeException()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (RangeFlag.RANGE_IS_COUNT == argFlags.rangeFlag) {
|
|
||||||
cmd.ranges.setDefaultLine(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Argument required
|
|
||||||
if (ArgumentFlag.ARGUMENT_REQUIRED == argFlags.argumentFlag && cmd.argument.isEmpty()) {
|
|
||||||
VimPlugin.showMessage(MessageHelper.message(Msg.e_argreq))
|
|
||||||
throw MissingArgumentException()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ArgumentFlag.ARGUMENT_FORBIDDEN == argFlags.argumentFlag && cmd.argument.isNotEmpty()) {
|
|
||||||
VimPlugin.showMessage(MessageHelper.message(Msg.e_argforb))
|
|
||||||
throw NoArgumentAllowedException()
|
|
||||||
}
|
|
||||||
if (editor.inVisualMode && Flag.SAVE_VISUAL !in argFlags.flags) {
|
if (editor.inVisualMode && Flag.SAVE_VISUAL !in argFlags.flags) {
|
||||||
editor.exitVisualMode()
|
editor.exitVisualMode()
|
||||||
}
|
}
|
||||||
@@ -179,6 +156,34 @@ sealed class CommandHandler {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun checkArgs(cmd: ExCommand) {
|
||||||
|
// No range allowed
|
||||||
|
if (RangeFlag.RANGE_FORBIDDEN == argFlags.rangeFlag && cmd.ranges.size() != 0) {
|
||||||
|
VimPlugin.showMessage(MessageHelper.message(Msg.e_norange))
|
||||||
|
throw NoRangeAllowedException()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (RangeFlag.RANGE_REQUIRED == argFlags.rangeFlag && cmd.ranges.size() == 0) {
|
||||||
|
VimPlugin.showMessage(MessageHelper.message(Msg.e_rangereq))
|
||||||
|
throw MissingRangeException()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (RangeFlag.RANGE_IS_COUNT == argFlags.rangeFlag) {
|
||||||
|
cmd.ranges.setDefaultLine(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Argument required
|
||||||
|
if (ArgumentFlag.ARGUMENT_REQUIRED == argFlags.argumentFlag && cmd.argument.isEmpty()) {
|
||||||
|
VimPlugin.showMessage(MessageHelper.message(Msg.e_argreq))
|
||||||
|
throw MissingArgumentException()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ArgumentFlag.ARGUMENT_FORBIDDEN == argFlags.argumentFlag && cmd.argument.isNotEmpty()) {
|
||||||
|
VimPlugin.showMessage(MessageHelper.message(Msg.e_argforb))
|
||||||
|
throw NoArgumentAllowedException()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data class CommandHandlerFlags(
|
data class CommandHandlerFlags(
|
||||||
|
@@ -126,7 +126,6 @@ public class CommandParser {
|
|||||||
private void processCommand(@NotNull Editor editor, @NotNull DataContext context, @NotNull String cmd,
|
private void processCommand(@NotNull Editor editor, @NotNull DataContext context, @NotNull String cmd,
|
||||||
int count, int aliasCountdown) throws ExException {
|
int count, int aliasCountdown) throws ExException {
|
||||||
// Nothing entered
|
// Nothing entered
|
||||||
int result = 0;
|
|
||||||
if (cmd.length() == 0) {
|
if (cmd.length() == 0) {
|
||||||
logger.warn("CMD is empty");
|
logger.warn("CMD is empty");
|
||||||
return;
|
return;
|
||||||
@@ -326,13 +325,12 @@ public class CommandParser {
|
|||||||
if (ch == '/' || ch == '?' || ch == '&') {
|
if (ch == '/' || ch == '?' || ch == '&') {
|
||||||
location.append(ch);
|
location.append(ch);
|
||||||
state = State.RANGE_PATTERN_MAYBE_DONE;
|
state = State.RANGE_PATTERN_MAYBE_DONE;
|
||||||
reprocess = false;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
error = MessageHelper.message(Msg.e_backslash);
|
error = MessageHelper.message(Msg.e_backslash);
|
||||||
state = State.ERROR;
|
state = State.ERROR;
|
||||||
reprocess = false;
|
|
||||||
}
|
}
|
||||||
|
reprocess = false;
|
||||||
break;
|
break;
|
||||||
case RANGE_PATTERN: // Reading a pattern range
|
case RANGE_PATTERN: // Reading a pattern range
|
||||||
// No trailing / or ? required if there is no command so look for newline to tell us we are done
|
// No trailing / or ? required if there is no command so look for newline to tell us we are done
|
||||||
|
@@ -34,7 +34,7 @@ import java.io.IOException
|
|||||||
class CmdFilterHandler : CommandHandler.SingleExecution() {
|
class CmdFilterHandler : CommandHandler.SingleExecution() {
|
||||||
override val argFlags = flags(RangeFlag.RANGE_OPTIONAL, ArgumentFlag.ARGUMENT_OPTIONAL, Access.WRITABLE)
|
override val argFlags = flags(RangeFlag.RANGE_OPTIONAL, ArgumentFlag.ARGUMENT_OPTIONAL, Access.WRITABLE)
|
||||||
override fun execute(editor: Editor, context: DataContext, cmd: ExCommand): Boolean {
|
override fun execute(editor: Editor, context: DataContext, cmd: ExCommand): Boolean {
|
||||||
logger.info("execute")
|
logger.debug("execute")
|
||||||
|
|
||||||
var command = cmd.argument
|
var command = cmd.argument
|
||||||
if (command.isEmpty()) {
|
if (command.isEmpty()) {
|
||||||
|
56
src/com/maddyhome/idea/vim/ex/handler/PlugHandler.kt
Normal file
56
src/com/maddyhome/idea/vim/ex/handler/PlugHandler.kt
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
|
||||||
|
import com.intellij.openapi.actionSystem.DataContext
|
||||||
|
import com.intellij.openapi.editor.Editor
|
||||||
|
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.ExCommand
|
||||||
|
import com.maddyhome.idea.vim.ex.flags
|
||||||
|
import com.maddyhome.idea.vim.ex.vimscript.VimScriptCommandHandler
|
||||||
|
import com.maddyhome.idea.vim.extension.VimExtensionRegistrar
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This handler is created to support `Plug` command from vim-plug and `Plugin` command from vundle.
|
||||||
|
*/
|
||||||
|
class PlugHandler : CommandHandler.SingleExecution(), VimScriptCommandHandler {
|
||||||
|
override val argFlags: CommandHandlerFlags = flags(RANGE_FORBIDDEN, ARGUMENT_REQUIRED, READ_ONLY)
|
||||||
|
|
||||||
|
override fun execute(editor: Editor, context: DataContext, cmd: ExCommand): Boolean = doExecute(cmd)
|
||||||
|
|
||||||
|
override fun execute(cmd: ExCommand) {
|
||||||
|
doExecute(cmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun doExecute(cmd: ExCommand): Boolean {
|
||||||
|
val argument = cmd.argument
|
||||||
|
val firstChar = argument[0]
|
||||||
|
if (firstChar != '"' && firstChar != '\'') return false
|
||||||
|
|
||||||
|
val pluginAlias = argument.drop(1).takeWhile { it != firstChar }
|
||||||
|
val option = VimExtensionRegistrar.getToggleByAlias(pluginAlias) ?: return false
|
||||||
|
option.set()
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
@@ -95,6 +95,10 @@ object VimScriptParser {
|
|||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun executeText(vararg text: String) {
|
||||||
|
executeText(listOf(*text))
|
||||||
|
}
|
||||||
|
|
||||||
fun executeText(text: List<String>) {
|
fun executeText(text: List<String>) {
|
||||||
for (line in text) {
|
for (line in text) {
|
||||||
// TODO: Build a proper parse tree for a VimL file instead of ignoring potentially nested lines (VIM-669)
|
// TODO: Build a proper parse tree for a VimL file instead of ignoring potentially nested lines (VIM-669)
|
||||||
|
64
src/com/maddyhome/idea/vim/extension/ExtensionBeanClass.kt
Normal file
64
src/com/maddyhome/idea/vim/extension/ExtensionBeanClass.kt
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* 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.extension
|
||||||
|
|
||||||
|
import com.intellij.openapi.application.ApplicationManager
|
||||||
|
import com.intellij.openapi.extensions.AbstractExtensionPointBean
|
||||||
|
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.XCollection
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean
|
||||||
|
|
||||||
|
// [Version Update] 202+
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
class ExtensionBeanClass : AbstractExtensionPointBean() {
|
||||||
|
init {
|
||||||
|
println()
|
||||||
|
}
|
||||||
|
@Attribute("implementation")
|
||||||
|
var implementation: String? = null
|
||||||
|
|
||||||
|
@Attribute("name")
|
||||||
|
var name: String? = null
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of aliases for the extension. These aliases are used to support `Plug` and `Plugin` commands.
|
||||||
|
* Technically, it would be enough to save here github link and short version of it ('author/plugin'),
|
||||||
|
* but it may contain more aliases just in case.
|
||||||
|
*/
|
||||||
|
@Tag("aliases")
|
||||||
|
@XCollection
|
||||||
|
var aliases: List<Alias>? = null
|
||||||
|
|
||||||
|
var initialized = AtomicBoolean(false)
|
||||||
|
|
||||||
|
val handler: VimExtension by lazy {
|
||||||
|
initialized.set(true)
|
||||||
|
this.instantiateClass<VimExtension>(
|
||||||
|
implementation ?: "", ApplicationManager.getApplication().picoContainer
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Tag("alias")
|
||||||
|
class Alias {
|
||||||
|
@Attribute("name")
|
||||||
|
var name: String? = null
|
||||||
|
}
|
@@ -21,16 +21,22 @@ 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.key.MappingOwner;
|
import com.maddyhome.idea.vim.key.MappingOwner;
|
||||||
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author vlan
|
* @author vlan
|
||||||
*/
|
*/
|
||||||
public interface VimExtension {
|
public interface VimExtension {
|
||||||
@NotNull ExtensionPointName<VimExtension> EP_NAME = ExtensionPointName.create("IdeaVIM.vimExtension");
|
@NotNull ExtensionPointName<ExtensionBeanClass> EP_NAME = ExtensionPointName.create("IdeaVIM.vimExtension");
|
||||||
|
|
||||||
@NotNull
|
/**
|
||||||
String getName();
|
* @deprecated This property is not used anymore, but we'll remove it much later to keep the compatibility of IdeaVim
|
||||||
|
* extensions with previous versions of IdeaVim.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
@ApiStatus.ScheduledForRemoval(inVersion = "0.65")
|
||||||
|
@NotNull String getName();
|
||||||
|
|
||||||
default MappingOwner getOwner() {
|
default MappingOwner getOwner() {
|
||||||
return MappingOwner.Plugin.Companion.get(getName());
|
return MappingOwner.Plugin.Companion.get(getName());
|
||||||
@@ -40,5 +46,5 @@ public interface VimExtension {
|
|||||||
|
|
||||||
default void dispose() {
|
default void dispose() {
|
||||||
VimPlugin.getKey().removeKeyMapping(getOwner());
|
VimPlugin.getKey().removeKeyMapping(getOwner());
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
@@ -22,14 +22,15 @@ import com.intellij.openapi.extensions.ExtensionPointListener
|
|||||||
import com.intellij.openapi.extensions.PluginDescriptor
|
import com.intellij.openapi.extensions.PluginDescriptor
|
||||||
import com.maddyhome.idea.vim.VimPlugin
|
import com.maddyhome.idea.vim.VimPlugin
|
||||||
import com.maddyhome.idea.vim.key.MappingOwner.Plugin.Companion.remove
|
import com.maddyhome.idea.vim.key.MappingOwner.Plugin.Companion.remove
|
||||||
|
import com.maddyhome.idea.vim.option.OptionsManager
|
||||||
import com.maddyhome.idea.vim.option.OptionsManager.addOption
|
import com.maddyhome.idea.vim.option.OptionsManager.addOption
|
||||||
import com.maddyhome.idea.vim.option.OptionsManager.isSet
|
import com.maddyhome.idea.vim.option.OptionsManager.isSet
|
||||||
import com.maddyhome.idea.vim.option.OptionsManager.removeOption
|
import com.maddyhome.idea.vim.option.OptionsManager.removeOption
|
||||||
import com.maddyhome.idea.vim.option.ToggleOption
|
import com.maddyhome.idea.vim.option.ToggleOption
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
object VimExtensionRegistrar {
|
object VimExtensionRegistrar {
|
||||||
private val registeredExtensions: MutableSet<String> = HashSet()
|
private val registeredExtensions: MutableSet<String> = HashSet()
|
||||||
|
private val extensionAliases = HashMap<String, String>()
|
||||||
private var extensionRegistered = false
|
private var extensionRegistered = false
|
||||||
private val logger = logger<VimExtensionRegistrar>()
|
private val logger = logger<VimExtensionRegistrar>()
|
||||||
|
|
||||||
@@ -37,48 +38,67 @@ object VimExtensionRegistrar {
|
|||||||
fun registerExtensions() {
|
fun registerExtensions() {
|
||||||
if (extensionRegistered) return
|
if (extensionRegistered) return
|
||||||
extensionRegistered = true
|
extensionRegistered = true
|
||||||
|
|
||||||
|
VimExtension.EP_NAME.extensions.forEach(this::registerExtension)
|
||||||
|
|
||||||
// [VERSION UPDATE] 202+
|
// [VERSION UPDATE] 202+
|
||||||
@Suppress("DEPRECATION")
|
@Suppress("DEPRECATION")
|
||||||
VimExtension.EP_NAME.getPoint(null).addExtensionPointListener(object : ExtensionPointListener<VimExtension> {
|
VimExtension.EP_NAME.getPoint(null).addExtensionPointListener(object : ExtensionPointListener<ExtensionBeanClass> {
|
||||||
override fun extensionAdded(extension: VimExtension, pluginDescriptor: PluginDescriptor) {
|
override fun extensionAdded(extension: ExtensionBeanClass, pluginDescriptor: PluginDescriptor) {
|
||||||
registerExtension(extension)
|
registerExtension(extension)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun extensionRemoved(extension: VimExtension, pluginDescriptor: PluginDescriptor) {
|
override fun extensionRemoved(extension: ExtensionBeanClass, pluginDescriptor: PluginDescriptor) {
|
||||||
unregisterExtension(extension)
|
unregisterExtension(extension)
|
||||||
}
|
}
|
||||||
}, true, VimPlugin.getInstance())
|
}, false, VimPlugin.getInstance())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
private fun registerExtension(extension: VimExtension) {
|
private fun registerExtension(extensionBean: ExtensionBeanClass) {
|
||||||
val name = extension.name
|
val name = extensionBean.name ?: extensionBean.handler.name
|
||||||
if (name in registeredExtensions) return
|
if (name in registeredExtensions) return
|
||||||
|
|
||||||
registeredExtensions.add(name)
|
registeredExtensions.add(name)
|
||||||
|
registerAliases(extensionBean)
|
||||||
val option = ToggleOption(name, name, false)
|
val option = ToggleOption(name, name, false)
|
||||||
option.addOptionChangeListener { _, _ ->
|
option.addOptionChangeListener { _, _ ->
|
||||||
for (extensionInListener in VimExtension.EP_NAME.extensionList) {
|
if (isSet(name)) {
|
||||||
if (name != extensionInListener.name) continue
|
extensionBean.handler.init()
|
||||||
if (isSet(name)) {
|
logger.info("IdeaVim extension '$name' initialized")
|
||||||
extensionInListener.init()
|
} else {
|
||||||
logger.info("IdeaVim extension '$name' initialized")
|
extensionBean.handler.dispose()
|
||||||
} else {
|
|
||||||
extensionInListener.dispose()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
addOption(option)
|
addOption(option)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
private fun unregisterExtension(extension: VimExtension) {
|
private fun unregisterExtension(extension: ExtensionBeanClass) {
|
||||||
val name = extension.name
|
val name = extension.name ?: extension.handler.name
|
||||||
if (name !in registeredExtensions) return
|
if (name !in registeredExtensions) return
|
||||||
registeredExtensions.remove(name)
|
registeredExtensions.remove(name)
|
||||||
extension.dispose()
|
removeAliases(extension)
|
||||||
|
if (extension.initialized.get()) {
|
||||||
|
extension.handler.dispose()
|
||||||
|
}
|
||||||
removeOption(name)
|
removeOption(name)
|
||||||
remove(name)
|
remove(name)
|
||||||
logger.info("IdeaVim extension '$name' disposed")
|
logger.info("IdeaVim extension '$name' disposed")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getToggleByAlias(alias: String): ToggleOption? {
|
||||||
|
val name = extensionAliases[alias] ?: return null
|
||||||
|
return OptionsManager.getOption(name) as ToggleOption?
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun registerAliases(extension: ExtensionBeanClass) {
|
||||||
|
extension.aliases
|
||||||
|
?.mapNotNull { it.name }
|
||||||
|
?.forEach { alias -> extensionAliases[alias] = extension.name ?: extension.handler.name }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun removeAliases(extension: ExtensionBeanClass) {
|
||||||
|
extension.aliases?.mapNotNull { it.name }?.forEach { extensionAliases.remove(it) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -17,8 +17,7 @@ import com.maddyhome.idea.vim.listener.VimListenerSuppressor;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.EnumSet;
|
import java.util.*;
|
||||||
import java.util.Stack;
|
|
||||||
|
|
||||||
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;
|
||||||
@@ -50,13 +49,13 @@ public class VimArgTextObjExtension implements VimExtension {
|
|||||||
/**
|
/**
|
||||||
* The pairs of brackets that delimit different types of argument lists.
|
* The pairs of brackets that delimit different types of argument lists.
|
||||||
*/
|
*/
|
||||||
static private class BracketPairs {
|
private static class BracketPairs {
|
||||||
// NOTE: brackets must match by the position, and ordered by rank (highest to lowest).
|
// NOTE: brackets must match by the position, and ordered by rank (highest to lowest).
|
||||||
@NotNull private final String openBrackets;
|
@NotNull private final String openBrackets;
|
||||||
@NotNull private final String closeBrackets;
|
@NotNull private final String closeBrackets;
|
||||||
|
|
||||||
static class ParseError extends Exception {
|
static class ParseException extends Exception {
|
||||||
public ParseError(@NotNull String message) {
|
public ParseException(@NotNull String message) {
|
||||||
super(message);
|
super(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -73,10 +72,10 @@ public class VimArgTextObjExtension implements VimExtension {
|
|||||||
* as VIM's @c matchpairs option: "(:),{:},[:]"
|
* as VIM's @c matchpairs option: "(:),{:},[:]"
|
||||||
*
|
*
|
||||||
* @param bracketPairs comma-separated list of colon-separated bracket pairs.
|
* @param bracketPairs comma-separated list of colon-separated bracket pairs.
|
||||||
* @throws ParseError if a syntax error is detected.
|
* @throws ParseException if a syntax error is detected.
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
static BracketPairs fromBracketPairList(@NotNull final String bracketPairs) throws ParseError {
|
static BracketPairs fromBracketPairList(@NotNull final String bracketPairs) throws ParseException {
|
||||||
StringBuilder openBrackets = new StringBuilder();
|
StringBuilder openBrackets = new StringBuilder();
|
||||||
StringBuilder closeBrackets = new StringBuilder();
|
StringBuilder closeBrackets = new StringBuilder();
|
||||||
ParseState state = ParseState.OPEN;
|
ParseState state = ParseState.OPEN;
|
||||||
@@ -90,13 +89,13 @@ public class VimArgTextObjExtension implements VimExtension {
|
|||||||
if (ch == ':') {
|
if (ch == ':') {
|
||||||
state = ParseState.CLOSE;
|
state = ParseState.CLOSE;
|
||||||
} else {
|
} else {
|
||||||
throw new ParseError("expecting ':', but got '" + ch + "' instead");
|
throw new ParseException("expecting ':', but got '" + ch + "' instead");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CLOSE:
|
case CLOSE:
|
||||||
final char lastOpenBracket = openBrackets.charAt(openBrackets.length() - 1);
|
final char lastOpenBracket = openBrackets.charAt(openBrackets.length() - 1);
|
||||||
if (lastOpenBracket == ch) {
|
if (lastOpenBracket == ch) {
|
||||||
throw new ParseError("open and close brackets must be different");
|
throw new ParseException("open and close brackets must be different");
|
||||||
}
|
}
|
||||||
closeBrackets.append(ch);
|
closeBrackets.append(ch);
|
||||||
state = ParseState.COMMA;
|
state = ParseState.COMMA;
|
||||||
@@ -105,13 +104,13 @@ public class VimArgTextObjExtension implements VimExtension {
|
|||||||
if (ch == ',') {
|
if (ch == ',') {
|
||||||
state = ParseState.OPEN;
|
state = ParseState.OPEN;
|
||||||
} else {
|
} else {
|
||||||
throw new ParseError("expecting ',', but got '" + ch + "' instead");
|
throw new ParseException("expecting ',', but got '" + ch + "' instead");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (state != ParseState.COMMA) {
|
if (state != ParseState.COMMA) {
|
||||||
throw new ParseError("list of pairs is incomplete");
|
throw new ParseException("list of pairs is incomplete");
|
||||||
}
|
}
|
||||||
return new BracketPairs(openBrackets.toString(), closeBrackets.toString());
|
return new BracketPairs(openBrackets.toString(), closeBrackets.toString());
|
||||||
}
|
}
|
||||||
@@ -183,8 +182,8 @@ public class VimArgTextObjExtension implements VimExtension {
|
|||||||
if (bracketPairsVar != null) {
|
if (bracketPairsVar != null) {
|
||||||
try {
|
try {
|
||||||
bracketPairs = BracketPairs.fromBracketPairList(bracketPairsVar);
|
bracketPairs = BracketPairs.fromBracketPairList(bracketPairsVar);
|
||||||
} catch (BracketPairs.ParseError parseError) {
|
} catch (BracketPairs.ParseException parseException) {
|
||||||
VimPlugin.showMessage("argtextobj: Invalid value of g:argtextobj_pairs -- " + parseError.getMessage());
|
VimPlugin.showMessage("argtextobj: Invalid value of g:argtextobj_pairs -- " + parseException.getMessage());
|
||||||
VimPlugin.indicateError();
|
VimPlugin.indicateError();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -590,20 +589,20 @@ public class VimArgTextObjExtension implements VimExtension {
|
|||||||
private int skipSexp(final int start, final int end, SexpDirection dir) {
|
private int skipSexp(final int start, final int end, SexpDirection dir) {
|
||||||
char lastChar = getCharAt(start);
|
char lastChar = getCharAt(start);
|
||||||
assert dir.isOpenBracket(lastChar);
|
assert dir.isOpenBracket(lastChar);
|
||||||
Stack<Character> bracketStack = new Stack<>();
|
Deque<Character> bracketStack = new ArrayDeque<>();
|
||||||
bracketStack.push(lastChar);
|
bracketStack.push(lastChar);
|
||||||
int i = start + dir.delta();
|
int i = start + dir.delta();
|
||||||
while (!bracketStack.empty() && i != end) {
|
while (!bracketStack.isEmpty() && i != end) {
|
||||||
final char ch = getCharAt(i);
|
final char ch = getCharAt(i);
|
||||||
if (dir.isOpenBracket(ch)) {
|
if (dir.isOpenBracket(ch)) {
|
||||||
bracketStack.push(ch);
|
bracketStack.push(ch);
|
||||||
} else {
|
} else {
|
||||||
if (dir.isCloseBracket(ch)) {
|
if (dir.isCloseBracket(ch)) {
|
||||||
if (bracketStack.lastElement() == brackets.matchingBracket(ch)) {
|
if (bracketStack.getLast() == brackets.matchingBracket(ch)) {
|
||||||
bracketStack.pop();
|
bracketStack.pop();
|
||||||
} else {
|
} else {
|
||||||
//noinspection StatementWithEmptyBody
|
//noinspection StatementWithEmptyBody
|
||||||
if (brackets.getBracketPrio(ch) < brackets.getBracketPrio(bracketStack.lastElement())) {
|
if (brackets.getBracketPrio(ch) < brackets.getBracketPrio(bracketStack.getLast())) {
|
||||||
// (<...) -> (...)
|
// (<...) -> (...)
|
||||||
bracketStack.pop();
|
bracketStack.pop();
|
||||||
// Retry the same character again for cases like (...<<...).
|
// Retry the same character again for cases like (...<<...).
|
||||||
@@ -621,7 +620,7 @@ public class VimArgTextObjExtension implements VimExtension {
|
|||||||
}
|
}
|
||||||
i += dir.delta();
|
i += dir.delta();
|
||||||
}
|
}
|
||||||
if (bracketStack.empty()) {
|
if (bracketStack.isEmpty()) {
|
||||||
return i;
|
return i;
|
||||||
} else {
|
} else {
|
||||||
return start + dir.delta();
|
return start + dir.delta();
|
||||||
|
@@ -64,6 +64,7 @@ import com.maddyhome.idea.vim.key.OperatorFunction
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
class VimExchangeExtension : VimExtension {
|
class VimExchangeExtension : VimExtension {
|
||||||
|
|
||||||
override fun getName() = "exchange"
|
override fun getName() = "exchange"
|
||||||
|
|
||||||
override fun init() {
|
override fun init() {
|
||||||
|
@@ -18,6 +18,8 @@
|
|||||||
|
|
||||||
package com.maddyhome.idea.vim.extension.highlightedyank
|
package com.maddyhome.idea.vim.extension.highlightedyank
|
||||||
|
|
||||||
|
import com.intellij.ide.ui.LafManager
|
||||||
|
import com.intellij.ide.ui.LafManagerListener
|
||||||
import com.intellij.openapi.Disposable
|
import com.intellij.openapi.Disposable
|
||||||
import com.intellij.openapi.application.ApplicationManager
|
import com.intellij.openapi.application.ApplicationManager
|
||||||
import com.intellij.openapi.editor.Editor
|
import com.intellij.openapi.editor.Editor
|
||||||
@@ -44,8 +46,19 @@ import java.util.concurrent.TimeUnit
|
|||||||
const val DEFAULT_HIGHLIGHT_DURATION: Long = 300
|
const val DEFAULT_HIGHLIGHT_DURATION: Long = 300
|
||||||
private const val HIGHLIGHT_DURATION_VARIABLE_NAME = "g:highlightedyank_highlight_duration"
|
private const val HIGHLIGHT_DURATION_VARIABLE_NAME = "g:highlightedyank_highlight_duration"
|
||||||
private const val HIGHLIGHT_COLOR_VARIABLE_NAME = "g:highlightedyank_highlight_color"
|
private const val HIGHLIGHT_COLOR_VARIABLE_NAME = "g:highlightedyank_highlight_color"
|
||||||
private val DEFAULT_HIGHLIGHT_TEXT_COLOR: Color = EditorColors.TEXT_SEARCH_RESULT_ATTRIBUTES.defaultAttributes.backgroundColor
|
private var defaultHighlightTextColor: Color? = null
|
||||||
|
|
||||||
|
private fun getDefaultHighlightTextColor(): Color {
|
||||||
|
return defaultHighlightTextColor
|
||||||
|
?: return EditorColors.TEXT_SEARCH_RESULT_ATTRIBUTES.defaultAttributes.backgroundColor
|
||||||
|
.also { defaultHighlightTextColor = it }
|
||||||
|
}
|
||||||
|
|
||||||
|
class HighlightColorResetter : LafManagerListener {
|
||||||
|
override fun lookAndFeelChanged(source: LafManager) {
|
||||||
|
defaultHighlightTextColor = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author KostkaBrukowa (@kostkabrukowa)
|
* @author KostkaBrukowa (@kostkabrukowa)
|
||||||
@@ -164,7 +177,7 @@ class VimHighlightedYank: VimExtension, VimYankListener, VimInsertListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun extractUsersHighlightColor(): Color {
|
private fun extractUsersHighlightColor(): Color {
|
||||||
return extractVariable(HIGHLIGHT_COLOR_VARIABLE_NAME, DEFAULT_HIGHLIGHT_TEXT_COLOR) { value ->
|
return extractVariable(HIGHLIGHT_COLOR_VARIABLE_NAME, getDefaultHighlightTextColor()) { value ->
|
||||||
val rgba = value
|
val rgba = value
|
||||||
.substring(4)
|
.substring(4)
|
||||||
.filter { it != '(' && it != ')' && !it.isWhitespace() }
|
.filter { it != '(' && it != ')' && !it.isWhitespace() }
|
||||||
|
@@ -57,6 +57,7 @@ private const val ALL_OCCURRENCES = "<Plug>AllOccurrences"
|
|||||||
* See https://github.com/terryma/vim-multiple-cursors
|
* See https://github.com/terryma/vim-multiple-cursors
|
||||||
* */
|
* */
|
||||||
class VimMultipleCursorsExtension : VimExtension {
|
class VimMultipleCursorsExtension : VimExtension {
|
||||||
|
|
||||||
override fun getName() = "multiple-cursors"
|
override fun getName() = "multiple-cursors"
|
||||||
|
|
||||||
override fun init() {
|
override fun init() {
|
||||||
|
@@ -34,7 +34,6 @@ import com.maddyhome.idea.vim.extension.VimExtensionFacade.putKeyMapping
|
|||||||
import com.maddyhome.idea.vim.extension.VimExtensionFacade.setOperatorFunction
|
import com.maddyhome.idea.vim.extension.VimExtensionFacade.setOperatorFunction
|
||||||
import com.maddyhome.idea.vim.extension.VimExtensionHandler
|
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.RegisterGroup
|
|
||||||
import com.maddyhome.idea.vim.group.copy.PutData
|
import com.maddyhome.idea.vim.group.copy.PutData
|
||||||
import com.maddyhome.idea.vim.group.visual.VimSelection
|
import com.maddyhome.idea.vim.group.visual.VimSelection
|
||||||
import com.maddyhome.idea.vim.helper.EditorDataContext
|
import com.maddyhome.idea.vim.helper.EditorDataContext
|
||||||
@@ -46,6 +45,7 @@ import com.maddyhome.idea.vim.key.OperatorFunction
|
|||||||
|
|
||||||
|
|
||||||
class ReplaceWithRegister : VimExtension {
|
class ReplaceWithRegister : VimExtension {
|
||||||
|
|
||||||
override fun getName(): String = "ReplaceWithRegister"
|
override fun getName(): String = "ReplaceWithRegister"
|
||||||
|
|
||||||
override fun init() {
|
override fun init() {
|
||||||
@@ -144,7 +144,7 @@ class ReplaceWithRegister : VimExtension {
|
|||||||
VimPlugin.getPut().putText(editor, EditorDataContext(editor), putData)
|
VimPlugin.getPut().putText(editor, EditorDataContext(editor), putData)
|
||||||
|
|
||||||
VimPlugin.getRegister().saveRegister(savedRegister.name, savedRegister)
|
VimPlugin.getRegister().saveRegister(savedRegister.name, savedRegister)
|
||||||
VimPlugin.getRegister().saveRegister(RegisterGroup.DEFAULT_REGISTER, savedRegister)
|
VimPlugin.getRegister().saveRegister(VimPlugin.getRegister().defaultRegister, savedRegister)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -52,6 +52,7 @@ import javax.swing.KeyStroke
|
|||||||
* @author vlan
|
* @author vlan
|
||||||
*/
|
*/
|
||||||
class VimSurroundExtension : VimExtension {
|
class VimSurroundExtension : VimExtension {
|
||||||
|
|
||||||
override fun getName() = "surround"
|
override fun getName() = "surround"
|
||||||
|
|
||||||
override fun init() {
|
override fun init() {
|
||||||
|
@@ -61,12 +61,14 @@ import static com.maddyhome.idea.vim.helper.StringHelper.parseKeys;
|
|||||||
* @author Alexandre Grison (@agrison)
|
* @author Alexandre Grison (@agrison)
|
||||||
*/
|
*/
|
||||||
public class VimTextObjEntireExtension implements VimExtension {
|
public class VimTextObjEntireExtension implements VimExtension {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NotNull
|
public @NotNull
|
||||||
String getName() {
|
String getName() {
|
||||||
return "textobj-entire";
|
return "textobj-entire";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init() {
|
public void init() {
|
||||||
putExtensionHandlerMapping(MappingMode.XO, parseKeys("<Plug>textobj-entire-a"), getOwner(),
|
putExtensionHandlerMapping(MappingMode.XO, parseKeys("<Plug>textobj-entire-a"), getOwner(),
|
||||||
|
@@ -1254,10 +1254,9 @@ public class ChangeGroup {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (kludge) {
|
if (kludge) {
|
||||||
int size = fileSize;
|
|
||||||
int cnt = count * motion.getCount();
|
int cnt = count * motion.getCount();
|
||||||
int pos1 = SearchHelper.findNextWordEnd(chars, offset, size, cnt, bigWord, false);
|
int pos1 = SearchHelper.findNextWordEnd(chars, offset, fileSize, cnt, bigWord, false);
|
||||||
int pos2 = SearchHelper.findNextWordEnd(chars, pos1, size, -cnt, bigWord, false);
|
int pos2 = SearchHelper.findNextWordEnd(chars, pos1, fileSize, -cnt, bigWord, false);
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug("pos=" + offset);
|
logger.debug("pos=" + offset);
|
||||||
logger.debug("pos1=" + pos1);
|
logger.debug("pos1=" + pos1);
|
||||||
@@ -1773,7 +1772,7 @@ public class ChangeGroup {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void resetCaret(@NotNull VirtualFile virtualFile, Project proj, boolean insert) {
|
private static void resetCaret(@NotNull VirtualFile virtualFile, Project proj, boolean insert) {
|
||||||
logger.info("Reset caret to a " + (insert ? "non-block" : "block") + " shape");
|
logger.debug("Reset caret to a " + (insert ? "non-block" : "block") + " shape");
|
||||||
Document doc = FileDocumentManager.getInstance().getDocument(virtualFile);
|
Document doc = FileDocumentManager.getInstance().getDocument(virtualFile);
|
||||||
if (doc == null) return; // Must be no text editor (such as image)
|
if (doc == null) return; // Must be no text editor (such as image)
|
||||||
Editor[] editors = EditorFactory.getInstance().getEditors(doc, proj);
|
Editor[] editors = EditorFactory.getInstance().getEditors(doc, proj);
|
||||||
@@ -1978,7 +1977,7 @@ public class ChangeGroup {
|
|||||||
if (!Character.isLetter(ch)) throw new RuntimeException("Not alpha number : " + text);
|
if (!Character.isLetter(ch)) throw new RuntimeException("Not alpha number : " + text);
|
||||||
ch += count;
|
ch += count;
|
||||||
if (Character.isLetter(ch)) {
|
if (Character.isLetter(ch)) {
|
||||||
number = "" + ch;
|
number = String.valueOf(ch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (SearchHelper.NumberType.DEC.equals(numberType)) {
|
else if (SearchHelper.NumberType.DEC.equals(numberType)) {
|
||||||
|
@@ -51,7 +51,7 @@ class CommandGroup {
|
|||||||
return name in this.aliases
|
return name in this.aliases
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getAlias(name: String): Alias {
|
private fun getAlias(name: String): Alias {
|
||||||
return this.aliases[name]!!
|
return this.aliases[name]!!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -498,8 +498,8 @@ public class KeyGroup implements PersistentStateComponent<Element> {
|
|||||||
if (action instanceof VimShortcutKeyAction) {
|
if (action instanceof VimShortcutKeyAction) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
final com.intellij.openapi.actionSystem.Shortcut[] shortcuts = action.getShortcutSet().getShortcuts();
|
final Shortcut[] shortcuts = action.getShortcutSet().getShortcuts();
|
||||||
for (com.intellij.openapi.actionSystem.Shortcut shortcut : shortcuts) {
|
for (Shortcut shortcut : shortcuts) {
|
||||||
if (shortcut.isKeyboard() && shortcut.startsWith(keyStrokeShortcut) && !results.contains(action)) {
|
if (shortcut.isKeyboard() && shortcut.startsWith(keyStrokeShortcut) && !results.contains(action)) {
|
||||||
results.add(action);
|
results.add(action);
|
||||||
}
|
}
|
||||||
|
@@ -122,7 +122,7 @@ public class MarkGroup implements PersistentStateComponent<Element> {
|
|||||||
else if (FILE_MARKS.indexOf(ch) >= 0) {
|
else if (FILE_MARKS.indexOf(ch) >= 0) {
|
||||||
final HashMap<Character, Mark> fmarks = getFileMarks(editor.getDocument());
|
final HashMap<Character, Mark> fmarks = getFileMarks(editor.getDocument());
|
||||||
if (fmarks != null) {
|
if (fmarks != null) {
|
||||||
mark = (Mark)fmarks.get(ch);
|
mark = fmarks.get(ch);
|
||||||
if (mark != null && mark.isClear()) {
|
if (mark != null && mark.isClear()) {
|
||||||
fmarks.remove(ch);
|
fmarks.remove(ch);
|
||||||
mark = null;
|
mark = null;
|
||||||
@@ -171,7 +171,7 @@ public class MarkGroup implements PersistentStateComponent<Element> {
|
|||||||
if (fmarks == null) {
|
if (fmarks == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
Mark mark = (Mark)fmarks.get(ch);
|
Mark mark = fmarks.get(ch);
|
||||||
if (mark != null && mark.isClear()) {
|
if (mark != null && mark.isClear()) {
|
||||||
fmarks.remove(ch);
|
fmarks.remove(ch);
|
||||||
mark = null;
|
mark = null;
|
||||||
@@ -752,7 +752,7 @@ public class MarkGroup implements PersistentStateComponent<Element> {
|
|||||||
|
|
||||||
public static class MarkListener implements BookmarksListener {
|
public static class MarkListener implements BookmarksListener {
|
||||||
|
|
||||||
private WeakReference<Project> project;
|
private final WeakReference<Project> project;
|
||||||
private Bookmark bookmarkTemplate = null;
|
private Bookmark bookmarkTemplate = null;
|
||||||
|
|
||||||
@Contract(pure = true)
|
@Contract(pure = true)
|
||||||
|
@@ -42,10 +42,12 @@ 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.option.NumberOption;
|
import com.maddyhome.idea.vim.option.NumberOption;
|
||||||
|
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.ExEntryPanel;
|
||||||
import kotlin.Pair;
|
import kotlin.Pair;
|
||||||
import kotlin.ranges.IntProgression;
|
import kotlin.ranges.IntProgression;
|
||||||
|
import org.jetbrains.annotations.Contract;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
@@ -184,7 +186,7 @@ public class MotionGroup {
|
|||||||
if (caretVisualLine < topVisualLine + scrollOffset) {
|
if (caretVisualLine < topVisualLine + scrollOffset) {
|
||||||
newVisualLine = normalizeVisualLine(editor, topVisualLine + scrollOffset);
|
newVisualLine = normalizeVisualLine(editor, topVisualLine + scrollOffset);
|
||||||
}
|
}
|
||||||
else if (caretVisualLine >= bottomVisualLine - scrollOffset) {
|
else if (caretVisualLine > bottomVisualLine - scrollOffset) {
|
||||||
newVisualLine = normalizeVisualLine(editor, bottomVisualLine - scrollOffset);
|
newVisualLine = normalizeVisualLine(editor, bottomVisualLine - scrollOffset);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -631,10 +633,10 @@ public class MotionGroup {
|
|||||||
private static void scrollCaretIntoViewVertically(@NotNull Editor editor, final int caretLine) {
|
private static void scrollCaretIntoViewVertically(@NotNull Editor editor, final int caretLine) {
|
||||||
|
|
||||||
// TODO: Make this work with soft wraps
|
// TODO: Make this work with soft wraps
|
||||||
// Vim's algorithm works counts line heights for wrapped lines. We're using visual lines, which handles collapsed
|
// Vim's algorithm works by counting line heights for wrapped lines. We're using visual lines, which handles
|
||||||
// folds, but treats soft wrapped lines as individual lines.
|
// collapsed folds, but treats soft wrapped lines as individual lines.
|
||||||
// Ironically, after figuring out how Vim's algorithm works (although not *why*), it looks likely to be rewritten as
|
// Ironically, after figuring out how Vim's algorithm works (although not *why*) and reimplementing, it looks likely
|
||||||
// a dumb line for line reimplementation.
|
// that this needs to be replaced as a more or less dumb line for line rewrite.
|
||||||
|
|
||||||
final int topLine = getVisualLineAtTopOfScreen(editor);
|
final int topLine = getVisualLineAtTopOfScreen(editor);
|
||||||
final int bottomLine = getVisualLineAtBottomOfScreen(editor);
|
final int bottomLine = getVisualLineAtBottomOfScreen(editor);
|
||||||
@@ -642,7 +644,7 @@ public class MotionGroup {
|
|||||||
// We need the non-normalised value here, so we can handle cases such as so=999 to keep the current line centred
|
// We need the non-normalised value here, so we can handle cases such as so=999 to keep the current line centred
|
||||||
final int scrollOffset = OptionsManager.INSTANCE.getScrolloff().value();
|
final int scrollOffset = OptionsManager.INSTANCE.getScrolloff().value();
|
||||||
final int topBound = topLine + scrollOffset;
|
final int topBound = topLine + scrollOffset;
|
||||||
final int bottomBound = Math.max(topBound + 1, bottomLine - scrollOffset);
|
final int bottomBound = Math.max(topBound, bottomLine - scrollOffset);
|
||||||
|
|
||||||
// If we need to scroll the current line more than half a screen worth of lines then we just centre the new
|
// If we need to scroll the current line more than half a screen worth of lines then we just centre the new
|
||||||
// current line. This mimics vim behavior of e.g. 100G in a 300 line file with a screen size of 25 centering line
|
// current line. This mimics vim behavior of e.g. 100G in a 300 line file with a screen size of 25 centering line
|
||||||
@@ -650,7 +652,6 @@ public class MotionGroup {
|
|||||||
// Note that block inlays means that the pixel height we are scrolling can be larger than half the screen, even if
|
// Note that block inlays means that the pixel height we are scrolling can be larger than half the screen, even if
|
||||||
// the number of lines is less. I'm not sure what impact this has.
|
// the number of lines is less. I'm not sure what impact this has.
|
||||||
final int height = bottomLine - topLine + 1;
|
final int height = bottomLine - topLine + 1;
|
||||||
final int halfHeight = Math.max(2, (height / 2) - 1);
|
|
||||||
|
|
||||||
// Scrolljump isn't handled as you might expect. It is the minimal number of lines to scroll, but that doesn't mean
|
// Scrolljump isn't handled as you might expect. It is the minimal number of lines to scroll, but that doesn't mean
|
||||||
// newLine = caretLine +/- MAX(sj, so)
|
// newLine = caretLine +/- MAX(sj, so)
|
||||||
@@ -663,7 +664,7 @@ public class MotionGroup {
|
|||||||
// (See move.c:scroll_cursor_top)
|
// (See move.c:scroll_cursor_top)
|
||||||
//
|
//
|
||||||
// When scrolling down (`j` - scrolling window down in the buffer; more lines are visible at the bottom), Vim again
|
// When scrolling down (`j` - scrolling window down in the buffer; more lines are visible at the bottom), Vim again
|
||||||
// expands lines above and below the new bottom line, but calcualtes things a little differently. The total number
|
// expands lines above and below the new bottom line, but calculates things a little differently. The total number
|
||||||
// of lines expanded is at least scrolljump and there must be at least scrolloff lines below.
|
// of lines expanded is at least scrolljump and there must be at least scrolloff lines below.
|
||||||
// Since the lines are advancing simultaneously, it is only possible to get scrolljump/2 above the new cursor line.
|
// Since the lines are advancing simultaneously, it is only possible to get scrolljump/2 above the new cursor line.
|
||||||
// If there are fewer than scrolljump/2 lines between the current bottom line and the new cursor line, the extra
|
// If there are fewer than scrolljump/2 lines between the current bottom line and the new cursor line, the extra
|
||||||
@@ -678,10 +679,26 @@ public class MotionGroup {
|
|||||||
// out correct scroll locations
|
// out correct scroll locations
|
||||||
final int scrollJump = getScrollJump(editor, height);
|
final int scrollJump = getScrollJump(editor, height);
|
||||||
|
|
||||||
if (caretLine < topBound) {
|
// Unavoidable fudge value. Multiline rendered doc comments can mean we have very few actual lines, and scrolling
|
||||||
|
// can get stuck in a loop as we re-centre the cursor instead of actually moving it. But if we ignore all inlays
|
||||||
|
// and use the approximate screen height instead of the actual screen height (in lines), we make incorrect
|
||||||
|
// assumptions about the top/bottom line numbers and can scroll to the wrong location. E.g. if there are enough doc
|
||||||
|
// comments (String.java) it's possible to get 12 lines of actual code on screen. Given scrolloff=5, it's very easy
|
||||||
|
// to hit problems, and have (scrolloffset > height / 2) and scroll to the middle of the screen. We'll use this
|
||||||
|
// fudge value to make sure we're working with sensible values. Note that this problem doesn't affect code without
|
||||||
|
// block inlays as positioning the cursor in the middle of the screen always positions it in a deterministic manner,
|
||||||
|
// relative to other text in the file.
|
||||||
|
final int inlayAwareMinHeightFudge = getApproximateScreenHeight(editor) / 2;
|
||||||
|
|
||||||
|
// Note that while these calculations do the same thing that Vim does, it processes them differently. E.g. it
|
||||||
|
// optionally checks and moves the top line, then optionally checks the bottom line. This gives us the same results
|
||||||
|
// via the tests.
|
||||||
|
if (height > inlayAwareMinHeightFudge && scrollOffset > height / 2) {
|
||||||
|
scrollVisualLineToMiddleOfScreen(editor, caretLine);
|
||||||
|
} else if (caretLine < topBound) {
|
||||||
// Scrolling up, put the cursor at the top of the window (minus scrolloff)
|
// Scrolling up, put the cursor at the top of the window (minus scrolloff)
|
||||||
// Initial approximation in move.c:update_topline
|
// Initial approximation in move.c:update_topline (including same calculation for halfHeight)
|
||||||
if (topLine + scrollOffset - caretLine >= halfHeight) {
|
if (topLine + scrollOffset - caretLine >= Math.max(2, (height / 2) - 1)) {
|
||||||
scrollVisualLineToMiddleOfScreen(editor, caretLine);
|
scrollVisualLineToMiddleOfScreen(editor, caretLine);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -692,9 +709,12 @@ public class MotionGroup {
|
|||||||
final int scrollOffsetTopLine = Math.max(0, caretLine - scrollOffset);
|
final int scrollOffsetTopLine = Math.max(0, caretLine - scrollOffset);
|
||||||
final int newTopLine = Math.min(scrollOffsetTopLine, scrollJumpTopLine);
|
final int newTopLine = Math.min(scrollOffsetTopLine, scrollJumpTopLine);
|
||||||
|
|
||||||
// Used is set to the line height of caretLine, and then incremented by line height of the lines above and
|
// Used is set to the line height of caretLine (1 or how many lines soft wraps take up), and then incremented by
|
||||||
// below caretLine (up to scrolloff or end of file)
|
// the line heights of the lines above and below caretLine (up to scrolloff or end of file).
|
||||||
final int used = 1 + (newTopLine - topLine) + Math.min(scrollOffset, getVisualLineCount(editor) - topLine);
|
// Our implementation ignores soft wrap line heights. Folds already have a line height of 1.
|
||||||
|
final int usedAbove = caretLine - newTopLine;
|
||||||
|
final int usedBelow = Math.min(scrollOffset, getVisualLineCount(editor) - caretLine);
|
||||||
|
final int used = 1 + usedAbove + usedBelow;
|
||||||
if (used > height) {
|
if (used > height) {
|
||||||
scrollVisualLineToMiddleOfScreen(editor, caretLine);
|
scrollVisualLineToMiddleOfScreen(editor, caretLine);
|
||||||
}
|
}
|
||||||
@@ -1374,4 +1394,21 @@ public class MotionGroup {
|
|||||||
return moveCaretToLineEnd(editor, visualLineToLogicalLine(editor, line), allowPastEnd);
|
return moveCaretToLineEnd(editor, visualLineToLogicalLine(editor, line), allowPastEnd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class ScrollOptionsChangeListener implements OptionChangeListener<String> {
|
||||||
|
public static ScrollOptionsChangeListener INSTANCE = new ScrollOptionsChangeListener();
|
||||||
|
|
||||||
|
@Contract(pure = true)
|
||||||
|
private ScrollOptionsChangeListener() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void valueChange(String oldValue, String newValue) {
|
||||||
|
for (Editor editor : EditorFactory.getInstance().getAllEditors()) {
|
||||||
|
if (UserDataManager.getVimEditorGroup(editor)) {
|
||||||
|
MotionGroup.scrollCaretIntoView(editor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -52,7 +52,7 @@ public class ProcessGroup {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String initText = "";
|
String initText = "";
|
||||||
String label = "" + leader;
|
String label = String.valueOf(leader);
|
||||||
|
|
||||||
ExEntryPanel panel = ExEntryPanel.getInstance();
|
ExEntryPanel panel = ExEntryPanel.getInstance();
|
||||||
panel.activate(editor, context, label, initText, count);
|
panel.activate(editor, context, label, initText, count);
|
||||||
|
@@ -88,9 +88,9 @@ public class RegisterGroup implements PersistentStateComponent<Element> {
|
|||||||
private static final List<Character> CLIPBOARD_REGISTERS = ImmutableList.of('*', '+');
|
private static final List<Character> CLIPBOARD_REGISTERS = ImmutableList.of('*', '+');
|
||||||
private static final Logger logger = Logger.getInstance(RegisterGroup.class.getName());
|
private static final Logger logger = Logger.getInstance(RegisterGroup.class.getName());
|
||||||
|
|
||||||
public final static char UNNAMED_REGISTER = '"';
|
public static final char UNNAMED_REGISTER = '"';
|
||||||
public static char DEFAULT_REGISTER = UNNAMED_REGISTER;
|
private char defaultRegister = UNNAMED_REGISTER;
|
||||||
private char lastRegister = DEFAULT_REGISTER;
|
private char lastRegister = defaultRegister;
|
||||||
private final @NotNull HashMap<Character, Register> registers = new HashMap<>();
|
private final @NotNull HashMap<Character, Register> registers = new HashMap<>();
|
||||||
private char recordRegister = 0;
|
private char recordRegister = 0;
|
||||||
private @Nullable List<KeyStroke> recordList = null;
|
private @Nullable List<KeyStroke> recordList = null;
|
||||||
@@ -99,15 +99,15 @@ public class RegisterGroup implements PersistentStateComponent<Element> {
|
|||||||
final ListOption clipboardOption = OptionsManager.INSTANCE.getClipboard();
|
final ListOption clipboardOption = OptionsManager.INSTANCE.getClipboard();
|
||||||
clipboardOption.addOptionChangeListenerAndExecute((oldValue, newValue) -> {
|
clipboardOption.addOptionChangeListenerAndExecute((oldValue, newValue) -> {
|
||||||
if (clipboardOption.contains("unnamed")) {
|
if (clipboardOption.contains("unnamed")) {
|
||||||
DEFAULT_REGISTER = '*';
|
defaultRegister = '*';
|
||||||
}
|
}
|
||||||
else if (clipboardOption.contains("unnamedplus")) {
|
else if (clipboardOption.contains("unnamedplus")) {
|
||||||
DEFAULT_REGISTER = '+';
|
defaultRegister = '+';
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
DEFAULT_REGISTER = UNNAMED_REGISTER;
|
defaultRegister = UNNAMED_REGISTER;
|
||||||
}
|
}
|
||||||
lastRegister = DEFAULT_REGISTER;
|
lastRegister = defaultRegister;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,7 +144,7 @@ public class RegisterGroup implements PersistentStateComponent<Element> {
|
|||||||
* Reset the selected register back to the default register.
|
* Reset the selected register back to the default register.
|
||||||
*/
|
*/
|
||||||
public void resetRegister() {
|
public void resetRegister() {
|
||||||
lastRegister = DEFAULT_REGISTER;
|
lastRegister = defaultRegister;
|
||||||
logger.debug("Last register reset to default register");
|
logger.debug("Last register reset to default register");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -228,7 +228,7 @@ public class RegisterGroup implements PersistentStateComponent<Element> {
|
|||||||
editor.offsetToLogicalPosition(start).line == editor.offsetToLogicalPosition(end).line;
|
editor.offsetToLogicalPosition(start).line == editor.offsetToLogicalPosition(end).line;
|
||||||
|
|
||||||
// Deletes go into numbered registers only if text is smaller than a line, register is used or it's a special case
|
// Deletes go into numbered registers only if text is smaller than a line, register is used or it's a special case
|
||||||
if (!smallInlineDeletion || register != DEFAULT_REGISTER || isSmallDeletionSpecialCase(editor)) {
|
if (!smallInlineDeletion || register != defaultRegister || isSmallDeletionSpecialCase(editor)) {
|
||||||
// Old 1 goes to 2, etc. Old 8 to 9, old 9 is lost
|
// Old 1 goes to 2, etc. Old 8 to 9, old 9 is lost
|
||||||
for (char d = '8'; d >= '1'; d--) {
|
for (char d = '8'; d >= '1'; d--) {
|
||||||
Register t = registers.get(d);
|
Register t = registers.get(d);
|
||||||
@@ -241,12 +241,12 @@ public class RegisterGroup implements PersistentStateComponent<Element> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Deletes smaller than one line and without specified register go the the "-" register
|
// Deletes smaller than one line and without specified register go the the "-" register
|
||||||
if (smallInlineDeletion && register == DEFAULT_REGISTER) {
|
if (smallInlineDeletion && register == defaultRegister) {
|
||||||
registers.put('-', new Register('-', type, processedText, new ArrayList<>(transferableData)));
|
registers.put('-', new Register('-', type, processedText, new ArrayList<>(transferableData)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Yanks also go to register 0 if the default register was used
|
// Yanks also go to register 0 if the default register was used
|
||||||
else if (register == DEFAULT_REGISTER) {
|
else if (register == defaultRegister) {
|
||||||
registers.put('0', new Register('0', type, processedText, new ArrayList<>(transferableData)));
|
registers.put('0', new Register('0', type, processedText, new ArrayList<>(transferableData)));
|
||||||
if (logger.isDebugEnabled()) logger.debug("register '" + '0' + "' contains: \"" + processedText + "\"");
|
if (logger.isDebugEnabled()) logger.debug("register '" + '0' + "' contains: \"" + processedText + "\"");
|
||||||
}
|
}
|
||||||
@@ -372,7 +372,7 @@ public class RegisterGroup implements PersistentStateComponent<Element> {
|
|||||||
* The register key for the default register.
|
* The register key for the default register.
|
||||||
*/
|
*/
|
||||||
public char getDefaultRegister() {
|
public char getDefaultRegister() {
|
||||||
return DEFAULT_REGISTER;
|
return defaultRegister;
|
||||||
}
|
}
|
||||||
|
|
||||||
public @NotNull List<Register> getRegisters() {
|
public @NotNull List<Register> getRegisters() {
|
||||||
|
@@ -874,7 +874,7 @@ public class SearchGroup implements PersistentStateComponent<Element> {
|
|||||||
|
|
||||||
private int findItOffset(@NotNull Editor editor, int startOffset, int count, int dir) {
|
private int findItOffset(@NotNull Editor editor, int startOffset, int count, int dir) {
|
||||||
boolean wrap = OptionsManager.INSTANCE.getWrapscan().isSet();
|
boolean wrap = OptionsManager.INSTANCE.getWrapscan().isSet();
|
||||||
logger.info("Perform search. Direction: " + dir + " wrap: " + wrap);
|
logger.debug("Perform search. Direction: " + dir + " wrap: " + wrap);
|
||||||
|
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
boolean offsetIsLineOffset = false;
|
boolean offsetIsLineOffset = false;
|
||||||
@@ -977,11 +977,8 @@ public class SearchGroup implements PersistentStateComponent<Element> {
|
|||||||
|
|
||||||
res = search(editor, lastOffset.substring(ppos + 1), res, 1, flags);
|
res = search(editor, lastOffset.substring(ppos + 1), res, 1, flags);
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@RWLockLabel.SelfSynchronized
|
@RWLockLabel.SelfSynchronized
|
||||||
|
@@ -182,7 +182,7 @@ class YankGroup {
|
|||||||
|
|
||||||
private fun yankRange(editor: Editor, range: TextRange, type: SelectionType,
|
private fun yankRange(editor: Editor, range: TextRange, type: SelectionType,
|
||||||
startOffsets: Map<Caret, Int>?): Boolean {
|
startOffsets: Map<Caret, Int>?): Boolean {
|
||||||
startOffsets?.forEach { caret, offset -> MotionGroup.moveCaret(editor, caret, offset) }
|
startOffsets?.forEach { (caret, offset) -> MotionGroup.moveCaret(editor, caret, offset) }
|
||||||
|
|
||||||
notifyListeners(editor, range)
|
notifyListeners(editor, range)
|
||||||
|
|
||||||
|
@@ -55,7 +55,7 @@ object IdeaSelectionControl {
|
|||||||
|
|
||||||
if (editor.isIdeaVimDisabledHere) return@singleTask
|
if (editor.isIdeaVimDisabledHere) return@singleTask
|
||||||
|
|
||||||
logger.info("Adjust non-vim selection. Source: $selectionSource")
|
logger.debug("Adjust non-vim selection. Source: $selectionSource")
|
||||||
|
|
||||||
// Perform logic in one of the next cases:
|
// Perform logic in one of the next cases:
|
||||||
// - There was no selection and now it is
|
// - There was no selection and now it is
|
||||||
@@ -69,13 +69,13 @@ object IdeaSelectionControl {
|
|||||||
return@singleTask
|
return@singleTask
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info("Some carets have selection. State before adjustment: ${editor.commandState.toSimpleString()}")
|
logger.debug("Some carets have selection. State before adjustment: ${editor.commandState.toSimpleString()}")
|
||||||
|
|
||||||
editor.popAllModes()
|
editor.popAllModes()
|
||||||
|
|
||||||
activateMode(editor, chooseSelectionMode(editor, selectionSource, true))
|
activateMode(editor, chooseSelectionMode(editor, selectionSource, true))
|
||||||
} else {
|
} else {
|
||||||
logger.info("None of carets have selection. State before adjustment: ${editor.commandState.toSimpleString()}")
|
logger.debug("None of carets have selection. State before adjustment: ${editor.commandState.toSimpleString()}")
|
||||||
if (editor.inVisualMode) editor.exitVisualMode()
|
if (editor.inVisualMode) editor.exitVisualMode()
|
||||||
if (editor.inSelectMode) editor.exitSelectMode(false)
|
if (editor.inSelectMode) editor.exitSelectMode(false)
|
||||||
|
|
||||||
@@ -86,7 +86,7 @@ object IdeaSelectionControl {
|
|||||||
|
|
||||||
KeyHandler.getInstance().reset(editor)
|
KeyHandler.getInstance().reset(editor)
|
||||||
updateCaretState(editor)
|
updateCaretState(editor)
|
||||||
logger.info("${editor.mode} is enabled")
|
logger.debug("${editor.mode} is enabled")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,23 +132,23 @@ object IdeaSelectionControl {
|
|||||||
private fun chooseSelectionMode(editor: Editor, selectionSource: VimListenerManager.SelectionSource, logReason: Boolean): CommandState.Mode {
|
private fun chooseSelectionMode(editor: Editor, selectionSource: VimListenerManager.SelectionSource, logReason: Boolean): CommandState.Mode {
|
||||||
return when {
|
return when {
|
||||||
editor.isOneLineMode -> {
|
editor.isOneLineMode -> {
|
||||||
if (logReason) logger.info("Enter select mode. Reason: one line mode")
|
if (logReason) logger.debug("Enter select mode. Reason: one line mode")
|
||||||
CommandState.Mode.SELECT
|
CommandState.Mode.SELECT
|
||||||
}
|
}
|
||||||
selectionSource == VimListenerManager.SelectionSource.MOUSE && SelectModeOptionData.mouse in OptionsManager.selectmode -> {
|
selectionSource == VimListenerManager.SelectionSource.MOUSE && SelectModeOptionData.mouse in OptionsManager.selectmode -> {
|
||||||
if (logReason) logger.info("Enter select mode. Selection source is mouse and selectMode option has mouse")
|
if (logReason) logger.debug("Enter select mode. Selection source is mouse and selectMode option has mouse")
|
||||||
CommandState.Mode.SELECT
|
CommandState.Mode.SELECT
|
||||||
}
|
}
|
||||||
editor.isTemplateActive() && IdeaRefactorMode.selectMode() -> {
|
editor.isTemplateActive() && IdeaRefactorMode.selectMode() -> {
|
||||||
if (logReason) logger.info("Enter select mode. Template is active and selectMode has template")
|
if (logReason) logger.debug("Enter select mode. Template is active and selectMode has template")
|
||||||
CommandState.Mode.SELECT
|
CommandState.Mode.SELECT
|
||||||
}
|
}
|
||||||
selectionSource == VimListenerManager.SelectionSource.OTHER && SelectModeOptionData.ideaselectionEnabled() -> {
|
selectionSource == VimListenerManager.SelectionSource.OTHER && SelectModeOptionData.ideaselectionEnabled() -> {
|
||||||
if (logReason) logger.info("Enter select mode. Selection source is OTHER and selectMode has refactoring")
|
if (logReason) logger.debug("Enter select mode. Selection source is OTHER and selectMode has refactoring")
|
||||||
CommandState.Mode.SELECT
|
CommandState.Mode.SELECT
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
if (logReason) logger.info("Enter visual mode")
|
if (logReason) logger.debug("Enter visual mode")
|
||||||
CommandState.Mode.VISUAL
|
CommandState.Mode.VISUAL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -152,7 +152,7 @@ class VimBlockSelection(
|
|||||||
override val vimStart: Int,
|
override val vimStart: Int,
|
||||||
override val vimEnd: Int,
|
override val vimEnd: Int,
|
||||||
override val editor: Editor,
|
override val editor: Editor,
|
||||||
val toLineEnd: Boolean
|
private val toLineEnd: Boolean
|
||||||
) : VimSelection() {
|
) : VimSelection() {
|
||||||
override fun getNativeStartAndEnd() = blockToNativeSelection(editor, vimStart, vimEnd, CommandState.Mode.VISUAL).let {
|
override fun getNativeStartAndEnd() = blockToNativeSelection(editor, vimStart, vimEnd, CommandState.Mode.VISUAL).let {
|
||||||
editor.logicalPositionToOffset(it.first) to editor.logicalPositionToOffset(it.second)
|
editor.logicalPositionToOffset(it.first) to editor.logicalPositionToOffset(it.second)
|
||||||
|
@@ -43,6 +43,12 @@ import static java.lang.Integer.max;
|
|||||||
* This is a set of helper methods for working with editors. All line and column values are zero based.
|
* This is a set of helper methods for working with editors. All line and column values are zero based.
|
||||||
*/
|
*/
|
||||||
public class EditorHelper {
|
public class EditorHelper {
|
||||||
|
// Set a max height on block inlays to be made visible at the top/bottom of a line when scrolling up/down. This
|
||||||
|
// mitigates the visible area bouncing around too much and even pushing the cursor line off screen with large
|
||||||
|
// multiline rendered doc comments, while still providing some visibility of the block inlay (e.g. Rider's single line
|
||||||
|
// Code Vision)
|
||||||
|
private static final int BLOCK_INLAY_MAX_LINE_HEIGHT = 3;
|
||||||
|
|
||||||
public static @NotNull Rectangle getVisibleArea(final @NotNull Editor editor) {
|
public static @NotNull Rectangle getVisibleArea(final @NotNull Editor editor) {
|
||||||
return editor.getScrollingModel().getVisibleAreaOnScrollingFinished();
|
return editor.getScrollingModel().getVisibleAreaOnScrollingFinished();
|
||||||
}
|
}
|
||||||
@@ -201,7 +207,7 @@ public class EditorHelper {
|
|||||||
* @param editor The editor
|
* @param editor The editor
|
||||||
* @return The number of screen lines
|
* @return The number of screen lines
|
||||||
*/
|
*/
|
||||||
private static int getApproximateScreenHeight(final @NotNull Editor editor) {
|
public static int getApproximateScreenHeight(final @NotNull Editor editor) {
|
||||||
return getVisibleArea(editor).height / editor.getLineHeight();
|
return getVisibleArea(editor).height / editor.getLineHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -641,7 +647,10 @@ public class EditorHelper {
|
|||||||
* @return Returns true if the window was moved
|
* @return Returns true if the window was moved
|
||||||
*/
|
*/
|
||||||
public static boolean scrollVisualLineToTopOfScreen(final @NotNull Editor editor, int visualLine) {
|
public static boolean scrollVisualLineToTopOfScreen(final @NotNull Editor editor, int visualLine) {
|
||||||
int y = EditorUtil.getVisualLineAreaStartY(editor, normalizeVisualLine(editor, visualLine));
|
|
||||||
|
final int inlayHeight = EditorUtil.getInlaysHeight(editor, visualLine, true);
|
||||||
|
final int maxInlayHeight = BLOCK_INLAY_MAX_LINE_HEIGHT * editor.getLineHeight();
|
||||||
|
int y = editor.visualLineToY(visualLine) - Math.min(inlayHeight, maxInlayHeight);
|
||||||
|
|
||||||
// Normalise Y so that we don't try to scroll the editor to a location it can't reach. The editor will handle this,
|
// Normalise Y so that we don't try to scroll the editor to a location it can't reach. The editor will handle this,
|
||||||
// but when we ask for the target location to move the caret to match, we'll get the incorrect value.
|
// but when we ask for the target location to move the caret to match, we'll get the incorrect value.
|
||||||
@@ -653,7 +662,7 @@ public class EditorHelper {
|
|||||||
// Get the max line number that can sit at the top of the screen
|
// Get the max line number that can sit at the top of the screen
|
||||||
final int editorHeight = getVisibleArea(editor).height;
|
final int editorHeight = getVisibleArea(editor).height;
|
||||||
final int virtualSpaceHeight = editor.getSettings().getAdditionalLinesCount() * editor.getLineHeight();
|
final int virtualSpaceHeight = editor.getSettings().getAdditionalLinesCount() * editor.getLineHeight();
|
||||||
final int yLastLine = editor.visualLineToY(EditorHelper.getLineCount(editor)); // last line + 1
|
final int yLastLine = editor.visualLineToY(getLineCount(editor)); // last line + 1
|
||||||
y = Math.min(y, yLastLine + virtualSpaceHeight - editorHeight);
|
y = Math.min(y, yLastLine + virtualSpaceHeight - editorHeight);
|
||||||
}
|
}
|
||||||
return scrollVertically(editor, y);
|
return scrollVertically(editor, y);
|
||||||
@@ -662,21 +671,25 @@ public class EditorHelper {
|
|||||||
/**
|
/**
|
||||||
* Scrolls the editor to place the given visual line in the middle of the current window.
|
* Scrolls the editor to place the given visual line in the middle of the current window.
|
||||||
*
|
*
|
||||||
|
* <p>Snaps the line to the nearest standard line height grid, which gives a good position for both an odd and even
|
||||||
|
* number of lines and mimics what Vim does.</p>
|
||||||
|
*
|
||||||
* @param editor The editor to scroll
|
* @param editor The editor to scroll
|
||||||
* @param visualLine The visual line to place in the middle of the current window
|
* @param visualLine The visual line to place in the middle of the current window
|
||||||
*/
|
*/
|
||||||
public static void scrollVisualLineToMiddleOfScreen(@NotNull Editor editor, int visualLine) {
|
public static void scrollVisualLineToMiddleOfScreen(@NotNull Editor editor, int visualLine) {
|
||||||
int y = editor.visualLineToY(normalizeVisualLine(editor, visualLine));
|
final int y = editor.visualLineToY(normalizeVisualLine(editor, visualLine));
|
||||||
int lineHeight = editor.getLineHeight();
|
final int screenHeight = getVisibleArea(editor).height;
|
||||||
int height = getVisibleArea(editor).height;
|
final int lineHeight = editor.getLineHeight();
|
||||||
scrollVertically(editor, y - ((height - lineHeight) / 2));
|
scrollVertically(editor, y - ((screenHeight - lineHeight) / lineHeight / 2 * lineHeight));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scrolls the editor to place the given visual line at the bottom of the screen.
|
* Scrolls the editor to place the given visual line at the bottom of the screen.
|
||||||
*
|
*
|
||||||
* When we're moving the caret down a few lines and want to scroll to keep this visible, we need to be able to place a
|
* <p>When we're moving the caret down a few lines and want to scroll to keep this visible, we need to be able to
|
||||||
* line at the bottom of the screen. Due to block inlays, we can't do this by specifying a top line to scroll to.
|
* place a line at the bottom of the screen. Due to block inlays, we can't do this by specifying a top line to scroll
|
||||||
|
* to.</p>
|
||||||
*
|
*
|
||||||
* @param editor The editor to scroll
|
* @param editor The editor to scroll
|
||||||
* @param visualLine The visual line to place at the bottom of the current window
|
* @param visualLine The visual line to place at the bottom of the current window
|
||||||
@@ -690,7 +703,12 @@ public class EditorHelper {
|
|||||||
if (ExEntryPanel.getInstanceWithoutShortcuts().isActive()) {
|
if (ExEntryPanel.getInstanceWithoutShortcuts().isActive()) {
|
||||||
exPanelHeight += ExEntryPanel.getInstanceWithoutShortcuts().getHeight();
|
exPanelHeight += ExEntryPanel.getInstanceWithoutShortcuts().getHeight();
|
||||||
}
|
}
|
||||||
final int y = EditorUtil.getVisualLineAreaEndY(editor, normalizeVisualLine(editor, visualLine)) + exPanelHeight;
|
|
||||||
|
final int normalizedVisualLine = normalizeVisualLine(editor, visualLine);
|
||||||
|
final int lineHeight = editor.getLineHeight();
|
||||||
|
final int inlayHeight = EditorUtil.getInlaysHeight(editor, normalizedVisualLine, false);
|
||||||
|
final int maxInlayHeight = BLOCK_INLAY_MAX_LINE_HEIGHT * lineHeight;
|
||||||
|
final int y = editor.visualLineToY(normalizedVisualLine) + lineHeight + Math.min(inlayHeight, maxInlayHeight) + exPanelHeight;
|
||||||
final Rectangle visibleArea = getVisibleArea(editor);
|
final Rectangle visibleArea = getVisibleArea(editor);
|
||||||
return scrollVertically(editor, max(0, y - visibleArea.height));
|
return scrollVertically(editor, max(0, y - visibleArea.height));
|
||||||
}
|
}
|
||||||
@@ -714,19 +732,19 @@ public class EditorHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final int columnLeftX = editor.visualPositionToXY(new VisualPosition(visualLine, targetVisualColumn)).x;
|
final int columnLeftX = editor.visualPositionToXY(new VisualPosition(visualLine, targetVisualColumn)).x;
|
||||||
EditorHelper.scrollHorizontally(editor, columnLeftX);
|
scrollHorizontally(editor, columnLeftX);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void scrollColumnToMiddleOfScreen(@NotNull Editor editor, int visualLine, int visualColumn) {
|
public static void scrollColumnToMiddleOfScreen(@NotNull Editor editor, int visualLine, int visualColumn) {
|
||||||
final Point point = editor.visualPositionToXY(new VisualPosition(visualLine, visualColumn));
|
final Point point = editor.visualPositionToXY(new VisualPosition(visualLine, visualColumn));
|
||||||
final int screenWidth = EditorHelper.getVisibleArea(editor).width;
|
final int screenWidth = getVisibleArea(editor).width;
|
||||||
|
|
||||||
// Snap the column to the nearest standard column grid. This positions us nicely if there are an odd or even number
|
// Snap the column to the nearest standard column grid. This positions us nicely if there are an odd or even number
|
||||||
// of columns. It also works with inline inlays and folds. It is slightly inaccurate for proportional fonts, but is
|
// of columns. It also works with inline inlays and folds. It is slightly inaccurate for proportional fonts, but is
|
||||||
// still a good solution. Besides, what kind of monster uses Vim with proportional fonts?
|
// still a good solution. Besides, what kind of monster uses Vim with proportional fonts?
|
||||||
final int standardColumnWidth = EditorUtil.getPlainSpaceWidth(editor);
|
final int standardColumnWidth = EditorUtil.getPlainSpaceWidth(editor);
|
||||||
final int x = point.x - (screenWidth / standardColumnWidth / 2 * standardColumnWidth);
|
final int x = point.x - (screenWidth / standardColumnWidth / 2 * standardColumnWidth);
|
||||||
EditorHelper.scrollHorizontally(editor, x);
|
scrollHorizontally(editor, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void scrollColumnToRightOfScreen(@NotNull Editor editor, int visualLine, int visualColumn) {
|
public static void scrollColumnToRightOfScreen(@NotNull Editor editor, int visualLine, int visualColumn) {
|
||||||
@@ -751,8 +769,8 @@ public class EditorHelper {
|
|||||||
|
|
||||||
// Scroll to the left edge of the target column, minus a screenwidth, and adjusted for inlays
|
// Scroll to the left edge of the target column, minus a screenwidth, and adjusted for inlays
|
||||||
final int targetColumnRightX = editor.visualPositionToXY(new VisualPosition(visualLine, targetVisualColumn + 1)).x;
|
final int targetColumnRightX = editor.visualPositionToXY(new VisualPosition(visualLine, targetVisualColumn + 1)).x;
|
||||||
final int screenWidth = EditorHelper.getVisibleArea(editor).width;
|
final int screenWidth = getVisibleArea(editor).width;
|
||||||
EditorHelper.scrollHorizontally(editor, targetColumnRightX - screenWidth);
|
scrollHorizontally(editor, targetColumnRightX - screenWidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -20,14 +20,15 @@
|
|||||||
|
|
||||||
package com.maddyhome.idea.vim.helper
|
package com.maddyhome.idea.vim.helper
|
||||||
|
|
||||||
import com.intellij.ide.ui.laf.darcula.DarculaUIUtil
|
|
||||||
import com.intellij.openapi.diagnostic.logger
|
import com.intellij.openapi.diagnostic.logger
|
||||||
import com.intellij.openapi.editor.Caret
|
|
||||||
import com.intellij.openapi.editor.Editor
|
import com.intellij.openapi.editor.Editor
|
||||||
import com.intellij.openapi.editor.VisualPosition
|
|
||||||
import com.intellij.openapi.editor.ex.util.EditorUtil
|
import com.intellij.openapi.editor.ex.util.EditorUtil
|
||||||
import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx
|
import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx
|
||||||
|
import com.intellij.util.ui.table.JBTableRowEditor
|
||||||
import com.maddyhome.idea.vim.option.OptionsManager
|
import com.maddyhome.idea.vim.option.OptionsManager
|
||||||
|
import java.awt.Component
|
||||||
|
import javax.swing.JComponent
|
||||||
|
import javax.swing.JTable
|
||||||
import kotlin.system.measureTimeMillis
|
import kotlin.system.measureTimeMillis
|
||||||
|
|
||||||
val Editor.fileSize: Int
|
val Editor.fileSize: Int
|
||||||
@@ -41,26 +42,33 @@ val Editor.isIdeaVimDisabledHere: Boolean
|
|||||||
get() {
|
get() {
|
||||||
var res = true
|
var res = true
|
||||||
val start = System.currentTimeMillis()
|
val start = System.currentTimeMillis()
|
||||||
val times = mutableListOf<Long>()
|
val times = mutableListOf<Pair<Long, String>>()
|
||||||
val timeForCalculation = measureTimeMillis {
|
val timeForCalculation = measureTimeMillis {
|
||||||
res = (disabledInDialog.apply { times += System.currentTimeMillis() }
|
res = (disabledInDialog.apply { times += System.currentTimeMillis() to "Disabled in dialog" }
|
||||||
|| (!OptionsManager.ideaenabledbufs.contains("singleline") && isDatabaseCell).apply { times += System.currentTimeMillis() }
|
|
||||||
|| (!OptionsManager.ideaenabledbufs.contains("singleline") && isOneLineMode).apply { times += System.currentTimeMillis() }
|
|| (!OptionsManager.ideavimsupport.contains("singleline")
|
||||||
|
.apply { times += System.currentTimeMillis() to "first single line check" }
|
||||||
|
&& isDatabaseCell(times).apply { times += System.currentTimeMillis() to "is db cell" })
|
||||||
|
|
||||||
|
|| (!OptionsManager.ideavimsupport.contains("singleline")
|
||||||
|
.apply { times += System.currentTimeMillis() to "second single line check" }
|
||||||
|
&& isOneLineMode.apply { times += System.currentTimeMillis() to "is one line" })
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
if (timeForCalculation > 10) {
|
if (timeForCalculation > 10) {
|
||||||
val timeDiffs = times.map { it - start }
|
val timeDiffs = times.map { it.second + ": " + (it.first - start) }
|
||||||
val message = "Time for calculation of 'isIdeaVimDisabledHere' took $timeForCalculation ms. Time diff: $timeDiffs"
|
val message = "Time for calculation of 'isIdeaVimDisabledHere' took $timeForCalculation ms. Time diff: $timeDiffs"
|
||||||
logger<Editor>().error(message)
|
logger<Editor>().error(message)
|
||||||
}
|
}
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
private val Editor.isDatabaseCell: Boolean
|
private fun Editor.isDatabaseCell(times: MutableList<Pair<Long, String>>): Boolean {
|
||||||
get() = DarculaUIUtil.isTableCellEditor(this.component)
|
return isTableCellEditor(this.component, times)
|
||||||
|
}
|
||||||
|
|
||||||
private val Editor.disabledInDialog: Boolean
|
private val Editor.disabledInDialog: Boolean
|
||||||
get() = (!OptionsManager.ideaenabledbufs.contains("dialog") && !OptionsManager.ideaenabledbufs.contains("dialoglegacy"))
|
get() = (!OptionsManager.ideavimsupport.contains("dialog") && !OptionsManager.ideavimsupport.contains("dialoglegacy"))
|
||||||
&& (!this.isPrimaryEditor() && !EditorHelper.isFileEditor(this))
|
&& (!this.isPrimaryEditor() && !EditorHelper.isFileEditor(this))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -72,3 +80,26 @@ fun Editor.isPrimaryEditor(): Boolean {
|
|||||||
return fileEditorManager.allEditors.any { fileEditor -> this == EditorUtil.getEditorEx(fileEditor) }
|
return fileEditorManager.allEditors.any { fileEditor -> this == EditorUtil.getEditorEx(fileEditor) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Optimized clone of com.intellij.ide.ui.laf.darcula.DarculaUIUtil.isTableCellEditor
|
||||||
|
private fun isTableCellEditor(c: Component, times: MutableList<Pair<Long, String>>): Boolean {
|
||||||
|
return (java.lang.Boolean.TRUE == (c as JComponent).getClientProperty("JComboBox.isTableCellEditor"))
|
||||||
|
.apply { times += System.currentTimeMillis() to "is property tru" } ||
|
||||||
|
|
||||||
|
(findParentByCondition(c) { it is JTable } != null)
|
||||||
|
.apply { times += System.currentTimeMillis() to "is not null" } &&
|
||||||
|
|
||||||
|
(findParentByCondition(c) { it is JBTableRowEditor } == null)
|
||||||
|
.apply { times += System.currentTimeMillis() to "is null" }
|
||||||
|
}
|
||||||
|
|
||||||
|
private const val PARENT_BY_CONDITION_DEPTH = 10
|
||||||
|
|
||||||
|
private inline fun findParentByCondition(c: Component?, condition: (Component?) -> Boolean): Component? {
|
||||||
|
var eachParent = c
|
||||||
|
var goDeep = PARENT_BY_CONDITION_DEPTH
|
||||||
|
while (eachParent != null && --goDeep > 0) {
|
||||||
|
if (condition(eachParent)) return eachParent
|
||||||
|
eachParent = eachParent.parent
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
@@ -138,7 +138,7 @@ public class SearchHelper {
|
|||||||
type == chars.charAt(start - 1) &&
|
type == chars.charAt(start - 1) &&
|
||||||
end < chars.length() &&
|
end < chars.length() &&
|
||||||
close == chars.charAt(end)) {
|
close == chars.charAt(end)) {
|
||||||
start = start - 1;
|
start -= 1;
|
||||||
pos = start;
|
pos = start;
|
||||||
rangeSelection = true;
|
rangeSelection = true;
|
||||||
}
|
}
|
||||||
@@ -608,7 +608,7 @@ public class SearchHelper {
|
|||||||
final Pattern tagPattern = Pattern.compile(String.format("(?:%s)|(?:%s)", openingTagPattern, closingTagPattern));
|
final Pattern tagPattern = Pattern.compile(String.format("(?:%s)|(?:%s)", openingTagPattern, closingTagPattern));
|
||||||
final Matcher matcher = tagPattern.matcher(sequence.subSequence(position, sequence.length()));
|
final Matcher matcher = tagPattern.matcher(sequence.subSequence(position, sequence.length()));
|
||||||
|
|
||||||
final Stack<String> openTags = new Stack<>();
|
final Deque<String> openTags = new ArrayDeque<>();
|
||||||
|
|
||||||
while (matcher.find()) {
|
while (matcher.find()) {
|
||||||
boolean isClosingTag = matcher.group(1) == null;
|
boolean isClosingTag = matcher.group(1) == null;
|
||||||
@@ -655,7 +655,7 @@ public class SearchHelper {
|
|||||||
final Pattern tagPattern =
|
final Pattern tagPattern =
|
||||||
Pattern.compile(String.format(patternString, quotedTagName, quotedTagName), Pattern.CASE_INSENSITIVE);
|
Pattern.compile(String.format(patternString, quotedTagName, quotedTagName), Pattern.CASE_INSENSITIVE);
|
||||||
final Matcher matcher = tagPattern.matcher(sequence.subSequence(0, position + 1));
|
final Matcher matcher = tagPattern.matcher(sequence.subSequence(0, position + 1));
|
||||||
final Stack<TextRange> openTags = new Stack<>();
|
final Deque<TextRange> openTags = new ArrayDeque<>();
|
||||||
|
|
||||||
while (matcher.find()) {
|
while (matcher.find()) {
|
||||||
final TextRange match = new TextRange(matcher.start(), matcher.end());
|
final TextRange match = new TextRange(matcher.start(), matcher.end());
|
||||||
@@ -786,7 +786,7 @@ public class SearchHelper {
|
|||||||
if (pos == size - 1 ||
|
if (pos == size - 1 ||
|
||||||
!Character.isLetter(chars.charAt(pos + 1)) ||
|
!Character.isLetter(chars.charAt(pos + 1)) ||
|
||||||
(Character.isUpperCase(chars.charAt(pos + 1)) &&
|
(Character.isUpperCase(chars.charAt(pos + 1)) &&
|
||||||
pos <= size - 2 &&
|
pos < size - 2 &&
|
||||||
Character.isLowerCase(chars.charAt(pos + 2)))) {
|
Character.isLowerCase(chars.charAt(pos + 2)))) {
|
||||||
res = pos;
|
res = pos;
|
||||||
found++;
|
found++;
|
||||||
@@ -1375,7 +1375,7 @@ public class SearchHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (goForward && anyNonWhitespace(editor, end, 1)) {
|
if (goForward && anyNonWhitespace(editor, end, 1)) {
|
||||||
while (end < max &&
|
while (end + 1 < max &&
|
||||||
CharacterHelper.charType(chars.charAt(end + 1), false) == CharacterHelper.CharacterType.WHITESPACE) {
|
CharacterHelper.charType(chars.charAt(end + 1), false) == CharacterHelper.CharacterType.WHITESPACE) {
|
||||||
end++;
|
end++;
|
||||||
}
|
}
|
||||||
|
@@ -115,13 +115,10 @@ public class StringHelper {
|
|||||||
break;
|
break;
|
||||||
case ESCAPE:
|
case ESCAPE:
|
||||||
state = KeyParserState.INIT;
|
state = KeyParserState.INIT;
|
||||||
if (c == '\\' || c == '<') {
|
if (c != '\\' && c != '<') {
|
||||||
result.add(getKeyStroke(c));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
result.add(getKeyStroke('\\'));
|
result.add(getKeyStroke('\\'));
|
||||||
result.add(getKeyStroke(c));
|
|
||||||
}
|
}
|
||||||
|
result.add(getKeyStroke(c));
|
||||||
break;
|
break;
|
||||||
case SPECIAL:
|
case SPECIAL:
|
||||||
if (c == '>' || c == '»') {
|
if (c == '>' || c == '»') {
|
||||||
@@ -168,7 +165,7 @@ public class StringHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static @Nullable List<KeyStroke> parseMapLeader(@NotNull String s) {
|
private static @Nullable List<KeyStroke> parseMapLeader(@NotNull String s) {
|
||||||
if ("leader".equals(s.toLowerCase())) {
|
if ("leader".equalsIgnoreCase(s)) {
|
||||||
final Object mapLeader = VimScriptGlobalEnvironment.getInstance().getVariables().get("mapleader");
|
final Object mapLeader = VimScriptGlobalEnvironment.getInstance().getVariables().get("mapleader");
|
||||||
if (mapLeader instanceof String) {
|
if (mapLeader instanceof String) {
|
||||||
return stringToKeys((String)mapLeader);
|
return stringToKeys((String)mapLeader);
|
||||||
@@ -292,7 +289,7 @@ public class StringHelper {
|
|||||||
} else if (CharacterHelper.isInvisibleControlCharacter(c) || CharacterHelper.isZeroWidthCharacter(c)) {
|
} else if (CharacterHelper.isInvisibleControlCharacter(c) || CharacterHelper.isZeroWidthCharacter(c)) {
|
||||||
return String.format("<%04x>", (int) c);
|
return String.format("<%04x>", (int) c);
|
||||||
}
|
}
|
||||||
return "" + c;
|
return String.valueOf(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean containsUpperCase(@NotNull String text) {
|
public static boolean containsUpperCase(@NotNull String text) {
|
||||||
@@ -430,7 +427,6 @@ public class StringHelper {
|
|||||||
case "esc":
|
case "esc":
|
||||||
return VK_ESCAPE;
|
return VK_ESCAPE;
|
||||||
case "bs":
|
case "bs":
|
||||||
return VK_BACK_SPACE;
|
|
||||||
case "backspace":
|
case "backspace":
|
||||||
return VK_BACK_SPACE;
|
return VK_BACK_SPACE;
|
||||||
case "tab":
|
case "tab":
|
||||||
|
@@ -101,7 +101,7 @@ class ToKeysMappingInfo(
|
|||||||
}
|
}
|
||||||
|
|
||||||
class ToHandlerMappingInfo(
|
class ToHandlerMappingInfo(
|
||||||
val extensionHandler: VimExtensionHandler,
|
private val extensionHandler: VimExtensionHandler,
|
||||||
fromKeys: List<KeyStroke>,
|
fromKeys: List<KeyStroke>,
|
||||||
isRecursive: Boolean,
|
isRecursive: Boolean,
|
||||||
owner: MappingOwner
|
owner: MappingOwner
|
||||||
|
@@ -106,6 +106,7 @@ object VimListenerManager {
|
|||||||
|
|
||||||
OptionsManager.number.addOptionChangeListener(EditorGroup.NumberChangeListener.INSTANCE)
|
OptionsManager.number.addOptionChangeListener(EditorGroup.NumberChangeListener.INSTANCE)
|
||||||
OptionsManager.relativenumber.addOptionChangeListener(EditorGroup.NumberChangeListener.INSTANCE)
|
OptionsManager.relativenumber.addOptionChangeListener(EditorGroup.NumberChangeListener.INSTANCE)
|
||||||
|
OptionsManager.scrolloff.addOptionChangeListener(MotionGroup.ScrollOptionsChangeListener.INSTANCE)
|
||||||
OptionsManager.showcmd.addOptionChangeListener(ShowCmdOptionChangeListener)
|
OptionsManager.showcmd.addOptionChangeListener(ShowCmdOptionChangeListener)
|
||||||
|
|
||||||
EventFacade.getInstance().addEditorFactoryListener(VimEditorFactoryListener, VimPlugin.getInstance())
|
EventFacade.getInstance().addEditorFactoryListener(VimEditorFactoryListener, VimPlugin.getInstance())
|
||||||
@@ -116,6 +117,7 @@ object VimListenerManager {
|
|||||||
|
|
||||||
OptionsManager.number.removeOptionChangeListener(EditorGroup.NumberChangeListener.INSTANCE)
|
OptionsManager.number.removeOptionChangeListener(EditorGroup.NumberChangeListener.INSTANCE)
|
||||||
OptionsManager.relativenumber.removeOptionChangeListener(EditorGroup.NumberChangeListener.INSTANCE)
|
OptionsManager.relativenumber.removeOptionChangeListener(EditorGroup.NumberChangeListener.INSTANCE)
|
||||||
|
OptionsManager.scrolloff.removeOptionChangeListener(MotionGroup.ScrollOptionsChangeListener.INSTANCE)
|
||||||
OptionsManager.showcmd.removeOptionChangeListener(ShowCmdOptionChangeListener)
|
OptionsManager.showcmd.removeOptionChangeListener(ShowCmdOptionChangeListener)
|
||||||
|
|
||||||
EventFacade.getInstance().removeEditorFactoryListener(VimEditorFactoryListener)
|
EventFacade.getInstance().removeEditorFactoryListener(VimEditorFactoryListener)
|
||||||
@@ -212,7 +214,7 @@ object VimListenerManager {
|
|||||||
val document = editor.document
|
val document = editor.document
|
||||||
|
|
||||||
if (SelectionVimListenerSuppressor.isNotLocked) {
|
if (SelectionVimListenerSuppressor.isNotLocked) {
|
||||||
logger.info("Adjust non vim selection change")
|
logger.debug("Adjust non vim selection change")
|
||||||
IdeaSelectionControl.controlNonVimSelectionChange(editor)
|
IdeaSelectionControl.controlNonVimSelectionChange(editor)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -213,7 +213,7 @@ public final class KeywordOption extends ListOption {
|
|||||||
} 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 {
|
||||||
return (char)spec.rangeLow.intValue() + "";
|
return String.valueOf((char)spec.rangeLow.intValue());
|
||||||
}
|
}
|
||||||
}).collect(Collectors.toList());
|
}).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
package com.maddyhome.idea.vim.option;
|
package com.maddyhome.idea.vim.option;
|
||||||
|
|
||||||
|
import com.intellij.util.ArrayUtil;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
@@ -30,7 +31,7 @@ import java.util.StringTokenizer;
|
|||||||
* This is an option that accepts an arbitrary list of values
|
* This is an option that accepts an arbitrary list of values
|
||||||
*/
|
*/
|
||||||
public class ListOption extends TextOption {
|
public class ListOption extends TextOption {
|
||||||
public static final @NotNull ListOption empty = new ListOption("", "", new String[0], "");
|
public static final @NotNull ListOption empty = new ListOption("", "", ArrayUtil.EMPTY_STRING_ARRAY, "");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the value of the option as a comma separated list of values
|
* Gets the value of the option as a comma separated list of values
|
||||||
|
@@ -88,7 +88,7 @@ object OptionsManager {
|
|||||||
val ideastatusicon = addOption(BoundStringOption(IdeaStatusIcon.name, IdeaStatusIcon.name, IdeaStatusIcon.enabled, IdeaStatusIcon.allValues))
|
val ideastatusicon = addOption(BoundStringOption(IdeaStatusIcon.name, IdeaStatusIcon.name, IdeaStatusIcon.enabled, IdeaStatusIcon.allValues))
|
||||||
val ideastrictmode = addOption(ToggleOption("ideastrictmode", "ideastrictmode", false))
|
val ideastrictmode = addOption(ToggleOption("ideastrictmode", "ideastrictmode", false))
|
||||||
val ideawrite = addOption(BoundStringOption("ideawrite", "ideawrite", IdeaWriteData.all, IdeaWriteData.allValues))
|
val ideawrite = addOption(BoundStringOption("ideawrite", "ideawrite", IdeaWriteData.all, IdeaWriteData.allValues))
|
||||||
val ideaenabledbufs = addOption(BoundListOption("ideaenabledbufs", "ideaenabledbufs", arrayOf("dialog"), arrayOf("dialog", "singleline", "dialoglegacy")))
|
val ideavimsupport = addOption(BoundListOption("ideavimsupport", "ideavimsupport", arrayOf("dialog"), arrayOf("dialog", "singleline", "dialoglegacy")))
|
||||||
|
|
||||||
fun isSet(name: String): Boolean {
|
fun isSet(name: String): Boolean {
|
||||||
val option = getOption(name)
|
val option = getOption(name)
|
||||||
@@ -368,7 +368,7 @@ object OptionsManager {
|
|||||||
|
|
||||||
object KeyModelOptionData {
|
object KeyModelOptionData {
|
||||||
const val name = "keymodel"
|
const val name = "keymodel"
|
||||||
const val abbr = "km"
|
private const val abbr = "km"
|
||||||
|
|
||||||
const val startsel = "startsel"
|
const val startsel = "startsel"
|
||||||
const val stopsel = "stopsel"
|
const val stopsel = "stopsel"
|
||||||
@@ -384,7 +384,7 @@ object KeyModelOptionData {
|
|||||||
|
|
||||||
object SelectModeOptionData {
|
object SelectModeOptionData {
|
||||||
const val name = "selectmode"
|
const val name = "selectmode"
|
||||||
const val abbr = "slm"
|
private const val abbr = "slm"
|
||||||
|
|
||||||
const val mouse = "mouse"
|
const val mouse = "mouse"
|
||||||
const val key = "key"
|
const val key = "key"
|
||||||
@@ -433,14 +433,14 @@ object ClipboardOptionsData {
|
|||||||
|
|
||||||
object IdeaJoinOptionsData {
|
object IdeaJoinOptionsData {
|
||||||
const val name = "ideajoin"
|
const val name = "ideajoin"
|
||||||
const val defaultValue = false
|
private const val defaultValue = false
|
||||||
|
|
||||||
val option = ToggleOption(name, name, defaultValue)
|
val option = ToggleOption(name, name, defaultValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
object IdeaMarkskOptionsData {
|
object IdeaMarkskOptionsData {
|
||||||
const val name = "ideamarks"
|
const val name = "ideamarks"
|
||||||
const val defaultValue = true
|
private const val defaultValue = true
|
||||||
|
|
||||||
val option = ToggleOption(name, name, defaultValue)
|
val option = ToggleOption(name, name, defaultValue)
|
||||||
}
|
}
|
||||||
|
@@ -62,7 +62,7 @@
|
|||||||
* |i_CTRL-Z| TO BE IMPLEMENTED
|
* |i_CTRL-Z| TO BE IMPLEMENTED
|
||||||
* |i_<Esc>| {@link com.maddyhome.idea.vim.action.change.insert.InsertExitModeAction}
|
* |i_<Esc>| {@link com.maddyhome.idea.vim.action.change.insert.InsertExitModeAction}
|
||||||
* |i_CTRL-[| {@link com.maddyhome.idea.vim.action.change.insert.InsertExitModeAction}
|
* |i_CTRL-[| {@link com.maddyhome.idea.vim.action.change.insert.InsertExitModeAction}
|
||||||
* |i_CTRL-\_CTRL-N| {@link com.maddyhome.idea.vim.action.change.insert.InsertExitModeAction}
|
* |i_CTRL-\_CTRL-N| {@link com.maddyhome.idea.vim.action.ResetModeAction}
|
||||||
* |i_CTRL-\_CTRL-G| TO BE IMPLEMENTED
|
* |i_CTRL-\_CTRL-G| TO BE IMPLEMENTED
|
||||||
* |i_CTRL-]} TO BE IMPLEMENTED
|
* |i_CTRL-]} TO BE IMPLEMENTED
|
||||||
* |i_CTRL-^| TO BE IMPLEMENTED
|
* |i_CTRL-^| TO BE IMPLEMENTED
|
||||||
|
@@ -4726,11 +4726,11 @@ public class RegExp {
|
|||||||
private int regnzpar; /* \z() count. */
|
private int regnzpar; /* \z() count. */
|
||||||
private char re_has_z; /* \z item detected */
|
private char re_has_z; /* \z item detected */
|
||||||
private CharPointer regcode; /* Code-emit pointer */
|
private CharPointer regcode; /* Code-emit pointer */
|
||||||
private @NotNull boolean[] had_endbrace = new boolean[NSUBEXP]; /* flags, true if end of () found */
|
private boolean[] had_endbrace = new boolean[NSUBEXP]; /* flags, true if end of () found */
|
||||||
private int regflags; /* RF_ flags for prog */
|
private int regflags; /* RF_ flags for prog */
|
||||||
private @NotNull int[] brace_min = new int[10]; /* Minimums for complex brace repeats */
|
private int[] brace_min = new int[10]; /* Minimums for complex brace repeats */
|
||||||
private @NotNull int[] brace_max = new int[10]; /* Maximums for complex brace repeats */
|
private int[] brace_max = new int[10]; /* Maximums for complex brace repeats */
|
||||||
private @NotNull int[] brace_count = new int[10]; /* Current counts for complex brace repeats */
|
private int[] brace_count = new int[10]; /* Current counts for complex brace repeats */
|
||||||
private boolean had_eol; /* true when EOL found by vim_regcomp() */
|
private boolean had_eol; /* true when EOL found by vim_regcomp() */
|
||||||
private boolean one_exactly = false; /* only do one char for EXACTLY */
|
private boolean one_exactly = false; /* only do one char for EXACTLY */
|
||||||
|
|
||||||
|
@@ -142,7 +142,7 @@ public class ExEditorKit extends DefaultEditorKit {
|
|||||||
if (key != null) {
|
if (key != null) {
|
||||||
final char c = key.getKeyChar();
|
final char c = key.getKeyChar();
|
||||||
if (c > 0) {
|
if (c > 0) {
|
||||||
ActionEvent event = new ActionEvent(e.getSource(), e.getID(), "" + c, e.getWhen(), e.getModifiers());
|
ActionEvent event = new ActionEvent(e.getSource(), e.getID(), String.valueOf(c), e.getWhen(), e.getModifiers());
|
||||||
super.actionPerformed(event);
|
super.actionPerformed(event);
|
||||||
target.saveLastEntry();
|
target.saveLastEntry();
|
||||||
}
|
}
|
||||||
|
@@ -331,14 +331,12 @@ public class ExOutputPanel extends JPanel {
|
|||||||
myExOutputPanel.scrollHalfPage();
|
myExOutputPanel.scrollHalfPage();
|
||||||
break;
|
break;
|
||||||
case 'q':
|
case 'q':
|
||||||
|
case '\u001b':
|
||||||
myExOutputPanel.close();
|
myExOutputPanel.close();
|
||||||
break;
|
break;
|
||||||
case '\n':
|
case '\n':
|
||||||
myExOutputPanel.handleEnter();
|
myExOutputPanel.handleEnter();
|
||||||
break;
|
break;
|
||||||
case '\u001b':
|
|
||||||
myExOutputPanel.close();
|
|
||||||
break;
|
|
||||||
case KeyEvent.CHAR_UNDEFINED: {
|
case KeyEvent.CHAR_UNDEFINED: {
|
||||||
switch (e.getKeyCode()) {
|
switch (e.getKeyCode()) {
|
||||||
case KeyEvent.VK_ENTER:
|
case KeyEvent.VK_ENTER:
|
||||||
|
@@ -49,7 +49,7 @@ import static java.lang.Math.min;
|
|||||||
*/
|
*/
|
||||||
public class ExTextField extends JTextField {
|
public class ExTextField extends JTextField {
|
||||||
|
|
||||||
public final static String KEYMAP_NAME = "ex";
|
public static final String KEYMAP_NAME = "ex";
|
||||||
|
|
||||||
ExTextField() {
|
ExTextField() {
|
||||||
// We need to store this in a field, because we can't trust getCaret(), as it will return an instance of
|
// We need to store this in a field, because we can't trust getCaret(), as it will return an instance of
|
||||||
@@ -178,7 +178,7 @@ public class ExTextField extends JTextField {
|
|||||||
VimPlugin.indicateError();
|
VimPlugin.indicateError();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
histIndex = histIndex + dir;
|
histIndex += dir;
|
||||||
String txt;
|
String txt;
|
||||||
if (histIndex == history.size()) {
|
if (histIndex == history.size()) {
|
||||||
txt = lastEntry;
|
txt = lastEntry;
|
||||||
@@ -274,7 +274,7 @@ public class ExTextField extends JTextField {
|
|||||||
// dispatcher that checks that the plugin is enabled, checks that the component with the focus is ExTextField,
|
// dispatcher that checks that the plugin is enabled, checks that the component with the focus is ExTextField,
|
||||||
// dispatch to ExEntryPanel#handleKey and if it's processed, mark the event as consumed.
|
// dispatch to ExEntryPanel#handleKey and if it's processed, mark the event as consumed.
|
||||||
if (currentAction != null) {
|
if (currentAction != null) {
|
||||||
currentAction.actionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, "" + c, modifiers));
|
currentAction.actionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, String.valueOf(c), modifiers));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
KeyEvent event = new KeyEvent(this, keyChar != KeyEvent.CHAR_UNDEFINED ? KeyEvent.KEY_TYPED :
|
KeyEvent event = new KeyEvent(this, keyChar != KeyEvent.CHAR_UNDEFINED ? KeyEvent.KEY_TYPED :
|
||||||
|
@@ -94,13 +94,13 @@ class Widget(project: Project) : EditorBasedWidget(project), StatusBarWidget.Mul
|
|||||||
|
|
||||||
override fun ID() = ShowCmd.ID
|
override fun ID() = ShowCmd.ID
|
||||||
|
|
||||||
override fun getPresentation(): StatusBarWidget.WidgetPresentation? = this
|
override fun getPresentation(): StatusBarWidget.WidgetPresentation = this
|
||||||
|
|
||||||
override fun getClickConsumer(): Consumer<MouseEvent>? = null
|
override fun getClickConsumer(): Consumer<MouseEvent>? = null
|
||||||
|
|
||||||
override fun getTooltipText(): String {
|
override fun getTooltipText(): String {
|
||||||
var count = ShowCmd.getFullText(this.editor)
|
var count = ShowCmd.getFullText(this.editor)
|
||||||
if (!count.isBlank()) count = ": $count"
|
if (count.isNotBlank()) count = ": $count"
|
||||||
return "${ShowCmd.displayName}$count"
|
return "${ShowCmd.displayName}$count"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -126,7 +126,7 @@ class VimStatusBar : StatusBarWidget, StatusBarWidget.IconPresentation {
|
|||||||
popup.show(RelativePoint(component, at))
|
popup.show(RelativePoint(component, at))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getPresentation(): StatusBarWidget.WidgetPresentation? = this
|
override fun getPresentation(): StatusBarWidget.WidgetPresentation = this
|
||||||
}
|
}
|
||||||
|
|
||||||
class VimActions : DumbAwareAction() {
|
class VimActions : DumbAwareAction() {
|
||||||
|
@@ -86,12 +86,11 @@ public class VimEmulationConfigurable implements Configurable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static final class VimSettingsPanel extends JPanel {
|
private static final class VimSettingsPanel extends JPanel {
|
||||||
private final @NotNull VimShortcutConflictsTable myShortcutConflictsTable;
|
|
||||||
|
|
||||||
public VimSettingsPanel(@NotNull VimShortcutConflictsTable.Model model) {
|
public VimSettingsPanel(@NotNull VimShortcutConflictsTable.Model model) {
|
||||||
myShortcutConflictsTable = new VimShortcutConflictsTable(model);
|
VimShortcutConflictsTable shortcutConflictsTable = new VimShortcutConflictsTable(model);
|
||||||
setLayout(new BorderLayout());
|
setLayout(new BorderLayout());
|
||||||
final JScrollPane scrollPane = new JBScrollPane(myShortcutConflictsTable);
|
final JScrollPane scrollPane = new JBScrollPane(shortcutConflictsTable);
|
||||||
scrollPane.setBorder(new LineBorder(JBColor.border()));
|
scrollPane.setBorder(new LineBorder(JBColor.border()));
|
||||||
final JPanel conflictsPanel = new JPanel(new BorderLayout());
|
final JPanel conflictsPanel = new JPanel(new BorderLayout());
|
||||||
final String title = "Shortcut Conflicts for Active Keymap";
|
final String title = "Shortcut Conflicts for Active Keymap";
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
# Manual Tests
|
# Manual Tests
|
||||||
|
|
||||||
## #1 [Last run: 2020-10-09]
|
## #1 [Last run: 2020-11-12]
|
||||||
|
|
||||||
_Initial mode:_ NORMAL
|
_Initial mode:_ NORMAL
|
||||||
|
|
||||||
@@ -14,7 +14,7 @@ Word is selected, block-caret is placed on the word end (offset = `word end - 1`
|
|||||||

|

|
||||||
|
|
||||||
|
|
||||||
## #2 [Last run: 2020-10-09]
|
## #2 [Last run: 2020-11-12]
|
||||||
|
|
||||||
_Initial mode:_ NORMAL
|
_Initial mode:_ NORMAL
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@ Last word is selected, block caret is placed on the word end without bouncing
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
## #3 [Last run: 2020-10-09]
|
## #3 [Last run: 2020-11-12]
|
||||||
|
|
||||||
_Initial mode:_ NORMAL
|
_Initial mode:_ NORMAL
|
||||||
|
|
||||||
@@ -38,7 +38,7 @@ Line is selected. Caret is placed on the line end
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
## #4 [Last run: 2020-10-09]
|
## #4 [Last run: 2020-11-12]
|
||||||
|
|
||||||
_Initial mode:_ NORMAL
|
_Initial mode:_ NORMAL
|
||||||
|
|
||||||
@@ -51,7 +51,7 @@ After mouse release, caret moves one character back and becomes block shape
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
## #5 [Last run: 2020-10-09]
|
## #5 [Last run: 2020-11-12]
|
||||||
|
|
||||||
_Initial mode:_ NORMAL
|
_Initial mode:_ NORMAL
|
||||||
|
|
||||||
@@ -65,7 +65,7 @@ After mouse release, caret moves one character back and becomes block shape
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
## #6 [Last run: 2020-10-09]
|
## #6 [Last run: 2020-11-12]
|
||||||
|
|
||||||
_Initial mode:_ NORMAL
|
_Initial mode:_ NORMAL
|
||||||
|
|
||||||
@@ -77,7 +77,7 @@ Line is selected, caret is on the first position
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
## #6 [Last run: 2020-10-09]
|
## #6 [Last run: 2020-11-12]
|
||||||
|
|
||||||
_Initial mode:_ NORMAL
|
_Initial mode:_ NORMAL
|
||||||
|
|
||||||
@@ -94,7 +94,7 @@ Caret stays in _block_ shape with a normal mode
|
|||||||

|

|
||||||
|
|
||||||
|
|
||||||
## #7 [Last run: 2020-10-09]
|
## #7 [Last run: 2020-11-12]
|
||||||
|
|
||||||
_Action:_
|
_Action:_
|
||||||
Turn emulation off and on
|
Turn emulation off and on
|
||||||
@@ -102,7 +102,7 @@ Turn emulation off and on
|
|||||||
_Result:_
|
_Result:_
|
||||||
Vim emulator works as expected
|
Vim emulator works as expected
|
||||||
|
|
||||||
## #8 [Last run: 2020-10-09
|
## #8 [Last run: 2020-11-12
|
||||||
|
|
||||||
_Action:_
|
_Action:_
|
||||||
Start up IJ with disabled emulator, turn it on
|
Start up IJ with disabled emulator, turn it on
|
||||||
@@ -110,7 +110,7 @@ Start up IJ with disabled emulator, turn it on
|
|||||||
_Result:_
|
_Result:_
|
||||||
Vim emulator works as expected
|
Vim emulator works as expected
|
||||||
|
|
||||||
## #9 [Last run: 2020-10-09]
|
## #9 [Last run: 2020-11-12]
|
||||||
|
|
||||||
_Action:_
|
_Action:_
|
||||||
Wrap with if
|
Wrap with if
|
||||||
|
@@ -31,12 +31,13 @@ import junit.framework.Assert
|
|||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
internal object NeovimTesting {
|
internal object NeovimTesting {
|
||||||
lateinit var neovimApi: NeovimApi
|
private lateinit var neovimApi: NeovimApi
|
||||||
lateinit var neovim: Process
|
private lateinit var neovim: Process
|
||||||
|
|
||||||
fun setUp(test: VimTestCase) {
|
fun setUp(test: VimTestCase) {
|
||||||
if (!neovimEnabled(test)) return
|
if (!neovimEnabled(test)) return
|
||||||
val pb = ProcessBuilder("nvim", "-u", "NONE", "--embed", "--headless")
|
val nvimPath = System.getenv("ideavim.nvim.path") ?: "nvim"
|
||||||
|
val pb = ProcessBuilder(nvimPath, "-u", "NONE", "--embed", "--headless")
|
||||||
neovim = pb.start()
|
neovim = pb.start()
|
||||||
val neovimConnection = ProcessRPCConnection(neovim, true)
|
val neovimConnection = ProcessRPCConnection(neovim, true)
|
||||||
neovimApi = NeovimApis.getApiForConnection(neovimConnection)
|
neovimApi = NeovimApis.getApiForConnection(neovimConnection)
|
||||||
@@ -47,11 +48,11 @@ internal object NeovimTesting {
|
|||||||
neovim.destroy()
|
neovim.destroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun neovimEnabled(test: VimTestCase): Boolean {
|
private fun neovimEnabled(test: VimTestCase): Boolean {
|
||||||
val method = test.javaClass.getMethod(test.name)
|
val method = test.javaClass.getMethod(test.name)
|
||||||
return !method.isAnnotationPresent(VimBehaviorDiffers::class.java)
|
return !method.isAnnotationPresent(VimBehaviorDiffers::class.java)
|
||||||
&& !method.isAnnotationPresent(TestWithoutNeovim::class.java)
|
&& !method.isAnnotationPresent(TestWithoutNeovim::class.java)
|
||||||
&& System.getProperty("ideavim.neovim.test", "false")!!.toBoolean()
|
&& System.getProperty("ideavim.nvim.test", "false")!!.toBoolean()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setupEditor(editor: Editor, test: VimTestCase) {
|
fun setupEditor(editor: Editor, test: VimTestCase) {
|
||||||
|
@@ -94,7 +94,7 @@ abstract class VimTestCase : UsefulTestCase() {
|
|||||||
NeovimTesting.setUp(this)
|
NeovimTesting.setUp(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
protected val testDataPath: String
|
private val testDataPath: String
|
||||||
get() = PathManager.getHomePath() + "/community/plugins/ideavim/testData"
|
get() = PathManager.getHomePath() + "/community/plugins/ideavim/testData"
|
||||||
|
|
||||||
@Throws(Exception::class)
|
@Throws(Exception::class)
|
||||||
@@ -180,26 +180,30 @@ abstract class VimTestCase : UsefulTestCase() {
|
|||||||
|
|
||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
protected fun setPositionAndScroll(scrollToLogicalLine: Int, caretLogicalLine: Int, caretLogicalColumn: Int = 0) {
|
protected fun setPositionAndScroll(scrollToLogicalLine: Int, caretLogicalLine: Int, caretLogicalColumn: Int = 0) {
|
||||||
val scrolloff = min(OptionsManager.scrolloff.value(), screenHeight / 2)
|
|
||||||
|
// Note that it is possible to request a position which would be invalid under normal Vim!
|
||||||
|
// We disable scrolloff + scrolljump, position as requested, and reset. When resetting scrolloff, Vim will
|
||||||
|
// recalculate the correct offsets, and that could move the top and/or caret line
|
||||||
|
val scrolloff = OptionsManager.scrolloff.value()
|
||||||
val scrolljump = OptionsManager.scrolljump.value()
|
val scrolljump = OptionsManager.scrolljump.value()
|
||||||
|
OptionsManager.scrolloff.set(0)
|
||||||
OptionsManager.scrolljump.set(1)
|
OptionsManager.scrolljump.set(1)
|
||||||
|
|
||||||
// Convert to visual lines to handle any collapsed folds
|
// Convert to visual lines to handle any collapsed folds
|
||||||
val scrollToVisualLine = EditorHelper.logicalLineToVisualLine(myFixture.editor, scrollToLogicalLine)
|
val scrollToVisualLine = EditorHelper.logicalLineToVisualLine(myFixture.editor, scrollToLogicalLine)
|
||||||
val bottomVisualLine = scrollToVisualLine + screenHeight - 1
|
val bottomVisualLine = scrollToVisualLine + EditorHelper.getApproximateScreenHeight(myFixture.editor) - 1
|
||||||
val bottomLogicalLine = EditorHelper.visualLineToLogicalLine(myFixture.editor, bottomVisualLine)
|
val bottomLogicalLine = EditorHelper.visualLineToLogicalLine(myFixture.editor, bottomVisualLine)
|
||||||
|
|
||||||
// Make sure we're not trying to put caret in an invalid location
|
// Make sure we're not trying to put caret in an invalid location
|
||||||
val boundsTop = EditorHelper.visualLineToLogicalLine(myFixture.editor,
|
val boundsTop = EditorHelper.visualLineToLogicalLine(myFixture.editor, scrollToVisualLine)
|
||||||
if (scrollToVisualLine > scrolloff) scrollToVisualLine + scrolloff else scrollToVisualLine)
|
val boundsBottom = EditorHelper.visualLineToLogicalLine(myFixture.editor, bottomVisualLine)
|
||||||
val boundsBottom = EditorHelper.visualLineToLogicalLine(myFixture.editor,
|
|
||||||
if (bottomVisualLine > EditorHelper.getVisualLineCount(myFixture.editor) - scrolloff - 1) bottomVisualLine - scrolloff else bottomVisualLine)
|
|
||||||
Assert.assertTrue("Caret line $caretLogicalLine not inside legal screen bounds (${boundsTop} - ${boundsBottom})",
|
Assert.assertTrue("Caret line $caretLogicalLine not inside legal screen bounds (${boundsTop} - ${boundsBottom})",
|
||||||
caretLogicalLine in boundsTop..boundsBottom)
|
caretLogicalLine in boundsTop..boundsBottom)
|
||||||
|
|
||||||
typeText(parseKeys("${scrollToLogicalLine+scrolloff+1}z<CR>", "${caretLogicalLine+1}G", "${caretLogicalColumn+1}|"))
|
typeText(parseKeys("${scrollToLogicalLine+1}z<CR>", "${caretLogicalLine+1}G", "${caretLogicalColumn+1}|"))
|
||||||
|
|
||||||
OptionsManager.scrolljump.set(scrolljump)
|
OptionsManager.scrolljump.set(scrolljump)
|
||||||
|
OptionsManager.scrolloff.set(scrolloff)
|
||||||
|
|
||||||
// Make sure we're where we want to be
|
// Make sure we're where we want to be
|
||||||
assertVisibleArea(scrollToLogicalLine, bottomLogicalLine)
|
assertVisibleArea(scrollToLogicalLine, bottomLogicalLine)
|
||||||
|
@@ -25,6 +25,7 @@ import static com.maddyhome.idea.vim.helper.StringHelper.parseKeys;
|
|||||||
public class ReformatCodeTest extends VimTestCase {
|
public class ReformatCodeTest extends VimTestCase {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
[VERSION UPDATE] 2020.2+
|
||||||
public void testEmpty() {
|
public void testEmpty() {
|
||||||
configureByJavaText("<caret>");
|
configureByJavaText("<caret>");
|
||||||
typeText(parseKeys("gqq"));
|
typeText(parseKeys("gqq"));
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user