如何在 Go 中检测当前终端是不是支持 16 色或 256 色?

Posted

技术标签:

【中文标题】如何在 Go 中检测当前终端是不是支持 16 色或 256 色?【英文标题】:How to Detect If Current Terminal Supports 16-Color or 256-Color in Go?如何在 Go 中检测当前终端是否支持 16 色或 256 色? 【发布时间】:2021-11-19 10:37:22 【问题描述】:

我们在 Go 中有许多流行的包来在终端中渲染彩色文本,例如 fatih/color、gookit/color、lucasb-eyer/go-colorful。

但是我面临一个问题 --- 除了亲眼所见之外,如何检测当前终端是否在 Go 中以编程方式支持 16 色或 256 色(即使在 Windows 上)?

【问题讨论】:

对于将是this 的Unix 终端。不过我对 Windows 控制台一无所知。 @kostix 它正在使用终端本身。但是如何在终端启动的 Go cli 应用程序中检测到这一点? 我不太明白:定义的“在终端中启动的 Go CLI 应用程序”与所述终端交互——它可以使用专门的包(例如 github.com/nsf/termbox-go)来实现,但它除了通过“使用终端”之外,没有其他方式与用户交互。那么问题是什么呢? 【参考方案1】:

如“Determine whether the current Linux console supports 256 colours?”中所述(在 Linux 上,Windows 上也会存在同样的可移植性问题)

作为非便携式选项的示例,您可以使用 curses(在 Linux 上),如 discussed here 并在 curses.go 中实现:

查看 tput colorstigetnum('colors')(返回 1、8、256 或更大的数字)更符合功能测试的路线,这样既不老套,也更面向未来。

func Init(theme *ColorTheme, black bool, mouse bool) 
    
        in, err := os.OpenFile("/dev/tty", syscall.O_RDONLY, 0)
        if err != nil 
            panic("Failed to open /dev/tty")
        
        _in = in
        // Break STDIN
        // syscall.Dup2(int(in.Fd()), int(os.Stdin.Fd()))
    

    C.setlocale(C.LC_ALL, C.CString(""))
    _screen = C.c_newterm()
    if _screen == nil 
        fmt.Println("Invalid $TERM: " + os.Getenv("TERM"))
        os.Exit(2)
    
    C.set_term(_screen)
    if mouse 
        C.mousemask(C.ALL_MOUSE_EVENTS, nil)
    
    C.noecho()
    C.raw() // stty dsusp undef

    if theme != nil 
        C.start_color()
        var baseTheme *ColorTheme
        if C.tigetnum(C.CString("colors")) >= 256 
            baseTheme = Dark256
         else 
            baseTheme = Default16
        
        initPairs(baseTheme, theme, black)
        _color = attrColored
     else 
        _color = attrMono
    

【讨论】:

以上是关于如何在 Go 中检测当前终端是不是支持 16 色或 256 色?的主要内容,如果未能解决你的问题,请参考以下文章

如何检测 Python 是不是在 Git Bash 终端或 Windows cmd 中运行?

如何检测是不是支持 HTML5 自动播放属性?

我如何保证终端具有 NCURSES 的 Unicode/宽字符支持?

检测本地浏览器是不是支持 ICE 涓流

如何检测我的 shell 脚本是不是通过管道运行?

Android 多窗口支持:检测状态栏是不是可见?