Add better color support detection, for #134

This commit is contained in:
David Dworken 2023-12-31 13:00:56 -08:00
parent 4013726c24
commit 77313dfb48
No known key found for this signature in database
5 changed files with 86 additions and 19 deletions

View File

@ -4,11 +4,13 @@ import (
"context" "context"
"fmt" "fmt"
"math/rand" "math/rand"
"os"
"strings" "strings"
"github.com/ddworken/hishtory/client/hctx" "github.com/ddworken/hishtory/client/hctx"
"github.com/ddworken/hishtory/client/lib" "github.com/ddworken/hishtory/client/lib"
"github.com/ddworken/hishtory/client/tui" "github.com/ddworken/hishtory/client/tui"
"github.com/muesli/termenv"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -62,6 +64,27 @@ var exportCmd = &cobra.Command{
}, },
} }
var getColorSupportCmd = &cobra.Command{
Use: "getColorSupport",
Hidden: true,
Short: "[Internal-only] Get the supported color format (returned as an exit code)",
GroupID: GROUP_ID_QUERYING,
Run: func(cmd *cobra.Command, args []string) {
switch termenv.ColorProfile() {
case termenv.TrueColor:
os.Exit(1)
case termenv.ANSI256:
os.Exit(2)
case termenv.ANSI:
os.Exit(3)
case termenv.Ascii:
os.Exit(4)
default:
os.Exit(0)
}
},
}
var updateLocalDbFromRemoteCmd = &cobra.Command{ var updateLocalDbFromRemoteCmd = &cobra.Command{
Use: "updateLocalDbFromRemote", Use: "updateLocalDbFromRemote",
Hidden: true, Hidden: true,
@ -147,4 +170,5 @@ func init() {
rootCmd.AddCommand(tqueryCmd) rootCmd.AddCommand(tqueryCmd)
rootCmd.AddCommand(exportCmd) rootCmd.AddCommand(exportCmd)
rootCmd.AddCommand(updateLocalDbFromRemoteCmd) rootCmd.AddCommand(updateLocalDbFromRemoteCmd)
rootCmd.AddCommand(getColorSupportCmd)
} }

View File

@ -1,3 +1,7 @@
# For detecting color rendering support for this terminal, see #134
hishtory getColorSupport
export _hishtory_tui_color=$status
function _hishtory_post_exec --on-event fish_preexec function _hishtory_post_exec --on-event fish_preexec
# Runs after <ENTER>, but before the command is executed # Runs after <ENTER>, but before the command is executed
set --global _hishtory_command $argv set --global _hishtory_command $argv

View File

@ -5,6 +5,10 @@
if [ -n "$__hishtory_bash_config_sourced" ]; then return; fi if [ -n "$__hishtory_bash_config_sourced" ]; then return; fi
__hishtory_bash_config_sourced=`date` __hishtory_bash_config_sourced=`date`
# For detecting color rendering support for this terminal, see #134
hishtory getColorSupport
export _hishtory_tui_color=$?
# Implementation of running before/after every command based on https://jichu4n.com/posts/debug-trap-and-prompt_command-in-bash/ # Implementation of running before/after every command based on https://jichu4n.com/posts/debug-trap-and-prompt_command-in-bash/
function __hishtory_precommand() { function __hishtory_precommand() {
if [ -z "${HISHTORY_AT_PROMPT:-}" ]; then if [ -z "${HISHTORY_AT_PROMPT:-}" ]; then

View File

@ -4,6 +4,10 @@ add-zsh-hook precmd _hishtory_precmd
_hishtory_first_prompt=1 _hishtory_first_prompt=1
# For detecting color rendering support for this terminal, see #134
hishtory getColorSupport
export _hishtory_tui_color=$?
function _hishtory_add() { function _hishtory_add() {
# Runs after <ENTER>, but before the command is executed # Runs after <ENTER>, but before the command is executed
# $1 contains the command that was run # $1 contains the command that was run

View File

@ -6,6 +6,7 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"regexp" "regexp"
"strconv"
"strings" "strings"
"time" "time"
@ -800,37 +801,67 @@ func deleteHistoryEntry(ctx context.Context, entry data.HistoryEntry) error {
return lib.SendDeletionRequest(ctx, dr) return lib.SendDeletionRequest(ctx, dr)
} }
func TuiQuery(ctx context.Context, initialQuery string) error { func configureColorProfile(ctx context.Context) {
if hctx.GetConf(ctx).ColorScheme == hctx.GetDefaultColorScheme() { if hctx.GetConf(ctx).ColorScheme == hctx.GetDefaultColorScheme() {
// Set termenv.ANSI for the default color scheme, so that we preserve // Set termenv.ANSI for the default color scheme, so that we preserve
// the true default color scheme of hishtory which was initially // the true default color scheme of hishtory which was initially
// configured with termenv.ANSI (even though we want to support // configured with termenv.ANSI (even though we want to support
// full colors) for custom color schemes. // full colors) for custom color schemes.
lipgloss.SetColorProfile(termenv.ANSI) lipgloss.SetColorProfile(termenv.ANSI)
} else if os.Getenv("HISHTORY_TEST") != "" { return
}
if os.Getenv("HISHTORY_TEST") != "" {
// We also set termenv.ANSI for tests so as to ensure that all our // We also set termenv.ANSI for tests so as to ensure that all our
// test environments behave the same (by default, github actions // test environments behave the same (by default, github actions
// ubuntu and macos have different termenv support). // ubuntu and macos have different termenv support).
lipgloss.SetColorProfile(termenv.ANSI) lipgloss.SetColorProfile(termenv.ANSI)
} else { return
// When the shell launches control-R it isn't hooked up to the main TTY, }
// which means that termenv isn't able to accurately detect color support // When the shell launches control-R it isn't hooked up to the main TTY,
// in the current terminal. This means we have to guess the right option, // which means that termenv isn't able to accurately detect color support
// where we risk either: // in the current terminal. We set the environment variable _hishtory_tui_color
// * Choosing too high of a color support, and breaking hishtory colors // to an int representing the termenv. If it is unset or set to 0, then we don't
// in certain terminals // know the current color support, and we have to guess it. This means we
// * Choosing too low of a color support, and ending up with truncating // risk either:
// customized colors // * Choosing too high of a color support, and breaking hishtory colors
// // in certain terminals
// This is a tough situation with no right answer (as far as I can tell). // * Choosing too low of a color support, and ending up with truncating
// The default terminal app on MacOS only supports termenv.ANSI256 (8 bit // customized colors
// colors), which means we likely shouldn't default to TrueColor. From //
// my own digging, I can't find any modern terminals that don't support // The default terminal app on MacOS only supports termenv.ANSI256 (8 bit
// termenv.ANSI256, so it seems like a reasonable default here. // colors), which means we likely shouldn't default to TrueColor. From
// // my own digging, I can't find any modern terminals that don't support
// TODO: In the long term, we may want to make this configurable. // termenv.ANSI256, so it seems like a reasonable default here.
colorProfileStr := os.Getenv("_hishtory_tui_color")
if colorProfileStr == "" {
// Fall back to the default
lipgloss.SetColorProfile(termenv.ANSI256)
return
}
colorProfileInt, err := strconv.Atoi(colorProfileStr)
if err != nil {
colorProfileInt = 0
}
// The int mappings for this are defined in query.go
switch colorProfileInt {
case 1:
lipgloss.SetColorProfile(termenv.TrueColor)
case 2:
lipgloss.SetColorProfile(termenv.ANSI256)
case 3:
lipgloss.SetColorProfile(termenv.ANSI)
case 4:
lipgloss.SetColorProfile(termenv.Ascii)
default:
fallthrough
case 0:
// Unknown, so fall back to the default
lipgloss.SetColorProfile(termenv.ANSI256) lipgloss.SetColorProfile(termenv.ANSI256)
} }
}
func TuiQuery(ctx context.Context, initialQuery string) error {
configureColorProfile(ctx)
p := tea.NewProgram(initialModel(ctx, initialQuery), tea.WithOutput(os.Stderr)) p := tea.NewProgram(initialModel(ctx, initialQuery), tea.WithOutput(os.Stderr))
// Async: Get the initial set of rows // Async: Get the initial set of rows
go func() { go func() {