diff --git a/java/java-terminal/src/com/intellij/java/terminal/JavaShellCommandSpecsProvider.kt b/java/java-terminal/src/com/intellij/java/terminal/JavaShellCommandSpecsProvider.kt index 935cc75eb827..3b1ef48bde4a 100644 --- a/java/java-terminal/src/com/intellij/java/terminal/JavaShellCommandSpecsProvider.kt +++ b/java/java-terminal/src/com/intellij/java/terminal/JavaShellCommandSpecsProvider.kt @@ -19,10 +19,12 @@ class JavaShellCommandSpecsProvider : ShellCommandSpecsProvider { } private fun getSpecs(): ShellCommandSpec = ShellCommandSpec("java") { - parserOptions = ShellCommandParserOptions.builder() - .flagsArePosixNonCompliant(true) - .optionsMustPrecedeArguments(true) - .build() + parserOptions( + ShellCommandParserOptions.builder() + .flagsArePosixNonCompliant(true) + .optionsMustPrecedeArguments(true) + .build() + ) dynamicOptions { terminalContext -> val javaContext = JavaShellCommandContext.create(terminalContext) @@ -38,7 +40,7 @@ class JavaShellCommandSpecsProvider : ShellCommandSpecsProvider { val errorStreamName: @Nls String = JavaTerminalBundle.message("error.stream.name") description(JavaTerminalBundle.message("java.command.terminal.description")) option("-?", "-help", "-h") { - exclusiveOn = listOf("--help") + exclusiveOn(listOf("--help")) description(JavaTerminalBundle.message("java.command.terminal.help.option.description", errorStreamName)) } option("-jar") { @@ -49,11 +51,11 @@ class JavaShellCommandSpecsProvider : ShellCommandSpecsProvider { description(JavaTerminalBundle.message("java.command.terminal.jar.option.description")) } option("-version") { - exclusiveOn = listOf("--version") + exclusiveOn(listOf("--version")) description(JavaTerminalBundle.message("java.command.terminal.version.option.description", errorStreamName)) } option("-classpath", "-cp") { - exclusiveOn = listOf("--class-path") + exclusiveOn(listOf("--class-path")) description(JavaTerminalBundle.message("java.command.terminal.classpath.option.description")) argument { suggestions(JavaShellCommandUtils.classpathSuggestionsGenerator()) @@ -61,7 +63,7 @@ class JavaShellCommandSpecsProvider : ShellCommandSpecsProvider { } } option("-showversion") { - exclusiveOn = listOf("--show-version") + exclusiveOn(listOf("--show-version")) description(JavaTerminalBundle.message("java.command.terminal.show.version.option.description", errorStreamName)) } argument { @@ -88,12 +90,12 @@ class JavaShellCommandSpecsProvider : ShellCommandSpecsProvider { description(optionDescription) val info = OPTION_UI_INFO_MAP[presentableName] ?: DEFAULT_UI_OPTION_INSTANCE - repeatTimes = info.repeatTimes - separator = info.separator + repeatTimes(info.repeatTimes) + info.separator?.let { separator(it) } val argumentName = info.argumentName if (argumentName != null) { argument { - isOptional = info.isArgumentOptional + if (info.isArgumentOptional) optional() displayName(argumentName) } } @@ -104,15 +106,15 @@ class JavaShellCommandSpecsProvider : ShellCommandSpecsProvider { private fun ShellChildOptionsContext.addOptionsFromJava11() { val outputStreamName = JavaTerminalBundle.message("output.stream.name") option("--version") { - exclusiveOn = listOf("-version") + exclusiveOn(listOf("-version")) description(JavaTerminalBundle.message("java.command.terminal.version.option.description", outputStreamName)) } option("--show-version") { - exclusiveOn = listOf("-show-version") + exclusiveOn(listOf("-show-version")) description(JavaTerminalBundle.message("java.command.terminal.show.version.option.description", outputStreamName)) } option("--dry-run") { - exclusiveOn = listOf("-dry-run") + exclusiveOn(listOf("-dry-run")) description(JavaTerminalBundle.message("java.command.terminal.dry.run.option.description")) } option("--class-path") { @@ -123,7 +125,7 @@ class JavaShellCommandSpecsProvider : ShellCommandSpecsProvider { } } option("--help") { - exclusiveOn = listOf("-?", "-help", "-h") + exclusiveOn(listOf("-?", "-help", "-h")) description(JavaTerminalBundle.message("java.command.terminal.help.option.description", outputStreamName)) } option("--enable-preview") { @@ -132,10 +134,10 @@ class JavaShellCommandSpecsProvider : ShellCommandSpecsProvider { option("-verbose") { description(JavaTerminalBundle.message("java.command.terminal.verbose.option.description")) - separator=":" - repeatTimes = 0 + separator(":") + repeatTimes(0) argument { - isOptional = true + optional() displayName(CLASS_GC_GNI_MODULE_ARGUMENT_NAME) } } @@ -144,10 +146,10 @@ class JavaShellCommandSpecsProvider : ShellCommandSpecsProvider { private fun ShellChildOptionsContext.addOptionsFromJava8() { option("-verbose") { description(JavaTerminalBundle.message("java.command.terminal.verbose.option.description")) - separator=":" - repeatTimes = 0 + separator(":") + repeatTimes(0) argument { - isOptional = true + optional() displayName(CLASS_GC_GNI_ARGUMENT_NAME) } } diff --git a/plugins/git4idea/terminal/src/com/intellij/vcs/git/terminal/GitAliasContributor.kt b/plugins/git4idea/terminal/src/com/intellij/vcs/git/terminal/GitAliasContributor.kt index 517d44b4d149..7e10ffb9d1b4 100644 --- a/plugins/git4idea/terminal/src/com/intellij/vcs/git/terminal/GitAliasContributor.kt +++ b/plugins/git4idea/terminal/src/com/intellij/vcs/git/terminal/GitAliasContributor.kt @@ -40,7 +40,7 @@ internal fun aliasGenerator(): ShellRuntimeDataGenerator") { description(GitTerminalBundle.message("suggestion.headn.description")) - insertValue = "HEAD~" + insertValue("HEAD~") } ) } @@ -224,8 +220,8 @@ internal val gitOverrideSpec = ShellCommandSpec("git") { suggestions(allBranchesGenerator) - isOptional = true - isVariadic = true + optional() + variadic() } } @@ -237,8 +233,8 @@ internal val gitOverrideSpec = ShellCommandSpec("git") { suggestions(allBranchesGenerator) - isOptional = true - isVariadic = true + optional() + variadic() } } @@ -250,48 +246,47 @@ internal val gitOverrideSpec = ShellCommandSpec("git") { } suggestions(allBranchesGenerator) suggestions(remotesGenerator) - isOptional = true - isVariadic = false + optional() } argument { displayName(GitTerminalBundle.message("rebase.arg2.name")) suggestions(localBranchesGenerator) - isOptional = true + optional() } } subcommand("push") { argument { displayName(GitTerminalBundle.message("push.arg1.name")) suggestions(remotesGenerator) - isOptional = true + optional() } argument { displayName(GitTerminalBundle.message("push.arg2.name")) suggestions(localBranchesGenerator) - isOptional = true + optional() } } subcommand("pull") { option("--rebase") { - separator = "=" + separator("=") description(GitTerminalBundle.message("pull.opt-rebase.description")) argument { displayName(GitTerminalBundle.message("pull.opt-rebase.arg1.name")) suggestions("false", "true", "merges", "preserve", "interactive") suggestions(remotesGenerator) - isOptional = true + optional() } } argument { displayName(GitTerminalBundle.message("pull.arg1.name")) suggestions(remotesGenerator) - isOptional = true + optional() } argument { displayName(GitTerminalBundle.message("pull.arg2.name")) suggestions(localBranchesGenerator) - isOptional = true + optional() } } subcommand("remote") { @@ -319,16 +314,16 @@ internal val gitOverrideSpec = ShellCommandSpec("git") { argument { displayName(GitTerminalBundle.message("fetch.arg1.name")) suggestions(remotesGenerator) - isOptional = true + optional() } argument { displayName(GitTerminalBundle.message("fetch.arg2.name")) suggestions(localBranchesGenerator) - isOptional = true + optional() } argument { displayName(GitTerminalBundle.message("fetch.arg3.name")) - isOptional = true + optional() } } subcommand("stash") { @@ -340,7 +335,7 @@ internal val gitOverrideSpec = ShellCommandSpec("git") { } argument { displayName(GitTerminalBundle.message("stash.branch.arg2.name")) - isOptional = true + optional() } } } @@ -356,7 +351,7 @@ internal val gitOverrideSpec = ShellCommandSpec("git") { ) } suggestions(localOrRemoteBranchesGenerator) - isVariadic = true + variadic() } } option("-d", "--delete") { @@ -369,7 +364,7 @@ internal val gitOverrideSpec = ShellCommandSpec("git") { ) } suggestions(localOrRemoteBranchesGenerator) - isVariadic = true + variadic() } } option("-m", "--move") { @@ -400,16 +395,16 @@ internal val gitOverrideSpec = ShellCommandSpec("git") { argument { displayName(GitTerminalBundle.message("branch.opt-set-upstream.arg1.name")) suggestions(allBranchesGenerator) - isOptional = true + optional() } } option("--set-upstream-to") { description(GitTerminalBundle.message("branch.opt-set-upstream.description")) - separator = "=" + separator("=") argument { displayName(GitTerminalBundle.message("branch.opt-set-upstream.arg1.name")) suggestions(allBranchesGenerator) - isOptional = true + optional() } } option("--unset-upstream") { @@ -417,7 +412,7 @@ internal val gitOverrideSpec = ShellCommandSpec("git") { argument { displayName(GitTerminalBundle.message("branch.opt-unset-upstream.arg1.name")) suggestions(localBranchesGenerator) - isOptional = true + optional() } } trackingOptions() @@ -438,15 +433,15 @@ internal val gitOverrideSpec = ShellCommandSpec("git") { suggestions(allBranchesGenerator) - isOptional = true + optional() } argument { displayName(GitTerminalBundle.message("checkout.arg2.name")) suggestions(ShellDataGenerators.fileSuggestionsGenerator(false)) - isVariadic = true - isOptional = true + variadic() + optional() } } subcommand("merge") { @@ -459,8 +454,8 @@ internal val gitOverrideSpec = ShellCommandSpec("git") { suggestions(allBranchesGenerator) - isVariadic = true - isOptional = true + variadic() + optional() } } subcommand("switch") { @@ -477,7 +472,7 @@ internal val gitOverrideSpec = ShellCommandSpec("git") { } argument { displayName(GitTerminalBundle.message("switch.arg2.name")) - isOptional = true + optional() } } } diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/block/completion/spec/ShellDataGenerators.kt b/plugins/terminal/src/org/jetbrains/plugins/terminal/block/completion/spec/ShellDataGenerators.kt index dfe4b5c36542..b43f1764191e 100644 --- a/plugins/terminal/src/org/jetbrains/plugins/terminal/block/completion/spec/ShellDataGenerators.kt +++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/block/completion/spec/ShellDataGenerators.kt @@ -57,8 +57,8 @@ object ShellDataGenerators { val type = if (it.type == ShellFileInfo.Type.DIRECTORY) ShellSuggestionType.FOLDER else ShellSuggestionType.FILE val name = it.name + if (type == ShellSuggestionType.FOLDER) File.separator else "" val suggestion = ShellCompletionSuggestion(name) { - this.type = type - this.prefixReplacementIndex = prefixReplacementIndex + type(type) + prefixReplacementIndex(prefixReplacementIndex) } if (type == ShellSuggestionType.FILE) { listOf(suggestion) @@ -67,9 +67,9 @@ object ShellDataGenerators { // Directory suggestion has a trailing file separator, but suggestion without it is also valid. // It is needed for the parser to consider it as a valid suggestion and not mark it as something unknown. val hiddenSuggestion = ShellCompletionSuggestion(it.name) { - this.type = ShellSuggestionType.FOLDER - this.prefixReplacementIndex = prefixReplacementIndex - this.isHidden = true + type(ShellSuggestionType.FOLDER) + prefixReplacementIndex(prefixReplacementIndex) + hidden() } listOf(suggestion, hiddenSuggestion) } @@ -80,8 +80,8 @@ object ShellDataGenerators { // It is needed for the parser to consider current typed prefix as a valid file suggestion. return if (path.isNotEmpty() && path == adjustedPrefix) { val emptySuggestion = ShellCompletionSuggestion("") { - this.prefixReplacementIndex = prefixReplacementIndex - this.isHidden = true + prefixReplacementIndex(prefixReplacementIndex) + hidden() } suggestions + emptySuggestion } diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/block/completion/spec/dsl/ShellArgumentContext.kt b/plugins/terminal/src/org/jetbrains/plugins/terminal/block/completion/spec/dsl/ShellArgumentContext.kt index b3049b4bfe52..72f1a849af92 100644 --- a/plugins/terminal/src/org/jetbrains/plugins/terminal/block/completion/spec/dsl/ShellArgumentContext.kt +++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/block/completion/spec/dsl/ShellArgumentContext.kt @@ -29,28 +29,35 @@ sealed interface ShellArgumentContext { fun displayName(supplier: Supplier<@Nls String>) /** - * Whether this argument is not required to have a value. + * Specifies that this argument is not required to have a value. * - * False by default (the argument is required). + * By default, the argument is required. */ + fun optional() + + @Deprecated("Please use optional() method instead") var isOptional: Boolean /** * Specifies that this argument can be repeated infinitely. * For example, `git add` takes a variadic argument of filenames. * - * False by default. + * By default, the argument value can be specified only once. */ + fun variadic() + + @Deprecated("Please use variadic() method instead") var isVariadic: Boolean /** - * Specifies that the options can be placed between values of the variadic argument. - * For example, it is true for `git add` command. - * We can write like this: `git add file1 file2 -v file3`. Where `-v` is the option. + * Specifies that the options can't be placed between values of the variadic argument. + * By default, this behavior is allowed. * - * True by default. + * For example, it is not allowed for `echo` command. + * If we write: `echo hello -n world`, `-n` will be considered as a variadic argument value rather than an option. + * So, we should write `echo -n hello world` instead. */ - var optionsCanBreakVariadicArg: Boolean + fun optionsCantBreakVariadicArg() /** * Generate suggestions for the argument values. diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/block/completion/spec/dsl/ShellArgumentContextImpl.kt b/plugins/terminal/src/org/jetbrains/plugins/terminal/block/completion/spec/dsl/ShellArgumentContextImpl.kt index 09c9fe7e3a7b..4e546424aa7e 100644 --- a/plugins/terminal/src/org/jetbrains/plugins/terminal/block/completion/spec/dsl/ShellArgumentContextImpl.kt +++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/block/completion/spec/dsl/ShellArgumentContextImpl.kt @@ -11,13 +11,14 @@ import java.util.function.Supplier /** * Params [parentNames] and [argNumber] used to build cache key/debug name of the generators */ +@Suppress("OVERRIDE_DEPRECATION") internal class ShellArgumentContextImpl( private val parentNames: List, private val argNumber: Int ) : ShellArgumentContext { override var isOptional: Boolean = false override var isVariadic: Boolean = false - override var optionsCanBreakVariadicArg: Boolean = true + private var optionsCanBreakVariadicArg: Boolean = true private var displayNameSupplier: Supplier? = null @@ -29,6 +30,18 @@ internal class ShellArgumentContextImpl( displayNameSupplier = supplier } + override fun optional() { + isOptional = true + } + + override fun variadic() { + isVariadic = true + } + + override fun optionsCantBreakVariadicArg() { + optionsCanBreakVariadicArg = false + } + private val generators: MutableList>> = mutableListOf() override fun suggestions(content: suspend (ShellRuntimeContext) -> List) { @@ -42,7 +55,7 @@ internal class ShellArgumentContextImpl( override fun suggestions(vararg names: String) { val generator = ShellRuntimeDataGenerator(debugName = createCacheKey()) { - names.map { ShellCompletionSuggestion(it) { type = ShellSuggestionType.ARGUMENT } } + names.map { ShellCompletionSuggestion(it) { type(ShellSuggestionType.ARGUMENT) } } } generators.add(generator) } diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/block/completion/spec/dsl/ShellCommandContext.kt b/plugins/terminal/src/org/jetbrains/plugins/terminal/block/completion/spec/dsl/ShellCommandContext.kt index bd22a901fa12..a0fca5274755 100644 --- a/plugins/terminal/src/org/jetbrains/plugins/terminal/block/completion/spec/dsl/ShellCommandContext.kt +++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/block/completion/spec/dsl/ShellCommandContext.kt @@ -17,17 +17,15 @@ import org.jetbrains.annotations.ApiStatus @ShellCommandSpecDsl sealed interface ShellCommandContext : ShellSuggestionContext { /** - * Whether this command can't be executed without mentioning the subcommand. - * - * False by default. + * Specifies that this command can't be executed without mentioning the subcommand. */ - var requiresSubcommand: Boolean + fun requiresSubcommand() /** * Allows modifying default parser options. * @see [ShellCommandParserOptions] */ - var parserOptions: ShellCommandParserOptions + fun parserOptions(options: ShellCommandParserOptions) /** * Specify the subcommands of the current command. @@ -62,7 +60,7 @@ sealed interface ShellCommandContext : ShellSuggestionContext { /** * Specifies that this Shell command should have an argument. * Note that arguments are not optional by default. - * If your argument is not necessary to be specified, then set [ShellArgumentContext.isOptional] to true. + * If your argument is not necessary to be specified, specify [ShellArgumentContext.optional]. * Arguments should be defined in the same order as it is expected in the command line. * @param [content] description of the argument */ diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/block/completion/spec/dsl/ShellCommandContextImpl.kt b/plugins/terminal/src/org/jetbrains/plugins/terminal/block/completion/spec/dsl/ShellCommandContextImpl.kt index 888bbe297dbb..0a2f129bb1a9 100644 --- a/plugins/terminal/src/org/jetbrains/plugins/terminal/block/completion/spec/dsl/ShellCommandContextImpl.kt +++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/block/completion/spec/dsl/ShellCommandContextImpl.kt @@ -14,8 +14,8 @@ internal class ShellCommandContextImpl( names: List, private val parentNames: List = emptyList() ) : ShellSuggestionContextBase(names), ShellCommandContext { - override var requiresSubcommand: Boolean = false - override var parserOptions: ShellCommandParserOptions = ShellCommandParserOptions.DEFAULT + private var requiresSubcommand: Boolean = false + private var parserOptions: ShellCommandParserOptions = ShellCommandParserOptions.DEFAULT private var subcommandSuppliers: MutableList List> = mutableListOf() private var dynamicOptionSuppliers: MutableList List> = mutableListOf() @@ -24,6 +24,14 @@ internal class ShellCommandContextImpl( private val parentNamesWithSelf: List = parentNames + names.first() + override fun requiresSubcommand() { + requiresSubcommand = true + } + + override fun parserOptions(options: ShellCommandParserOptions) { + parserOptions = options + } + override fun subcommands(content: suspend ShellChildCommandsContext.(ShellRuntimeContext) -> Unit) { val supplier: suspend (ShellRuntimeContext) -> List = { shellContext -> val context = ShellChildCommandsContextImpl(parentNamesWithSelf) diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/block/completion/spec/dsl/ShellCompletionSuggestionContext.kt b/plugins/terminal/src/org/jetbrains/plugins/terminal/block/completion/spec/dsl/ShellCompletionSuggestionContext.kt index 5e1b02d5958d..b45bac1d8586 100644 --- a/plugins/terminal/src/org/jetbrains/plugins/terminal/block/completion/spec/dsl/ShellCompletionSuggestionContext.kt +++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/block/completion/spec/dsl/ShellCompletionSuggestionContext.kt @@ -15,7 +15,7 @@ sealed interface ShellCompletionSuggestionContext : ShellSuggestionContext { /** * Used for now only to automatically configure the icon. */ - var type: ShellSuggestionType + fun type(type: ShellSuggestionType) /** * Custom icon instead of autodetected from [type]. @@ -30,15 +30,15 @@ sealed interface ShellCompletionSuggestionContext : ShellSuggestionContext { * 2. If typed prefix is `foo/b` and suggestion name is `bar` (we want to suggest the part of the path after `/`), * then the replacement index should be `4`. */ - var prefixReplacementIndex: Int + fun prefixReplacementIndex(index: Int) /** - * If true, then this suggestion won't be shown in the completion popup. - * It may be needed to specify that this suggestion is also a valid value for the argument. + * Marks this suggestion to not show it in the completion popup. + * It may be necessary to specify that this suggestion is also a valid value for the argument. * So parser will be able to distinguish it and not mark it as something unknown. * * For example, if there is a directory suggestion, then it may have a trailing file separator or may not. * Both options are acceptable, but only one of them should be shown in the completion popup. */ - var isHidden: Boolean + fun hidden() } \ No newline at end of file diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/block/completion/spec/dsl/ShellCompletionSuggestionContextImpl.kt b/plugins/terminal/src/org/jetbrains/plugins/terminal/block/completion/spec/dsl/ShellCompletionSuggestionContextImpl.kt index 0082ceb4e89f..e496f71087b4 100644 --- a/plugins/terminal/src/org/jetbrains/plugins/terminal/block/completion/spec/dsl/ShellCompletionSuggestionContextImpl.kt +++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/block/completion/spec/dsl/ShellCompletionSuggestionContextImpl.kt @@ -11,15 +11,27 @@ import javax.swing.Icon internal class ShellCompletionSuggestionContextImpl( private val name: String, ) : ShellSuggestionContextBase(listOf(name)), ShellCompletionSuggestionContext { - override var type: ShellSuggestionType = ShellSuggestionType.ARGUMENT + private var type: ShellSuggestionType = ShellSuggestionType.ARGUMENT private var icon: Icon? = null - override var prefixReplacementIndex: Int = 0 - override var isHidden: Boolean = false + private var prefixReplacementIndex: Int = 0 + private var isHidden: Boolean = false + + override fun type(type: ShellSuggestionType) { + this.type = type + } override fun icon(icon: Icon) { this.icon = icon } + override fun prefixReplacementIndex(index: Int) { + this.prefixReplacementIndex = index + } + + override fun hidden() { + isHidden = true + } + fun build(): ShellCompletionSuggestion { return ShellCompletionSuggestionImpl( name = name, diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/block/completion/spec/dsl/ShellOptionContext.kt b/plugins/terminal/src/org/jetbrains/plugins/terminal/block/completion/spec/dsl/ShellOptionContext.kt index 4bdd8502aea6..7582f2361e0e 100644 --- a/plugins/terminal/src/org/jetbrains/plugins/terminal/block/completion/spec/dsl/ShellOptionContext.kt +++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/block/completion/spec/dsl/ShellOptionContext.kt @@ -16,56 +16,47 @@ import org.jetbrains.annotations.ApiStatus @ShellCommandSpecDsl sealed interface ShellOptionContext : ShellSuggestionContext { /** - * Whether this option can be available for all subcommands of the current Shell command. - * - * False by default. + * Makes this option available for all subcommands of the current Shell command. */ - var isPersistent: Boolean + fun persistent() /** - * Whether this option always must be present in the Shell command call. - * - * False by default. + * Specifies that this option always must be present in the Shell command call. */ - var isRequired: Boolean + fun required() /** - * The separator between the option name and the argument value (if option has an argument). + * Specifies the separator between the option name and the argument value (if the option has an argument). * For example, in case of `--opt=value`, the separator should be `=`. - * - * Whitespace is used as a separator by default (but the value of the property is null in this case). + * Whitespace is used as a separator by default. */ - var separator: String? + fun separator(separator: String) /** - * The maximum amount of times this option can be present in the command line. + * Specifies the maximum number of times this option can be present in the command line. * Zero value means that it can be repeated infinitely. * If the option is already present this number of times in the command, it won't be shown in the completion popup anymore. * * One by default. */ - var repeatTimes: Int + fun repeatTimes(times: Int) /** - * Names of the options with those this option cannot be used. + * Specifies the names of the options with those this option cannot be used. * If any of such options is used in the command, this option won't be shown in the completion popup. - * - * Empty list by default. */ - var exclusiveOn: List + fun exclusiveOn(on: List) /** - * Names of the options required to use this option. + * Specifies names of the options required to use this option. * Until all such options are used in the command, this option won't be shown in the completion popup. - * - * Empty list by default. */ - var dependsOn: List + fun dependsOn(on: List) /** * Specifies that this Shell option should have an argument. * Note that arguments are not optional by default. - * If your argument is not necessary to be specified, then set [ShellArgumentContext.isOptional] to true. + * If your argument is not necessary to be specified, specify [ShellArgumentContext.optional]. * Arguments should be defined in the same order as it is expected in the command line. * @param [content] description of the argument */ diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/block/completion/spec/dsl/ShellOptionContextImpl.kt b/plugins/terminal/src/org/jetbrains/plugins/terminal/block/completion/spec/dsl/ShellOptionContextImpl.kt index da4b3352d2c8..920ebe5a1b7e 100644 --- a/plugins/terminal/src/org/jetbrains/plugins/terminal/block/completion/spec/dsl/ShellOptionContextImpl.kt +++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/block/completion/spec/dsl/ShellOptionContextImpl.kt @@ -12,15 +12,39 @@ internal class ShellOptionContextImpl( names: List, private val parentCommandNames: List ) : ShellSuggestionContextBase(names), ShellOptionContext { - override var isPersistent: Boolean = false - override var isRequired: Boolean = false - override var separator: String? = null - override var repeatTimes: Int = 1 - override var exclusiveOn: List = emptyList() - override var dependsOn: List = emptyList() + private var isPersistent: Boolean = false + private var isRequired: Boolean = false + private var separator: String? = null + private var repeatTimes: Int = 1 + private var exclusiveOn: List = emptyList() + private var dependsOn: List = emptyList() private val arguments: MutableList = mutableListOf() + override fun persistent() { + isPersistent = true + } + + override fun required() { + isRequired = true + } + + override fun separator(separator: String) { + this.separator = separator + } + + override fun repeatTimes(times: Int) { + repeatTimes = times + } + + override fun exclusiveOn(on: List) { + exclusiveOn = on + } + + override fun dependsOn(on: List) { + dependsOn = on + } + override fun argument(content: ShellArgumentContext.() -> Unit) { val context = ShellArgumentContextImpl(parentCommandNames + names.first(), argNumber = arguments.size + 1) content.invoke(context) diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/block/completion/spec/dsl/ShellSuggestionContext.kt b/plugins/terminal/src/org/jetbrains/plugins/terminal/block/completion/spec/dsl/ShellSuggestionContext.kt index e3ea0fadaf7f..b2e04da15019 100644 --- a/plugins/terminal/src/org/jetbrains/plugins/terminal/block/completion/spec/dsl/ShellSuggestionContext.kt +++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/block/completion/spec/dsl/ShellSuggestionContext.kt @@ -3,7 +3,6 @@ package org.jetbrains.plugins.terminal.block.completion.spec.dsl import org.jetbrains.annotations.ApiStatus import org.jetbrains.annotations.Nls -import org.jetbrains.annotations.NonNls import java.util.function.Supplier /** @@ -12,12 +11,10 @@ import java.util.function.Supplier @ApiStatus.Experimental @ShellCommandSpecDsl sealed interface ShellSuggestionContext { - val names: List<@NonNls String> - /** - * The string to be shown in the completion popup instead of command/option name. + * Sets the string to be shown in the completion popup instead of command/option name. */ - var displayName: String? + fun displayName(name: String) /** * Text to be shown in the documentation popup for this command/option. @@ -34,12 +31,15 @@ sealed interface ShellSuggestionContext { * Supports specifying caret position after completion item insertion in a form `some{caret}item`. * In this example `someitem` text will be inserted and caret is placed between `some` and `item`. */ - var insertValue: String? + fun insertValue(value: String) + + @set:Deprecated("Please use priority() method instead") + var priority: Int /** * Int from 0 to 100 with default 50. * Allows specifying the order of the items in the completion popup. * The greater the number, the closer the item will be to the first place. */ - var priority: Int + fun priority(priority: Int) } \ No newline at end of file diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/block/completion/spec/dsl/ShellSuggestionContextBase.kt b/plugins/terminal/src/org/jetbrains/plugins/terminal/block/completion/spec/dsl/ShellSuggestionContextBase.kt index e677f22fdab6..f02d055eb26f 100644 --- a/plugins/terminal/src/org/jetbrains/plugins/terminal/block/completion/spec/dsl/ShellSuggestionContextBase.kt +++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/block/completion/spec/dsl/ShellSuggestionContextBase.kt @@ -5,10 +5,12 @@ import org.jetbrains.annotations.Nls import java.util.function.Supplier internal abstract class ShellSuggestionContextBase( - final override val names: List, + protected val names: List, ) : ShellSuggestionContext { - override var displayName: String? = null - override var insertValue: String? = null + protected var displayName: String? = null + protected var insertValue: String? = null + + @Suppress("OVERRIDE_DEPRECATION") override var priority: Int = 50 set(value) { if (value in 0..100) { @@ -19,6 +21,10 @@ internal abstract class ShellSuggestionContextBase( protected var descriptionSupplier: Supplier<@Nls String>? = null + override fun displayName(name: String) { + displayName = name + } + override fun description(text: String) { descriptionSupplier = Supplier { text } } @@ -27,6 +33,14 @@ internal abstract class ShellSuggestionContextBase( descriptionSupplier = supplier } + override fun insertValue(value: String) { + this.insertValue = value + } + + override fun priority(priority: Int) { + this.priority = priority + } + init { if (names.isEmpty()) { error("At least one name must be provided") diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/block/completion/spec/json/ShellJsonBasedArgumentSpec.kt b/plugins/terminal/src/org/jetbrains/plugins/terminal/block/completion/spec/json/ShellJsonBasedArgumentSpec.kt index 1b95c5f01cd9..d5f8814dc5c8 100644 --- a/plugins/terminal/src/org/jetbrains/plugins/terminal/block/completion/spec/json/ShellJsonBasedArgumentSpec.kt +++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/block/completion/spec/json/ShellJsonBasedArgumentSpec.kt @@ -39,11 +39,11 @@ internal class ShellJsonBasedArgumentSpec( s.names.map { name -> // TODO: there should be a way to localize the json-based descriptions ShellCompletionSuggestion(name) { - type = ShellSuggestionType.ARGUMENT - displayName = s.displayName - if (s.description != null) description(s.description!!) - insertValue = s.insertValue - priority = s.priority + type(ShellSuggestionType.ARGUMENT) + s.displayName?.let { displayName(it) } + s.description?.let { description(it) } + s.insertValue?.let { insertValue(it) } + priority(s.priority) } } } diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/block/completion/spec/specs/ShellCdCommandSpec.kt b/plugins/terminal/src/org/jetbrains/plugins/terminal/block/completion/spec/specs/ShellCdCommandSpec.kt index 116611c3e5fd..edca1fde4527 100644 --- a/plugins/terminal/src/org/jetbrains/plugins/terminal/block/completion/spec/specs/ShellCdCommandSpec.kt +++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/block/completion/spec/specs/ShellCdCommandSpec.kt @@ -25,21 +25,21 @@ internal fun cdCommandSpec() = ShellCommandSpec("cd") { val replacementIndex = path.length + if (context.typedPrefix.startsWith('"')) 1 else 0 val suggestions = directories.flatMap { val suggestion = ShellCompletionSuggestion(it.name + File.separator) { - type = ShellSuggestionType.FOLDER - prefixReplacementIndex = replacementIndex + type(ShellSuggestionType.FOLDER) + prefixReplacementIndex(replacementIndex) } val hiddenSuggestion = ShellCompletionSuggestion(it.name) { - type = ShellSuggestionType.FOLDER - prefixReplacementIndex = replacementIndex - isHidden = true + type(ShellSuggestionType.FOLDER) + prefixReplacementIndex(replacementIndex) + hidden() } listOf(suggestion, hiddenSuggestion) } val adjustedPrefix = context.typedPrefix.removePrefix("\"").removeSuffix("'") if (path.isNotEmpty() && path == adjustedPrefix) { val emptySuggestion = ShellCompletionSuggestion("") { - prefixReplacementIndex = replacementIndex - isHidden = true + prefixReplacementIndex(replacementIndex) + hidden() } suggestions + emptySuggestion } diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/block/completion/spec/specs/make/ShellMakeCommandSpec.kt b/plugins/terminal/src/org/jetbrains/plugins/terminal/block/completion/spec/specs/make/ShellMakeCommandSpec.kt index 47d457c6e363..eba50b19136a 100644 --- a/plugins/terminal/src/org/jetbrains/plugins/terminal/block/completion/spec/specs/make/ShellMakeCommandSpec.kt +++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/block/completion/spec/specs/make/ShellMakeCommandSpec.kt @@ -19,7 +19,7 @@ object ShellMakeCommandSpec { fun create(): ShellCommandSpec = ShellCommandSpec("make") { description(TerminalBundle.messagePointer("make.command.description")) argument { - isVariadic = true + variadic() displayName(TerminalBundle.messagePointer("make.command.arg.displayName")) @@ -52,7 +52,7 @@ object ShellMakeCommandSpec { .mapNotNull { MakefileTarget.parse(it) } .map { makefileTarget -> ShellCompletionSuggestion(makefileTarget.name) { - type = ShellSuggestionType.ARGUMENT + type(ShellSuggestionType.ARGUMENT) @Suppress("HardCodedStringLiteral") val desc = listOfNotNull( makefileTarget.comment diff --git a/plugins/terminal/tests/src/com/intellij/terminal/tests/block/completion/ShellCommandSpecSuggestionsTest.kt b/plugins/terminal/tests/src/com/intellij/terminal/tests/block/completion/ShellCommandSpecSuggestionsTest.kt index c4a9d160ffe8..b3df5c41eefb 100644 --- a/plugins/terminal/tests/src/com/intellij/terminal/tests/block/completion/ShellCommandSpecSuggestionsTest.kt +++ b/plugins/terminal/tests/src/com/intellij/terminal/tests/block/completion/ShellCommandSpecSuggestionsTest.kt @@ -50,18 +50,18 @@ internal class ShellCommandSpecSuggestionsTest(private val engine: TerminalEngin private val spec = ShellCommandSpec(commandName) { option("-a", "--asd") option("--bcde") { - isPersistent = true - repeatTimes = 2 + persistent() + repeatTimes(2) } option("--argum") { argument { - isOptional = true + optional() suggestions("all", "none", "default") } } argument { - isOptional = true + optional() suggestions("abc") } @@ -69,7 +69,7 @@ internal class ShellCommandSpecSuggestionsTest(private val engine: TerminalEngin subcommand("sub") { option("-o", "--opt1") option("-a") { - repeatTimes = 0 + repeatTimes(0) } option("--long") option("--withReqArg") { @@ -79,7 +79,7 @@ internal class ShellCommandSpecSuggestionsTest(private val engine: TerminalEngin } option("--withOptArg") { argument { - isOptional = true + optional() } } @@ -87,26 +87,26 @@ internal class ShellCommandSpecSuggestionsTest(private val engine: TerminalEngin suggestions("file") } argument { - isOptional = true + optional() suggestions("s1") } } subcommand("excl") { option("-a") { - exclusiveOn = listOf("-b") + exclusiveOn(listOf("-b")) } option("-b") { - exclusiveOn = listOf("-a") + exclusiveOn(listOf("-a")) } option("-c") option("-d") { - dependsOn = listOf("-a", "-c") + dependsOn(listOf("-a", "-c")) } } subcommand("reqSub") { - requiresSubcommand = true + requiresSubcommand() subcommands { subcommand("abc") } @@ -115,14 +115,14 @@ internal class ShellCommandSpecSuggestionsTest(private val engine: TerminalEngin subcommand("manyArgs") { argument { - isOptional = true + optional() suggestions("arg1") } argument { suggestions("arg2", "arg22") } argument { - isOptional = true + optional() suggestions("arg3") } argument { @@ -131,13 +131,15 @@ internal class ShellCommandSpecSuggestionsTest(private val engine: TerminalEngin } subcommand("optPrecedeArgs") { - parserOptions = ShellCommandParserOptions.builder() - .optionsMustPrecedeArguments(true) - .build() + parserOptions( + ShellCommandParserOptions.builder() + .optionsMustPrecedeArguments(true) + .build() + ) option("-c") option("-d") argument { - isOptional = true + optional() suggestions("arg") } @@ -156,7 +158,7 @@ internal class ShellCommandSpecSuggestionsTest(private val engine: TerminalEngin option("-a") option("--var") { argument { - isVariadic = true + variadic() suggestions("var1", "var2") } } @@ -164,11 +166,11 @@ internal class ShellCommandSpecSuggestionsTest(private val engine: TerminalEngin suggestions("req") } argument { - isVariadic = true + variadic() suggestions("v") } argument { - isOptional = true + optional() suggestions("opt") } } @@ -177,14 +179,14 @@ internal class ShellCommandSpecSuggestionsTest(private val engine: TerminalEngin option("-b") option("---") { argument { - isVariadic = true - optionsCanBreakVariadicArg = false + variadic() + optionsCantBreakVariadicArg() suggestions("var") } } argument { - isVariadic = true - optionsCanBreakVariadicArg = false + variadic() + optionsCantBreakVariadicArg() suggestions("v") } argument { @@ -209,17 +211,17 @@ internal class ShellCommandSpecSuggestionsTest(private val engine: TerminalEngin option("--opt") { argument { suggestions("3", "4", "5") - isOptional = true + optional() } } argument { suggestions("1", "2", "3") - isOptional = true + optional() } argument { suggestions("2", "3", "4") - isOptional = true + optional() } } diff --git a/plugins/terminal/tests/src/com/intellij/terminal/tests/block/completion/ShellCommandTreeBuilderTest.kt b/plugins/terminal/tests/src/com/intellij/terminal/tests/block/completion/ShellCommandTreeBuilderTest.kt index 3a133d070b6f..245136b90804 100644 --- a/plugins/terminal/tests/src/com/intellij/terminal/tests/block/completion/ShellCommandTreeBuilderTest.kt +++ b/plugins/terminal/tests/src/com/intellij/terminal/tests/block/completion/ShellCommandTreeBuilderTest.kt @@ -44,13 +44,13 @@ internal class ShellCommandTreeBuilderTest(private val engine: TerminalEngine) { option("--bcde") option("--argum") { argument { - isOptional = true + optional() suggestions("someArg") } } argument { - isOptional = true + optional() suggestions("aaa", "bbb") } @@ -61,7 +61,7 @@ internal class ShellCommandTreeBuilderTest(private val engine: TerminalEngine) { option("--manyArgs") { argument() argument { - isOptional = true + optional() suggestions("a2") } } @@ -71,7 +71,7 @@ internal class ShellCommandTreeBuilderTest(private val engine: TerminalEngine) { option("-a") argument { - isOptional = true + optional() suggestions { listOf( ShellAliasSuggestion("alias-1", "al --manyArgs somearg"), @@ -93,23 +93,23 @@ internal class ShellCommandTreeBuilderTest(private val engine: TerminalEngine) { } option("--withOptArg") { argument { - isOptional = true + optional() } } option("--manyArgs") { argument() argument { - isOptional = true + optional() suggestions("a2") } } option("--skippedArg") { argument { - isOptional = true + optional() } argument() argument { - isOptional = true + optional() suggestions("opt2") } } @@ -118,22 +118,24 @@ internal class ShellCommandTreeBuilderTest(private val engine: TerminalEngine) { suggestions("somePath") } argument { - isOptional = true + optional() suggestions("arg1", "arg2") } } subcommand("nonPosix") { - parserOptions = ShellCommandParserOptions.builder() - .flagsArePosixNonCompliant(true) - .build() + parserOptions( + ShellCommandParserOptions.builder() + .flagsArePosixNonCompliant(true) + .build() + ) option("-a") option("-b") } subcommand("sep") { option("--withSeparator") { - separator = "=" + separator("=") argument() } } diff --git a/plugins/terminal/tests/src/com/intellij/terminal/tests/reworked/frontend/completion/TerminalCompletionPopupTest.kt b/plugins/terminal/tests/src/com/intellij/terminal/tests/reworked/frontend/completion/TerminalCompletionPopupTest.kt index f5d614a9de40..5ca7d7740d3b 100644 --- a/plugins/terminal/tests/src/com/intellij/terminal/tests/reworked/frontend/completion/TerminalCompletionPopupTest.kt +++ b/plugins/terminal/tests/src/com/intellij/terminal/tests/reworked/frontend/completion/TerminalCompletionPopupTest.kt @@ -31,14 +31,14 @@ class TerminalCompletionPopupTest : BasePlatformTestCase() { subcommand("sync") subcommand("show") { argument { - isOptional = true + optional() suggestions("roots", "files", "statuses") } } subcommand("start") { argument { - isOptional = true + optional() suggestions("platform/", "platform-ui/", "shared\\", "shared-ui\\") } } @@ -58,8 +58,8 @@ class TerminalCompletionPopupTest : BasePlatformTestCase() { } } - val abPriority = ShellCompletionSuggestion("ab") { priority = 100 } - val acPriority = ShellCompletionSuggestion("ac") { priority = 100 } + val abPriority = ShellCompletionSuggestion("ab") { priority(100) } + val acPriority = ShellCompletionSuggestion("ac") { priority(100) } listOf(abPriority, acPriority) + items.map { ShellCompletionSuggestion(it) } } }