Remove direct access to ui, go through client

Client can now update menu/info positions when the window move
around.
This commit is contained in:
Maxime Coste 2016-02-27 17:23:13 +00:00
parent f0edf40543
commit 3987463e75
12 changed files with 174 additions and 108 deletions

View File

@ -4,12 +4,12 @@
#include "context.hh" #include "context.hh"
#include "buffer_manager.hh" #include "buffer_manager.hh"
#include "buffer_utils.hh" #include "buffer_utils.hh"
#include "user_interface.hh"
#include "file.hh" #include "file.hh"
#include "remote.hh" #include "remote.hh"
#include "client_manager.hh" #include "client_manager.hh"
#include "command_manager.hh" #include "command_manager.hh"
#include "event_manager.hh" #include "event_manager.hh"
#include "user_interface.hh"
#include "window.hh" #include "window.hh"
#include <signal.h> #include <signal.h>
@ -31,8 +31,11 @@ Client::Client(std::unique_ptr<UserInterface>&& ui,
context().set_client(*this); context().set_client(*this);
context().set_window(*m_window); context().set_window(*m_window);
m_window->set_dimensions(m_ui->dimensions());
m_window->options().register_watcher(*this); m_window->options().register_watcher(*this);
m_ui->set_ui_options(m_window->options()["ui_options"].get<UserInterface::Options>()); m_ui->set_ui_options(m_window->options()["ui_options"].get<UserInterface::Options>());
m_ui->set_input_callback([this](EventMode mode) { handle_available_input(mode); });
} }
Client::~Client() Client::~Client()
@ -154,19 +157,43 @@ void Client::change_buffer(Buffer& buffer)
context().selections_write_only() = std::move(ws.selections); context().selections_write_only() = std::move(ws.selections);
context().set_window(*m_window); context().set_window(*m_window);
m_window->set_dimensions(ui().dimensions()); m_window->set_dimensions(m_ui->dimensions());
m_window->hooks().run_hook("WinDisplay", buffer.name(), context()); m_window->hooks().run_hook("WinDisplay", buffer.name(), context());
} }
static bool is_inline(InfoStyle style)
{
return style == InfoStyle::Inline or
style == InfoStyle::InlineAbove or
style == InfoStyle::InlineBelow;
}
void Client::redraw_ifn() void Client::redraw_ifn()
{ {
Window& window = context().window(); Window& window = context().window();
UserInterface& ui = context().ui();
const bool needs_redraw = window.needs_redraw(context()); const bool needs_redraw = window.needs_redraw(context());
if (needs_redraw) if (needs_redraw)
ui.draw(window.update_display_buffer(context()), get_face("Default")); {
auto window_pos = window.position();
m_ui->draw(window.update_display_buffer(context()), get_face("Default"));
// window moved, reanchor eventual menu and info
if (window_pos != window.position())
{
if (not m_menu.items.empty() and m_menu.style == MenuStyle::Inline)
{
m_ui->menu_show(m_menu.items, window.display_position(m_menu.anchor),
get_face("MenuForeground"), get_face("MenuBackground"), m_menu.style);
m_ui->menu_select(m_menu.selected);
}
if (not m_info.content.empty() and is_inline(m_info.style))
m_ui->info_show(m_info.title, m_info.content,
window.display_position(m_info.anchor),
get_face("Information"), m_info.style);
}
}
DisplayLine mode_line = generate_mode_line(); DisplayLine mode_line = generate_mode_line();
if (needs_redraw or if (needs_redraw or
@ -176,10 +203,10 @@ void Client::redraw_ifn()
m_mode_line = std::move(mode_line); m_mode_line = std::move(mode_line);
m_status_line = m_pending_status_line; m_status_line = m_pending_status_line;
ui.draw_status(m_status_line, m_mode_line, get_face("StatusLine")); m_ui->draw_status(m_status_line, m_mode_line, get_face("StatusLine"));
} }
ui.refresh(); m_ui->refresh();
} }
void Client::force_redraw() void Client::force_redraw()
@ -277,4 +304,36 @@ void Client::on_option_changed(const Option& option)
m_ui->set_ui_options(option.get<UserInterface::Options>()); m_ui->set_ui_options(option.get<UserInterface::Options>());
} }
void Client::menu_show(Vector<DisplayLine> choices, ByteCoord anchor, MenuStyle style)
{
m_menu = Menu{ std::move(choices), anchor, style, -1 };
CharCoord ui_anchor = style == MenuStyle::Inline ? context().window().display_position(anchor) : CharCoord{};
m_ui->menu_show(m_menu.items, ui_anchor, get_face("MenuForeground"), get_face("MenuBackground"), style);
}
void Client::menu_select(int selected)
{
m_menu.selected = selected;
m_ui->menu_select(selected);
}
void Client::menu_hide()
{
m_menu = Menu{};
m_ui->menu_hide();
}
void Client::info_show(String title, String content, ByteCoord anchor, InfoStyle style)
{
m_info = Info{ std::move(title), std::move(content), anchor, style };
CharCoord ui_anchor = is_inline(style) ? context().window().display_position(anchor) : CharCoord{};
m_ui->info_show(m_info.title, m_info.content, ui_anchor, get_face("Information"), style);
}
void Client::info_hide()
{
m_info = Info{};
m_ui->info_hide();
}
} }

