Re: [code] [textadept] How to set "bright" ansi colors as background color in curses mode?

From: Peter Kazmier <pete.att.kazmier.com>
Date: Tue, 2 Apr 2013 20:47:55 -0500

Hi Mitchell,

On Apr 2, 2013, at 9:32 AM, Mitchell <m.att.foicica.com> wrote:

> Hi Pete,
>
> On Tue, 2 Apr 2013, Peter Kazmier wrote:
>
>> On Apr 2, 2013, at 12:57 AM, Mitchell <m.att.foicica.com> wrote:
>>> This is tricky. Only 64 color pairs can be defined at once (using the 8 basic colors), e.g. White-Black, Red-Black, Green-Black, etc. So combinations like White-Black|Bold are not possible, at least for background colors. (However, a combination like White|Bold-Black is perfectly legitimate and does not count as a pair due to the current implementation.) The only way to get around this is, in your terminal application, to define Black as your "Bright Black" and Black|Bold as your "Normal Black", which may seem counter intuitive.
>>
>> After looking into this more, I think I understand it a bit better. Ncurses does support 16-color terminals. When setting colors, they are assigned 0-15. I'm trying to figure out how to set colors 8-15.
>>
>> Forget the extra 8 colors, doesn't something have to convert the rgb values in the 'term' theme to one of the 0-7 colors supported by the terminal? Where would that mapping happen? I'm hoping to see if I can find what rgb values would map to 8-15.
>
> There is no color map to colors 8-15. In lexer.lua, you set the "bold" style attribute in tandem with one of the 8 recognized colors as the "fore" attribute to use colors 8-15.

I'm stubborn to get my solarized terminal theme to work so after reading and doing some experimenting, I discovered it is possible to set colors 8-15 assuming your terminal supports 16 colors (mine is xterm-16color and screen-16color when running inside of tmux). Here is a simple curses experiment to set the foreground to color 12 and the background to color 8:

#include <stdio.h>
#include <curses.h>

int main()
{
  initscr();
  start_color();
  init_pair(1, 12, 8);
  bkgd(COLOR_PAIR(1));
  addstr("Default Solarized Foreground and Background");
  getch();
  endwin();
}

If I inspect the COLORS and COLOR_PAIRS definitions, on my terminal, they are 16 and 256 respectively. This was good news as now all I had to do is figure out how to hack textadept to set 16 colors. That led me to ScintillaTerm.cxx and with a small change in the for loops below (changed the 8 to 16):

void init_colors() {
  if (inited_colors) return;
  if (has_colors()) {
    start_color();
    for (int back = 0; back < 16; back++)
      for (int fore = 0; fore < 16; fore++)
        init_pair(SCI_COLOR_PAIR(fore, back), fore, back);
  }
  inited_colors = true;
}

Then I added the definitions for the BRIGHT versions of the colors:

#define COLOR_BRBLACK 8
#define COLOR_BRRED 9
#define COLOR_BRGREEN 10
#define COLOR_BRYELLOW 11
#define COLOR_BRBLUE 12
#define COLOR_BRMAGENTA 13
#define COLOR_BRCYAN 14
#define COLOR_BRWHITE 15

Then I had to make up some bogus RGB values to represent my new BRIGHT versions, so I just tweaked the Blue value by 1 to keep it simple so I could remember when setting the colors in my lexer.lua theme file (ideally, these should have better values). These can be any values so long as the person specifying them in lexer.lua uses the same values:

static ColourDesired BRBLACK(0, 0, 1);
static ColourDesired BRRED(0xFF, 0, 1);
static ColourDesired BRGREEN(0, 0xFF, 1);
static ColourDesired BRYELLOW(0xFF, 0xFF, 1);
static ColourDesired BRBLUE(0, 0, 0xFE);
static ColourDesired BRMAGENTA(0xFF, 0, 0xFE);
static ColourDesired BRCYAN(0, 0xFF, 0xFE);
static ColourDesired BRWHITE(0xFF, 0xFF, 0xFE);

Finally, adding the new colors to the term_color mapping routine, which maps the ColourDesired (as specified by user in lexer.lua) to the correct ANSI color slot:

