diff --git a/plugins/terminal/frontend/src/com/intellij/terminal/frontend/action/TerminalCommandCompletionActionGen2.kt b/plugins/terminal/frontend/src/com/intellij/terminal/frontend/action/TerminalCommandCompletionActionGen2.kt index 1b8edffba9bd..a86fa151eeb0 100644 --- a/plugins/terminal/frontend/src/com/intellij/terminal/frontend/action/TerminalCommandCompletionActionGen2.kt +++ b/plugins/terminal/frontend/src/com/intellij/terminal/frontend/action/TerminalCommandCompletionActionGen2.kt @@ -16,6 +16,7 @@ import org.jetbrains.plugins.terminal.block.reworked.TerminalCommandCompletion import org.jetbrains.plugins.terminal.block.util.TerminalDataContextUtils.isOutputModelEditor import org.jetbrains.plugins.terminal.block.util.TerminalDataContextUtils.isSuppressCompletion import org.jetbrains.plugins.terminal.block.util.TerminalDataContextUtils.terminalEditor +import org.jetbrains.plugins.terminal.session.guessShellName import org.jetbrains.plugins.terminal.util.getNow import org.jetbrains.plugins.terminal.view.shellIntegration.TerminalOutputStatus.TypingCommand @@ -36,9 +37,12 @@ internal class TerminalCommandCompletionActionGen2 : BaseCodeCompletionAction(), override fun update(e: AnActionEvent) { super.update(e) val project = e.project - val isCommandTypingMode = e.terminalView?.shellIntegrationDeferred?.getNow()?.outputStatus?.value == TypingCommand + val terminalView = e.terminalView + val shellName = terminalView?.startupOptionsDeferred?.getNow()?.guessShellName() + val isCommandTypingMode = terminalView?.shellIntegrationDeferred?.getNow()?.outputStatus?.value == TypingCommand e.presentation.isEnabledAndVisible = e.terminalEditor?.isOutputModelEditor == true && project != null && TerminalCommandCompletion.isEnabled(project) + && shellName != null && TerminalCommandCompletion.isSupportedForShell(shellName) && isCommandTypingMode } diff --git a/plugins/terminal/frontend/src/com/intellij/terminal/frontend/view/impl/TerminalEventsHandlerImpl.kt b/plugins/terminal/frontend/src/com/intellij/terminal/frontend/view/impl/TerminalEventsHandlerImpl.kt index 7883e065a09d..aec2cf8fa064 100644 --- a/plugins/terminal/frontend/src/com/intellij/terminal/frontend/view/impl/TerminalEventsHandlerImpl.kt +++ b/plugins/terminal/frontend/src/com/intellij/terminal/frontend/view/impl/TerminalEventsHandlerImpl.kt @@ -20,6 +20,8 @@ import org.jetbrains.plugins.terminal.block.reworked.TerminalCommandCompletion import org.jetbrains.plugins.terminal.block.reworked.TerminalSessionModel import org.jetbrains.plugins.terminal.block.reworked.TerminalUsageLocalStorage import org.jetbrains.plugins.terminal.block.util.TerminalDataContextUtils.isOutputModelEditor +import org.jetbrains.plugins.terminal.session.TerminalStartupOptions +import org.jetbrains.plugins.terminal.session.guessShellName import org.jetbrains.plugins.terminal.session.impl.TerminalState import org.jetbrains.plugins.terminal.util.getNow import org.jetbrains.plugins.terminal.view.TerminalOutputModel @@ -48,6 +50,7 @@ internal open class TerminalEventsHandlerImpl( private val scrollingModel: TerminalOutputScrollingModel?, private val outputModel: TerminalOutputModel, private val shellIntegrationDeferred: Deferred?, + private val startupOptionsDeferred: Deferred?, private val typeAhead: TerminalTypeAhead?, ) : TerminalEventsHandler { private var ignoreNextKeyTypedEvent: Boolean = false @@ -408,9 +411,11 @@ internal open class TerminalEventsHandlerImpl( private fun scheduleCompletionPopupIfNeeded(charTyped: Char) { val project = editor.project ?: return + val shellName = startupOptionsDeferred?.getNow()?.guessShellName() ?: return val shellIntegration = shellIntegrationDeferred?.getNow() ?: return if (editor.isOutputModelEditor && TerminalCommandCompletion.isEnabled(project) + && TerminalCommandCompletion.isSupportedForShell(shellName) && TerminalOptionsProvider.instance.showCompletionPopupAutomatically && shellIntegration.outputStatus.value == TerminalOutputStatus.TypingCommand && canTriggerCompletion(charTyped) diff --git a/plugins/terminal/frontend/src/com/intellij/terminal/frontend/view/impl/TerminalViewImpl.kt b/plugins/terminal/frontend/src/com/intellij/terminal/frontend/view/impl/TerminalViewImpl.kt index 948c4bcb93e0..5d8ee1ab78a8 100644 --- a/plugins/terminal/frontend/src/com/intellij/terminal/frontend/view/impl/TerminalViewImpl.kt +++ b/plugins/terminal/frontend/src/com/intellij/terminal/frontend/view/impl/TerminalViewImpl.kt @@ -170,6 +170,7 @@ class TerminalViewImpl( scrollingModel = null, alternateBufferModel, shellIntegrationDeferred = null, + startupOptionsDeferred = null, typeAhead = null, ) configureOutputEditor( @@ -217,6 +218,7 @@ class TerminalViewImpl( scrollingModel, outputModel, shellIntegrationDeferred, + startupOptionsDeferred, typeAhead = outputModelController ) diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/block/reworked/TerminalCommandCompletion.kt b/plugins/terminal/src/org/jetbrains/plugins/terminal/block/reworked/TerminalCommandCompletion.kt index 3aa74b563b23..390a76a34b6d 100644 --- a/plugins/terminal/src/org/jetbrains/plugins/terminal/block/reworked/TerminalCommandCompletion.kt +++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/block/reworked/TerminalCommandCompletion.kt @@ -10,6 +10,7 @@ import com.intellij.platform.eel.provider.getEelDescriptor import com.intellij.util.system.OS import org.jetbrains.annotations.ApiStatus import org.jetbrains.annotations.TestOnly +import org.jetbrains.plugins.terminal.session.ShellName @ApiStatus.Internal object TerminalCommandCompletion { @@ -22,6 +23,10 @@ object TerminalCommandCompletion { && project.getEelDescriptor() == LocalEelDescriptor // Disable in non-local projects for now as it requires additional support } + fun isSupportedForShell(name: ShellName): Boolean { + return name == ShellName.ZSH || name == ShellName.BASH + } + @TestOnly fun enableForTests(parentDisposable: Disposable) { Registry.get(REGISTRY_KEY).setValue(true, parentDisposable) diff --git a/plugins/terminal/tests/src/com/intellij/terminal/tests/reworked/frontend/completion/TerminalCompletionFixture.kt b/plugins/terminal/tests/src/com/intellij/terminal/tests/reworked/frontend/completion/TerminalCompletionFixture.kt index 5604eeafac6b..d7ac1308fb8c 100644 --- a/plugins/terminal/tests/src/com/intellij/terminal/tests/reworked/frontend/completion/TerminalCompletionFixture.kt +++ b/plugins/terminal/tests/src/com/intellij/terminal/tests/reworked/frontend/completion/TerminalCompletionFixture.kt @@ -28,6 +28,7 @@ import org.jetbrains.plugins.terminal.block.completion.spec.ShellCommandSpecConf import org.jetbrains.plugins.terminal.block.completion.spec.ShellCommandSpecInfo import org.jetbrains.plugins.terminal.block.completion.spec.ShellCommandSpecsProvider import org.jetbrains.plugins.terminal.block.reworked.TerminalCommandCompletion +import org.jetbrains.plugins.terminal.session.impl.TerminalStartupOptionsImpl import org.jetbrains.plugins.terminal.util.terminalProjectScope import org.jetbrains.plugins.terminal.view.TerminalOffset import org.jetbrains.plugins.terminal.view.TerminalOutputModel @@ -56,6 +57,14 @@ class TerminalCompletionFixture(val project: Project, val testRootDisposable: Di val shellIntegration = TerminalShellIntegrationImpl(outputModel, view.sessionModel, terminalScope.childScope("TerminalShellIntegration")) view.shellIntegrationDeferred.complete(shellIntegration) + // Need to specify some options to make `TerminalCommandCompletion.isSupportedForShell` pass. + val startupOptions = TerminalStartupOptionsImpl( + shellCommand = listOf("/bin/zsh", "--login", "-i"), + workingDirectory = project.basePath!!, + envVariables = emptyMap(), + ) + view.startupOptionsDeferred.complete(startupOptions) + shellIntegration.onPromptFinished(TerminalOffset.ZERO) // To make TerminalOutputStatus = TypingCommand assertEquals(TerminalOutputStatus.TypingCommand, shellIntegration.outputStatus.value)