View File

@ -8,11 +8,11 @@
#include "utils.hh" #include "utils.hh"
#include "option_manager.hh" #include "option_manager.hh"
#include "enum.hh" #include "enum.hh"
#include "user_interface.hh"
namespace Kakoune namespace Kakoune
{ {
class UserInterface;
class Window; class Window;
class String; class String;
struct Key; struct Key;
@ -34,13 +34,20 @@ public:
// handle all the keys currently available in the user interface // handle all the keys currently available in the user interface
void handle_available_input(EventMode mode); void handle_available_input(EventMode mode);
void menu_show(Vector<DisplayLine> choices, ByteCoord anchor, MenuStyle style);
void menu_select(int selected);
void menu_hide();
void info_show(String title, String content, ByteCoord anchor, InfoStyle style);
void info_hide();
void print_status(DisplayLine status_line); void print_status(DisplayLine status_line);
CharCoord dimensions() const { return m_ui->dimensions(); }
void force_redraw(); void force_redraw();
void redraw_ifn(); void redraw_ifn();
UserInterface& ui() const { return *m_ui; }
void check_if_buffer_needs_reloading(); void check_if_buffer_needs_reloading();
Context& context() { return m_input_handler.context(); } Context& context() { return m_input_handler.context(); }
@ -78,6 +85,22 @@ private:
DisplayLine m_pending_status_line; DisplayLine m_pending_status_line;
DisplayLine m_mode_line; DisplayLine m_mode_line;
struct Menu
{
Vector<DisplayLine> items;
ByteCoord anchor;
MenuStyle style;
int selected;
} m_menu;
struct Info
{
String title;
String content;
ByteCoord anchor;
InfoStyle style;
} m_info;
Vector<Key, MemoryDomain::Client> m_pending_keys; Vector<Key, MemoryDomain::Client> m_pending_keys;
bool m_buffer_reload_dialog_opened = false; bool m_buffer_reload_dialog_opened = false;

View File

@ -6,7 +6,6 @@
#include "event_manager.hh" #include "event_manager.hh"
#include "face_registry.hh" #include "face_registry.hh"
#include "file.hh" #include "file.hh"
#include "user_interface.hh"
#include "window.hh" #include "window.hh"
namespace Kakoune namespace Kakoune
@ -59,10 +58,6 @@ Client* ClientManager::create_client(std::unique_ptr<UserInterface>&& ui,
return nullptr; return nullptr;
} }
client->ui().set_input_callback([client](EventMode mode) {
client->handle_available_input(mode);
});
return client; return client;
} }

View File

