Cover style "halves": left and right half blocks only
Twice the horizontal detail of "cells", for terminals such as macOS Terminal whose upper and lower half blocks do not meet at the middle of the cell. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019reK4DUGYqDUjniWYJvwUW
This commit is contained in:
@@ -40,7 +40,8 @@ type UI struct {
|
||||
// CoverStyle selects the block characters posters are drawn with:
|
||||
// "quadrant" (2x2 pixels per cell, every font has the glyphs), "cells" (1
|
||||
// pixel per cell, background colors only, for terminals that draw block
|
||||
// glyphs unevenly such as macOS Terminal), "sextant"
|
||||
// glyphs unevenly such as macOS Terminal), "halves" (2x1, left and right
|
||||
// half blocks only, for the same terminals), "sextant"
|
||||
// (2x3, sharper, needs a font with the Symbols for Legacy Computing
|
||||
// block, e.g. kitty, WezTerm, foot, Ghostty), "kitty" (real images through
|
||||
// the Kitty graphics protocol with Unicode placeholders: kitty and
|
||||
@@ -266,9 +267,9 @@ func (c *Config) Validate() error {
|
||||
}
|
||||
}
|
||||
switch c.UI.CoverStyle {
|
||||
case "", "auto", "quadrant", "sextant", "cells", "kitty":
|
||||
case "", "auto", "quadrant", "sextant", "halves", "cells", "kitty":
|
||||
default:
|
||||
errs = append(errs, fmt.Errorf(`ui.cover_style: %q must be "auto", "kitty", "sextant", "quadrant" or "cells"`, c.UI.CoverStyle))
|
||||
errs = append(errs, fmt.Errorf(`ui.cover_style: %q must be "auto", "kitty", "sextant", "quadrant", "halves" or "cells"`, c.UI.CoverStyle))
|
||||
}
|
||||
return errors.Join(errs...)
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ func TestShowCovers(t *testing.T) {
|
||||
|
||||
func TestCoverStyleValidation(t *testing.T) {
|
||||
base := `{"radarr":{"url":"http://r","apikey":"k"},"sonarr":{"url":"http://s","apikey":"k"},"sabnzbd":{"url":"http://a","apikey":"k"},"ui":{"cover_style":`
|
||||
for _, ok := range []string{`"auto"`, `"quadrant"`, `"sextant"`, `"cells"`, `"kitty"`, `""`} {
|
||||
for _, ok := range []string{`"auto"`, `"quadrant"`, `"sextant"`, `"cells"`, `"halves"`, `"kitty"`, `""`} {
|
||||
if _, err := Parse([]byte(base + ok + `}}`)); err != nil {
|
||||
t.Errorf("%s rejected: %v", ok, err)
|
||||
}
|
||||
|
||||
@@ -99,6 +99,10 @@ var (
|
||||
// Coarse, but exact in terminals that draw block elements from the font
|
||||
// with the halves off the cell's middle (macOS Terminal).
|
||||
cellsStyle = coverStyle{"cells", 1, 1, func(int) rune { return ' ' }}
|
||||
// halvesStyle (2×1 pixels): left and right half blocks only. Twice the
|
||||
// detail of cells across, for terminals whose upper and lower halves do not
|
||||
// meet at the middle but whose left and right ones do.
|
||||
halvesStyle = coverStyle{"halves", 2, 1, func(mask int) rune { return [4]rune{' ', '▌', '▐', '█'}[mask] }}
|
||||
)
|
||||
|
||||
// quadrants[mask] is the glyph that fills the quadrants set in mask
|
||||
@@ -141,6 +145,8 @@ func coverStyleFor(setting string, env func(string) string) coverStyle {
|
||||
return quadrantStyle
|
||||
case "cells":
|
||||
return cellsStyle
|
||||
case "halves":
|
||||
return halvesStyle
|
||||
}
|
||||
// Terminal.app draws block elements from the font, and their halves do
|
||||
// not meet at the cell's middle: rows of a poster come out uneven.
|
||||
|
||||
@@ -277,6 +277,7 @@ func TestCoverStyleFor(t *testing.T) {
|
||||
{"sextant", nil, "sextant"},
|
||||
{"auto", map[string]string{"TERM": "xterm-256color", "TERM_PROGRAM": "Apple_Terminal"}, "cells"},
|
||||
{"cells", map[string]string{"TERM": "xterm-kitty"}, "cells"},
|
||||
{"halves", map[string]string{"TERM_PROGRAM": "Apple_Terminal"}, "halves"},
|
||||
{"quadrant", map[string]string{"TERM_PROGRAM": "Apple_Terminal"}, "quadrant"},
|
||||
} {
|
||||
if got := coverStyleFor(tc.setting, env(tc.env)).name; got != tc.want {
|
||||
@@ -358,3 +359,11 @@ func TestCellsStyleIsFlat(t *testing.T) {
|
||||
t.Errorf("got %q %v %v", ch, fg, bg)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHalvesStyle(t *testing.T) {
|
||||
dark, light := color.RGBA{0, 0, 0, 255}, color.RGBA{250, 250, 250, 255}
|
||||
ch, fg, bg := halvesStyle.bestCell([]color.RGBA{light, dark})
|
||||
if ch != '▌' || fg != light || bg != dark {
|
||||
t.Errorf("light left half: %q %v %v", ch, fg, bg)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ type settingsValues struct {
|
||||
notify, bell bool
|
||||
}
|
||||
|
||||
var coverStyles = []string{"auto", "kitty", "sextant", "quadrant", "cells"}
|
||||
var coverStyles = []string{"auto", "kitty", "sextant", "quadrant", "halves", "cells"}
|
||||
|
||||
// settingsFrom reads the settings in use.
|
||||
func settingsFrom(c *config.Config) settingsValues {
|
||||
|
||||
Reference in New Issue
Block a user