To: vim_dev@googlegroups.com Subject: Patch 8.0.0754 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.0.0754 Problem: Terminal window does not support colors. Solution: Lookup the color attribute. Files: src/terminal.c, src/syntax.c, src/proto/syntax.pro *** ../vim-8.0.0753/src/terminal.c 2017-07-22 22:32:51.233745323 +0200 --- src/terminal.c 2017-07-23 15:46:30.738502829 +0200 *************** *** 33,38 **** --- 33,41 ---- * while, if the terminal window is visible, the screen contents is drawn. * * TODO: + * - color for GUI + * - color for 'termguicolors' + * - cursor flickers when moving the cursor * - set buffer options to be scratch, hidden, nomodifiable, etc. * - set buffer name to command, add (1) to avoid duplicates. * - Add a scrollback buffer (contains lines to scroll off the top). *************** *** 587,592 **** --- 590,743 ---- } /* + * Reverse engineer the RGB value into a cterm color index. + * First color is 1. Return 0 if no match found. + */ + static int + color2index(VTermColor *color) + { + int red = color->red; + int blue = color->blue; + int green = color->green; + + if (red == 0) + { + if (green == 0) + { + if (blue == 0) + return 1; /* black */ + if (blue == 224) + return 5; /* blue */ + } + else if (green == 224) + { + if (blue == 0) + return 3; /* green */ + if (blue == 224) + return 7; /* cyan */ + } + } + else if (red == 224) + { + if (green == 0) + { + if (blue == 0) + return 2; /* red */ + if (blue == 224) + return 6; /* magenta */ + } + else if (green == 224) + { + if (blue == 0) + return 4; /* yellow */ + if (blue == 224) + return 8; /* white */ + } + } + else if (red == 128) + { + if (green == 128 && blue == 128) + return 9; /* high intensity bladk */ + } + else if (red == 255) + { + if (green == 64) + { + if (blue == 64) + return 10; /* high intensity red */ + if (blue == 255) + return 14; /* high intensity magenta */ + } + else if (green == 255) + { + if (blue == 64) + return 12; /* high intensity yellow */ + if (blue == 255) + return 16; /* high intensity white */ + } + } + else if (red == 64) + { + if (green == 64) + { + if (blue == 255) + return 13; /* high intensity blue */ + } + else if (green == 255) + { + if (blue == 64) + return 11; /* high intensity green */ + if (blue == 255) + return 15; /* high intensity cyan */ + } + } + if (t_colors >= 256) + { + if (red == blue && red == green) + { + /* 24-color greyscale */ + static int cutoff[23] = { + 0x05, 0x10, 0x1B, 0x26, 0x31, 0x3C, 0x47, 0x52, + 0x5D, 0x68, 0x73, 0x7F, 0x8A, 0x95, 0xA0, 0xAB, + 0xB6, 0xC1, 0xCC, 0xD7, 0xE2, 0xED, 0xF9}; + int i; + + for (i = 0; i < 23; ++i) + if (red < cutoff[i]) + return i + 233; + return 256; + } + + /* 216-color cube */ + return 17 + ((red + 25) / 0x33) * 36 + + ((green + 25) / 0x33) * 6 + + (blue + 25) / 0x33; + } + return 0; + } + + /* + * Convert the attributes of a vterm cell into an attribute index. + */ + static int + cell2attr(VTermScreenCell *cell) + { + int attr = 0; + + if (cell->attrs.bold) + attr |= HL_BOLD; + if (cell->attrs.underline) + attr |= HL_UNDERLINE; + if (cell->attrs.italic) + attr |= HL_ITALIC; + if (cell->attrs.strike) + attr |= HL_STANDOUT; + if (cell->attrs.reverse) + attr |= HL_INVERSE; + if (cell->attrs.strike) + attr |= HL_UNDERLINE; + + #ifdef FEAT_GUI + if (gui.in_use) + { + /* TODO */ + } + else + #endif + #ifdef FEAT_TERMGUICOLORS + if (p_tgc) + { + /* TODO */ + } + #endif + { + return get_cterm_attr_idx(attr, color2index(&cell->fg), + color2index(&cell->bg)); + } + return 0; + } + + /* * Called to update the window that contains the terminal. */ void *************** *** 648,654 **** VTermScreenCell cell; int c; ! vterm_screen_get_cell(screen, pos, &cell); c = cell.chars[0]; if (c == NUL) { --- 799,808 ---- VTermScreenCell cell; int c; ! if (vterm_screen_get_cell(screen, pos, &cell) == 0) ! vim_memset(&cell, 0, sizeof(cell)); ! ! /* TODO: composing chars */ c = cell.chars[0]; if (c == NUL) { *************** *** 672,679 **** ScreenLines[off] = c; #endif } ! /* TODO: use cell.attrs and colors */ ! ScreenAttrs[off] = 0; ++pos.col; ++off; --- 826,832 ---- ScreenLines[off] = c; #endif } ! ScreenAttrs[off] = cell2attr(&cell); ++pos.col; ++off; *************** *** 731,736 **** --- 884,901 ---- vterm_screen_set_callbacks(screen, &screen_callbacks, term); /* TODO: depends on 'encoding'. */ vterm_set_utf8(vterm, 1); + + /* Vterm uses a default black background. Set it to white when + * 'background' is "light". */ + if (*p_bg == 'l') + { + VTermColor fg, bg; + + fg.red = fg.green = fg.blue = 0; + bg.red = bg.green = bg.blue = 255; + vterm_state_set_default_colors(vterm_obtain_state(vterm), &fg, &bg); + } + /* Required to initialize most things. */ vterm_screen_reset(screen, 1 /* hard */); } *** ../vim-8.0.0753/src/syntax.c 2017-06-24 22:52:19.162618436 +0200 --- src/syntax.c 2017-07-23 15:44:34.427311382 +0200 *************** *** 8781,8786 **** --- 8781,8801 ---- } /* + * Get an attribute index for a cterm entry. + * Uses an existing entry when possible or adds one when needed. + */ + int + get_cterm_attr_idx(int attr, int fg, int bg) + { + attrentry_T at_en; + + at_en.ae_attr = attr; + at_en.ae_u.cterm.fg_color = fg; + at_en.ae_u.cterm.bg_color = bg; + return get_attr_entry(&cterm_attr_table, &at_en); + } + + /* * Clear all highlight tables. */ void *** ../vim-8.0.0753/src/proto/syntax.pro 2017-06-18 22:40:36.528444633 +0200 --- src/proto/syntax.pro 2017-07-23 15:44:32.191326904 +0200 *************** *** 31,36 **** --- 31,37 ---- void hl_set_font_name(char_u *font_name); void hl_set_bg_color_name(char_u *name); void hl_set_fg_color_name(char_u *name); + int get_cterm_attr_idx(int attr, int fg, int bg); void clear_hl_tables(void); int hl_combine_attr(int char_attr, int prim_attr); attrentry_T *syn_gui_attr2entry(int attr); *** ../vim-8.0.0753/src/version.c 2017-07-22 22:32:51.233745323 +0200 --- src/version.c 2017-07-23 14:17:11.323788341 +0200 *************** *** 771,772 **** --- 771,774 ---- { /* Add new patch number below this line */ + /**/ + 754, /**/ -- I noticed my daughter's Disney-net password on a sticky note: "MickeyMinnieGoofyPluto". I asked her why it was so long. "Because they say it has to have at least four characters." /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///