static int term_color(ColourDesired color) {
  if (color == BLACK) return COLOR_BLACK;
  else if (color == RED) return COLOR_RED;
  else if (color == GREEN) return COLOR_GREEN;
  else if (color == YELLOW) return COLOR_YELLOW;
  else if (color == BLUE) return COLOR_BLUE;
  else if (color == MAGENTA) return COLOR_MAGENTA;
  else if (color == CYAN) return COLOR_CYAN;
  else if (color == BRBLACK) return COLOR_BRBLACK;
  else if (color == BRRED) return COLOR_BRRED;
  else if (color == BRGREEN) return COLOR_BRGREEN;
  else if (color == BRYELLOW) return COLOR_BRYELLOW;
  else if (color == BRBLUE) return COLOR_BRBLUE;
  else if (color == BRMAGENTA) return COLOR_BRMAGENTA;
  else if (color == BRWHITE) return COLOR_BRWHITE;
  else return COLOR_WHITE;
}

Quick compile and it works!! Well, mostly, my background color is set correctly as ANSI color 8, but for some reason I get a horrible background color behind my text. I can't figure out what's going on, but at least I made it this far. Here is a screenshot: http://www.kazmier.com/~kaz/textadept.png

Here is my lexer.lua from my theme (note: the RGB values for the bright colors match those defined in ScintillaTerm.cxx, solarized renames the colors to some weird baseNN notation, but you should still get the point):

local l, color, style = lexer, lexer.color, lexer.style

l.colors = {
    base03 = color("00", "00", "01"),
    base02 = color("00", "00", "00"),
    base01 = color("00", "FF", "01"),
    base00 = color("FF", "FF", "01"),
    base0 = color("00", "00", "FE"),
    base1 = color("00", "FF", "FE"),
    base2 = color("FF", "FF", "FF"),
    base3 = color("FF", "FF", "FE"),
    yellow = color("FF", "FF", "00"),
    orange = color("FF", "00", "01"),
    red = color("FF", "00", "00"),
    magenta = color("FF", "00", "FF"),
    violet = color("FF", "00", "FE"),
    blue = color("00", "00", "FF"),
    cyan = color("00", "FF", "FF"),
    green = color("00", "FF", "00"),
}

l.style_nothing = style{ }
l.style_class = style{fore = l.colors.orange }
l.style_comment = style{fore = l.colors.base01 }
l.style_constant = style{fore = l.colors.orange }
l.style_definition = style{fore = l.colors.red, }
l.style_error = style{fore = l.colors.red, }
l.style_function = style{fore = l.colors.blue }
l.style_keyword = style{fore = l.colors.green }
l.style_label = style{fore = l.colors.magenta }
l.style_number = style{fore = l.colors.cyan }
l.style_operator = style{fore = l.colors.yellow }
l.style_regex = style{fore = l.colors.green }
l.style_string = style{fore = l.colors.violet }
l.style_preproc = style{fore = l.colors.magenta }
l.style_tag = style{fore = l.colors.white }
l.style_type = style{fore = l.colors.magenta }
l.style_variable = style{fore = l.colors.blue }
l.style_whitespace = l.style_nothing
l.style_embedded = l.style_tag..{back = l.colors.base03 }
l.style_identifier = l.style_nothing

-- Default styles.
l.style_default = style{fore = l.colors.base0, back = l.colors.base03 }
l.style_line_number = l.style_default
l.style_bracelight = style{fore = l.colors.base1 }
l.style_bracebad = style{fore = l.colors.red }
l.style_controlchar = l.style_nothing
l.style_indentguide = l.style_nothing
l.style_calltip = l.style_default

Now all I need to do is figure out what is mucking with the background of all my characters. Any quick ideas? Maybe I need to check view.lua and buffer.lua in the theme directory too. I realized I have not done that.

Pete

-- 
You are subscribed to code.att.foicica.com.
To change subscription settings, send an e-mail to code+help.att.foicica.com.
To unsubscribe, send an e-mail to code+unsubscribe.att.foicica.com.
Received on Tue 02 Apr 2013 - 21:47:55 EDT

This archive was generated by hypermail 2.2.0 : Wed 03 Apr 2013 - 06:38:41 EDT