diff --git a/README.asciidoc b/README.asciidoc index e5ca76cc..d090bcc2 100644 --- a/README.asciidoc +++ b/README.asciidoc @@ -946,6 +946,8 @@ Some options are built in Kakoune, and can be used to control it's behaviour: - `ncurses_assistant`: specify the nice assistant you get in info boxes, can be 'clippy' (the default), 'cat' or 'none' - `ncurses_enable_mouse`: boolean option that enables mouse support + - `ncurses_change_colors`: boolean option that can disable color palette + changing if the terminfo enables it but the terminal does not support it. - `ncurses_wheel_down_button` and `ncurses_wheel_up_button`: specify which button send for wheel down/up events. - `ncurses_buffer_padding_str`: string that will be used to mark the diff --git a/doc/manpages/options.asciidoc b/doc/manpages/options.asciidoc index 725e5728..e5a1909a 100644 --- a/doc/manpages/options.asciidoc +++ b/doc/manpages/options.asciidoc @@ -158,6 +158,10 @@ Builtin options *ncurses_enable_mouse*::: boolean option that enables mouse support + *ncurses_change_colors*::: + boolean option that can disable color palette changing if the + terminfo enables it but the terminal does not support it. + *ncurses_wheel_down_button*, *ncurses_wheel_up_button*::: specify which button send for wheel down/up events diff --git a/src/main.cc b/src/main.cc index cc27f953..88646230 100644 --- a/src/main.cc +++ b/src/main.cc @@ -272,10 +272,9 @@ void register_options() " ncurses_status_on_top bool\n" " ncurses_set_title bool\n" " ncurses_enable_mouse bool\n" + " ncurses_change_colors bool\n" " ncurses_wheel_up_button int\n" - " ncurses_wheel_down_button int\n" - " ncurses_buffer_padding_str str\n" - " ncurses_buffer_padding_type fill|single|off\n", + " ncurses_wheel_down_button int\n", UserInterface::Options{}); reg.declare_option("modelinefmt", "format string used to generate the modeline", "%val{bufname} %val{cursor_line}:%val{cursor_char_column} "_str); diff --git a/src/ncurses_ui.cc b/src/ncurses_ui.cc index 64f9a82a..1c57172d 100644 --- a/src/ncurses_ui.cc +++ b/src/ncurses_ui.cc @@ -133,7 +133,7 @@ int NCursesUI::get_color(Color color) auto it = m_colors.find(color); if (it != m_colors.end()) return it->second; - else if (can_change_color() and COLORS > 16) + else if (m_change_colors and can_change_color() and COLORS > 16) { kak_assert(color.color == Color::RGB); if (m_next_color > COLORS) @@ -168,26 +168,22 @@ int NCursesUI::get_color(Color color) int NCursesUI::get_color_pair(const Face& face) { - static int next_pair = 1; - ColorPair colors{face.fg, face.bg}; auto it = m_colorpairs.find(colors); if (it != m_colorpairs.end()) return it->second; else { - init_pair(next_pair, get_color(face.fg), get_color(face.bg)); - m_colorpairs[colors] = next_pair; - return next_pair++; + init_pair(m_next_pair, get_color(face.fg), get_color(face.bg)); + m_colorpairs[colors] = m_next_pair; + return m_next_pair++; } } void NCursesUI::set_face(NCursesWin* window, Face face, const Face& default_face) { - static int current_pair = -1; - - if (current_pair != -1) - wattroff(window, COLOR_PAIR(current_pair)); + if (m_active_pair != -1) + wattroff(window, COLOR_PAIR(m_active_pair)); if (face.fg == Color::Default) face.fg = default_face.fg; @@ -196,8 +192,8 @@ void NCursesUI::set_face(NCursesWin* window, Face face, const Face& default_face if (face.fg != Color::Default or face.bg != Color::Default) { - current_pair = get_color_pair(face); - wattron(window, COLOR_PAIR(current_pair)); + m_active_pair = get_color_pair(face); + wattron(window, COLOR_PAIR(m_active_pair)); } set_attribute(window, A_UNDERLINE, face.attributes & Attribute::Underline); @@ -218,6 +214,19 @@ void on_term_resize(int) EventManager::instance().force_signal(0); } +static constexpr std::initializer_list> +default_colors = { + { Color::Default, -1 }, + { Color::Black, COLOR_BLACK }, + { Color::Red, COLOR_RED }, + { Color::Green, COLOR_GREEN }, + { Color::Yellow, COLOR_YELLOW }, + { Color::Blue, COLOR_BLUE }, + { Color::Magenta, COLOR_MAGENTA }, + { Color::Cyan, COLOR_CYAN }, + { Color::White, COLOR_WHITE }, +}; + NCursesUI::NCursesUI() : m_stdin_watcher{0, FdEvents::Read, [this](FDWatcher&, FdEvents, EventMode mode) { @@ -228,17 +237,7 @@ NCursesUI::NCursesUI() m_on_key(*key); }}, m_assistant(assistant_clippy), - m_colors{ - { Color::Default, -1 }, - { Color::Black, COLOR_BLACK }, - { Color::Red, COLOR_RED }, - { Color::Green, COLOR_GREEN }, - { Color::Yellow, COLOR_YELLOW }, - { Color::Blue, COLOR_BLUE }, - { Color::Magenta, COLOR_MAGENTA }, - { Color::Cyan, COLOR_CYAN }, - { Color::White, COLOR_WHITE }, - } + m_colors{default_colors} { initscr(); raw(); @@ -1015,6 +1014,24 @@ void NCursesUI::set_ui_options(const Options& options) (it->value == "yes" or it->value == "true"); } + { + auto it = options.find("ncurses_change_colors"); + auto value = it == options.end() or + (it->value == "yes" or it->value == "true"); + + if (can_change_color() and m_change_colors != value) + { + fputs("\033]104;\007", stdout); // try to reset palette + fflush(stdout); + m_colorpairs.clear(); + m_colors = default_colors; + m_next_color = 16; + m_next_pair = 1; + m_active_pair = -1; + } + m_change_colors = value; + } + { auto enable_mouse_it = options.find("ncurses_enable_mouse"); enable_mouse(enable_mouse_it == options.end() or diff --git a/src/ncurses_ui.hh b/src/ncurses_ui.hh index bd330627..a25dbd64 100644 --- a/src/ncurses_ui.hh +++ b/src/ncurses_ui.hh @@ -80,6 +80,8 @@ private: UnorderedMap m_colors; UnorderedMap m_colorpairs; int m_next_color = 16; + int m_next_pair = 1; + int m_active_pair = -1; struct Window : Rect { @@ -130,6 +132,7 @@ private: int m_wheel_down_button = 5; bool m_set_title = true; + bool m_change_colors = true; bool m_dirty = false; };