prompt-toolkit / python-prompt-toolkit

Library for building powerful interactive command line applications in Python
https://python-prompt-toolkit.readthedocs.io/
BSD 3-Clause "New" or "Revised" License
9.37k stars 716 forks source link

Support terminal output color indexes #355

Open memeplex opened 8 years ago

memeplex commented 8 years ago

Currently _color_to_code implements sophisticated support for vt100 terminal colors:

  1. Ansi names.
  2. 16 colors.
  3. 256 colors.
  4. True color.

What is missing is the possibility to directly pass the code. This is important since some people (like me, using base16 themes) customize the first 16 colors to their heart contents. I believe it's a very simple change: if color is an int simply return it as a code.

What do you think?

memeplex commented 8 years ago

This is sad: my motivating use case was to fix ipython 5 colors, but now I realize pygments requires a specific color format that bans the int codification. Maybe it's better to just rely on true color support.

memeplex commented 8 years ago

I ended up with a hackish solution which consists in updating the color caches with my own color indexes.

I think you may offer a more formal interface to do that, something like set_exact_colors(list of (index, color)), so that __missing__ can look there first and only then try to be smart about approximating colors. This will work with pygments, unlike my proposal above.

jonathanslenders commented 8 years ago

Hi @memeplex,

What about using the ANSI colors? The idea is that they map exactly to those 16 colors. @Carreau made a patch to Pygments (not yet released) to support ANSI colors as well. But prompt-toolkit applications have it already, because they use the compatible style implementation of prompt-toolkit itself.

The style should look like this:

{
    Token:  'bg:#ansired  #ansiyellow',
}

https://github.com/jonathanslenders/python-prompt-toolkit/blob/master/prompt_toolkit/styles/base.py#L39

Is there something that I'm missing, or do you prefer numeric names for the colors?

memeplex commented 8 years ago

I had thought about using the ansi colors but:

  1. They dont map to the 0-15 space according to https://github.com/jonathanslenders/python-prompt-toolkit/blob/master/prompt_toolkit/terminal/vt100_output.py. Maybe I'm missing something here.
  2. They didn't play well with my version of pygments.
jonathanslenders commented 8 years ago

They should map 0-15. Remember that the (foreground) colors are in the 30–37 range and the high intensity colors are in the 90–97 range. See this page for more information: https://en.wikipedia.org/wiki/ANSI_escape_code#Colors

memeplex commented 8 years ago

Ok, then I will wait for the pygments patch and there is no need to do anything else. Thanks!

memeplex commented 8 years ago

I'm reopening this because I realize simple ansi colors won't cover my use case (create a base16 theme for prompt_toolkit + pygments + ipython): base16-shell sets colors 16 to 23. More in general, the idea of having a user color map as I described above seems pretty easy to implement and it gives a very flexible hook for power users. True, real hackers can just set the "private" _xxx_colors caches, but this interface is not stable and it might involve updating three caches. Having a __missing__ that first looks at the user map is cleaner.

Carreau commented 8 years ago

I would need to understand a bit more how windows does things, the point of the ansi color code is that the terminal itself choose the theme:

color

[Look at the (rootenv) text that change live.]

So you should be able to create a ainsi theme, and set your terminal to be in general base16. There might be some error in the logic, but yet an intermediate abstraction seem too much. Unless I'm missing something.

memeplex commented 8 years ago

Some people set a palette for their terminal using X resources or escape sequences. This palette is not restricted to 16 colors, so the ansii names are not general enough. The 6x6x6 color cube is a nice, plug&play, solution but: 1. It's only an approximation, 2. If you have set your own palette above color 0F, then you have screwed up the color cube (for good).

Specifically regarding base16: despite its name, base16-shell sets colors above the first 16. It does this because it wants to preserve a nice 16-color palette (first 8 colors of the theme plus 8 bright variants of them) while exposing more colors (second 8 colors of the theme) to aware applications (like vim).

memeplex commented 8 years ago

This is the base16-shell default-dark palette:

2016-07-22-141530_760x330_scrot

This is what I'm doing:

base00 = "#181818"
base01 = "#282828"
base02 = "#383838"
base03 = "#585858"
base04 = "#b8b8b8"
base05 = "#d8d8d8"
base06 = "#e8e8e8"
base07 = "#f8f8f8"
base08 = "#ab4642"
base09 = "#dc9656"
base0A = "#f7ca88"
base0B = "#a1b56c"
base0C = "#86c1b9"
base0D = "#7cafc2"
base0E = "#ba8baf"
base0F = "#a16946"

colors = (globals()['base0' + d] for d in '08BADEC5379F1246')
for i, color in enumerate(colors):
    r, g, b = int(color[1:3], 16), int(color[3:5], 16), int(color[5:], 16)
    _256_colors[r, g, b] = i + 6 if i > 8 else i
...
set pygments, pt and ipython colors

Notice that bright colors are not really part of the base16 palette http://chriskempson.com/projects/base16/ (except for bright black and bright white).

memeplex commented 8 years ago

@jonathanslenders are you interested in a PR implementing something like that described in https://github.com/jonathanslenders/python-prompt-toolkit/issues/355#issuecomment-234588330?

memeplex commented 7 years ago

I have converted my prompt toolkit theme into a template and generated all base16 themes from it. I'm now in the process of registering my repo as an "official" base16 source.

https://github.com/memeplex/base16-prompt-toolkit