Skip to content

Commit

Permalink
Merge branch 'johan/color-underline'
Browse files Browse the repository at this point in the history
Fixes #237.
  • Loading branch information
walles committed Aug 12, 2024
2 parents 37cf840 + f69e58d commit 27e9c0d
Show file tree
Hide file tree
Showing 11 changed files with 190 additions and 131 deletions.
16 changes: 14 additions & 2 deletions m/textstyles/ansiTokenizer.go
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,18 @@ func rawUpdateStyle(style twin.Style, escapeSequenceWithoutHeader string, number
case 49:
style = style.WithBackground(twin.ColorDefault)

case 58:
var err error
var color *twin.Color
index, color, err = consumeCompositeColor(numbersBuffer, index-1)
if err != nil {
return style, numbersBuffer, fmt.Errorf("Underline: %w", err)
}
style = style.WithUnderlineColor(*color)

case 59:
style = style.WithUnderlineColor(twin.ColorDefault)

// Bright foreground colors: see https://pkg.go.dev/github.com/gdamore/Color
//
// After testing vs less and cat on iTerm2 3.3.9 / macOS Catalina
Expand Down Expand Up @@ -573,9 +585,9 @@ func joinUints(ints []uint) string {
// * A color value that can be applied to a style
func consumeCompositeColor(numbers []uint, index int) (int, *twin.Color, error) {
baseIndex := index
if numbers[index] != 38 && numbers[index] != 48 {
if numbers[index] != 38 && numbers[index] != 48 && numbers[index] != 58 {
err := fmt.Errorf(
"unknown start of color sequence <%d>, expected 38 (foreground) or 48 (background): <CSI %sm>",
"unknown start of color sequence <%d>, expected 38 (foreground), 48 (background) or 58 (underline): <CSI %sm>",
numbers[index],
joinUints(numbers[baseIndex:]))
return -1, nil, err
Expand Down
2 changes: 1 addition & 1 deletion m/textstyles/ansiTokenizer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ func TestConsumeCompositeColorBadPrefix(t *testing.T) {
// 8 bit color
// Example from: https://github.com/walles/moar/issues/14
_, color, err := consumeCompositeColor([]uint{29}, 0)
assert.Equal(t, err.Error(), "unknown start of color sequence <29>, expected 38 (foreground) or 48 (background): <CSI 29m>")
assert.Equal(t, err.Error(), "unknown start of color sequence <29>, expected 38 (foreground), 48 (background) or 58 (underline): <CSI 29m>")
assert.Assert(t, color == nil)
}

Expand Down
30 changes: 15 additions & 15 deletions moar.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ const defaultLightTheme = "tango"

var versionString = "Should be set when building, please use build.sh to build"

func renderLessTermcapEnvVar(envVarName string, description string, colors twin.ColorType) string {
func renderLessTermcapEnvVar(envVarName string, description string, colors twin.ColorCount) string {
value := os.Getenv(envVarName)
if len(value) == 0 {
return ""
Expand Down Expand Up @@ -67,7 +67,7 @@ func renderLessTermcapEnvVar(envVarName string, description string, colors twin.
)
}

func renderPagerEnvVar(name string, colors twin.ColorType) string {
func renderPagerEnvVar(name string, colors twin.ColorCount) string {
bold := twin.StyleDefault.WithAttr(twin.AttrBold).RenderUpdateFrom(twin.StyleDefault, colors)
notBold := twin.StyleDefault.RenderUpdateFrom(twin.StyleDefault.WithAttr(twin.AttrBold), colors)

Expand Down Expand Up @@ -129,14 +129,14 @@ func printCommandline(output io.Writer) {
fmt.Fprintln(output)
}

func heading(text string, colors twin.ColorType) string {
func heading(text string, colors twin.ColorCount) string {
style := twin.StyleDefault.WithAttr(twin.AttrItalic)
prefix := style.RenderUpdateFrom(twin.StyleDefault, colors)
suffix := twin.StyleDefault.RenderUpdateFrom(style, colors)
return prefix + text + suffix
}

func printUsage(flagSet *flag.FlagSet, colors twin.ColorType) {
func printUsage(flagSet *flag.FlagSet, colors twin.ColorCount) {
// This controls where PrintDefaults() prints, see below
flagSet.SetOutput(os.Stdout)

Expand Down Expand Up @@ -315,7 +315,7 @@ func parseStyleOption(styleOption string) (*chroma.Style, error) {
return style, nil
}

func parseColorsOption(colorsOption string) (twin.ColorType, error) {
func parseColorsOption(colorsOption string) (twin.ColorCount, error) {
if strings.ToLower(colorsOption) == "auto" {
colorsOption = "16M"
if os.Getenv("COLORTERM") != "truecolor" && strings.Contains(os.Getenv("TERM"), "256") {
Expand All @@ -326,16 +326,16 @@ func parseColorsOption(colorsOption string) (twin.ColorType, error) {

switch strings.ToUpper(colorsOption) {
case "8":
return twin.ColorType8, nil
return twin.ColorCount8, nil
case "16":
return twin.ColorType16, nil
return twin.ColorCount16, nil
case "256":
return twin.ColorType256, nil
return twin.ColorCount256, nil
case "16M":
return twin.ColorType24bit, nil
return twin.ColorCount24bit, nil
}

var noColor twin.ColorType
var noColor twin.ColorCount
return noColor, fmt.Errorf("Valid counts are 8, 16, 256, 16M or auto")
}

Expand Down Expand Up @@ -519,7 +519,7 @@ func noLineNumbersDefault() bool {
// Can return a nil pager on --help or --version, or if pumping to stdout.
func pagerFromArgs(
args []string,
newScreen func(mouseMode twin.MouseMode, terminalColorCount twin.ColorType) (twin.Screen, error),
newScreen func(mouseMode twin.MouseMode, terminalColorCount twin.ColorCount) (twin.Screen, error),
stdinIsRedirected bool,
stdoutIsRedirected bool,
) (
Expand Down Expand Up @@ -674,11 +674,11 @@ func pagerFromArgs(
}

formatter := formatters.TTY256
if *terminalColorsCount == twin.ColorType8 {
if *terminalColorsCount == twin.ColorCount8 {
formatter = formatters.TTY8
} else if *terminalColorsCount == twin.ColorType16 {
} else if *terminalColorsCount == twin.ColorCount16 {
formatter = formatters.TTY16
} else if *terminalColorsCount == twin.ColorType24bit {
} else if *terminalColorsCount == twin.ColorCount24bit {
formatter = formatters.TTY16m
}

Expand Down Expand Up @@ -803,7 +803,7 @@ func main() {

pager, screen, style, formatter, err := pagerFromArgs(
os.Args,
twin.NewScreenWithMouseModeAndColorType,
twin.NewScreenWithMouseModeAndColorCount,
stdinIsRedirected,
stdoutIsRedirected,
)
Expand Down
2 changes: 1 addition & 1 deletion moar_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ func TestParseScrollHint(t *testing.T) {
func TestPageOneInputFile(t *testing.T) {
pager, screen, _, formatter, err := pagerFromArgs(
[]string{"", "moar_test.go"},
func(_ twin.MouseMode, _ twin.ColorType) (twin.Screen, error) {
func(_ twin.MouseMode, _ twin.ColorCount) (twin.Screen, error) {
return twin.NewFakeScreen(80, 24), nil
},
false, // stdin is redirected
Expand Down
1 change: 1 addition & 0 deletions sample-files/colored-underlines.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[58:5:196mRed underline Default colored underline
Loading

0 comments on commit 27e9c0d

Please sign in to comment.