diff options
| -rw-r--r-- | INSTALL | 2 | ||||
| -rw-r--r-- | TODO | 11 | ||||
| -rw-r--r-- | configure.ac | 4 | ||||
| m--------- | contrib/scinterm | 0 | ||||
| m--------- | contrib/scintilla | 0 | ||||
| -rw-r--r-- | doc/sciteco.7.template | 14 | ||||
| -rw-r--r-- | lib/colors/contrast.tes | 2 | ||||
| -rw-r--r-- | lib/colors/solarized.tes | 2 | ||||
| -rw-r--r-- | lib/colors/terminal.tes | 2 | ||||
| -rw-r--r-- | lib/opener.tes | 4 | ||||
| -rw-r--r-- | src/core-commands.c | 34 | ||||
| -rw-r--r-- | src/interface-curses/interface.c | 170 | ||||
| -rw-r--r-- | src/interface-gtk/interface.c | 1 | ||||
| -rw-r--r-- | src/interface.h | 3 | ||||
| -rw-r--r-- | src/view.c | 4 |
15 files changed, 162 insertions, 91 deletions
@@ -48,7 +48,7 @@ installed by the user manually: * Scintilla (v5.3.0 or later): http://www.scintilla.org/ * When choosing the Curses interface: - * Scinterm (v5.5 or later): + * Scinterm (v6.0 or later): http://foicica.com/scinterm/ * Lexilla (v5.0.0 or later, optional): https://www.scintilla.org/Lexilla.html @@ -804,17 +804,6 @@ Features: We'd have to handle an overlapping info popup, though. Should we deactivate the hardware cursor via curs_set(0) if it overlaps the popup? - * ncurses: Support default colors (use_default_colors()). - Instead of drawing a black background and white foreground - we could use pair number -1. - This means you don't suddenly become white-on-black on terminals - that use black-on-white by default. - On the other hand, not all color schemes might look good, - so this would have to be a setting (ED flag). - Also, Scinterm would have to support it as well. - This also appears to be responsible for the greyish background - on Haiku and GNOME Terminal: They don't have a true black as color 0 - even if the default terminal background is a true black. * Ctags support Perhaps can be Video TECO compatible. https://github.com/universal-ctags/ctags diff --git a/configure.ac b/configure.ac index f64636b..b5cac0b 100644 --- a/configure.ac +++ b/configure.ac @@ -307,7 +307,7 @@ case $INTERFACE in # Scinterm cares about the correct flags itself. AC_DEFINE(NCURSES_WIDECHAR, 1, [Provide wide-character functions]) - AC_CHECK_FUNCS([tigetstr]) + AC_CHECK_FUNCS([tigetstr use_default_colors]) ;; netbsd-curses) @@ -331,7 +331,7 @@ case $INTERFACE in CXXFLAGS="$CXXFLAGS $CURSES_CFLAGS" LIBS="$LIBS $CURSES_LIBS" - AC_CHECK_FUNCS([tigetstr]) + AC_CHECK_FUNCS([tigetstr use_default_colors]) ;; xcurses) diff --git a/contrib/scinterm b/contrib/scinterm -Subproject 274656ad8fd7478ff7ed7fc4e04eedb7863b2f9 +Subproject 14c560e63d280f2a8f26b4bbf287d7af679b0a1 diff --git a/contrib/scintilla b/contrib/scintilla -Subproject 748f9cbc4f2a9d7a4216feaa37aee8e834123f0 +Subproject a534721011f35a1a56c2a815f8b2fa31e0a8ebb diff --git a/doc/sciteco.7.template b/doc/sciteco.7.template index cb718e0..87e8574 100644 --- a/doc/sciteco.7.template +++ b/doc/sciteco.7.template @@ -910,9 +910,17 @@ The \fBSTYLE_CALLTIP\fP (38) style is also accessed by \*(ST to style the \fIpopup area\fP and is initialized to black on white by \*(ST. .LP -On curses user interfaces, only a selection of 16 terminal -colors can be used, although it is possible to request changing -the default color mapping (see \fBEJ\fP command). +On curses user interfaces the Scintilla RGB color values +can refer to the terminal's color palette, initialize new +colors on-demand or refer to the terminal's default foreground +and background colors (see \fBEJ\fP command). +The availability of colors, the size of the terminal's +palette, the availability of arbitrary RGB colors, the +number of concurrent colors on screen and the maximum +number of foreground-background combinations on screen +is subject to terminal-specific limits. +\*(ST supports monochrome terminals by mapping non-black +(non-null Scintilla RGB codes) to reverse video. .LP Scintilla styles will usually be set up in the profile macro or \fBED\fP hook (for syntax highlighting). diff --git a/lib/colors/contrast.tes b/lib/colors/contrast.tes index 256faad..c75ec9c 100644 --- a/lib/colors/contrast.tes +++ b/lib/colors/contrast.tes @@ -3,6 +3,8 @@ * This only highlights strings and comments (if supported by the terminal). * This is also the recommended color scheme on monochrome displays. *! +-1,-1,7EJ !* no default colors *! + [color.default] 0,Q[color.black],Q[color.white] [[color.default]][color.linenumber] Q[color.black]U[color.caretline] diff --git a/lib/colors/solarized.tes b/lib/colors/solarized.tes index 91b2718..aeb9cb9 100644 --- a/lib/colors/solarized.tes +++ b/lib/colors/solarized.tes @@ -17,7 +17,7 @@ * `solarized.toggle` will be mapped to the F5 function key. * F5 will also automatically terminate the command line. *! -0,3EJ +0,3EJ -1,-1,7EJ !* no palette & no default colors *! 000,043,054:M[color.rgb]U[color.base03] 007,054,066:M[color.rgb]U[color.base02] diff --git a/lib/colors/terminal.tes b/lib/colors/terminal.tes index 39c5bac..b4ba88d 100644 --- a/lib/colors/terminal.tes +++ b/lib/colors/terminal.tes @@ -1,4 +1,6 @@ !* Default terminal color scheme *! +-1,-1,7EJ !* no default colors *! + [color.default] 0,Q[color.black],Q[color.white] [color.linenumber] 0,Q[color.black],Q[color.white] Q[color.black]U[color.caretline] diff --git a/lib/opener.tes b/lib/opener.tes index 8bcd896..66a97e7 100644 --- a/lib/opener.tes +++ b/lib/opener.tes @@ -44,10 +44,10 @@ *! @[opener.check-recovery]{ :Q*"= ' - [* + [*[_ EQ.f G* I# R <-A"I 1; ' :R;> I# 1:EN*Q.f"S 2Detected recovery file "Q.f" ' - ]* + ]_]* } diff --git a/src/core-commands.c b/src/core-commands.c index d2c8b9d..63d8dbc 100644 --- a/src/core-commands.c +++ b/src/core-commands.c @@ -2084,7 +2084,7 @@ teco_state_ecommand_flags(teco_machine_main_t *ctx, GError **error) /*$ EJ properties * [key]EJ -> value -- Get and set system properties * value,keyEJ - * rgb,color,3EJ + * [fore,]back,7EJ * -EJ -> event * -2EJ -> y, x * @@ -2136,6 +2136,7 @@ teco_state_ecommand_flags(teco_machine_main_t *ctx, GError **error) * first. * Memory limiting is enabled by default. * .IP 3: + * .SCITECO_TOPIC palette * This \fBwrite-only\fP property allows disabling use of * the 16 color palette of default colors when using * the Curses user interface. @@ -2188,6 +2189,25 @@ teco_state_ecommand_flags(teco_machine_main_t *ctx, GError **error) * After changing the interval, the new value may become * active only after the previous interval expires. * Recovery files are not dumped in batch mode. + * .IP 7: + * .SCITECO_TOPIC "default colors" + * This \fBwrite-only\fP property allows configuring the default + * foreground and background colors, given as two + * Scintilla-encoded RGB (0xBBGGRR) numbers. + * When asked to draw these colors, the terminal's native + * default colors \(em which may be some kind of white on black or + * black on white \(em are used instead. + * Therefore this command does not change any colors on screen + * \(em it just defines placeholder values for the terminal's + * default colors. + * This may be used e.g. to get a true black background where + * the terminal emulator's palette uses a different hue for + * Curses color COLOR_BLACK without having to resort to + * color redefinitions. + * With caution this may even be used to build color schemes that + * work both on white on black and black on white terminals. + * Use -1 to disable default foreground or background colors. + * It has no effect when using the GTK interface. * . * .IP -1: * Type of the last mouse event (\fBread-only\fP). @@ -2242,7 +2262,8 @@ teco_state_ecommand_properties(teco_machine_main_t *ctx, GError **error) EJ_PALETTE, EJ_CARETX, EJ_CMDLINE_HEIGHT, - EJ_RECOVERY_INTERVAL + EJ_RECOVERY_INTERVAL, + EJ_DEFAULT_COLORS }; static teco_int_t caret_x = 0; @@ -2298,6 +2319,15 @@ teco_state_ecommand_properties(teco_machine_main_t *ctx, GError **error) /* FIXME: Perhaps signal the interface to reprogram timers */ break; + case EJ_DEFAULT_COLORS: { + teco_int_t fore; + + if (!teco_expressions_pop_num_calc(&fore, -1, error)) + return; + teco_interface_set_default_colors(fore, value); + break; + } + default: g_set_error(error, TECO_ERROR, TECO_ERROR_FAILED, "Cannot set property %" TECO_INT_FORMAT " " diff --git a/src/interface-curses/interface.c b/src/interface-curses/interface.c index 21e728f..ff6a0f2 100644 --- a/src/interface-curses/interface.c +++ b/src/interface-curses/interface.c @@ -200,6 +200,12 @@ static struct { * so every color is initialized to exact RGB values. */ gboolean use_palette; + /** + * Scintilla RGB values which should be rendered + * as the terminal's default foreground/background colors. + * This is -1 if colors haven't been configured. + */ + gint32 default_fg, default_bg; int stdin_orig, stdout_orig, stderr_orig; SCREEN *screen; @@ -237,58 +243,6 @@ static struct { } teco_interface; /** - * Returns the curses color pair for the given curses foreground and background colors. - * Initializes a new pair if necessary. - * - * Scinterm no longer initializes all color pairs for all combinations of - * the builtin foreground and background colors. - * Since curses does not guarantee any number of color pairs, we cannot do that either. - * Instead we allocate color pairs in the first half of - * color pair space on demand, while the second half is reserved to Scinterm. - * - * @param attr attributes to modify (for supporting monochrome terminals) - * @param fg curses foreground color - * @param bg curses background color - * @return curses color pair number - */ -static gshort -teco_color_pair(attr_t *attr, gshort fg, gshort bg) -{ - static guint next_pair = 1; - - /* - * Basic support for monochrome terminals: - * Every background, that is not black is assumed to be a - * dark-on-bright area, rendered in reverse. - * This will at least work with the terminal.tes and contrast.tes - * color schemes. - */ - if (!has_colors()) { - if (bg != COLOR_BLACK) - *attr |= WA_REVERSE; - return 0; - } - - G_STATIC_ASSERT(sizeof(gshort)*2 <= sizeof(guint)); - gpointer key = GUINT_TO_POINTER(((guint)fg << 8*sizeof(bg)) | bg); - gpointer value = g_hash_table_lookup(teco_interface.pair_table, key); - if (G_LIKELY(value != NULL)) - return GPOINTER_TO_UINT(value); - if (G_UNLIKELY(next_pair >= MAX_PAIRS)) - return 0; - init_pair(next_pair, fg, bg); - g_hash_table_insert(teco_interface.pair_table, key, GUINT_TO_POINTER(next_pair)); - return next_pair++; -} - -static inline gint -teco_wattr_set(WINDOW *win, attr_t attr, gshort fg, gshort bg) -{ - gshort pair = teco_color_pair(&attr, fg, bg); - return wattr_set(win, attr, pair, NULL); -} - -/** * Translate a Scintilla-compatible RGB color value * (0xBBGGRR) to a Curses color triple (0 to 1000 * for each component). @@ -358,6 +312,72 @@ teco_rgb2curses(guint32 rgb) return next_color; } +/** + * Returns the curses color pair for the given curses foreground and background colors. + * Initializes a new pair if necessary. + * + * Scinterm no longer initializes all color pairs for all combinations of + * the builtin foreground and background colors. + * Since curses does not guarantee any number of color pairs, we cannot do that either. + * Instead we allocate color pairs in the first half of + * color pair space on demand, while the second half is reserved to Scinterm. + * + * @param attr attributes to modify (for supporting monochrome terminals) + * @param fg curses foreground color (0xBBGGRR) + * @param bg curses background color (0xBBGGRR) + * @return curses color pair number + */ +static gshort +teco_color_pair(attr_t *attr, guint32 fg, guint32 bg) +{ + static guint next_pair = 1; + + /* + * Basic support for monochrome terminals: + * Every background, that is not black is assumed to be a + * dark-on-bright area, rendered in reverse. + * This will at least work with the terminal.tes and contrast.tes + * color schemes. + */ + if (!has_colors()) { + if (bg != 0x000000) + *attr ^= WA_REVERSE; + return 0; + } + + gshort fg_id, bg_id; + + /* + * Prefer to use reverse attribute since it will work with + * the terminals default colors. + */ + if (fg == teco_interface.default_bg && bg == teco_interface.default_fg) { + fg_id = bg_id = -1; + *attr ^= WA_REVERSE; + } else { + fg_id = fg == teco_interface.default_fg ? -1 : teco_rgb2curses(fg); + bg_id = bg == teco_interface.default_bg ? -1 : teco_rgb2curses(bg); + } + + G_STATIC_ASSERT(sizeof(gshort)*2 <= sizeof(guint)); + gpointer key = GUINT_TO_POINTER(((guint)fg_id << 8*sizeof(bg_id)) | bg_id); + gpointer value = g_hash_table_lookup(teco_interface.pair_table, key); + if (G_LIKELY(value != NULL)) + return GPOINTER_TO_UINT(value); + if (G_UNLIKELY(next_pair >= MAX_PAIRS)) + return 0; + init_pair(next_pair, fg_id, bg_id); + g_hash_table_insert(teco_interface.pair_table, key, GUINT_TO_POINTER(next_pair)); + return next_pair++; +} + +static inline gint +teco_wattr_set(WINDOW *win, attr_t attr, guint32 fg, guint32 bg) +{ + gshort pair = teco_color_pair(&attr, fg, bg); + return wattr_set(win, attr, pair, NULL); +} + static gint teco_xterm_version(void) { @@ -461,6 +481,8 @@ void teco_interface_init(gint argc, gchar **argv) { teco_interface.use_palette = TRUE; + teco_interface.default_fg = 0xC0C0C0; /* white */ + teco_interface.default_bg = 0x000000; /* black */; teco_interface.stdin_orig = teco_interface.stdout_orig = teco_interface.stderr_orig = -1; @@ -506,7 +528,13 @@ void teco_interface_disable_palette(void) { teco_interface.use_palette = FALSE; - scintilla_disable_color_palette(); +} + +void +teco_interface_set_default_colors(gint32 fg, gint32 bg) +{ + teco_interface.default_fg = fg; + teco_interface.default_bg = bg; } #ifdef CURSES_TTY @@ -652,6 +680,14 @@ teco_interface_init_interactive(GError **error) teco_interface.pair_table = g_hash_table_new(g_direct_hash, g_direct_equal); start_color(); scintilla_set_color_offsets(MAX_COLORS, MAX_PAIRS); + if (!teco_interface.use_palette) + scintilla_disable_color_palette(); +#ifdef HAVE_USE_DEFAULT_COLORS + /* color -1 will be the terminal's default foreground or background color */ + use_default_colors(); +#endif + scintilla_set_default_colors(teco_interface.default_fg, + teco_interface.default_bg); if (teco_interface.use_palette && has_colors()) { teco_interface_insert_color(0x000000, COLOR_BLACK); @@ -851,23 +887,23 @@ teco_interface_msg_literal(teco_msg_t type, const gchar *str, gsize len) teco_interface_stdio_msg(type, str, len); #endif - gshort fg, bg; + guint32 fg, bg; - fg = teco_rgb2curses(teco_interface_ssm(SCI_STYLEGETBACK, STYLE_DEFAULT, 0)); + fg = teco_interface_ssm(SCI_STYLEGETBACK, STYLE_DEFAULT, 0); switch (type) { default: case TECO_MSG_USER: - bg = teco_rgb2curses(teco_interface_ssm(SCI_STYLEGETFORE, STYLE_DEFAULT, 0)); + bg = teco_interface_ssm(SCI_STYLEGETFORE, STYLE_DEFAULT, 0); break; case TECO_MSG_INFO: - bg = COLOR_GREEN; + bg = 0x008000; /* green */ break; case TECO_MSG_WARNING: - bg = COLOR_YELLOW; + bg = 0x008080; /* yellow */ break; case TECO_MSG_ERROR: - bg = COLOR_RED; + bg = 0x000080; /* red */ beep(); break; } @@ -884,8 +920,8 @@ teco_interface_msg_clear(void) if (!teco_interface.input_pad) /* batch mode */ return; - gshort fg = teco_rgb2curses(teco_interface_ssm(SCI_STYLEGETBACK, STYLE_DEFAULT, 0)); - gshort bg = teco_rgb2curses(teco_interface_ssm(SCI_STYLEGETFORE, STYLE_DEFAULT, 0)); + guint32 fg = teco_interface_ssm(SCI_STYLEGETBACK, STYLE_DEFAULT, 0); + guint32 bg = teco_interface_ssm(SCI_STYLEGETFORE, STYLE_DEFAULT, 0); wmove(teco_interface.msg_window, 0, 0); teco_wattr_set(teco_interface.msg_window, 0, fg, bg); @@ -1077,8 +1113,8 @@ teco_interface_draw_info(void) * the current buffer's STYLE_DEFAULT. * The same style is used for MSG_USER messages. */ - gshort fg = teco_rgb2curses(teco_interface_ssm(SCI_STYLEGETBACK, STYLE_DEFAULT, 0)); - gshort bg = teco_rgb2curses(teco_interface_ssm(SCI_STYLEGETFORE, STYLE_DEFAULT, 0)); + guint32 fg = teco_interface_ssm(SCI_STYLEGETBACK, STYLE_DEFAULT, 0); + guint32 bg = teco_interface_ssm(SCI_STYLEGETFORE, STYLE_DEFAULT, 0); wmove(teco_interface.info_window, 0, 0); teco_wattr_set(teco_interface.info_window, 0, fg, bg); @@ -1650,8 +1686,8 @@ teco_interface_popup_show(gsize prefix_len) /* batch mode */ return; - gshort fg = teco_rgb2curses(teco_interface_ssm(SCI_STYLEGETFORE, STYLE_CALLTIP, 0)); - gshort bg = teco_rgb2curses(teco_interface_ssm(SCI_STYLEGETBACK, STYLE_CALLTIP, 0)); + guint32 fg = teco_interface_ssm(SCI_STYLEGETFORE, STYLE_CALLTIP, 0); + guint32 bg = teco_interface_ssm(SCI_STYLEGETBACK, STYLE_CALLTIP, 0); teco_interface.popup_prefix_len = prefix_len; attr_t attr = 0; @@ -1856,8 +1892,8 @@ teco_interface_process_mevent(MEVENT *event, GError **error) else if (event->bstate & BUTTON_NUM(5)) teco_curses_info_popup_scroll(&teco_interface.popup, +2); - gshort fg = teco_rgb2curses(teco_interface_ssm(SCI_STYLEGETFORE, STYLE_CALLTIP, 0)); - gshort bg = teco_rgb2curses(teco_interface_ssm(SCI_STYLEGETBACK, STYLE_CALLTIP, 0)); + guint32 fg = teco_interface_ssm(SCI_STYLEGETFORE, STYLE_CALLTIP, 0); + guint32 bg = teco_interface_ssm(SCI_STYLEGETBACK, STYLE_CALLTIP, 0); attr_t attr = 0; gshort pair = teco_color_pair(&attr, fg, bg); teco_curses_info_popup_show(&teco_interface.popup, attr, pair); diff --git a/src/interface-gtk/interface.c b/src/interface-gtk/interface.c index 9ef86a1..06f9a38 100644 --- a/src/interface-gtk/interface.c +++ b/src/interface-gtk/interface.c @@ -405,6 +405,7 @@ teco_interface_get_options(void) } void teco_interface_disable_palette(void) {} +void teco_interface_set_default_colors(gint32, gint32) {} void teco_interface_msg_literal(teco_msg_t type, const gchar *str, gsize len) diff --git a/src/interface.h b/src/interface.h index ace0e3d..a7968d1 100644 --- a/src/interface.h +++ b/src/interface.h @@ -59,6 +59,9 @@ GOptionGroup *teco_interface_get_options(void); /** @pure makes sense only on Curses */ void teco_interface_disable_palette(void); +/** @pure makes sense only on Curses */ +void teco_interface_set_default_colors(gint32 fg, gint32 bg); + typedef enum { TECO_MSG_USER = 0, TECO_MSG_INFO, @@ -109,7 +109,7 @@ teco_view_setup(teco_view_t *ctx) teco_view_ssm(ctx, SCI_SETCARETSTYLE, CARETSTYLE_BLOCK | CARETSTYLE_OVERSTRIKE_BLOCK | CARETSTYLE_BLOCK_AFTER, 0); teco_view_ssm(ctx, SCI_SETCARETPERIOD, 0, 0); - teco_view_ssm(ctx, SCI_SETCARETFORE, 0xFFFFFF, 0); + teco_view_ssm(ctx, SCI_SETCARETFORE, 0xC0C0C0, 0); teco_view_ssm(ctx, SCI_SETSELFORE, TRUE, 0x000000); teco_view_ssm(ctx, SCI_SETSELBACK, TRUE, 0xC0C0C0); @@ -132,7 +132,7 @@ teco_view_setup(teco_view_t *ctx) * default if no color-scheme is applied (and --no-profile). */ teco_view_ssm(ctx, SCI_STYLESETFORE, STYLE_CALLTIP, 0x000000); - teco_view_ssm(ctx, SCI_STYLESETBACK, STYLE_CALLTIP, 0xFFFFFF); + teco_view_ssm(ctx, SCI_STYLESETBACK, STYLE_CALLTIP, 0xC0C0C0); /* * Since we have patched out Scintilla's original SetRepresentations(), |
