2013-09-13 01:47:23 +04:00
|
|
|
#include "client.hh"
|
2012-09-03 16:22:02 +04:00
|
|
|
|
2013-04-09 21:39:03 +04:00
|
|
|
#include "color_registry.hh"
|
2012-09-03 16:22:02 +04:00
|
|
|
#include "context.hh"
|
2012-09-26 16:22:24 +04:00
|
|
|
#include "editor.hh"
|
2013-05-20 16:10:53 +04:00
|
|
|
#include "buffer_manager.hh"
|
2013-04-09 21:39:03 +04:00
|
|
|
#include "user_interface.hh"
|
2013-08-02 20:58:37 +04:00
|
|
|
#include "file.hh"
|
2013-10-11 21:43:23 +04:00
|
|
|
#include "remote.hh"
|
2013-10-15 21:51:31 +04:00
|
|
|
#include "client_manager.hh"
|
2013-11-15 01:12:59 +04:00
|
|
|
#include "window.hh"
|
2012-09-03 16:22:02 +04:00
|
|
|
|
|
|
|
namespace Kakoune
|
|
|
|
{
|
|
|
|
|
2013-11-14 22:09:15 +04:00
|
|
|
Client::Client(std::unique_ptr<UserInterface>&& ui, Editor& editor, String name)
|
2013-11-15 00:51:25 +04:00
|
|
|
: m_input_handler(editor, std::move(name)), m_ui(std::move(ui))
|
2013-11-14 22:09:15 +04:00
|
|
|
{
|
|
|
|
context().set_client(*this);
|
|
|
|
}
|
|
|
|
|
|
|
|
Client::~Client()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void Client::handle_available_input()
|
|
|
|
{
|
|
|
|
while (m_ui->is_key_available())
|
|
|
|
{
|
|
|
|
m_input_handler.handle_key(m_ui->get_key());
|
|
|
|
m_input_handler.clear_mode_trash();
|
|
|
|
}
|
|
|
|
context().window().forget_timestamp();
|
|
|
|
}
|
|
|
|
|
2013-09-16 22:15:13 +04:00
|
|
|
void Client::print_status(DisplayLine status_line)
|
|
|
|
{
|
|
|
|
m_status_line = std::move(status_line);
|
2013-11-14 22:09:15 +04:00
|
|
|
context().window().forget_timestamp();
|
2013-09-16 22:15:13 +04:00
|
|
|
}
|
|
|
|
|
2013-10-11 00:34:19 +04:00
|
|
|
DisplayLine Client::generate_mode_line() const
|
2013-09-16 22:15:13 +04:00
|
|
|
{
|
2013-12-14 18:17:02 +04:00
|
|
|
auto pos = context().editor().selections().main().last();
|
2013-10-11 00:34:19 +04:00
|
|
|
auto col = context().buffer()[pos.line].char_count_to(pos.column);
|
2013-09-16 22:15:13 +04:00
|
|
|
|
|
|
|
std::ostringstream oss;
|
2013-10-11 00:34:19 +04:00
|
|
|
oss << context().buffer().display_name()
|
2013-09-16 22:15:13 +04:00
|
|
|
<< " " << (int)pos.line+1 << ":" << (int)col+1;
|
2013-10-11 00:34:19 +04:00
|
|
|
if (context().buffer().is_modified())
|
2013-09-16 22:15:13 +04:00
|
|
|
oss << " [+]";
|
2013-11-14 22:09:15 +04:00
|
|
|
if (m_input_handler.is_recording())
|
|
|
|
oss << " [recording (" << m_input_handler.recording_reg() << ")]";
|
2013-10-11 00:34:19 +04:00
|
|
|
if (context().buffer().flags() & Buffer::Flags::New)
|
2013-09-16 22:15:13 +04:00
|
|
|
oss << " [new file]";
|
2013-11-15 01:12:59 +04:00
|
|
|
oss << " [" << m_input_handler.mode_string() << "]" << " - "
|
2013-11-15 00:51:25 +04:00
|
|
|
<< context().name() << "@[" << Server::instance().session() << "]";
|
2013-09-16 22:15:13 +04:00
|
|
|
return { oss.str(), get_color("StatusLine") };
|
|
|
|
}
|
|
|
|
|
|
|
|
void Client::redraw_ifn()
|
|
|
|
{
|
2013-11-14 22:09:15 +04:00
|
|
|
if (context().window().timestamp() != context().buffer().timestamp())
|
2013-09-16 22:15:13 +04:00
|
|
|
{
|
2013-11-14 22:09:15 +04:00
|
|
|
DisplayCoord dimensions = context().ui().dimensions();
|
2013-09-16 22:15:13 +04:00
|
|
|
if (dimensions == DisplayCoord{0,0})
|
|
|
|
return;
|
2013-11-14 22:09:15 +04:00
|
|
|
context().window().set_dimensions(dimensions);
|
|
|
|
context().window().update_display_buffer();;
|
2013-09-16 22:15:13 +04:00
|
|
|
|
2013-11-14 22:09:15 +04:00
|
|
|
context().ui().draw(context().window().display_buffer(),
|
2013-10-11 00:34:19 +04:00
|
|
|
m_status_line, generate_mode_line());
|
2013-09-16 22:15:13 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-10-21 21:58:11 +04:00
|
|
|
static void reload_buffer(Context& context, const String& filename)
|
|
|
|
{
|
|
|
|
DisplayCoord view_pos = context.window().position();
|
2013-12-14 18:17:02 +04:00
|
|
|
BufferCoord cursor_pos = context.editor().selections().main().last();
|
2013-10-21 21:58:11 +04:00
|
|
|
Buffer* buf = create_buffer_from_file(filename);
|
|
|
|
if (not buf)
|
|
|
|
return;
|
|
|
|
Window& win = ClientManager::instance().get_unused_window_for_buffer(*buf);
|
|
|
|
win.select(cursor_pos);
|
|
|
|
win.set_position(view_pos);
|
|
|
|
context.change_editor(win);
|
|
|
|
context.print_status({ "'" + buf->display_name() + "' reloaded",
|
|
|
|
get_color("Information") });
|
|
|
|
}
|
|
|
|
|
2013-10-15 21:51:31 +04:00
|
|
|
void Client::check_buffer_fs_timestamp()
|
|
|
|
{
|
2013-11-14 22:09:15 +04:00
|
|
|
Buffer& buffer = context().buffer();
|
2013-10-21 21:58:11 +04:00
|
|
|
auto reload = context().options()["autoreload"].get<YesNoAsk>();
|
|
|
|
if (not (buffer.flags() & Buffer::Flags::File) or reload == No)
|
2013-10-15 21:51:31 +04:00
|
|
|
return;
|
2013-10-21 21:58:11 +04:00
|
|
|
|
|
|
|
const String& filename = buffer.name();
|
2013-10-15 21:51:31 +04:00
|
|
|
time_t ts = get_fs_timestamp(filename);
|
2013-10-21 21:58:11 +04:00
|
|
|
if (ts == buffer.fs_timestamp())
|
|
|
|
return;
|
|
|
|
if (reload == Ask)
|
2013-10-15 21:51:31 +04:00
|
|
|
{
|
|
|
|
print_status({"'" + buffer.display_name() + "' was modified externally, press r or y to reload, k or n to keep", get_color("Prompt")});
|
2013-11-14 22:09:15 +04:00
|
|
|
m_input_handler.on_next_key([this, ts, filename](Key key, Context& context) {
|
2013-10-15 21:51:31 +04:00
|
|
|
Buffer* buf = BufferManager::instance().get_buffer_ifp(filename);
|
|
|
|
// buffer got deleted while waiting for the key, do nothing
|
|
|
|
if (not buf)
|
|
|
|
{
|
|
|
|
print_status({});
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (key == 'r' or key == 'y')
|
2013-10-21 21:58:11 +04:00
|
|
|
reload_buffer(context, filename);
|
2013-10-15 21:51:31 +04:00
|
|
|
if (key == 'k' or key == 'n')
|
|
|
|
{
|
|
|
|
buf->set_fs_timestamp(ts);
|
|
|
|
print_status({"'" + buf->display_name() + "' kept", get_color("Information") });
|
|
|
|
}
|
|
|
|
else
|
|
|
|
check_buffer_fs_timestamp();
|
|
|
|
});
|
|
|
|
}
|
2013-10-21 21:58:11 +04:00
|
|
|
else
|
|
|
|
reload_buffer(context(), filename);
|
2013-10-15 21:51:31 +04:00
|
|
|
}
|
|
|
|
|
2012-09-03 16:22:02 +04:00
|
|
|
}
|