From 1bccc54b4aadae6bca1410018c6bc31ad8607eca Mon Sep 17 00:00:00 2001 From: Konstantin Hudyakov Date: Fri, 29 Mar 2024 17:35:33 +0200 Subject: [PATCH] [terminal] IDEA-350567 Report information about shell version and installed plugins GitOrigin-RevId: 015e8f59432622f93c6e9a071483701d5d3f8270 --- .../bash/command-block-support.bash | 36 ++++- .../powershell/command-block-support.ps1 | 18 ++- .../zsh/command-block-support.zsh | 49 +++++- .../terminal/exp/BlockTerminalController.kt | 9 +- .../exp/ShellCommandExecutionManager.kt | 2 +- .../terminal/exp/ShellCommandManager.kt | 22 +-- .../fus/TerminalShellInfoStatistics.kt | 137 +++++++++++++++++ .../terminal/fus/TerminalUsageCollector.kt | 40 ++++- .../terminal/fus/known-bashit-themes.txt | 81 ++++++++++ .../terminal/fus/known-ohmybash-themes.txt | 73 +++++++++ .../terminal/fus/known-ohmyposh-themes.txt | 125 +++++++++++++++ .../terminal/fus/known-ohmyzsh-themes.txt | 143 ++++++++++++++++++ .../terminal/fus/known-prezto-themes.txt | 34 +++++ .../exp/util/TerminalSessionTestUtil.kt | 2 +- 14 files changed, 753 insertions(+), 18 deletions(-) create mode 100644 plugins/terminal/src/org/jetbrains/plugins/terminal/fus/TerminalShellInfoStatistics.kt create mode 100644 plugins/terminal/src/org/jetbrains/plugins/terminal/fus/known-bashit-themes.txt create mode 100644 plugins/terminal/src/org/jetbrains/plugins/terminal/fus/known-ohmybash-themes.txt create mode 100644 plugins/terminal/src/org/jetbrains/plugins/terminal/fus/known-ohmyposh-themes.txt create mode 100644 plugins/terminal/src/org/jetbrains/plugins/terminal/fus/known-ohmyzsh-themes.txt create mode 100644 plugins/terminal/src/org/jetbrains/plugins/terminal/fus/known-prezto-themes.txt diff --git a/plugins/terminal/resources/shell-integrations/bash/command-block-support.bash b/plugins/terminal/resources/shell-integrations/bash/command-block-support.bash index 1f3a6805bbf5..03a377885477 100644 --- a/plugins/terminal/resources/shell-integrations/bash/command-block-support.bash +++ b/plugins/terminal/resources/shell-integrations/bash/command-block-support.bash @@ -124,8 +124,9 @@ __jetbrains_intellij_command_terminated() { __jetbrains_intellij_report_prompt_state if [ -z "$__jetbrains_intellij_initialized" ]; then __jetbrains_intellij_initialized='1' + builtin local shell_info="$(__jetbrains_intellij_collect_shell_info)" __jetbrains_intellij_debug_log 'initialized' - builtin printf '\e]1341;initialized\a' + builtin printf '\e]1341;initialized;shell_info=%s\a' "$(__jetbrains_intellij_encode $shell_info)" builtin local hist="$(builtin history)" builtin printf '\e]1341;command_history;history_string=%s\a' "$(__jetbrains_intellij_encode "$hist")" else @@ -158,6 +159,39 @@ __jetbrains_intellij_report_prompt_state() { "$(__jetbrains_intellij_encode "${conda_env}")" } +__jetbrains_intellij_collect_shell_info() { + builtin local is_oh_my_bash='false' + if [ -n "${OSH_THEME:-}" ] || [ -n "${OSH:-}" ] || [ -n "${OSH_CACHE_DIR:-}" ]; then + is_oh_my_bash='true' + fi + builtin local is_starship='false' + if [ -n "${STARSHIP_START_TIME:-}" ] || [ -n "${STARSHIP_SHELL:-}" ] || [ -n "${STARSHIP_SESSION_KEY:-}" ]; then + is_starship='true' + fi + builtin local is_bash_it='false' + if [ -n "${BASH_IT_THEME:-}" ] || [ -n "${BASH_IT:-}" ] || [ -n "${BASH_IT_BASHRC:-}" ]; then + is_bash_it='true' + fi + + builtin local oh_my_bash_theme="${OSH_THEME:-}" + builtin local bash_it_theme="${BASH_IT_THEME:-}" + builtin local oh_my_posh_theme='' + if [ -n "${POSH_THEME:-}" ] || [ -n "${POSH_PID:-}" ] || [ -n "${POSH_SHELL_VERSION:-}" ]; then + oh_my_posh_theme="${POSH_THEME:-default}" + fi + + builtin local content_json="{"\ +"\"shellVersion\": \"$(__jetbrains_intellij_escape_json "${BASH_VERSION:-}")\", "\ +"\"isOhMyBash\": \"$is_oh_my_bash\", "\ +"\"isStarship\": \"$is_starship\", "\ +"\"isBashIt\": \"$is_bash_it\", "\ +"\"ohMyBashTheme\": \"$(__jetbrains_intellij_escape_json $oh_my_bash_theme)\", "\ +"\"ohMyPoshTheme\": \"$(__jetbrains_intellij_escape_json $oh_my_posh_theme)\", "\ +"\"bashItTheme\": \"$(__jetbrains_intellij_escape_json $bash_it_theme)\""\ +"}" + builtin printf '%s' $content_json +} + # override clear behaviour to handle it on IDE side and remove the blocks clear() { builtin printf '\e]1341;clear_invoked\a' diff --git a/plugins/terminal/resources/shell-integrations/powershell/command-block-support.ps1 b/plugins/terminal/resources/shell-integrations/powershell/command-block-support.ps1 index cb9f5b1d6d40..6411e30d2799 100644 --- a/plugins/terminal/resources/shell-integrations/powershell/command-block-support.ps1 +++ b/plugins/terminal/resources/shell-integrations/powershell/command-block-support.ps1 @@ -61,11 +61,12 @@ function Global:Prompt() { $History = Get-Content -Raw (Get-PSReadlineOption).HistorySavePath $HistoryOSC = Global:__JetBrainsIntellijOSC "command_history;history_string=$(__JetBrainsIntellijEncode $History)" + $ShellInfo = Global:__JetBrainsIntellijCollectShellInfo $Global:__JetBrainsIntellijTerminalInitialized = $true if ($Env:JETBRAINS_INTELLIJ_TERMINAL_DEBUG_LOG_LEVEL) { [Console]::WriteLine("initialized") } - $InitializedEvent = Global:__JetBrainsIntellijOSC "initialized" + $InitializedEvent = Global:__JetBrainsIntellijOSC "initialized;shell_info=$(__JetBrainsIntellijEncode $ShellInfo)" $Result = $CommandEndMarker + $PromptStateOSC + $HistoryOSC + $InitializedEvent } return $Result @@ -99,6 +100,21 @@ function Global:__JetBrainsIntellijCreatePromptStateOSC() { return $StateOSC } +function Global:__JetBrainsIntellijCollectShellInfo() { + $ShellVersion = if ($PSVersionTable -ne $null) { $PSVersionTable.PSVersion.toString() } else { "" } + $IsStarship = ($Env:STARSHIP_START_TIME -ne $null) -or ($Env:STARSHIP_SHELL -ne $null) -or ($Env:STARSHIP_SESSION_KEY -ne $null) + $OhMyPoshTheme = "" + if (($Env:POSH_THEME -ne $null) -or ($Env:POSH_PID -ne $null) -or ($Env:POSH_SHELL_VERSION -ne $null)) { + $OhMyPoshTheme = if ($Env:POSH_THEME -ne $null) { $Env:POSH_THEME } else { "default" } + } + $ShellInfo = [PSCustomObject]@{ + shellVersion = $ShellVersion + isStarship = $IsStarship + ohMyPoshTheme = $OhMyPoshTheme + } + return $ShellInfo | ConvertTo-Json -Compress +} + function Global:__JetBrainsIntellij_ClearAllAndMoveCursorToTopLeft() { [Console]::Clear() } diff --git a/plugins/terminal/resources/shell-integrations/zsh/command-block-support.zsh b/plugins/terminal/resources/shell-integrations/zsh/command-block-support.zsh index e01b70b06a25..c529fdbfe690 100644 --- a/plugins/terminal/resources/shell-integrations/zsh/command-block-support.zsh +++ b/plugins/terminal/resources/shell-integrations/zsh/command-block-support.zsh @@ -127,6 +127,50 @@ __jetbrains_intellij_report_prompt_state() { "$(__jetbrains_intellij_encode "${conda_env}")" } +__jetbrains_intellij_collect_shell_info() { + builtin local is_oh_my_zsh='false' + if [ -n "${ZSH_THEME:-}" ] || [ -n "${ZSH_COMPDUMP:-}" ] || [ -n "${ZSH_CACHE_DIR:-}" ]; then + is_oh_my_zsh='true' + fi + builtin local is_p10k='false' + if [ -n "${P9K_VERSION:-}" ] || [ -n "${POWERLEVEL9K_INSTANT_PROMPT:-}" ]; then + is_p10k='true' + fi + builtin local is_starship='false' + if [ -n "${STARSHIP_START_TIME:-}" ] || [ -n "${STARSHIP_SHELL:-}" ] || [ -n "${STARSHIP_SESSION_KEY:-}" ]; then + is_starship='true' + fi + builtin local is_spaceship='false' + if [ -n "${SPACESHIP_CONFIG_PATH:-}" ] || [ -n "${SPACESHIP_PROMPT_ORDER:-}" ]; then + is_spaceship='true' + fi + builtin local is_prezto='false' + if [ -n "${ZPREZTODIR:-}" ]; then + is_prezto='true' + fi + + builtin local oh_my_zsh_theme="${ZSH_THEME:-}" + builtin local oh_my_posh_theme='' + if [ -n "${POSH_THEME:-}" ] || [ -n "${POSH_PID:-}" ] || [ -n "${POSH_SHELL_VERSION:-}" ]; then + oh_my_posh_theme="${POSH_THEME:-default}" + fi + builtin local prezto_theme='' + zstyle -s ':prezto:module:prompt' theme prezto_theme + + builtin local content_json="{"\ +"\"shellVersion\": \"$(__jetbrains_intellij_escape_json "${ZSH_VERSION:-}")\", "\ +"\"isOhMyZsh\": \"$is_oh_my_zsh\", "\ +"\"isP10K\": \"$is_p10k\", "\ +"\"isStarship\": \"$is_starship\", "\ +"\"isSpaceship\": \"$is_spaceship\", "\ +"\"isPrezto\": \"$is_prezto\", "\ +"\"ohMyZshTheme\": \"$(__jetbrains_intellij_escape_json $oh_my_zsh_theme)\", "\ +"\"ohMyPoshTheme\": \"$(__jetbrains_intellij_escape_json $oh_my_posh_theme)\", "\ +"\"preztoTheme\": \"$(__jetbrains_intellij_escape_json $prezto_theme)\""\ +"}" + builtin printf '%s' $content_json +} + # override clear behaviour to handle it on IDE side and remove the blocks clear() { builtin printf '\e]1341;clear_invoked\a' @@ -145,6 +189,7 @@ __jetbrains_intellij_report_prompt_state builtin local hist="$(builtin history 1)" builtin printf '\e]1341;command_history;history_string=%s\a' "$(__jetbrains_intellij_encode_large "${hist}")" +builtin local shell_info="$(__jetbrains_intellij_collect_shell_info)" # This script is sourced from inside a `precmd` hook, i.e. right before the first prompt. -builtin printf '\e]1341;initialized\a' -builtin print "${JETBRAINS_INTELLIJ_COMMAND_END_MARKER:-}" +builtin printf '\e]1341;initialized;shell_info=%s\a' "$(__jetbrains_intellij_encode_large $shell_info)" +builtin print "${JETBRAINS_INTELLIJ_COMMAND_END_MARKER:-}" \ No newline at end of file diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/exp/BlockTerminalController.kt b/plugins/terminal/src/org/jetbrains/plugins/terminal/exp/BlockTerminalController.kt index f2866527ec57..e11e18d13d42 100644 --- a/plugins/terminal/src/org/jetbrains/plugins/terminal/exp/BlockTerminalController.kt +++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/exp/BlockTerminalController.kt @@ -7,6 +7,7 @@ import com.intellij.find.FindUtil import com.intellij.find.SearchSession import com.intellij.openapi.Disposable import com.intellij.openapi.actionSystem.DataKey +import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.application.ModalityState import com.intellij.openapi.project.Project import com.intellij.openapi.util.Disposer @@ -14,6 +15,7 @@ import com.intellij.util.concurrency.annotations.RequiresEdt import com.jediterm.core.util.TermSize import org.jetbrains.plugins.terminal.exp.BlockTerminalSearchSession.Companion.isSearchInBlock import org.jetbrains.plugins.terminal.exp.TerminalOutputModel.TerminalOutputListener +import org.jetbrains.plugins.terminal.fus.TerminalShellInfoStatistics import org.jetbrains.plugins.terminal.fus.TerminalUsageTriggerCollector import java.util.concurrent.CopyOnWriteArrayList @@ -79,8 +81,13 @@ class BlockTerminalController( TerminalUsageLocalStorage.getInstance().recordCommandExecuted(session.shellIntegration.shellType.toString()) } - override fun initialized() { + override fun initialized(rawShellInfo: String) { finishCommandBlock(exitCode = 0) + ApplicationManager.getApplication().executeOnPooledThread { + TerminalShellInfoStatistics.getLoggableShellInfo(rawShellInfo)?.let { + TerminalUsageTriggerCollector.triggerLocalShellStarted(project, session.shellIntegration.shellType.toString(), it) + } + } } override fun commandFinished(event: CommandFinishedEvent) { diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/exp/ShellCommandExecutionManager.kt b/plugins/terminal/src/org/jetbrains/plugins/terminal/exp/ShellCommandExecutionManager.kt index 19a7bf147c60..8bc6028f8a1e 100644 --- a/plugins/terminal/src/org/jetbrains/plugins/terminal/exp/ShellCommandExecutionManager.kt +++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/exp/ShellCommandExecutionManager.kt @@ -32,7 +32,7 @@ internal class ShellCommandExecutionManager(private val session: BlockTerminalSe init { commandManager.addListener(object : ShellCommandListener { - override fun initialized() { + override fun initialized(rawShellInfo: String) { lock.withLock { withoutLock -> isInitialized = true cancelGenerators(withoutLock, "initialized") diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/exp/ShellCommandManager.kt b/plugins/terminal/src/org/jetbrains/plugins/terminal/exp/ShellCommandManager.kt index 76e03257c62c..4e9fa2b0b8d7 100644 --- a/plugins/terminal/src/org/jetbrains/plugins/terminal/exp/ShellCommandManager.kt +++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/exp/ShellCommandManager.kt @@ -25,7 +25,7 @@ class ShellCommandManager(private val session: BlockTerminalSession) { session.controller.addCustomCommandListener(TerminalCustomCommandListener { try { when (it.getOrNull(0)) { - "initialized" -> processInitialized() + "initialized" -> processInitialized(it) "prompt_shown" -> firePromptShown() "command_started" -> processCommandStartedEvent(it) "command_finished" -> processCommandFinishedEvent(it) @@ -42,15 +42,16 @@ class ShellCommandManager(private val session: BlockTerminalSession) { }) } - private fun processInitialized() { + private fun processInitialized(event: List) { + val shellInfo = Param.SHELL_INFO.getDecodedValueOrNull(event.getOrNull(1)) ?: "{}" if (session.commandBlockIntegration.commandEndMarker != null) { debug { "Received initialized event, waiting for command end marker" } ShellCommandEndMarkerListener(session) { - fireInitialized() + fireInitialized(shellInfo) } } else { - fireInitialized() + fireInitialized(shellInfo) } } @@ -125,10 +126,10 @@ class ShellCommandManager(private val session: BlockTerminalSession) { } } - private fun fireInitialized() { - debug { "Shell event: initialized" } + private fun fireInitialized(rawShellInfo: String) { + debug { "Shell event: initialized. Shell info: $rawShellInfo" } for (listener in listeners) { - listener.initialized() + listener.initialized(rawShellInfo) } clearTerminal() } @@ -224,7 +225,10 @@ class ShellCommandManager(private val session: BlockTerminalSession) { CURRENT_DIRECTORY, GIT_BRANCH, VIRTUAL_ENV, - CONDA_ENV; + CONDA_ENV, + + /** Json with the following content [org.jetbrains.plugins.terminal.fus.TerminalShellInfoStatistics.ShellInfo] */ + SHELL_INFO; private val paramNameWithSeparator: String = "${paramName()}=" @@ -250,7 +254,7 @@ class ShellCommandManager(private val session: BlockTerminalSession) { } interface ShellCommandListener { - fun initialized() {} + fun initialized(rawShellInfo: String) {} /** * Fired each time when prompt is printed. diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/fus/TerminalShellInfoStatistics.kt b/plugins/terminal/src/org/jetbrains/plugins/terminal/fus/TerminalShellInfoStatistics.kt new file mode 100644 index 000000000000..b8a2f2e73efe --- /dev/null +++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/fus/TerminalShellInfoStatistics.kt @@ -0,0 +1,137 @@ +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package org.jetbrains.plugins.terminal.fus + +import com.intellij.internal.statistic.eventLog.events.BooleanEventField +import com.intellij.internal.statistic.eventLog.events.EventFields +import com.intellij.internal.statistic.eventLog.events.StringEventField +import com.intellij.internal.statistic.eventLog.validator.rules.impl.AllowedItemsResourceWeakRefStorage +import com.intellij.openapi.diagnostic.thisLogger +import com.intellij.util.PathUtil +import kotlinx.serialization.Serializable +import kotlinx.serialization.json.Json + +internal object TerminalShellInfoStatistics { + private val knownPromptThemes: List = getKnownPromptThemes() + + val shellVersionField: StringEventField = EventFields.StringValidatedByRegexpReference("shell_version", "version") + val promptThemeField: StringEventField = EventFields.String("prompt_theme", knownPromptThemes) + + val isOhMyPoshField: BooleanEventField = EventFields.Boolean("is_oh_my_posh", "Zsh, Bash, Powershell") + val isStarshipField: BooleanEventField = EventFields.Boolean("is_starship", "Zsh, Bash, Powershell") + + val isOhMyZshField: BooleanEventField = EventFields.Boolean("is_oh_my_zsh", "Zsh only") + val isP10KField: BooleanEventField = EventFields.Boolean("is_p10k", "Zsh only") + val isSpaceshipField: BooleanEventField = EventFields.Boolean("is_spaceship", "Zsh only") + val isPreztoField: BooleanEventField = EventFields.Boolean("is_prezto", "Zsh only") + + val isOhMyBashField: BooleanEventField = EventFields.Boolean("is_oh_my_bash", "Bash only") + val isBashItField: BooleanEventField = EventFields.Boolean("is_bash_it", "Bash only") + + private val JSON: Json = Json { ignoreUnknownKeys = true } + + fun getLoggableShellInfo(rawShellInfo: String): LoggableShellInfo? { + val shellInfo = parseShellInfo(rawShellInfo) ?: return null + val shellVersion = adjustVersionString(shellInfo.shellVersion).takeIf { it.isNotEmpty() } + + val ohMyZshTheme = getThemeName(shellInfo.ohMyZshTheme) + val ohMyPoshTheme = getThemeName(shellInfo.ohMyPoshTheme)?.removeSuffix(".omp.json") + val preztoTheme = getThemeName(shellInfo.preztoTheme) + val ohMyBashTheme = getThemeName(shellInfo.ohMyBashTheme) + val bashItTheme = getThemeName(shellInfo.bashItTheme) + // It is hard to guess the real theme if themes from several plugins are set. So, it is more heuristic. + val theme = if (shellInfo.isP10K) { + ohMyBashTheme ?: ohMyZshTheme ?: ohMyPoshTheme ?: bashItTheme ?: preztoTheme + } + else ohMyBashTheme ?: ohMyPoshTheme ?: bashItTheme ?: ohMyZshTheme ?: preztoTheme + + return LoggableShellInfo( + shellVersion = shellVersion, + promptTheme = theme, + isOhMyZsh = shellInfo.isOhMyZsh, + isOhMyPosh = shellInfo.ohMyPoshTheme.isNotEmpty(), + isP10K = shellInfo.isP10K, + isStarship = shellInfo.isStarship, + isSpaceship = shellInfo.isSpaceship, + isPrezto = shellInfo.isPrezto, + isOhMyBash = shellInfo.isOhMyBash, + isBashIt = shellInfo.isBashIt, + ) + } + + private fun parseShellInfo(rawShellInfo: String): ShellInfo? { + return try { + JSON.decodeFromString(rawShellInfo) + } + catch (t: Throwable) { + thisLogger().error("Failed to parse shell info: $rawShellInfo") + null + } + } + + private fun getThemeName(themePath: String): String? { + return PathUtil.getFileName(themePath).takeIf { it.isNotEmpty() } + } + + /** + * Truncates the provided [version] to get the string, that contains only digits and dots. + * For example, the Bash version can look like this: `5.2.15(1)-release`. + * Better to leave only meaningful part `5.2.15` in this case to be able to pass validation of [shellVersionField]. + */ + private fun adjustVersionString(version: String): String { + val meaningfulInfoEndOffset = version.indexOfFirst { !it.isDigit() && it != '.' }.takeIf { it != -1 } ?: version.length + return version.substring(0, meaningfulInfoEndOffset) + } + + private fun getKnownPromptThemes(): List { + val ohMyZshThemes = getKnownThemes("known-ohmyzsh-themes.txt") + val ohMyPoshThemes = getKnownThemes("known-ohmyposh-themes.txt") + val preztoThemes = getKnownThemes("known-prezto-themes.txt") + val ohMyBashThemes = getKnownThemes("known-ohmybash-themes.txt") + val bashItThemes = getKnownThemes("known-bashit-themes.txt") + return sequence { + yieldAll(ohMyZshThemes) + yieldAll(ohMyPoshThemes) + yieldAll(preztoThemes) + yieldAll(ohMyBashThemes) + yieldAll(bashItThemes) + yield("default") // our own name for the default OhMyPosh theme + yield("powerlevel10k") + yield("powerlevel9k") + yield("spaceship") + }.distinct().toList() + } + + private fun getKnownThemes(path: String): Collection { + return AllowedItemsResourceWeakRefStorage(TerminalShellInfoStatistics::class.java, path).items + } + + @Serializable + private data class ShellInfo( + val shellVersion: String = "", + val isOhMyZsh: Boolean = false, + val isP10K: Boolean = false, + val isStarship: Boolean = false, + val isSpaceship: Boolean = false, + val isPrezto: Boolean = false, + val isOhMyBash: Boolean = false, + val isBashIt: Boolean = false, + val ohMyZshTheme: String = "", + val ohMyPoshTheme: String = "", + val preztoTheme: String = "", + val ohMyBashTheme: String = "", + val bashItTheme: String = "" + ) + + data class LoggableShellInfo( + val shellVersion: String?, + val promptTheme: String?, + val isOhMyZsh: Boolean, + val isOhMyPosh: Boolean, + val isP10K: Boolean, + val isStarship: Boolean, + val isSpaceship: Boolean, + val isPrezto: Boolean, + val isOhMyBash: Boolean, + val isBashIt: Boolean, + ) +} \ No newline at end of file diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/fus/TerminalUsageCollector.kt b/plugins/terminal/src/org/jetbrains/plugins/terminal/fus/TerminalUsageCollector.kt index 11c1f6ba5997..6a6a6e45f732 100644 --- a/plugins/terminal/src/org/jetbrains/plugins/terminal/fus/TerminalUsageCollector.kt +++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/fus/TerminalUsageCollector.kt @@ -23,6 +23,8 @@ object TerminalUsageTriggerCollector : CounterUsagesCollector() { private val TERMINAL_COMMAND_HANDLER_FIELD = EventFields.Class("terminalCommandHandler") private val RUN_ANYTHING_PROVIDER_FIELD = EventFields.Class("runAnythingProvider") + private val OS_VERSION_FIELD = EventFields.StringValidatedByRegexpReference("os-version", "version") + private val SHELL_FIELD = EventFields.String("shell", KNOWN_SHELLS.toList()) private val BLOCK_TERMINAL_FIELD = EventFields.Boolean("new_terminal") private val EXIT_CODE_FIELD = EventFields.Int("exit_code") private val EXECUTION_TIME_FIELD = EventFields.Long("execution_time", "Time in milliseconds") @@ -35,10 +37,26 @@ object TerminalUsageTriggerCollector : CounterUsagesCollector() { TERMINAL_COMMAND_HANDLER_FIELD, RUN_ANYTHING_PROVIDER_FIELD) private val localExecEvent = GROUP.registerEvent("local.exec", - EventFields.StringValidatedByRegexpReference("os-version", "version"), - EventFields.String("shell", KNOWN_SHELLS.toList()), + OS_VERSION_FIELD, + SHELL_FIELD, BLOCK_TERMINAL_FIELD) + /** New Terminal only event with additional information about shell version and plugins */ + private val shellStartedEvent = GROUP.registerVarargEvent("local.shell.started", + OS_VERSION_FIELD, + SHELL_FIELD, + TerminalShellInfoStatistics.shellVersionField, + TerminalShellInfoStatistics.promptThemeField, + TerminalShellInfoStatistics.isOhMyZshField, + TerminalShellInfoStatistics.isOhMyPoshField, + TerminalShellInfoStatistics.isP10KField, + TerminalShellInfoStatistics.isStarshipField, + TerminalShellInfoStatistics.isSpaceshipField, + TerminalShellInfoStatistics.isPreztoField, + TerminalShellInfoStatistics.isOhMyBashField, + TerminalShellInfoStatistics.isBashItField) + + private val commandStartedEvent = GROUP.registerEvent("terminal.command.executed", TerminalCommandUsageStatistics.commandExecutableField, TerminalCommandUsageStatistics.subCommandField, @@ -115,6 +133,24 @@ object TerminalUsageTriggerCollector : CounterUsagesCollector() { } } + /** New Terminal only event with additional information about shell version and plugins */ + internal fun triggerLocalShellStarted(project: Project, shellName: String, shellInfo: TerminalShellInfoStatistics.LoggableShellInfo) { + val osVersion = Version.parseVersion(SystemInfo.OS_VERSION)?.toCompactString() ?: "unknown" + shellStartedEvent.log(project, + OS_VERSION_FIELD with osVersion, + SHELL_FIELD with shellName.lowercase(), + TerminalShellInfoStatistics.shellVersionField with shellInfo.shellVersion, + TerminalShellInfoStatistics.promptThemeField with shellInfo.promptTheme, + TerminalShellInfoStatistics.isOhMyZshField with shellInfo.isOhMyZsh, + TerminalShellInfoStatistics.isOhMyPoshField with shellInfo.isOhMyPosh, + TerminalShellInfoStatistics.isP10KField with shellInfo.isP10K, + TerminalShellInfoStatistics.isStarshipField with shellInfo.isStarship, + TerminalShellInfoStatistics.isSpaceshipField with shellInfo.isSpaceship, + TerminalShellInfoStatistics.isPreztoField with shellInfo.isPrezto, + TerminalShellInfoStatistics.isOhMyBashField with shellInfo.isOhMyBash, + TerminalShellInfoStatistics.isBashItField with shellInfo.isBashIt) + } + internal fun triggerPromotionShown(project: Project) { promotionShownEvent.log(project) } diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/fus/known-bashit-themes.txt b/plugins/terminal/src/org/jetbrains/plugins/terminal/fus/known-bashit-themes.txt new file mode 100644 index 000000000000..7b1898ccabda --- /dev/null +++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/fus/known-bashit-themes.txt @@ -0,0 +1,81 @@ +90210 +agnoster +atomic +axin +bakke +barbuk +binaryanomaly +bira +bobby +bobby-python +brainy +brunton +candy +clean +codeword +cooperkid +cupcake +demula +dos +doubletime +doubletime_multiline +doubletime_multiline_pyonly +dulcie +duru +easy +elixr +emperor +envy +essential +font +gallifrey +gitline +hawaii50 +iterate +kitsune +liquidprompt +luan +mairan +mbriggs +metal +minimal +modern +modern-t +modern-time +morris +n0qorg +newin +norbu +nwinkler +nwinkler_random_colors +oh-my-posh +parrot +pete +powerline +powerline-multiline +powerline-naked +powerline-plain +powerturk +primer +pro +pure +purity +radek +rainbowbrite +ramses +rana +redline +rjorgenson +robbyrussell +roderik +sexy +simple +sirup +slick +standard +tonka +tonotdo +tylenol +wanelo +zitron +zork \ No newline at end of file diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/fus/known-ohmybash-themes.txt b/plugins/terminal/src/org/jetbrains/plugins/terminal/fus/known-ohmybash-themes.txt new file mode 100644 index 000000000000..5a83299a47d4 --- /dev/null +++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/fus/known-ohmybash-themes.txt @@ -0,0 +1,73 @@ +90210 +absimple +agnoster +axin +bakke +binaryanomaly +bobby +bobby-python +brainy +brunton +candy +clean +cooperkid +cupcake +demula +dos +doubletime +doubletime_multiline +doubletime_multiline_pyonly +dulcie +duru +edsonarios +emperor +envy +font +gallifrey +garo +half-life +hawaii50 +iterate +kitsune +luan +mairan +mbriggs +minimal +minimal-gh +modern +modern-t +morris +n0qorg +nwinkler +nwinkler_random_colors +pete +powerbash10k +powerline +powerline-icon +powerline-light +powerline-multiline +powerline-naked +powerline-plain +primer +pro +pure +purity +pzq +rainbowbrite +rana +rjorgenson +robbyrussell +roderik +rr +sexy +simple +sirup +slick +standard +tonka +tonotdo +tylenol +vscode +wanelo +zitron +zork \ No newline at end of file diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/fus/known-ohmyposh-themes.txt b/plugins/terminal/src/org/jetbrains/plugins/terminal/fus/known-ohmyposh-themes.txt new file mode 100644 index 000000000000..fe03d844b0dc --- /dev/null +++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/fus/known-ohmyposh-themes.txt @@ -0,0 +1,125 @@ +1_shell +M365Princess +agnoster.minimal +agnoster +agnosterplus +aliens +amro +atomic +atomicBit +avit +blue-owl +blueish +bubbles +bubblesextra +bubblesline +capr4n +catppuccin +catppuccin_frappe +catppuccin_latte +catppuccin_macchiato +catppuccin_mocha +cert +chips +cinnamon +clean-detailed +cloud-context +cloud-native-azure +cobalt2 +craver +darkblood +devious-diamonds.omp.yaml +di4am0nd +dracula +easy-term +emodipt-extend +emodipt +fish +free-ukraine +froczh +glowsticks.omp.yaml +gmay +grandpa-style +gruvbox +half-life +honukai +hotstick.minimal +hul10 +hunk +huvix +if_tea +illusi0n +iterm2 +jandedobbeleer +jblab_2021 +jonnychipz +json +jtracey93 +jv_sitecorian +kali +kushal +lambda +lambdageneration +larserikfinholt +lightgreen +marcduiker +markbull +material +microverse-power +mojada +montys +mt +multiverse-neon +negligible +neko +night-owl +nordtron +nu4a +onehalf.minimal +paradox +pararussel +patriksvensson +peru +pixelrobots +plague +poshmon +powerlevel10k_classic +powerlevel10k_lean +powerlevel10k_modern +powerlevel10k_rainbow +powerline +probua.minimal +pure +quick-term +remk +robbyrussell +rudolfs-dark +rudolfs-light +schema.json +sim-web +slim +slimfat +smoothie +sonicboom_dark +sonicboom_light +sorin +space +spaceship +star +stelbent-compact.minimal +stelbent.minimal +takuya +the-unnamed +thecyberden +tiwahu +tokyo +tokyonight_storm +tonybaloney +uew +unicorn +velvet +wholespace +wopian +xtoys +ys +zash \ No newline at end of file diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/fus/known-ohmyzsh-themes.txt b/plugins/terminal/src/org/jetbrains/plugins/terminal/fus/known-ohmyzsh-themes.txt new file mode 100644 index 000000000000..e28a3bed29b8 --- /dev/null +++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/fus/known-ohmyzsh-themes.txt @@ -0,0 +1,143 @@ +3den +Soliah +adben +af-magic +afowler +agnoster +alanpeabody +amuse +apple +arrow +aussiegeek +avit +awesomepanda +bira +blinks +bureau +candy-kingdom +candy +clean +cloud +crcandy +crunch +cypher +dallas +darkblood +daveverwer +dieter +dogenpunk +dpoggi +dst +dstufft +duellj +eastwood +edvardm +emotty +essembeh +evan +fino-time +fino +fishy +flazz +fletcherm +fox +frisk +frontcube +funky +fwalch +gallifrey +gallois +garyblessington +gentoo +geoffgarside +gianu +gnzh +gozilla +half-life +humza +imajes +intheloop +itchy +jaischeema +jbergantine +jispwoso +jnrowe +jonathan +josh +jreese +jtriley +juanghurtado +junkfood +kafeitu +kardan +kennethreitz +kiwi +kolo +kphoen +lambda +linuxonly +lukerandall +macovsky-ruby +macovsky +maran +mgutz +mh +michelebologna +mikeh +miloshadzic +minimal +mira +mlh +mortalscumbag +mrtazz +murilasso +muse +nanotech +nebirhos +nicoulaj +norm +obraun +oldgallois +peepcode +philips +pmcgee +pygmalion-virtualenv +pygmalion +random +re5et +refined +rgm +risto +rixius +rkj-repos +rkj +robbyrussell +sammy +simonoff +simple +skaro +smt +sonicradish +sorin +sporty_256 +steeef +strug +sunaku +sunrise +superjarin +suvash +takashiyoshida +terminalparty +theunraveler +tjkirch +tjkirch_mod +tonotdo +trapd00r +wedisagree +wezm+ +wezm +wuffers +xiong-chiamiov-plus +xiong-chiamiov +ys +zhann \ No newline at end of file diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/fus/known-prezto-themes.txt b/plugins/terminal/src/org/jetbrains/plugins/terminal/fus/known-prezto-themes.txt new file mode 100644 index 000000000000..e4b46d640d7d --- /dev/null +++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/fus/known-prezto-themes.txt @@ -0,0 +1,34 @@ +agnoster +cloud +damoekri +giddie +kylewest +minimal +nicoulaj +paradox +peepcode +powerlevel10k +powerline +pure +skwp +smiley +sorin +steeef +adam1 +adam2 +bart +bigfade +clint +default +elite2 +elite +fade +fire +off +oliver +pws +redhat +restore +suse +walters +zefram \ No newline at end of file diff --git a/plugins/terminal/tests/org/jetbrains/plugins/terminal/exp/util/TerminalSessionTestUtil.kt b/plugins/terminal/tests/org/jetbrains/plugins/terminal/exp/util/TerminalSessionTestUtil.kt index 1ea3add9a85a..ccf963331591 100644 --- a/plugins/terminal/tests/org/jetbrains/plugins/terminal/exp/util/TerminalSessionTestUtil.kt +++ b/plugins/terminal/tests/org/jetbrains/plugins/terminal/exp/util/TerminalSessionTestUtil.kt @@ -56,7 +56,7 @@ object TerminalSessionTestUtil { val initializedFuture = CompletableFuture() val listenersDisposable = Disposer.newDisposable() session.addCommandListener(object : ShellCommandListener { - override fun initialized() { + override fun initialized(rawShellInfo: String) { initializedFuture.complete(true) } }, listenersDisposable)