@ -22,7 +22,6 @@
#include "remote.hh" #include "remote.hh"
#include "shell_manager.hh" #include "shell_manager.hh"
#include "string.hh" #include "string.hh"
#include "user_interface.hh"
#include "window.hh" #include "window.hh"
#include <sys/types.h> #include <sys/types.h>
@ -1522,7 +1521,7 @@ const CommandDesc menu_cmd = {
select_cmds.push_back(parser[i+2]); select_cmds.push_back(parser[i+2]);
} }
context.input_handler().menu(choices, context.input_handler().menu(std::move(choices),
[=](int choice, MenuEvent event, Context& context) { [=](int choice, MenuEvent event, Context& context) {
ScopedSetBool disable_history{context.history_disabled()}; ScopedSetBool disable_history{context.history_disabled()};
@ -1571,20 +1570,24 @@ const CommandDesc info_cmd = {
CommandCompleter{}, CommandCompleter{},
[](const ParametersParser& parser, Context& context, const ShellContext&) [](const ParametersParser& parser, Context& context, const ShellContext&)
{ {
context.ui().info_hide(); if (not context.has_client())
return;
context.client().info_hide();
if (parser.positional_count() > 0) if (parser.positional_count() > 0)
{ {
InfoStyle style = InfoStyle::Prompt; InfoStyle style = InfoStyle::Prompt;
CharCoord pos; ByteCoord pos;
if (auto anchor = parser.get_switch("anchor")) if (auto anchor = parser.get_switch("anchor"))
{ {
auto dot = find(*anchor, '.'); auto dot = find(*anchor, '.');
if (dot == anchor->end()) if (dot == anchor->end())
throw runtime_error("expected <line>.<column> for anchor"); throw runtime_error("expected <line>.<column> for anchor");
ByteCoord coord{str_to_int({anchor->begin(), dot})-1,
pos = ByteCoord{str_to_int({anchor->begin(), dot})-1,
str_to_int({dot+1, anchor->end()})-1}; str_to_int({dot+1, anchor->end()})-1};
pos = context.window().display_position(coord);
style = InfoStyle::Inline; style = InfoStyle::Inline;
if (auto placement = parser.get_switch("placement")) if (auto placement = parser.get_switch("placement"))
{ {
if (*placement == "above") if (*placement == "above")
@ -1596,7 +1599,7 @@ const CommandDesc info_cmd = {
} }
} }
auto title = parser.get_switch("title").value_or(StringView{}); auto title = parser.get_switch("title").value_or(StringView{});
context.ui().info_show(title, parser[0], pos, get_face("Information"), style); context.client().info_show(title.str(), parser[0], pos, style);
} }
} }
}; };

View File

@ -2,7 +2,6 @@
#include "alias_registry.hh" #include "alias_registry.hh"
#include "client.hh" #include "client.hh"
#include "user_interface.hh"
#include "register_manager.hh" #include "register_manager.hh"
#include "window.hh" #include "window.hh"
@ -49,13 +48,6 @@ Client& Context::client() const
return *m_client; return *m_client;
} }
UserInterface& Context::ui() const
{
if (not has_ui())
throw runtime_error("no user interface in context");
return client().ui();
}
Scope& Context::scope() const Scope& Context::scope() const
{ {
if (has_window()) if (has_window())
@ -75,8 +67,6 @@ void Context::set_window(Window& window)
{ {
kak_assert(&window.buffer() == &buffer()); kak_assert(&window.buffer() == &buffer());
m_window.reset(&window); m_window.reset(&window);
if (has_ui())
m_window->set_dimensions(ui().dimensions());
} }
void Context::print_status(DisplayLine status) const void Context::print_status(DisplayLine status) const

View File

@ -107,9 +107,6 @@ public:
InputHandler& input_handler() const; InputHandler& input_handler() const;
bool has_input_handler() const { return (bool)m_input_handler; } bool has_input_handler() const { return (bool)m_input_handler; }
UserInterface& ui() const;
bool has_ui() const { return has_client(); }
SelectionList& selections(); SelectionList& selections();
const SelectionList& selections() const; const SelectionList& selections() const;
Vector<String> selections_content() const; Vector<String> selections_content() const;

View File

@ -10,7 +10,6 @@
#include "regex.hh" #include "regex.hh"
#include "register_manager.hh" #include "register_manager.hh"
#include "unordered_map.hh" #include "unordered_map.hh"
#include "user_interface.hh"
#include "utf8.hh" #include "utf8.hh"
#include "window.hh" #include "window.hh"
@ -244,8 +243,8 @@ public:
pop_mode(); pop_mode();
context().print_status({}); context().print_status({});
if (context().has_ui()) if (context().has_client())
context().ui().info_hide(); context().client().info_hide();
do_restore_hooks = true; do_restore_hooks = true;
auto it = std::lower_bound(keymap.begin(), keymap.end(), key, auto it = std::lower_bound(keymap.begin(), keymap.end(), key,
@ -254,9 +253,9 @@ public:
if (it != keymap.end() and it->key == key) if (it != keymap.end() and it->key == key)
{ {
auto autoinfo = context().options()["autoinfo"].get<AutoInfo>(); auto autoinfo = context().options()["autoinfo"].get<AutoInfo>();
if (autoinfo & AutoInfo::Normal and context().has_ui()) if (autoinfo & AutoInfo::Normal and context().has_client())
context().ui().info_show(key_to_str(key), it->docstring, CharCoord{}, context().client().info_show(key_to_str(key), it->docstring.str(),
get_face("Information"), InfoStyle::Prompt); {}, InfoStyle::Prompt);
// reset m_params now to be reentrant // reset m_params now to be reentrant
NormalParams params = m_params; NormalParams params = m_params;
@ -490,17 +489,16 @@ private:
class Menu : public InputMode class Menu : public InputMode
{ {
public: public:
Menu(InputHandler& input_handler, ConstArrayView<DisplayLine> choices, Menu(InputHandler& input_handler, Vector<DisplayLine> choices,
MenuCallback callback) MenuCallback callback)
: InputMode(input_handler), : InputMode(input_handler),
m_callback(callback), m_choices(choices.begin(), choices.end()), m_callback(callback), m_choices(choices.begin(), choices.end()),
m_selected(m_choices.begin()) m_selected(m_choices.begin())
{ {
if (not context().has_ui()) if (not context().has_client())
return; return;
context().ui().menu_show(choices, CharCoord{}, get_face("MenuForeground"), context().client().menu_show(std::move(choices), {}, MenuStyle::Prompt);
get_face("MenuBackground"), MenuStyle::Prompt); context().client().menu_select(0);
context().ui().menu_select(0);
} }
void on_key(Key key) override void on_key(Key key) override
@ -517,8 +515,8 @@ public:
if (key == ctrl('m')) if (key == ctrl('m'))
{ {
if (context().has_ui()) if (context().has_client())
context().ui().menu_hide(); context().client().menu_hide();
context().print_status(DisplayLine{}); context().print_status(DisplayLine{});
pop_mode(); pop_mode();
int selected = m_selected - m_choices.begin(); int selected = m_selected - m_choices.begin();
@ -536,8 +534,8 @@ public:
} }
else else
{ {
if (context().has_ui()) if (context().has_client())
context().ui().menu_hide(); context().client().menu_hide();
pop_mode(); pop_mode();
int selected = m_selected - m_choices.begin(); int selected = m_selected - m_choices.begin();
m_callback(selected, MenuEvent::Abort, context()); m_callback(selected, MenuEvent::Abort, context());
@ -576,10 +574,10 @@ public:
select(it); select(it);
} }
if (m_edit_filter and context().has_ui()) if (m_edit_filter and context().has_client())
{ {
auto prompt = "filter:"_str; auto prompt = "filter:"_str;
auto width = context().ui().dimensions().column - prompt.char_length(); auto width = context().client().dimensions().column - prompt.char_length();
auto display_line = m_filter_editor.build_display_line(width); auto display_line = m_filter_editor.build_display_line(width);
display_line.insert(display_line.begin(), { prompt, get_face("Prompt") }); display_line.insert(display_line.begin(), { prompt, get_face("Prompt") });
context().print_status(display_line); context().print_status(display_line);
@ -604,8 +602,8 @@ private:
{ {
m_selected = it; m_selected = it;
int selected = m_selected - m_choices.begin(); int selected = m_selected - m_choices.begin();
if (context().has_ui()) if (context().has_client())
context().ui().menu_select(selected); context().client().menu_select(selected);
m_callback(selected, MenuEvent::Select, context()); m_callback(selected, MenuEvent::Select, context());
} }
@ -671,8 +669,8 @@ public:
if (not context().history_disabled()) if (not context().history_disabled())
history_push(history, line); history_push(history, line);
context().print_status(DisplayLine{}); context().print_status(DisplayLine{});
if (context().has_ui()) if (context().has_client())
context().ui().menu_hide(); context().client().menu_hide();
pop_mode(); pop_mode();
// call callback after pop_mode so that callback // call callback after pop_mode so that callback
// may change the mode // may change the mode
@ -684,8 +682,8 @@ public:
if (not context().history_disabled()) if (not context().history_disabled())
history_push(history, line); history_push(history, line);
context().print_status(DisplayLine{}); context().print_status(DisplayLine{});
if (context().has_ui()) if (context().has_client())
context().ui().menu_hide(); context().client().menu_hide();
pop_mode(); pop_mode();
m_callback(line, PromptEvent::Abort, context()); m_callback(line, PromptEvent::Abort, context());
return; return;
@ -811,8 +809,8 @@ public:
} }
const String& completion = candidates[m_current_completion]; const String& completion = candidates[m_current_completion];
if (context().has_ui()) if (context().has_client())
context().ui().menu_select(m_current_completion); context().client().menu_select(m_current_completion);
m_line_editor.insert_from(line.char_count_to(m_completions.start), m_line_editor.insert_from(line.char_count_to(m_completions.start),
completion); completion);
@ -872,15 +870,12 @@ private:
const String& line = m_line_editor.line(); const String& line = m_line_editor.line();
m_completions = m_completer(context(), flags, line, m_completions = m_completer(context(), flags, line,
line.byte_count_to(m_line_editor.cursor_pos())); line.byte_count_to(m_line_editor.cursor_pos()));
if (context().has_ui() and not m_completions.candidates.empty()) if (context().has_client() and not m_completions.candidates.empty())
{ {
Vector<DisplayLine> items; Vector<DisplayLine> items;
for (auto& candidate : m_completions.candidates) for (auto& candidate : m_completions.candidates)
items.push_back({ candidate, {} }); items.push_back({ candidate, {} });
context().ui().menu_show(items, CharCoord{}, context().client().menu_show(items, {}, MenuStyle::Prompt);
get_face("MenuForeground"),
get_face("MenuBackground"),
MenuStyle::Prompt);
} }
} catch (runtime_error&) {} } catch (runtime_error&) {}
} }
@ -889,16 +884,16 @@ private:
{ {
m_current_completion = -1; m_current_completion = -1;
m_completions.candidates.clear(); m_completions.candidates.clear();
if (context().has_ui()) if (context().has_client())
context().ui().menu_hide(); context().client().menu_hide();
} }
void display() void display()
{ {
if (not context().has_ui()) if (not context().has_client())
return; return;
auto width = context().ui().dimensions().column - m_prompt.char_length(); auto width = context().client().dimensions().column - m_prompt.char_length();
auto display_line = m_line_editor.build_display_line(width); auto display_line = m_line_editor.build_display_line(width);
display_line.insert(display_line.begin(), { m_prompt, m_prompt_face }); display_line.insert(display_line.begin(), { m_prompt, m_prompt_face });
context().print_status(display_line); context().print_status(display_line);
@ -1350,9 +1345,9 @@ void InputHandler::set_prompt_face(Face prompt_face)
prompt->set_prompt_face(prompt_face); prompt->set_prompt_face(prompt_face);
} }
void InputHandler::menu(ConstArrayView<DisplayLine> choices, MenuCallback callback) void InputHandler::menu(Vector<DisplayLine> choices, MenuCallback callback)
{ {
push_mode(new InputModes::Menu(*this, choices, callback)); push_mode(new InputModes::Menu(*this, std::move(choices), callback));
} }
void InputHandler::on_next_key(KeymapMode keymap_mode, KeyCallback callback) void InputHandler::on_next_key(KeymapMode keymap_mode, KeyCallback callback)
@ -1420,12 +1415,17 @@ DisplayLine InputHandler::mode_line() const
bool show_auto_info_ifn(StringView title, StringView info, AutoInfo mask, const Context& context) bool show_auto_info_ifn(StringView title, StringView info, AutoInfo mask, const Context& context)
{ {
if (not (context.options()["autoinfo"].get<AutoInfo>() & mask) or if (not (context.options()["autoinfo"].get<AutoInfo>() & mask) or
not context.has_ui()) not context.has_client())
return false; return false;
Face face = get_face("Information"); context.client().info_show(title.str(), info.str(), {}, InfoStyle::Prompt);
context.ui().info_show(title, info, CharCoord{}, face, InfoStyle::Prompt);
return true; return true;
} }
void hide_auto_info_ifn(const Context& context, bool hide)
{
if (hide)
context.client().info_hide();
}
} }

View File

@ -8,8 +8,8 @@
#include "keys.hh" #include "keys.hh"
#include "string.hh" #include "string.hh"
#include "utils.hh" #include "utils.hh"
#include "user_interface.hh"
#include "safe_ptr.hh" #include "safe_ptr.hh"
#include "display_buffer.hh"
namespace Kakoune namespace Kakoune
{ {
@ -32,7 +32,6 @@ using PromptCallback = std::function<void (StringView, PromptEvent, Context&)>;
using KeyCallback = std::function<void (Key, Context&)>; using KeyCallback = std::function<void (Key, Context&)>;
class InputMode; class InputMode;
class DisplayLine;
enum class InsertMode : unsigned; enum class InsertMode : unsigned;
enum class KeymapMode : char; enum class KeymapMode : char;
@ -62,7 +61,7 @@ public:
// abort or validation with corresponding MenuEvent value // abort or validation with corresponding MenuEvent value
// returns to normal mode after validation if callback does // returns to normal mode after validation if callback does
// not change the mode itself // not change the mode itself
void menu(ConstArrayView<DisplayLine> choices, MenuCallback callback); void menu(Vector<DisplayLine> choices, MenuCallback callback);
// execute callback on next keypress and returns to normal mode // execute callback on next keypress and returns to normal mode
// if callback does not change the mode itself // if callback does not change the mode itself
@ -124,6 +123,7 @@ constexpr Array<EnumDesc<AutoInfo>, 3> enum_desc(AutoInfo)
} }
bool show_auto_info_ifn(StringView title, StringView info, AutoInfo mask, const Context& context); bool show_auto_info_ifn(StringView title, StringView info, AutoInfo mask, const Context& context);
void hide_auto_info_ifn(const Context& context, bool hide);
template<typename Cmd> template<typename Cmd>
void on_next_key_with_autoinfo(const Context& context, KeymapMode keymap_mode, Cmd cmd, void on_next_key_with_autoinfo(const Context& context, KeymapMode keymap_mode, Cmd cmd,
@ -132,11 +132,11 @@ void on_next_key_with_autoinfo(const Context& context, KeymapMode keymap_mode, C
const bool hide = show_auto_info_ifn(title, info, AutoInfo::OnKey, context); const bool hide = show_auto_info_ifn(title, info, AutoInfo::OnKey, context);
context.input_handler().on_next_key( context.input_handler().on_next_key(
keymap_mode, [hide,cmd](Key key, Context& context) mutable { keymap_mode, [hide,cmd](Key key, Context& context) mutable {
if (hide) hide_auto_info_ifn(context, hide);
context.ui().info_hide();
cmd(key, context); cmd(key, context);
}); });
} }
} }
#endif // input_handler_hh_INCLUDED #endif // input_handler_hh_INCLUDED

View File

@ -2,12 +2,12 @@
#include "buffer_manager.hh" #include "buffer_manager.hh"
#include "buffer_utils.hh" #include "buffer_utils.hh"
#include "client.hh"
#include "context.hh" #include "context.hh"
#include "display_buffer.hh" #include "display_buffer.hh"
#include "face_registry.hh" #include "face_registry.hh"
#include "file.hh" #include "file.hh"
#include "regex.hh" #include "regex.hh"
#include "user_interface.hh"
#include "window.hh" #include "window.hh"
#include "word_db.hh" #include "word_db.hh"
#include "utf8_iterator.hh" #include "utf8_iterator.hh"
@ -364,14 +364,14 @@ void InsertCompleter::select(int offset, Vector<Key>& keystrokes)
m_completions.end = cursor_pos; m_completions.end = cursor_pos;
m_completions.begin = buffer.advance(cursor_pos, -candidate.completion.length()); m_completions.begin = buffer.advance(cursor_pos, -candidate.completion.length());
m_completions.timestamp = buffer.timestamp(); m_completions.timestamp = buffer.timestamp();
if (m_context.has_ui()) if (m_context.has_client())
{ {
m_context.ui().menu_select(m_current_candidate); m_context.client().menu_select(m_current_candidate);
if (not candidate.docstring.empty()) if (not candidate.docstring.empty())
m_context.ui().info_show(candidate.completion, candidate.docstring, CharCoord{}, m_context.client().info_show(candidate.completion, candidate.docstring,
get_face("Information"), InfoStyle::MenuDoc); {}, InfoStyle::MenuDoc);
else else
m_context.ui().info_hide(); m_context.client().info_hide();
} }
for (auto i = 0_byte; i < prefix_len; ++i) for (auto i = 0_byte; i < prefix_len; ++i)
@ -395,10 +395,10 @@ void InsertCompleter::reset()
{ {
m_completions = InsertCompletion{}; m_completions = InsertCompletion{};
m_explicit_completer = nullptr; m_explicit_completer = nullptr;
if (m_context.has_ui()) if (m_context.has_client())
{ {
m_context.ui().menu_hide(); m_context.client().menu_hide();
m_context.ui().info_hide(); m_context.client().info_hide();
} }
} }
@ -435,19 +435,16 @@ bool InsertCompleter::setup_ifn()
void InsertCompleter::menu_show() void InsertCompleter::menu_show()
{ {
if (not m_context.has_ui()) if (not m_context.has_client())
return; return;
CharCoord menu_pos = m_context.window().display_position(m_completions.begin);
Vector<DisplayLine> menu_entries; Vector<DisplayLine> menu_entries;
for (auto& candidate : m_completions.candidates) for (auto& candidate : m_completions.candidates)
menu_entries.push_back(candidate.menu_entry); menu_entries.push_back(candidate.menu_entry);
m_context.ui().menu_show(menu_entries, menu_pos, m_context.client().menu_show(std::move(menu_entries), m_completions.begin,
get_face("MenuForeground"),
get_face("MenuBackground"),
MenuStyle::Inline); MenuStyle::Inline);
m_context.ui().menu_select(m_current_candidate); m_context.client().menu_select(m_current_candidate);
} }
void InsertCompleter::on_option_changed(const Option& opt) void InsertCompleter::on_option_changed(const Option& opt)

View File

@ -265,6 +265,7 @@ struct convert_to_client_mode
}; };
static Client* local_client = nullptr; static Client* local_client = nullptr;
static UserInterface* local_ui = nullptr;
static bool convert_to_client_pending = false; static bool convert_to_client_pending = false;
pid_t fork_server_to_background() pid_t fork_server_to_background()
@ -309,6 +310,8 @@ std::unique_ptr<UserInterface> create_local_ui(bool dummy_ui)
{ {
LocalUI() LocalUI()
{ {
kak_assert(not local_ui);
local_ui = this;
m_old_sighup = set_signal_handler(SIGHUP, [](int) { m_old_sighup = set_signal_handler(SIGHUP, [](int) {
ClientManager::instance().remove_client(*local_client, false); ClientManager::instance().remove_client(*local_client, false);
}); });
@ -318,7 +321,7 @@ std::unique_ptr<UserInterface> create_local_ui(bool dummy_ui)
*ClientManager::instance().begin() == local_client) *ClientManager::instance().begin() == local_client)
{ {
// Suspend normally if we are the only client // Suspend normally if we are the only client
auto current = set_signal_handler(SIGTSTP, static_cast<LocalUI&>(local_client->ui()).m_old_sigtstp); auto current = set_signal_handler(SIGTSTP, static_cast<LocalUI*>(local_ui)->m_old_sigtstp);
sigset_t unblock_sigtstp, old_mask; sigset_t unblock_sigtstp, old_mask;
sigemptyset(&unblock_sigtstp); sigemptyset(&unblock_sigtstp);
@ -341,6 +344,7 @@ std::unique_ptr<UserInterface> create_local_ui(bool dummy_ui)
set_signal_handler(SIGHUP, m_old_sighup); set_signal_handler(SIGHUP, m_old_sighup);
set_signal_handler(SIGTSTP, m_old_sigtstp); set_signal_handler(SIGTSTP, m_old_sigtstp);
local_client = nullptr; local_client = nullptr;
local_ui = nullptr;
if (not convert_to_client_pending and if (not convert_to_client_pending and
not ClientManager::instance().empty()) not ClientManager::instance().empty())
{ {

View File

@ -16,7 +16,6 @@
#include "selectors.hh" #include "selectors.hh"
#include "shell_manager.hh" #include "shell_manager.hh"
#include "string.hh" #include "string.hh"
#include "user_interface.hh"
#include "window.hh" #include "window.hh"
namespace Kakoune namespace Kakoune
@ -346,20 +345,19 @@ void command(Context& context, NormalParams params)
return CommandManager::instance().complete(context, flags, cmd_line, pos); return CommandManager::instance().complete(context, flags, cmd_line, pos);
}, },
[params](StringView cmdline, PromptEvent event, Context& context) { [params](StringView cmdline, PromptEvent event, Context& context) {
if (context.has_ui()) if (context.has_client())
{ {
context.ui().info_hide(); context.client().info_hide();
auto autoinfo = context.options()["autoinfo"].get<AutoInfo>(); auto autoinfo = context.options()["autoinfo"].get<AutoInfo>();
if (event == PromptEvent::Change and autoinfo & AutoInfo::Command) if (event == PromptEvent::Change and autoinfo & AutoInfo::Command)
{ {
Face face = get_face("Information");
if (cmdline.length() == 1 and is_horizontal_blank(cmdline[0_byte])) if (cmdline.length() == 1 and is_horizontal_blank(cmdline[0_byte]))
context.ui().info_show("prompt", "commands preceded by a blank wont be saved to history", context.client().info_show("prompt", "commands preceded by a blank wont be saved to history",
CharCoord{}, face, InfoStyle::Prompt); {}, InfoStyle::Prompt);
auto info = CommandManager::instance().command_info(context, cmdline); auto info = CommandManager::instance().command_info(context, cmdline);
if (not info.first.empty() and not info.second.empty()) if (not info.first.empty() and not info.second.empty())
context.ui().info_show(info.first, info.second, CharCoord{}, face, InfoStyle::Prompt); context.client().info_show(info.first, info.second, {}, InfoStyle::Prompt);
} }
} }
if (event == PromptEvent::Validate) if (event == PromptEvent::Validate)
@ -586,8 +584,8 @@ void regex_prompt(Context& context, const String prompt, T func)
[=](StringView str, PromptEvent event, Context& context) mutable { [=](StringView str, PromptEvent event, Context& context) mutable {
try try
{ {
if (event != PromptEvent::Change and context.has_ui()) if (event != PromptEvent::Change and context.has_client())
context.ui().info_hide(); context.client().info_hide();
const bool incsearch = context.options()["incsearch"].get<bool>(); const bool incsearch = context.options()["incsearch"].get<bool>();
if (incsearch) if (incsearch)

View File

@ -5,7 +5,7 @@
#include "highlighter.hh" #include "highlighter.hh"
#include "hook_manager.hh" #include "hook_manager.hh"
#include "input_handler.hh" #include "input_handler.hh"
#include "user_interface.hh" #include "client.hh"
#include <algorithm> #include <algorithm>
#include <sstream> #include <sstream>
@ -79,7 +79,7 @@ Window::Setup Window::build_setup(const Context& context) const
selections.push_back({sel.cursor(), sel.anchor()}); selections.push_back({sel.cursor(), sel.anchor()});
return { m_position, return { m_position,
context.ui().dimensions(), context.client().dimensions(),
context.buffer().timestamp(), context.buffer().timestamp(),
context.selections().main_index(), context.selections().main_index(),
std::move(selections) }; std::move(selections) };
@ -90,7 +90,7 @@ bool Window::needs_redraw(const Context& context) const
auto& selections = context.selections(); auto& selections = context.selections();
if (m_position != m_last_setup.position or if (m_position != m_last_setup.position or
context.ui().dimensions() != m_last_setup.dimensions or context.client().dimensions() != m_last_setup.dimensions or
context.buffer().timestamp() != m_last_setup.timestamp or context.buffer().timestamp() != m_last_setup.timestamp or
selections.main_index() != m_last_setup.main_selection or selections.main_index() != m_last_setup.main_selection or
selections.size() != m_last_setup.selections.size()) selections.size() != m_last_setup.selections.size())
@ -111,7 +111,7 @@ const DisplayBuffer& Window::update_display_buffer(const Context& context)
DisplayBuffer::LineList& lines = m_display_buffer.lines(); DisplayBuffer::LineList& lines = m_display_buffer.lines();
lines.clear(); lines.clear();
m_dimensions = context.ui().dimensions(); m_dimensions = context.client().dimensions();
if (m_dimensions == CharCoord{0,0}) if (m_dimensions == CharCoord{0,0})
return m_display_buffer; return m_display_buffer;