move color to top level, add windows support

This commit is contained in:
Sky Johnson 2025-06-05 20:21:34 -05:00
parent 4077ac03f1
commit bca4eef166
10 changed files with 89 additions and 22 deletions

View File

@ -3,12 +3,9 @@ package color
import ( import (
"os" "os"
"strings" "strings"
"syscall" "sync"
"unsafe"
) )
const ioctlReadTermios = 0x5401
// ANSI color codes // ANSI color codes
const ( const (
resetCode = "\033[0m" resetCode = "\033[0m"
@ -22,7 +19,10 @@ const (
grayCode = "\033[90m" grayCode = "\033[90m"
) )
var useColors = true var (
useColors bool
colorMu sync.RWMutex
)
// Color function; makes a call to makeColorFunc with the associated color code // Color function; makes a call to makeColorFunc with the associated color code
var ( var (
@ -37,9 +37,17 @@ var (
Gray = makeColorFunc(grayCode) Gray = makeColorFunc(grayCode)
) )
func init() {
useColors = DetectShellColors()
}
func makeColorFunc(code string) func(string) string { func makeColorFunc(code string) func(string) string {
return func(text string) string { return func(text string) string {
if useColors { colorMu.RLock()
enabled := useColors
colorMu.RUnlock()
if enabled {
return code + text + resetCode return code + text + resetCode
} }
return text return text
@ -74,23 +82,20 @@ func DetectShellColors() bool {
strings.Contains(term, "xterm") || strings.Contains(term, "xterm") ||
strings.Contains(term, "screen") || strings.Contains(term, "screen") ||
strings.Contains(term, "tmux") || strings.Contains(term, "tmux") ||
term == "linux" term == "linux" ||
isWindowsTerminal()
} }
// SetColors enables or disables colors globally // SetColors enables or disables colors globally
func SetColors(enabled bool) { func SetColors(enabled bool) {
colorMu.Lock()
useColors = enabled useColors = enabled
colorMu.Unlock()
} }
// ColorsEnabled returns current global color setting // ColorsEnabled returns current global color setting
func ColorsEnabled() bool { func ColorsEnabled() bool {
colorMu.RLock()
defer colorMu.RUnlock()
return useColors return useColors
} }
// isTerminal checks if the file is a terminal
func isTerminal(f *os.File) bool {
fd := f.Fd()
var termios syscall.Termios
_, _, err := syscall.Syscall6(syscall.SYS_IOCTL, fd, ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0)
return err == 0
}

33
color/color_unix.go Normal file
View File

@ -0,0 +1,33 @@
//go:build !windows
// +build !windows
package color
import (
"os"
"syscall"
"unsafe"
)
const ioctlReadTermios = 0x5401
// isTerminal checks if the file is a terminal
func isTerminal(f *os.File) bool {
fd := f.Fd()
var termios syscall.Termios
r1, _, errno := syscall.Syscall6(
syscall.SYS_IOCTL,
fd,
ioctlReadTermios,
uintptr(unsafe.Pointer(&termios)),
0, 0, 0,
)
return r1 == 0 && errno == 0
}
// isWindowsTerminal always returns false on Unix
func isWindowsTerminal() bool {
return false
}

29
color/color_windows.go Normal file
View File

@ -0,0 +1,29 @@
//go:build windows
// +build windows
package color
import (
"os"
"syscall"
"unsafe"
)
var (
kernel32 = syscall.NewLazyDLL("kernel32.dll")
procGetConsoleMode = kernel32.NewProc("GetConsoleMode")
)
// isTerminal checks if the file is a terminal on Windows
func isTerminal(f *os.File) bool {
handle := syscall.Handle(f.Fd())
var mode uint32
r1, _, _ := procGetConsoleMode.Call(uintptr(handle), uintptr(unsafe.Pointer(&mode)))
return r1 != 0
}
// isWindowsTerminal checks for Windows Terminal
func isWindowsTerminal() bool {
return os.Getenv("WT_SESSION") != ""
}

View File

@ -8,11 +8,11 @@ import (
"sync" "sync"
"time" "time"
"Moonshark/color"
"Moonshark/router" "Moonshark/router"
"Moonshark/runner" "Moonshark/runner"
"Moonshark/sessions" "Moonshark/sessions"
"Moonshark/utils" "Moonshark/utils"
"Moonshark/utils/color"
"Moonshark/utils/config" "Moonshark/utils/config"
"Moonshark/utils/logger" "Moonshark/utils/logger"
"Moonshark/utils/metadata" "Moonshark/utils/metadata"

View File

@ -13,12 +13,12 @@ import (
"syscall" "syscall"
"time" "time"
"Moonshark/color"
"Moonshark/http" "Moonshark/http"
"Moonshark/router" "Moonshark/router"
"Moonshark/runner" "Moonshark/runner"
"Moonshark/runner/lualibs" "Moonshark/runner/lualibs"
"Moonshark/sessions" "Moonshark/sessions"
"Moonshark/utils/color"
"Moonshark/utils/config" "Moonshark/utils/config"
"Moonshark/utils/logger" "Moonshark/utils/logger"
"Moonshark/utils/metadata" "Moonshark/utils/metadata"

View File

@ -10,7 +10,7 @@ import (
"strings" "strings"
"sync" "sync"
"Moonshark/utils/color" "Moonshark/color"
"Moonshark/utils/logger" "Moonshark/utils/logger"
luajit "git.sharkk.net/Sky/LuaJIT-to-Go" luajit "git.sharkk.net/Sky/LuaJIT-to-Go"

View File

@ -8,7 +8,7 @@ import (
"strings" "strings"
"time" "time"
"Moonshark/utils/color" "Moonshark/color"
"Moonshark/utils/logger" "Moonshark/utils/logger"
lru "git.sharkk.net/Go/LRU" lru "git.sharkk.net/Go/LRU"

View File

@ -11,7 +11,7 @@ import (
sqlite "zombiezen.com/go/sqlite" sqlite "zombiezen.com/go/sqlite"
"zombiezen.com/go/sqlite/sqlitex" "zombiezen.com/go/sqlite/sqlitex"
"Moonshark/utils/color" "Moonshark/color"
"Moonshark/utils/logger" "Moonshark/utils/logger"
luajit "git.sharkk.net/Sky/LuaJIT-to-Go" luajit "git.sharkk.net/Sky/LuaJIT-to-Go"

View File

@ -9,7 +9,7 @@ import (
"sync/atomic" "sync/atomic"
"time" "time"
"Moonshark/utils/color" "Moonshark/color"
) )
// Log levels // Log levels

View File

@ -5,9 +5,9 @@ import (
"strings" "strings"
"sync" "sync"
"Moonshark/color"
"Moonshark/router" "Moonshark/router"
"Moonshark/runner" "Moonshark/runner"
"Moonshark/utils/color"
"Moonshark/utils/logger" "Moonshark/utils/logger"
) )