From 7e66846172165eb1f860f26f51f7a20790b0af29 Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Sat, 16 Nov 2019 21:27:06 +1100 Subject: [PATCH] Rename NCursesUI to TerminalUI --- README.asciidoc | 2 - contrib/Tupfile | 8 +-- doc/coding-style.asciidoc | 2 +- doc/kak.1 | 2 +- doc/pages/changelog.asciidoc | 2 + doc/pages/options.asciidoc | 14 ++--- src/main.cc | 42 ++++++------- src/{ncurses_ui.cc => terminal_ui.cc} | 86 +++++++++++++-------------- src/{ncurses_ui.hh => terminal_ui.hh} | 16 ++--- 9 files changed, 84 insertions(+), 90 deletions(-) rename src/{ncurses_ui.cc => terminal_ui.cc} (94%) rename src/{ncurses_ui.hh => terminal_ui.hh} (92%) diff --git a/README.asciidoc b/README.asciidoc index 02739f77..3409d3e6 100644 --- a/README.asciidoc +++ b/README.asciidoc @@ -107,7 +107,6 @@ Kakoune dependencies are: * A {cpp}17 compliant compiler (GCC >= 7 or clang >= 6) along with its associated {cpp} standard library (libstdc{pp} or libc{pp}) - * ncurses with wide-characters support (>= 5.3, generally referred to as libncursesw) To build, just type *make* in the src directory. To generate man pages, type *make man* in the src directory. @@ -212,7 +211,6 @@ Building on Ubuntu 16.04 and 18.04. Make sure you have .local/bin in your path to make the kak binary available from your shell. ---------------------------------------------------------------- -sudo apt install libncursesw5-dev pkg-config git clone https://github.com/mawww/kakoune.git && cd kakoune/src make PREFIX=$HOME/.local make install diff --git a/contrib/Tupfile b/contrib/Tupfile index 9bed25ec..9b5b9e3e 100644 --- a/contrib/Tupfile +++ b/contrib/Tupfile @@ -37,17 +37,11 @@ ifeq ($(static),yes) LDFLAGS += -static -pthread endif -ifeq (@(TUP_PLATFORM),macosx) - LIBS += -lncurses - CPPFLAGS += -I/usr/local/opt/ncurses/include - LDFLAGS += -L/usr/local/opt/ncurses/lib -else +ifneq (@(TUP_PLATFORM),macosx) ifeq (@(TUP_PLATFORM),win32) LIBS += -lncursesw -ldbghelp CPPFLAGS += -D_XOPEN_SOURCE=700 else - LIBS += `pkg-config --libs ncursesw $(PKG_CONFIG_FLAGS)` - CPPFLAGS += `pkg-config --cflags ncursesw $(PKG_CONFIG_FLAGS)` LDFLAGS += -rdynamic endif endif diff --git a/doc/coding-style.asciidoc b/doc/coding-style.asciidoc index 250159df..3deb24df 100644 --- a/doc/coding-style.asciidoc +++ b/doc/coding-style.asciidoc @@ -3,7 +3,7 @@ C++ Coding Style Kakoune is written in C++14, here are the main coding style points: - * Avoid external dependencies besides posix/stdc++/ncurses + * Avoid external dependencies besides posix/stdc++ * 4 spaces for indentation, no tabs diff --git a/doc/kak.1 b/doc/kak.1 index dc81fe8b..be8b6ad7 100644 --- a/doc/kak.1 +++ b/doc/kak.1 @@ -123,7 +123,7 @@ Set the current session name to . .It Fl ui Ar type Select the user interface type, which can be -.Em ncurses , +.Em terminal , .Em dummy , or .Em json . diff --git a/doc/pages/changelog.asciidoc b/doc/pages/changelog.asciidoc index 9e824bf9..d9f6af2c 100644 --- a/doc/pages/changelog.asciidoc +++ b/doc/pages/changelog.asciidoc @@ -26,6 +26,8 @@ released versions. * Daemon mode (`-d` switch) does not fork anymore. +* Replace NCursesUI with a custom terminal UI implementation + == Kakoune 2020.08.04 * Introduce `User` hook support. diff --git a/doc/pages/options.asciidoc b/doc/pages/options.asciidoc index 7774fd5b..315bdc38 100644 --- a/doc/pages/options.asciidoc +++ b/doc/pages/options.asciidoc @@ -334,29 +334,29 @@ are exclusively available to built-in options. a list of `key=value` pairs that are forwarded to the user interface implementation. The NCurses UI support the following options: - *ncurses_set_title*::: + *terminal_set_title*::: if *yes* or *true*, the terminal emulator title will be changed - *ncurses_status_on_top*::: + *terminal_status_on_top*::: if *yes*, or *true* the status line will be placed at the top of the terminal rather than at the bottom - *ncurses_assistant*::: + *terminal_assistant*::: specify the nice assistant displayed in info boxes, can be *clippy* (the default), *cat*, *dilbert* or *none* - *ncurses_enable_mouse*::: + *terminal_enable_mouse*::: boolean option that enables mouse support - *ncurses_change_colors*::: + *terminal_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*::: + *terminal_wheel_down_button*, *terminal_wheel_up_button*::: specify which button send for wheel down/up events - *ncurses_shift_function_key*::: + *terminal_shift_function_key*::: Function key from which shifted function key start, if the terminal sends F13 for , this should be set to 12. diff --git a/src/main.cc b/src/main.cc index ad4088d6..d04a85a6 100644 --- a/src/main.cc +++ b/src/main.cc @@ -13,7 +13,7 @@ #include "highlighters.hh" #include "insert_completer.hh" #include "json_ui.hh" -#include "ncurses_ui.hh" +#include "terminal_ui.hh" #include "option_types.hh" #include "parameters_parser.hh" #include "ranges.hh" @@ -538,17 +538,17 @@ void register_options() "space separated list of = options that are " "passed to and interpreted by the user interface\n" "\n" - "The ncurses ui supports the following options:\n" + "The terminal ui supports the following options:\n" " : :\n" - " ncurses_assistant clippy|cat|dilbert|none|off\n" - " 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_wheel_scroll_amount int\n" - " ncurses_shift_function_key int\n", + " terminal_assistant clippy|cat|dilbert|none|off\n" + " terminal_status_on_top bool\n" + " terminal_set_title bool\n" + " terminal_enable_mouse bool\n" + " terminal_change_colors bool\n" + " terminal_wheel_up_button int\n" + " terminal_wheel_down_button int\n" + " terminal_wheel_scroll_amount int\n" + " terminal_shift_function_key int\n", UserInterface::Options{}); reg.declare_option("modelinefmt", "format string used to generate the modeline", "%val{bufname} %val{cursor_line}:%val{cursor_char_column} {{context_info}} {{mode_info}} - %val{client}@[%val{session}]"_str); @@ -572,14 +572,14 @@ static bool convert_to_client_pending = false; enum class UIType { - NCurses, + Terminal, Json, Dummy, }; UIType parse_ui_type(StringView ui_name) { - if (ui_name == "ncurses") return UIType::NCurses; + if (ui_name == "terminal") return UIType::Terminal; if (ui_name == "json") return UIType::Json; if (ui_name == "dummy") return UIType::Dummy; @@ -611,7 +611,7 @@ std::unique_ptr make_ui(UIType ui_type) switch (ui_type) { - case UIType::NCurses: return std::make_unique(); + case UIType::Terminal: return std::make_unique(); case UIType::Json: return std::make_unique(); case UIType::Dummy: return std::make_unique(); } @@ -634,17 +634,17 @@ pid_t fork_server_to_background() std::unique_ptr create_local_ui(UIType ui_type) { - if (ui_type != UIType::NCurses) + if (ui_type != UIType::Terminal) return make_ui(ui_type); - struct LocalUI : NCursesUI + struct LocalUI : TerminalUI { LocalUI() { set_signal_handler(SIGTSTP, [](int) { if (ClientManager::instance().count() == 1 and *ClientManager::instance().begin() == local_client) - NCursesUI::instance().suspend(); + TerminalUI::instance().suspend(); else convert_to_client_pending = true; }); @@ -659,7 +659,7 @@ std::unique_ptr create_local_ui(UIType ui_type) if (fork_server_to_background()) { - this->NCursesUI::~NCursesUI(); + this->TerminalUI::~TerminalUI(); exit(local_client_exit); } } @@ -1000,7 +1000,7 @@ int run_pipe(StringView session) void signal_handler(int signal) { - NCursesUI::restore_terminal(); + TerminalUI::restore_terminal(); const char* text = nullptr; switch (signal) { @@ -1057,7 +1057,7 @@ int main(int argc, char* argv[]) { "f", { true, "filter: for each file, select the entire buffer and execute the given keys" } }, { "i", { true, "backup the files on which a filter is applied using the given suffix" } }, { "q", { false, "in filter mode, be quiet about errors applying keys" } }, - { "ui", { true, "set the type of user interface to use (ncurses, dummy, or json)" } }, + { "ui", { true, "set the type of user interface to use (terminal, dummy, or json)" } }, { "l", { false, "list existing sessions" } }, { "clear", { false, "clear dead sessions" } }, { "debug", { true, "initial debug option value" } }, @@ -1129,7 +1129,7 @@ int main(int argc, char* argv[]) auto client_init = parser.get_switch("e").value_or(StringView{}); auto server_init = parser.get_switch("E").value_or(StringView{}); - const UIType ui_type = parse_ui_type(parser.get_switch("ui").value_or("ncurses")); + const UIType ui_type = parse_ui_type(parser.get_switch("ui").value_or("terminal")); if (auto keys = parser.get_switch("f")) { diff --git a/src/ncurses_ui.cc b/src/terminal_ui.cc similarity index 94% rename from src/ncurses_ui.cc rename to src/terminal_ui.cc index 8fc6d614..9ebf7023 100644 --- a/src/ncurses_ui.cc +++ b/src/terminal_ui.cc @@ -1,4 +1,4 @@ -#include "ncurses_ui.hh" +#include "terminal_ui.hh" #include "display_buffer.hh" #include "event_manager.hh" @@ -29,21 +29,21 @@ static void set_cursor_pos(DisplayCoord coord) printf("\033[%d;%dH", (int)coord.line + 1, (int)coord.column + 1); } -void NCursesUI::Window::create(const DisplayCoord& p, const DisplayCoord& s) +void TerminalUI::Window::create(const DisplayCoord& p, const DisplayCoord& s) { pos = p; size = s; lines.resize((int)size.line); } -void NCursesUI::Window::destroy() +void TerminalUI::Window::destroy() { pos = DisplayCoord{}; size = DisplayCoord{}; lines.clear(); } -void NCursesUI::Window::refresh(bool force) +void TerminalUI::Window::refresh(bool force) { if (lines.empty()) return; @@ -83,12 +83,12 @@ void NCursesUI::Window::refresh(bool force) } } -void NCursesUI::Window::move_cursor(DisplayCoord coord) +void TerminalUI::Window::move_cursor(DisplayCoord coord) { cursor = coord; } -void NCursesUI::Window::clear_line() +void TerminalUI::Window::clear_line() { auto& line = lines[(int)cursor.line]; auto it = line.begin(); @@ -105,7 +105,7 @@ void NCursesUI::Window::clear_line() } } -void NCursesUI::Window::draw(ConstArrayView atoms, +void TerminalUI::Window::draw(ConstArrayView atoms, const Face& default_face) { clear_line(); @@ -130,7 +130,7 @@ void NCursesUI::Window::draw(ConstArrayView atoms, lines[(int)cursor.line].push_back({String(' ', size.column - cursor.column), default_face}); } -constexpr int NCursesUI::default_shift_function_key; +constexpr int TerminalUI::default_shift_function_key; static constexpr StringView assistant_cat[] = { R"( ___ )", @@ -179,7 +179,7 @@ static void signal_handler(int) EventManager::instance().force_signal(0); } -NCursesUI::NCursesUI() +TerminalUI::TerminalUI() : m_cursor{CursorMode::Buffer, {}}, m_stdin_watcher{STDIN_FILENO, FdEvents::Read, EventMode::Urgent, [this](FDWatcher&, FdEvents, EventMode) { @@ -207,13 +207,13 @@ NCursesUI::NCursesUI() set_signal_handler(SIGWINCH, &signal_handler<&resize_pending>); set_signal_handler(SIGHUP, &signal_handler<&stdin_closed>); - set_signal_handler(SIGTSTP, [](int){ NCursesUI::instance().suspend(); }); + set_signal_handler(SIGTSTP, [](int){ TerminalUI::instance().suspend(); }); check_resize(true); redraw(false); } -NCursesUI::~NCursesUI() +TerminalUI::~TerminalUI() { enable_mouse(false); restore_terminal(); @@ -223,7 +223,7 @@ NCursesUI::~NCursesUI() set_signal_handler(SIGTSTP, SIG_DFL); } -void NCursesUI::suspend() +void TerminalUI::suspend() { bool mouse_enabled = m_mouse_enabled; enable_mouse(false); @@ -249,7 +249,7 @@ void NCursesUI::suspend() refresh(true); } -void NCursesUI::set_raw_mode() const +void TerminalUI::set_raw_mode() const { termios attr = m_original_termios; attr.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON); @@ -263,7 +263,7 @@ void NCursesUI::set_raw_mode() const tcsetattr(STDIN_FILENO, TCSANOW, &attr); } -void NCursesUI::redraw(bool force) +void TerminalUI::redraw(bool force) { m_window.refresh(force); @@ -280,12 +280,12 @@ void NCursesUI::redraw(bool force) fflush(stdout); } -void NCursesUI::set_cursor(CursorMode mode, DisplayCoord coord) +void TerminalUI::set_cursor(CursorMode mode, DisplayCoord coord) { m_cursor = Cursor{mode, coord}; } -void NCursesUI::refresh(bool force) +void TerminalUI::refresh(bool force) { if (m_dirty or force) redraw(force); @@ -294,7 +294,7 @@ void NCursesUI::refresh(bool force) static const DisplayLine empty_line = { String(" "), {} }; -void NCursesUI::draw(const DisplayBuffer& display_buffer, +void TerminalUI::draw(const DisplayBuffer& display_buffer, const Face& default_face, const Face& padding_face) { @@ -322,7 +322,7 @@ void NCursesUI::draw(const DisplayBuffer& display_buffer, m_dirty = true; } -void NCursesUI::draw_status(const DisplayLine& status_line, +void TerminalUI::draw_status(const DisplayLine& status_line, const DisplayLine& mode_line, const Face& default_face) { @@ -375,7 +375,7 @@ void NCursesUI::draw_status(const DisplayLine& status_line, m_dirty = true; } -void NCursesUI::check_resize(bool force) +void TerminalUI::check_resize(bool force) { if (not force and not resize_pending) return; @@ -414,7 +414,7 @@ void NCursesUI::check_resize(bool force) set_resize_pending(); } -Optional NCursesUI::get_next_key() +Optional TerminalUI::get_next_key() { if (stdin_closed) { @@ -700,7 +700,7 @@ T div_round_up(T a, T b) return (a - T(1)) / b + T(1); } -void NCursesUI::draw_menu() +void TerminalUI::draw_menu() { // menu show may have not created the window if it did not fit. // so be tolerant. @@ -784,7 +784,7 @@ static LineCount height_limit(MenuStyle style) return 0_line; } -void NCursesUI::menu_show(ConstArrayView items, +void TerminalUI::menu_show(ConstArrayView items, DisplayCoord anchor, Face fg, Face bg, MenuStyle style) { @@ -856,7 +856,7 @@ void NCursesUI::menu_show(ConstArrayView items, m_info.anchor, m_info.face, m_info.style); } -void NCursesUI::menu_select(int selected) +void TerminalUI::menu_select(int selected) { const int item_count = m_menu.items.size(); if (selected < 0 or selected >= item_count) @@ -897,7 +897,7 @@ void NCursesUI::menu_select(int selected) draw_menu(); } -void NCursesUI::menu_hide() +void TerminalUI::menu_hide() { if (not m_menu) return; @@ -912,7 +912,7 @@ void NCursesUI::menu_hide() } static DisplayCoord compute_pos(DisplayCoord anchor, DisplayCoord size, - NCursesUI::Rect rect, NCursesUI::Rect to_avoid, + TerminalUI::Rect rect, TerminalUI::Rect to_avoid, bool prefer_above) { DisplayCoord pos; @@ -984,7 +984,7 @@ static DisplayLineList wrap_lines(const DisplayLineList& lines, ColumnCount max_ return result; } -void NCursesUI::info_show(const DisplayLine& title, const DisplayLineList& content, +void TerminalUI::info_show(const DisplayLine& title, const DisplayLineList& content, DisplayCoord anchor, Face face, InfoStyle style) { info_hide(); @@ -1112,7 +1112,7 @@ void NCursesUI::info_show(const DisplayLine& title, const DisplayLineList& conte m_dirty = true; } -void NCursesUI::info_hide() +void TerminalUI::info_hide() { if (not m_info) return; @@ -1120,29 +1120,29 @@ void NCursesUI::info_hide() m_dirty = true; } -void NCursesUI::set_on_key(OnKeyCallback callback) +void TerminalUI::set_on_key(OnKeyCallback callback) { m_on_key = std::move(callback); EventManager::instance().force_signal(0); } -DisplayCoord NCursesUI::dimensions() +DisplayCoord TerminalUI::dimensions() { return m_dimensions; } -LineCount NCursesUI::content_line_offset() const +LineCount TerminalUI::content_line_offset() const { return m_status_on_top ? 1 : 0; } -void NCursesUI::set_resize_pending() +void TerminalUI::set_resize_pending() { m_resize_pending = true; EventManager::instance().force_signal(0); } -void NCursesUI::setup_terminal() +void TerminalUI::setup_terminal() { // enable alternative screen buffer fputs("\033[?1049h", stdout); @@ -1159,7 +1159,7 @@ void NCursesUI::setup_terminal() fflush(stdout); } -void NCursesUI::restore_terminal() +void TerminalUI::restore_terminal() { fputs("\033>", stdout); fputs("\033[?25h", stdout); @@ -1173,7 +1173,7 @@ void NCursesUI::restore_terminal() fflush(stdout); } -void NCursesUI::enable_mouse(bool enabled) +void TerminalUI::enable_mouse(bool enabled) { if (enabled == m_mouse_enabled) return; @@ -1197,10 +1197,10 @@ void NCursesUI::enable_mouse(bool enabled) fflush(stdout); } -void NCursesUI::set_ui_options(const Options& options) +void TerminalUI::set_ui_options(const Options& options) { { - auto it = options.find("ncurses_assistant"_sv); + auto it = options.find("terminal_assistant"_sv); if (it == options.end() or it->value == "clippy") m_assistant = assistant_clippy; else if (it->value == "cat") @@ -1212,39 +1212,39 @@ void NCursesUI::set_ui_options(const Options& options) } { - auto it = options.find("ncurses_status_on_top"_sv); + auto it = options.find("terminal_status_on_top"_sv); m_status_on_top = it != options.end() and (it->value == "yes" or it->value == "true"); } { - auto it = options.find("ncurses_set_title"_sv); + auto it = options.find("terminal_set_title"_sv); m_set_title = it == options.end() or (it->value == "yes" or it->value == "true"); } { - auto it = options.find("ncurses_shift_function_key"_sv); + auto it = options.find("terminal_shift_function_key"_sv); m_shift_function_key = it != options.end() ? str_to_int_ifp(it->value).value_or(default_shift_function_key) : default_shift_function_key; } { - auto enable_mouse_it = options.find("ncurses_enable_mouse"_sv); + auto enable_mouse_it = options.find("terminal_enable_mouse"_sv); enable_mouse(enable_mouse_it == options.end() or enable_mouse_it->value == "yes" or enable_mouse_it->value == "true"); - auto wheel_up_it = options.find("ncurses_wheel_up_button"_sv); + auto wheel_up_it = options.find("terminal_wheel_up_button"_sv); m_wheel_up_button = wheel_up_it != options.end() ? str_to_int_ifp(wheel_up_it->value).value_or(4) : 4; - auto wheel_down_it = options.find("ncurses_wheel_down_button"_sv); + auto wheel_down_it = options.find("terminal_wheel_down_button"_sv); m_wheel_down_button = wheel_down_it != options.end() ? str_to_int_ifp(wheel_down_it->value).value_or(5) : 5; - auto wheel_scroll_amount_it = options.find("ncurses_wheel_scroll_amount"_sv); + auto wheel_scroll_amount_it = options.find("terminal_wheel_scroll_amount"_sv); m_wheel_scroll_amount = wheel_scroll_amount_it != options.end() ? str_to_int_ifp(wheel_scroll_amount_it->value).value_or(3) : 3; } diff --git a/src/ncurses_ui.hh b/src/terminal_ui.hh similarity index 92% rename from src/ncurses_ui.hh rename to src/terminal_ui.hh index 0a7cef7c..bf332ba4 100644 --- a/src/ncurses_ui.hh +++ b/src/terminal_ui.hh @@ -1,5 +1,5 @@ -#ifndef ncurses_hh_INCLUDED -#define ncurses_hh_INCLUDED +#ifndef terminal_hh_INCLUDED +#define terminal_hh_INCLUDED #include "array_view.hh" #include "coord.hh" @@ -18,14 +18,14 @@ namespace Kakoune struct DisplayAtom; -class NCursesUI : public UserInterface, public Singleton +class TerminalUI : public UserInterface, public Singleton { public: - NCursesUI(); - ~NCursesUI() override; + TerminalUI(); + ~TerminalUI() override; - NCursesUI(const NCursesUI&) = delete; - NCursesUI& operator=(const NCursesUI&) = delete; + TerminalUI(const TerminalUI&) = delete; + TerminalUI& operator=(const TerminalUI&) = delete; bool is_ok() const override { return (bool)m_window; } @@ -164,4 +164,4 @@ private: } -#endif // ncurses_hh_INCLUDED +#endif // terminal_hh_INCLUDED