diff --git a/hanoi.tlv b/hanoi.tlv index 49ca232..a7a1e68 100644 --- a/hanoi.tlv +++ b/hanoi.tlv @@ -85,10 +85,11 @@ end]==], original]==], main = [==[ function main() + curses.assume_default_colors(250, 30) for i=1,7 do curses.init_pair(i, 0, i) end - curses.init_pair(15, 0, 15) + curses.init_pair(15, 0, 250) -- tower frames curses.init_pair(255, 15, 1) -- reserved for Teliva error messages while true do diff --git a/life.tlv b/life.tlv index 4c948c7..ba4f1e7 100644 --- a/life.tlv +++ b/life.tlv @@ -116,11 +116,13 @@ original]==], render = [==[ function render(window) window:clear() + curses.attron(curses.color_pair(1)) for line=1,lines do for col=1,cols do window:addstr(utf8(glyph[grid_char_to_glyph_index(grid_char(line, col))])) end end + curses.attroff(curses.color_pair(1)) curses.refresh() end ]==], @@ -263,10 +265,8 @@ end]==], original]==], main = [==[ function main() - for i=1,7 do - curses.init_pair(i, i, -1) - end curses.init_pair(255, 15, 1) -- reserved for Teliva error messages + curses.init_pair(1, 22, 189) -- initialize grid based on commandline args if (#arg == 0) then diff --git a/src/Makefile b/src/Makefile index 720a35e..65580bb 100644 --- a/src/Makefile +++ b/src/Makefile @@ -172,7 +172,7 @@ ltable.o: ltable.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \ ltablib.o: ltablib.c lua.h luaconf.h lauxlib.h lualib.h ltm.o: ltm.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h lzio.h \ lmem.h lstring.h lgc.h ltable.h -lua.o: lua.c lua.h luaconf.h lauxlib.h lualib.h +lua.o: lua.c lua.h luaconf.h lauxlib.h lualib.h teliva.h lundump.o: lundump.c lua.h luaconf.h ldebug.h lstate.h lobject.h \ llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lstring.h lgc.h lundump.h lvm.o: lvm.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \ @@ -181,5 +181,6 @@ lzio.o: lzio.c lua.h luaconf.h llimits.h lmem.h lstate.h lobject.h ltm.h \ lzio.h print.o: print.c ldebug.h lstate.h lua.h luaconf.h lobject.h llimits.h \ ltm.h lzio.h lmem.h lopcodes.h lundump.h +kilo.o: kilo.c teliva.h # (end of Makefile) diff --git a/src/kilo.c b/src/kilo.c index df7359a..a1a36e8 100644 --- a/src/kilo.c +++ b/src/kilo.c @@ -129,7 +129,7 @@ char *Lua_HL_keywords[] = { "and", "or", "not", "in", /* types */ - "nil", "false", "true", + "nil|", "false|", "true|", NULL }; @@ -306,16 +306,16 @@ static void editorUpdateSyntax(erow *row) { } /* Maps syntax highlight token types to terminal colors. */ -static int editorSyntaxToColor(int hl) { +static int editorSyntaxToColorPair(int hl) { switch(hl) { case HL_COMMENT: - case HL_MLCOMMENT: return 6; /* cyan */ - case HL_KEYWORD1: return 3; /* yellow */ - case HL_KEYWORD2: return 2; /* green */ - case HL_STRING: return 5; /* magenta */ - case HL_NUMBER: return 1; /* red */ - case HL_MATCH: return 4; /* blue */ - default: return 7; /* white */ + case HL_MLCOMMENT: return COLOR_PAIR_LUA_COMMENT; + case HL_KEYWORD1: return COLOR_PAIR_LUA_KEYWORD; + case HL_KEYWORD2: return COLOR_PAIR_LUA_CONSTANT; + case HL_STRING: return COLOR_PAIR_LUA_CONSTANT; + case HL_NUMBER: return COLOR_PAIR_LUA_CONSTANT; + case HL_MATCH: return COLOR_PAIR_MATCH; + default: return COLOR_PAIR_NORMAL; } } @@ -760,7 +760,7 @@ static void editorRefreshScreen(void (*menu_func)(void)) { } addch(c[j]); } else { - int color = editorSyntaxToColor(hl[j]); + int color = editorSyntaxToColorPair(hl[j]); if (color != current_color) { attrset(COLOR_PAIR(color)); current_color = color; diff --git a/src/lcurses/curses.c b/src/lcurses/curses.c index f6b425d..2c53022 100644 --- a/src/lcurses/curses.c +++ b/src/lcurses/curses.c @@ -366,6 +366,22 @@ Puse_default_colors(lua_State *L) } +/*** +Set -1 foreground and background colors. +@function use_default_colors +@treturn bool `true`, if successful +@see use_default_colors(3x) +@fixme ncurses only? +*/ +static int +Passume_default_colors(lua_State *L) +{ + int fg = checkint(L, 1); + int bg = checkint(L, 2); + return pushokresult(assume_default_colors(fg, bg)); +} + + /*** Associate a color pair id with a specific foreground and background color. @function init_pair @@ -1289,6 +1305,7 @@ static const luaL_Reg curseslib[] = LCURSES_FUNC( Punctrl ), LCURSES_FUNC( Pungetch ), LCURSES_FUNC( Puse_default_colors), + LCURSES_FUNC( Passume_default_colors), {NULL, NULL} }; diff --git a/src/lua.c b/src/lua.c index afceafd..9707712 100644 --- a/src/lua.c +++ b/src/lua.c @@ -27,10 +27,6 @@ #include "lualib.h" -#define BG(i) (COLOR_PAIR((i)+8)) -#define FG(i) (COLOR_PAIR(i)) - - static lua_State *globalL = NULL; static const char *progname = LUA_PROGNAME; @@ -503,7 +499,7 @@ static int render_wrapped_lua_text (int y, int xmin, int xmax, const char *text) for (int j = 0; j < strlen(text); ++j) { char c = text[j]; if (c == '-' && j+1 < strlen(text) && text[j+1] == '-') - attron(FG(6)); + attron(COLOR_PAIR(COLOR_PAIR_LUA_COMMENT)); if (c != '\n') { addch(text[j]); ++x; @@ -518,7 +514,7 @@ static int render_wrapped_lua_text (int y, int xmin, int xmax, const char *text) ++y; x = xmin; move(y, x); - attroff(FG(6)); + attroff(COLOR_PAIR(COLOR_PAIR_LUA_COMMENT)); } } return y; @@ -553,16 +549,16 @@ void render_recent_changes (lua_State *L, int history_array, int start_index, in /* save timestamp of binding if available */ lua_getfield(L, t, "__teliva_timestamp"); if (!lua_isnil(L, -1)) { - attron(FG(7)); + attron(COLOR_PAIR(COLOR_PAIR_FADE)); printw(" %s", lua_tostring(L, -1)); - attroff(FG(7)); + attroff(COLOR_PAIR(COLOR_PAIR_FADE)); } lua_pop(L, 1); lua_getfield(L, t, "__teliva_note"); if (!lua_isnil(L, -1)) { - attron(FG(6)); + attron(COLOR_PAIR(COLOR_PAIR_FADE)); printw(" -- %s", lua_tostring(L, -1)); - attroff(FG(6)); + attroff(COLOR_PAIR(COLOR_PAIR_FADE)); } lua_pop(L, 1); y++; @@ -724,9 +720,11 @@ static int is_current_definition(lua_State *L, const char *definition_name, int void draw_definition_name (const char *definition_name) { - attron(BG(7)); + attron(COLOR_PAIR(COLOR_PAIR_HIGHLIGHT)); + addstr(" "); addstr(definition_name); - attroff(BG(7)); + addstr(" "); + attroff(COLOR_PAIR(COLOR_PAIR_HIGHLIGHT)); addstr(" "); } @@ -928,11 +926,15 @@ char **Argv = NULL; extern void cleanup_curses (void); void developer_mode (lua_State *L) { /* clobber the app's ncurses colors; we'll restart the app when we rerun it. */ - for (int i = 0; i < 8; ++i) - init_pair(i, i, 7); - for (int i = 0; i < 8; ++i) - init_pair(i+8, 0, i); - init_pair(255, /*white fg*/ 15, /*red bg*/ 1); /* for teliva error messages */ + assume_default_colors(COLOR_FOREGROUND, COLOR_BACKGROUND); + init_pair(COLOR_PAIR_NORMAL, COLOR_FOREGROUND, COLOR_BACKGROUND); + init_pair(COLOR_PAIR_HIGHLIGHT, COLOR_HIGHLIGHT_FOREGROUND, COLOR_HIGHLIGHT_BACKGROUND); + init_pair(COLOR_PAIR_FADE, COLOR_FADE, COLOR_BACKGROUND); + init_pair(COLOR_PAIR_LUA_COMMENT, COLOR_LUA_COMMENT, COLOR_BACKGROUND); + init_pair(COLOR_PAIR_LUA_KEYWORD, COLOR_LUA_KEYWORD, COLOR_BACKGROUND); + init_pair(COLOR_PAIR_LUA_CONSTANT, COLOR_LUA_CONSTANT, COLOR_BACKGROUND); + init_pair(COLOR_PAIR_MATCH, COLOR_MATCH_FOREGROUND, COLOR_MATCH_BACKGROUND); + init_pair(COLOR_PAIR_ERROR, COLOR_ERROR_FOREGROUND, COLOR_ERROR_BACKGROUND); nodelay(stdscr, 0); /* make getch() block */ int switch_to_big_picture_view = 1; if (editor_view_in_progress(L)) @@ -1034,7 +1036,7 @@ int main (int argc, char **argv) { initscr(); keypad(stdscr, 1); start_color(); - assume_default_colors(0, 7); + assume_default_colors(COLOR_FOREGROUND, COLOR_BACKGROUND); draw_menu(L); echo(); s.argc = argc; diff --git a/src/teliva.h b/src/teliva.h index 772f17a..764a0b1 100644 --- a/src/teliva.h +++ b/src/teliva.h @@ -1,6 +1,8 @@ #ifndef __TELIVA_H__ #define __TELIVA_H__ +// Some names for hotkeys beyond those provided by ncurses. + enum KEY_ACTION { KEY_NULL = 0, CTRL_A = 1, @@ -25,4 +27,88 @@ enum KEY_ACTION { DELETE = 127, }; + +// Colors (experimental) +// Primary goal here: Keep text readable regardless of OS, terminal emulator +// and color scheme. Unfortunately I don't yet have a good answer, so this +// approach may yet change. Current approach: +// - Hardcode colors so that we can be sure we use legible combinations of +// foreground and background. +// - Use only the terminal palette in the range 16-255. +// - Not all terminals may support more than 256 colors. (I'm not yet sure +// everyone has even 256 colors. If you don't, please let me know: +// http://akkartik.name/contact) +// - Many terminals provide color schemes which give the ability to tweak +// colors 0-15. This makes it hard to assume specific combinations are +// legible. I'm hoping most terminal emulators don't tend to encourage +// messing with colors 16-255. (Please let me know if you know of +// counter-examples.) +// +// For now, you have to edit these values if you want to adjust colors in the +// editing environment. Check out https://www.robmeerman.co.uk/unix/256colours +// for a map of available colors. + +// Toggle between a few color schemes +#define COLOR_SCHEME 0 +#if COLOR_SCHEME == 0 +// Light color scheme. +enum color { + COLOR_FOREGROUND = 238, // almost black + COLOR_BACKGROUND = 253, // almost white + COLOR_FADE = 244, // closer to background + COLOR_HIGHLIGHT_FOREGROUND = 238, + COLOR_HIGHLIGHT_BACKGROUND = 250, + COLOR_ERROR_FOREGROUND = COLOR_BACKGROUND, + COLOR_ERROR_BACKGROUND = 124, // deep red + COLOR_LUA_COMMENT = 27, // blue + COLOR_LUA_KEYWORD = 172, // orange + COLOR_LUA_CONSTANT = 31, // cyan + COLOR_MATCH_FOREGROUND = COLOR_BACKGROUND, + COLOR_MATCH_BACKGROUND = 28, // green +}; +#elif COLOR_SCHEME == 1 +// Dark color scheme. +enum color { + COLOR_FOREGROUND = 253, // almost white + COLOR_BACKGROUND = 238, // almost black + COLOR_FADE = 244, // closer to background + COLOR_HIGHLIGHT_FOREGROUND = 238, + COLOR_HIGHLIGHT_BACKGROUND = 250, + COLOR_ERROR_FOREGROUND = COLOR_BACKGROUND, + COLOR_ERROR_BACKGROUND = 124, // deep red + COLOR_LUA_COMMENT = 39, // blue + COLOR_LUA_KEYWORD = 172, // orange + COLOR_LUA_CONSTANT = 37, // cyan + COLOR_MATCH_FOREGROUND = COLOR_BACKGROUND, + COLOR_MATCH_BACKGROUND = 28, // green +}; +#elif COLOR_SCHEME == 2 +// Solarized dark. +enum color { + COLOR_FOREGROUND = 250, // almost white + COLOR_BACKGROUND = 24, // dark blue-green + COLOR_FADE = 246, // closer to background + COLOR_HIGHLIGHT_FOREGROUND = 238, + COLOR_HIGHLIGHT_BACKGROUND = 31, + COLOR_ERROR_FOREGROUND = 250, + COLOR_ERROR_BACKGROUND = 124, // deep red + COLOR_LUA_COMMENT = 45, // light blue + COLOR_LUA_KEYWORD = 172, // orange + COLOR_LUA_CONSTANT = 37, // cyan + COLOR_MATCH_FOREGROUND = COLOR_FOREGROUND, + COLOR_MATCH_BACKGROUND = 125, // magenta +}; +#endif + +enum color_pair { + COLOR_PAIR_NORMAL = 0, + COLOR_PAIR_HIGHLIGHT = 1, + COLOR_PAIR_FADE = 2, + COLOR_PAIR_LUA_COMMENT = 3, + COLOR_PAIR_LUA_KEYWORD = 4, + COLOR_PAIR_LUA_CONSTANT = 5, + COLOR_PAIR_MATCH = 6, + COLOR_PAIR_ERROR = 255, +}; + #endif