Skip to content

refactor: move the color-enable decision into internal/ansi #93

Description

@sorafujitani

Context

The "should we emit ANSI escapes?" decision (explicit mode > NoColor flag > NO_COLOR env > TTY detection) is implemented twice and will drift as soon as one side learns a new rule (e.g. CLICOLOR_FORCE).

Current state (verified locations)

  • internal/list/list.go:113-145colorEnabled(opts) + isTerminal(f *os.File)
  • internal/preview/preview.go:400-429colorEnabled(opts) (used at preview.go:400)

Both packages already depend on internal/ansi for escape constants.

Task

  1. Compare the two implementations line by line and confirm the precedence is identical (mode "always"/"never" → NoColor bool → NO_COLOR env → TTY check). If they differ, note the difference in the PR description and preserve each caller's current behavior via parameters rather than silently changing one.
  2. Add to internal/ansi (new file color.go):
    // Enabled reports whether ANSI escapes should be emitted.
    // Precedence: mode ("always"/"never") > noColor > NO_COLOR env > out is a TTY.
    func Enabled(mode string, noColor bool, out *os.File) bool
    Move isTerminal there as an unexported helper.
  3. Replace both colorEnabled implementations with calls to ansi.Enabled, mapping each package's Options fields at the call site.
  4. Move the existing color-decision tests from internal/list / internal/preview into internal/ansi/color_test.go (table-driven: every mode × NoColor × NO_COLOR combination); keep one thin test per caller proving the Options mapping.

Acceptance criteria

  • One implementation of the precedence logic, in internal/ansi.
  • ccsession preview <id> | cat and NO_COLOR=1 ccsession list behave exactly as before (covered by tests).
  • go test ./..., go vet ./..., golangci-lint run, gofmt -l . pass/clean.

Metadata

Metadata

Assignees

No one assigned

    Labels

    good first issueGood for newcomersimpact: lowLower or indirect user-visible impactrefactorInternal restructuring with no behavior change

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions