Skip to content

Commit

Permalink
Add 24bit color aka "direct color" aka "truecolor"
Browse files Browse the repository at this point in the history
Also added several TERMs to Mode as supporting 256 colors.

This also adds 256 color TERMs to Mode::TERM_256 and used the mode
Regexps inside the support Regexp. This required swapping the require
order, because Support now depends on those Regexps from Mode.

I matched this up with my local laptop's terminfo DB (Ubuntu 20.04, with
ncurses 6.2.20200212, and a bunch of extra terminal packages installed).
I did make "ansi" support more conservative and added "^" to a few of
the other support cases (tput is still a fallback), but everything else
became more liberal.

To query terminfo, I ran the following bash script and several like it:

```bash
for term in $(toe -a | awk '{ print $1 }' | sort -u | xargs); do
    printf "%3d %s\n" "$(TERM="$term" tput colors)" "$term"
done | sort -n
```
  • Loading branch information
nevans committed Oct 31, 2020
1 parent 98831f2 commit 1d269b1
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 6 deletions.
2 changes: 1 addition & 1 deletion lib/tty/color.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# frozen_string_literal: true

require_relative "color/support"
require_relative "color/mode"
require_relative "color/support"
require_relative "color/version"

module TTY
Expand Down
12 changes: 9 additions & 3 deletions lib/tty/color/mode.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@
module TTY
module Color
class Mode
TERM_256 = /iTerm(\s\d+){0,1}.app/x
TERM_24BIT = /[+-]direct/
TRUECOLORS = 2 ** 24 # 8 bits per RGB channel

TERM_256 = /^(alacritty|iTerm\s?\d*\.app|kitty|mintty|ms-terminal|
nsterm|nsterm-build\d+|terminator|terminology(-[0-9.]+)?|
termite|vscode)$/x

TERM_64 = /^(hpterm-color|wy370|wy370-105k|wy370-EPC|wy370-nk|
wy370-rv|wy370-tek|wy370-vb|wy370-w|wy370-wvb)$/x
Expand All @@ -15,7 +20,7 @@ class Mode
d430c-unix-s|d430c-unix-sr|d430c-unix-w|d470|d470-7b|d470-dg|
d470c|d470c-7b|d470c-dg|dg+color|dg\+fixed|dgunix\+fixed|
dgmode\+color|hp\+color|ncr260wy325pp|ncr260wy325wpp|
ncr260wy350pp|ncr260wy350wpp|nsterm|nsterm-c|nsterm-c-acs|
ncr260wy350pp|ncr260wy350wpp|nsterm-c|nsterm-c-acs|
nsterm-c-s|nsterm-c-s-7|nsterm-c-s-acs|nsterm\+c|
nsterm-7-c|nsterm-bce)$/x

Expand All @@ -30,7 +35,7 @@ def initialize(env)
# Detect supported colors
#
# @return [Integer]
# out of 0, 8, 16, 52, 64, 256
# out of 0, 8, 16, 52, 66, 256, 2^24
#
# @api public
def mode
Expand All @@ -51,6 +56,7 @@ def mode
# @api private
def from_term
case @env["TERM"]
when TERM_24BIT then TRUECOLORS
when /[\-\+](\d+)color/ then $1.to_i
when /[\-\+](\d+)bit/ then 2 ** $1.to_i
when TERM_256 then 256
Expand Down
21 changes: 20 additions & 1 deletion lib/tty/color/support.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,25 @@ class Support
SOURCES = %w[from_term from_tput from_env from_curses].freeze
ENV_VARS = %w[COLORTERM ANSICON].freeze

TERM_REGEX = /
color| # explicitly claims color support in the name
direct| # explicitly claims "direct color" (24 bit) support
#{Mode::TERM_256}|
#{Mode::TERM_64}|
#{Mode::TERM_52}|
#{Mode::TERM_16}|
#{Mode::TERM_8}|
^ansi(\.sys.*)?$|
^cygwin|
^linux|
^putty|
^rxvt|
^screen|
^tmux|
^xterm /xi

# Initialize a color support
# @api public
def initialize(env, verbose: false)
Expand Down Expand Up @@ -47,7 +66,7 @@ def disabled?
def from_term
case @env["TERM"]
when "dumb" then false
when /^screen|^xterm|^vt100|color|ansi|cygwin|linux/i then true
when TERM_REGEX then true
else NoValue
end
end
Expand Down
9 changes: 9 additions & 0 deletions spec/unit/mode_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,16 @@

context "#from_term" do
{
"xterm+direct" => 16_777_216,
"vscode-direct" => 16_777_216,
"xterm-256color" => 256,
"alacritty" => 256,
"mintty" => 256,
"ms-terminal" => 256,
"nsterm" => 256,
"nsterm-build400" => 256,
"terminator" => 256,
"vscode" => 256,
"iTerm.app" => 256,
"iTerm 2.app" => 256,
"amiga-8bit" => 256,
Expand Down
4 changes: 3 additions & 1 deletion spec/unit/support_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@
end
end

context "#form_term" do
context "#from_term" do
it "fails to find color for dumb terminal" do
support = described_class.new({"TERM" => "dumb"})
expect(support.from_term).to eq(false)
Expand All @@ -99,6 +99,8 @@
it "inspects term variable for color capabilities" do
support = described_class.new({"TERM" => "xterm"})
expect(support.from_term).to eq(true)
support = described_class.new({"TERM" => "tmux-256color"})
expect(support.from_term).to eq(true)
end

it "fails to find color capabilities from term variable " do
Expand Down

0 comments on commit 1d269b1

Please sign in to comment.