summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxime Coste <frrrwww@gmail.com>2013-12-20 20:10:08 +0000
committerMaxime Coste <frrrwww@gmail.com>2013-12-20 20:14:57 +0000
commitc0973075fafc7003be1028922bf99a2c48bcdcd6 (patch)
tree303d3d6b03942857775f7c0d2e15d621a6f6df37
parentcb324a4b8842d6d45a7dba316cd4f909addb99c2 (diff)
Get rid of Editor for good
ClientManager now stores only the free windows, clients take ownership of its own.
-rw-r--r--src/buffer.cc3
-rw-r--r--src/buffer.hh6
-rw-r--r--src/client.cc25
-rw-r--r--src/client.hh14
-rw-r--r--src/client_manager.cc43
-rw-r--r--src/client_manager.hh9
-rw-r--r--src/commands.cc13
-rw-r--r--src/context.cc59
-rw-r--r--src/context.hh20
-rw-r--r--src/debug.cc2
-rw-r--r--src/dynamic_selection_list.cc2
-rw-r--r--src/dynamic_selection_list.hh2
-rw-r--r--src/editor.hh35
-rw-r--r--src/input_handler.cc6
-rw-r--r--src/input_handler.hh2
-rw-r--r--src/normal.cc10
-rw-r--r--src/selectors.hh1
-rw-r--r--src/unit_tests.cc1
-rw-r--r--src/utils.hh2
-rw-r--r--src/window.cc27
-rw-r--r--src/window.hh17
21 files changed, 136 insertions, 163 deletions
diff --git a/src/buffer.cc b/src/buffer.cc
index 2e248a3c..e2d01201 100644
--- a/src/buffer.cc
+++ b/src/buffer.cc
@@ -786,8 +786,7 @@ void Buffer::on_option_changed(const Option& option)
void Buffer::run_hook_in_own_context(const String& hook_name, const String& param)
{
- Editor hook_editor{*this};
- InputHandler hook_handler(hook_editor);
+ InputHandler hook_handler(*this, SelectionList{ {} });
m_hooks.run_hook(hook_name, param, hook_handler.context());
}
diff --git a/src/buffer.hh b/src/buffer.hh
index 81b1bab4..13b958c5 100644
--- a/src/buffer.hh
+++ b/src/buffer.hh
@@ -268,13 +268,13 @@ struct BufferListenerRegisterFuncs
class BufferChangeListener_AutoRegister
: public BufferChangeListener,
public AutoRegister<BufferChangeListener_AutoRegister,
- BufferListenerRegisterFuncs, const Buffer>
+ BufferListenerRegisterFuncs, Buffer>
{
public:
- BufferChangeListener_AutoRegister(const Buffer& buffer)
+ BufferChangeListener_AutoRegister(Buffer& buffer)
: AutoRegister(buffer) {}
- const Buffer& buffer() const { return registry(); }
+ Buffer& buffer() const { return registry(); }
};
}
diff --git a/src/client.cc b/src/client.cc
index a03c2e29..95802181 100644
--- a/src/client.cc
+++ b/src/client.cc
@@ -2,7 +2,6 @@
#include "color_registry.hh"
#include "context.hh"
-#include "editor.hh"
#include "buffer_manager.hh"
#include "user_interface.hh"
#include "file.hh"
@@ -13,10 +12,14 @@
namespace Kakoune
{
-Client::Client(std::unique_ptr<UserInterface>&& ui, Editor& editor, String name)
- : m_input_handler(editor, std::move(name)), m_ui(std::move(ui))
+Client::Client(std::unique_ptr<UserInterface>&& ui,
+ std::unique_ptr<Window>&& window,
+ SelectionList selections, String name)
+ : m_ui{std::move(ui)}, m_window{std::move(window)},
+ m_input_handler{m_window->buffer(), std::move(selections), std::move(name)}
{
context().set_client(*this);
+ context().set_window(*m_window);
}
Client::~Client()
@@ -58,6 +61,15 @@ DisplayLine Client::generate_mode_line() const
return { oss.str(), get_color("StatusLine") };
}
+void Client::change_buffer(Buffer& buffer)
+{
+ ClientManager::instance().add_free_window(std::move(m_window), std::move(context().selections()));
+ std::tie(m_window, context().m_selections) = ClientManager::instance().get_free_window(buffer);
+ context().set_window(*m_window);
+ m_window->set_dimensions(ui().dimensions());
+ m_window->hooks().run_hook("WinDisplay", buffer.name(), context());
+}
+
void Client::redraw_ifn()
{
if (context().window().timestamp() != context().buffer().timestamp())
@@ -80,10 +92,9 @@ static void reload_buffer(Context& context, const String& filename)
Buffer* buf = create_buffer_from_file(filename);
if (not buf)
return;
- Window& win = ClientManager::instance().get_unused_window_for_buffer(*buf);
- win.selections() = SelectionList{cursor_pos};
- win.set_position(view_pos);
- context.change_editor(win);
+ context.change_buffer(*buf);
+ context.selections() = SelectionList{cursor_pos};
+ context.window().set_position(view_pos);
context.print_status({ "'" + buf->display_name() + "' reloaded",
get_color("Information") });
}
diff --git a/src/client.hh b/src/client.hh
index 89fb46bc..ac191542 100644
--- a/src/client.hh
+++ b/src/client.hh
@@ -1,7 +1,6 @@
#ifndef client_hh_INCLUDED
#define client_hh_INCLUDED
-#include "editor.hh"
#include "string.hh"
#include "utils.hh"
#include "display_buffer.hh"
@@ -11,11 +10,14 @@ namespace Kakoune
{
class UserInterface;
+class Window;
class Client : public SafeCountable
{
public:
- Client(std::unique_ptr<UserInterface>&& ui, Editor& editor, String name);
+ Client(std::unique_ptr<UserInterface>&& ui,
+ std::unique_ptr<Window>&& window,
+ SelectionList selections, String name);
~Client();
// handle all the keys currently available in the user interface
@@ -26,18 +28,22 @@ public:
void redraw_ifn();
UserInterface& ui() const { return *m_ui; }
+ Window& window() const { return *m_window; }
void check_buffer_fs_timestamp();
Context& context() { return m_input_handler.context(); }
const Context& context() const { return m_input_handler.context(); }
-private:
- InputHandler m_input_handler;
+ void change_buffer(Buffer& buffer);
+private:
DisplayLine generate_mode_line() const;
std::unique_ptr<UserInterface> m_ui;
+ std::unique_ptr<Window> m_window;
+
+ InputHandler m_input_handler;
DisplayLine m_status_line;
};
diff --git a/src/client_manager.cc b/src/client_manager.cc
index 657e6d93..e5a3018b 100644
--- a/src/client_manager.cc
+++ b/src/client_manager.cc
@@ -28,8 +28,9 @@ Client* ClientManager::create_client(std::unique_ptr<UserInterface>&& ui,
const String& init_commands)
{
Buffer& buffer = **BufferManager::instance().begin();
- Client* client = new Client{std::move(ui), get_unused_window_for_buffer(buffer),
- generate_name()};
+ WindowAndSelections ws = get_free_window(buffer);
+ Client* client = new Client{std::move(ui), std::move(std::get<0>(ws)),
+ std::move(std::get<1>(ws)), generate_name()};
m_clients.emplace_back(client);
try
{
@@ -80,24 +81,27 @@ void ClientManager::remove_client(Client& client)
kak_assert(false);
}
-Window& ClientManager::get_unused_window_for_buffer(Buffer& buffer)
+WindowAndSelections ClientManager::get_free_window(Buffer& buffer)
{
- for (auto& w : m_windows)
+ for (auto it = m_free_windows.begin(), end = m_free_windows.end();
+ it != end; ++it)
{
- if (&w->buffer() != &buffer)
- continue;
-
- auto it = std::find_if(m_clients.begin(), m_clients.end(),
- [&](const std::unique_ptr<Client>& client)
- { return &client->context().window() == w.get(); });
- if (it == m_clients.end())
+ auto& w = std::get<0>(*it);
+ if (&w->buffer() == &buffer)
{
w->forget_timestamp();
- return *w;
+ WindowAndSelections res = std::move(*it);
+ m_free_windows.erase(it);
+ return res;
}
}
- m_windows.emplace_back(new Window(buffer));
- return *m_windows.back();
+ return WindowAndSelections{ std::unique_ptr<Window>{new Window{buffer}}, DynamicSelectionList{buffer, { Selection{ {}, {} } } } };
+}
+
+void ClientManager::add_free_window(std::unique_ptr<Window>&& window, SelectionList selections)
+{
+ Buffer& buffer = window->buffer();
+ m_free_windows.emplace_back(std::move(window), DynamicSelectionList{ buffer, std::move(selections) });
}
void ClientManager::ensure_no_client_uses_buffer(Buffer& buffer)
@@ -120,16 +124,15 @@ void ClientManager::ensure_no_client_uses_buffer(Buffer& buffer)
{
if (buf != &buffer)
{
- Window& w = get_unused_window_for_buffer(*buf);
- client->context().change_editor(w);
+ client->context().change_buffer(*buf);
break;
}
}
}
- auto end = std::remove_if(m_windows.begin(), m_windows.end(),
- [&buffer](const std::unique_ptr<Window>& w)
- { return &w->buffer() == &buffer; });
- m_windows.erase(end, m_windows.end());
+ auto end = std::remove_if(m_free_windows.begin(), m_free_windows.end(),
+ [&buffer](const WindowAndSelections& ws)
+ { return &std::get<0>(ws)->buffer() == &buffer; });
+ m_free_windows.erase(end, m_free_windows.end());
}
bool ClientManager::validate_client_name(const String& name) const
diff --git a/src/client_manager.hh b/src/client_manager.hh
index 2e6638e7..9c32404a 100644
--- a/src/client_manager.hh
+++ b/src/client_manager.hh
@@ -8,6 +8,9 @@ namespace Kakoune
struct client_removed{};
+using WindowAndSelections = std::tuple<std::unique_ptr<Window>,
+ DynamicSelectionList>;
+
class ClientManager : public Singleton<ClientManager>
{
public:
@@ -20,9 +23,11 @@ public:
bool empty() const { return m_clients.empty(); }
size_t count() const { return m_clients.size(); }
- Window& get_unused_window_for_buffer(Buffer& buffer);
void ensure_no_client_uses_buffer(Buffer& buffer);
+ WindowAndSelections get_free_window(Buffer& buffer);
+ void add_free_window(std::unique_ptr<Window>&& window, SelectionList selections);
+
void redraw_clients() const;
Client* get_client_ifp(const String& name);
@@ -34,7 +39,7 @@ private:
String generate_name() const;
std::vector<std::unique_ptr<Client>> m_clients;
- std::vector<std::unique_ptr<Window>> m_windows;
+ std::vector<WindowAndSelections> m_free_windows;
};
}
diff --git a/src/commands.cc b/src/commands.cc
index 21dce82f..d538ebf8 100644
--- a/src/commands.cc
+++ b/src/commands.cc
@@ -116,10 +116,7 @@ void edit(CommandParameters params, Context& context)
context.push_jump();
if (buffer != &context.buffer())
- {
- auto& manager = ClientManager::instance();
- context.change_editor(manager.get_unused_window_for_buffer(*buffer));
- }
+ context.change_buffer(*buffer);
if (param_count > 1 and not parser[1].empty())
{
@@ -210,8 +207,7 @@ void show_buffer(CommandParameters params, Context& context)
if (&buffer != &context.buffer())
{
context.push_jump();
- auto& manager = ClientManager::instance();
- context.change_editor(manager.get_unused_window_for_buffer(buffer));
+ context.change_buffer(buffer);
}
}
@@ -568,9 +564,7 @@ void context_wrap(CommandParameters params, Context& context, Func func)
if (parser.has_option("draft"))
{
- InputHandler input_handler(real_context->editor(), real_context->name());
- DynamicSelectionList sels{real_context->buffer(), real_context->selections()};
- auto restore_sels = on_scope_end([&]{ real_context->selections() = std::move(sels); });
+ InputHandler input_handler(real_context->buffer(), real_context->selections(), real_context->name());
// We do not want this draft context to commit undo groups if the real one is
// going to commit the whole thing later
@@ -579,6 +573,7 @@ void context_wrap(CommandParameters params, Context& context, Func func)
if (parser.has_option("itersel"))
{
+ DynamicSelectionList sels{real_context->buffer(), real_context->selections()};
for (auto& sel : sels)
{
input_handler.context().selections() = sel;
diff --git a/src/context.cc b/src/context.cc
index a638a927..d4ad1616 100644
--- a/src/context.cc
+++ b/src/context.cc
@@ -8,41 +8,24 @@ namespace Kakoune
{
Context::Context() = default;
+Context::~Context() = default;
-Context::Context(InputHandler& input_handler, Editor& editor, String name)
- : m_input_handler(&input_handler), m_editor(&editor),
- m_name(std::move(name)) {}
-
-Context::Context(Editor& editor, String name)
- : m_editor(&editor),
+Context::Context(InputHandler& input_handler, Buffer& buffer, SelectionList selections, String name)
+ : m_input_handler{&input_handler}, m_selections{{buffer, std::move(selections)}},
m_name(std::move(name)) {}
-Context::~Context() = default;
-
Buffer& Context::buffer() const
{
if (not has_buffer())
throw runtime_error("no buffer in context");
- return m_editor->buffer();
-}
-
-Editor& Context::editor() const
-{
- if (not has_editor())
- throw runtime_error("no editor in context");
- return *m_editor.get();
+ return (*m_selections).registry();
}
Window& Context::window() const
{
if (not has_window())
throw runtime_error("no window in context");
- return *dynamic_cast<Window*>(m_editor.get());
-}
-
-bool Context::has_window() const
-{
- return (bool)m_editor and dynamic_cast<Window*>(m_editor.get());
+ return *m_window;
}
InputHandler& Context::input_handler() const
@@ -99,6 +82,12 @@ void Context::set_client(Client& client)
m_client.reset(&client);
}
+void Context::set_window(Window& window)
+{
+ kak_assert(&window.buffer() == &buffer());
+ m_window.reset(&window);
+}
+
void Context::print_status(DisplayLine status) const
{
if (has_client())
@@ -111,14 +100,14 @@ void Context::push_jump()
if (m_current_jump != m_jump_list.end())
{
auto begin = m_current_jump;
- if (&editor().buffer() != &begin->buffer() or
+ if (&buffer() != &begin->buffer() or
(const SelectionList&)(*begin) != jump)
++begin;
m_jump_list.erase(begin, m_jump_list.end());
}
m_jump_list.erase(std::remove(begin(m_jump_list), end(m_jump_list), jump),
end(m_jump_list));
- m_jump_list.push_back({editor().buffer(), jump});
+ m_jump_list.push_back({buffer(), jump});
m_current_jump = m_jump_list.end();
}
@@ -168,27 +157,29 @@ void Context::forget_jumps_to_buffer(Buffer& buffer)
}
}
-void Context::change_editor(Editor& editor)
+void Context::change_buffer(Buffer& buffer)
{
- m_editor.reset(&editor);
- if (has_window())
- {
- if (has_ui())
- window().set_dimensions(ui().dimensions());
- window().hooks().run_hook("WinDisplay", buffer().name(), *this);
- }
+ m_window.reset();
+ if (has_client())
+ client().change_buffer(buffer);
+ else
+ m_selections = DynamicSelectionList{ buffer };
if (has_input_handler())
input_handler().reset_normal_mode();
}
SelectionList& Context::selections()
{
- return editor().selections();
+ if (not m_selections)
+ throw runtime_error("no selections in context");
+ return *m_selections;
}
const SelectionList& Context::selections() const
{
- return editor().selections();
+ if (not m_selections)
+ throw runtime_error("no selections in context");
+ return *m_selections;
}
std::vector<String> Context::selections_content() const
diff --git a/src/context.hh b/src/context.hh
index 54c79490..60d76c71 100644
--- a/src/context.hh
+++ b/src/context.hh
@@ -3,6 +3,8 @@
#include "dynamic_selection_list.hh"
+#include <boost/optional.hpp>
+
namespace Kakoune
{
@@ -25,21 +27,17 @@ class Context
{
public:
Context();
- Context(InputHandler& input_handler, Editor& editor, String name = "");
- Context(Editor& editor, String name = "");
+ Context(InputHandler& input_handler, Buffer& buffer, SelectionList selections, String name = "");
~Context();
Context(const Context&) = delete;
Context& operator=(const Context&) = delete;
Buffer& buffer() const;
- bool has_buffer() const { return (bool)m_editor; }
-
- Editor& editor() const;
- bool has_editor() const { return (bool)m_editor; }
+ bool has_buffer() const { return m_selections; }
Window& window() const;
- bool has_window() const;
+ bool has_window() const { return (bool)m_window; }
Client& client() const;
bool has_client() const { return (bool)m_client; }
@@ -54,9 +52,10 @@ public:
const SelectionList& selections() const;
std::vector<String> selections_content() const;
- void change_editor(Editor& editor);
+ void change_buffer(Buffer& buffer);
void set_client(Client& client);
+ void set_window(Window& window);
OptionManager& options() const;
HookManager& hooks() const;
@@ -81,10 +80,13 @@ private:
friend struct ScopedEdition;
- safe_ptr<Editor> m_editor;
safe_ptr<InputHandler> m_input_handler;
+ safe_ptr<Window> m_window;
safe_ptr<Client> m_client;
+ friend class Client;
+ boost::optional<DynamicSelectionList> m_selections;
+
String m_name;
using JumpList = std::vector<DynamicSelectionList>;
diff --git a/src/debug.cc b/src/debug.cc
index 7b97b2f0..61bc7116 100644
--- a/src/debug.cc
+++ b/src/debug.cc
@@ -1,8 +1,8 @@
#include "debug.hh"
#include "assert.hh"
+#include "buffer.hh"
#include "buffer_manager.hh"
-#include "editor.hh"
namespace Kakoune
{
diff --git a/src/dynamic_selection_list.cc b/src/dynamic_selection_list.cc
index 92a95d1c..35ac26a3 100644
--- a/src/dynamic_selection_list.cc
+++ b/src/dynamic_selection_list.cc
@@ -3,7 +3,7 @@
namespace Kakoune
{
-DynamicSelectionList::DynamicSelectionList(const Buffer& buffer,
+DynamicSelectionList::DynamicSelectionList(Buffer& buffer,
SelectionList selections)
: SelectionList(std::move(selections)),
BufferChangeListener_AutoRegister(buffer)
diff --git a/src/dynamic_selection_list.hh b/src/dynamic_selection_list.hh
index fc90dcfd..54cd2d5b 100644
--- a/src/dynamic_selection_list.hh
+++ b/src/dynamic_selection_list.hh
@@ -13,7 +13,7 @@ public:
using iterator = SelectionList::iterator;
using const_iterator = SelectionList::const_iterator;
- DynamicSelectionList(const Buffer& buffer, SelectionList selections = {});
+ DynamicSelectionList(Buffer& buffer, SelectionList selections = {});
DynamicSelectionList& operator=(SelectionList selections);
void check_invariant() const;
diff --git a/src/editor.hh b/src/editor.hh
deleted file mode 100644
index 11f3ecee..00000000
--- a/src/editor.hh
+++ /dev/null
@@ -1,35 +0,0 @@
-#ifndef editor_hh_INCLUDED
-#define editor_hh_INCLUDED
-
-#include "buffer.hh"
-#include "dynamic_selection_list.hh"
-#include "memoryview.hh"
-
-namespace Kakoune
-{
-
-// An Editor is a to be removed class from the past
-class Editor : public SafeCountable
-{
-public:
- Editor(Buffer& buffer)
- : m_buffer(&buffer),
- m_selections(buffer, {BufferCoord{}})
- {}
-
- virtual ~Editor() {}
-
- Buffer& buffer() const { return *m_buffer; }
-
- const SelectionList& selections() const { return m_selections; }
- SelectionList& selections() { return m_selections; }
-
-private:
- safe_ptr<Buffer> m_buffer;
- DynamicSelectionList m_selections;
-};
-
-}
-
-#endif // editor_hh_INCLUDED
-
diff --git a/src/input_handler.cc b/src/input_handler.cc
index 03c9f497..c68c0c76 100644
--- a/src/input_handler.cc
+++ b/src/input_handler.cc
@@ -995,7 +995,7 @@ private:
template<typename Type>
void move(Type offset)
{
- auto& selections = context().editor().selections();
+ auto& selections = context().selections();
for (auto& sel : selections)
{
auto last = context().has_window() ? context().window().offset_coord(sel.last(), offset)
@@ -1125,9 +1125,9 @@ void InputMode::reset_normal_mode()
m_input_handler.reset_normal_mode();
}
-InputHandler::InputHandler(Editor& editor, String name)
+InputHandler::InputHandler(Buffer& buffer, SelectionList selections, String name)
: m_mode(new InputModes::Normal(*this)),
- m_context(*this, editor, std::move(name))
+ m_context(*this, buffer, std::move(selections), std::move(name))
{
}
diff --git a/src/input_handler.hh b/src/input_handler.hh
index 93e0ae94..461470e0 100644
--- a/src/input_handler.hh
+++ b/src/input_handler.hh
@@ -37,7 +37,7 @@ enum class InsertMode : unsigned;
class InputHandler : public SafeCountable
{
public:
- InputHandler(Editor& editor, String name = "");
+ InputHandler(Buffer& buffer, SelectionList selections, String name = "");
~InputHandler();
// switch to insert mode
diff --git a/src/normal.cc b/src/normal.cc
index 175173c0..e612f6f7 100644
--- a/src/normal.cc
+++ b/src/normal.cc
@@ -285,8 +285,7 @@ void goto_commands(Context& context, int line)
if (it->get() == &buffer and ++it == buffer_manager.end())
break;
context.push_jump();
- auto& client_manager = ClientManager::instance();
- context.change_editor(client_manager.get_unused_window_for_buffer(**it));
+ context.change_buffer(**it);
break;
}
case 'f':
@@ -894,7 +893,7 @@ void scroll(Context& context, int)
auto cursor_pos = utf8::advance(buffer.iterator_at(position.line),
buffer.iterator_at(position.line+1),
position.column);
- select_coord(buffer, cursor_pos.coord(), window.selections());
+ select_coord(buffer, cursor_pos.coord(), context.selections());
window.set_position(position);
}
@@ -985,10 +984,7 @@ void jump(Context& context, int)
Buffer& buffer = const_cast<Buffer&>(jump.buffer());
BufferManager::instance().set_last_used_buffer(buffer);
if (&buffer != &context.buffer())
- {
- auto& manager = ClientManager::instance();
- context.change_editor(manager.get_unused_window_for_buffer(buffer));
- }
+ context.change_buffer(buffer);
context.selections() = jump;
}
diff --git a/src/selectors.hh b/src/selectors.hh
index da9b195f..0cfa7a68 100644
--- a/src/selectors.hh
+++ b/src/selectors.hh
@@ -3,7 +3,6 @@
#include "selection.hh"
#include "unicode.hh"
-#include "editor.hh"
#include "utf8_iterator.hh"
namespace Kakoune
diff --git a/src/unit_tests.cc b/src/unit_tests.cc
index 8bd0c5fc..3b2b2960 100644
--- a/src/unit_tests.cc
+++ b/src/unit_tests.cc
@@ -1,6 +1,5 @@
#include "assert.hh"
#include "buffer.hh"
-#include "editor.hh"
#include "keys.hh"
#include "selectors.hh"
diff --git a/src/utils.hh b/src/utils.hh
index a08e7707..0cbf4c91 100644
--- a/src/utils.hh
+++ b/src/utils.hh
@@ -109,7 +109,7 @@ public:
return *this;
}
- void reset(T* ptr)
+ void reset(T* ptr = nullptr)
{
*this = safe_ptr(ptr);
}
diff --git a/src/window.cc b/src/window.cc
index b7e4b0c8..c982bd82 100644
--- a/src/window.cc
+++ b/src/window.cc
@@ -18,12 +18,13 @@ void expand_tabulations(const Context& context, DisplayBuffer& display_buffer);
void expand_unprintable(const Context& context, DisplayBuffer& display_buffer);
Window::Window(Buffer& buffer)
- : Editor(buffer),
+ : m_buffer(&buffer),
m_hooks(buffer.hooks()),
m_options(buffer.options()),
m_keymaps(buffer.keymaps())
{
- InputHandler hook_handler{*this};
+ InputHandler hook_handler{*m_buffer, SelectionList{ {} } };
+ hook_handler.context().set_window(*this);
m_hooks.run_hook("WinCreate", buffer.name(), hook_handler.context());
m_options.register_watcher(*this);
@@ -37,7 +38,8 @@ Window::Window(Buffer& buffer)
Window::~Window()
{
- InputHandler hook_handler{*this};
+ InputHandler hook_handler{*m_buffer, SelectionList{ {} } };
+ hook_handler.context().set_window(*this);
m_hooks.run_hook("WinClose", buffer().name(), hook_handler.context());
m_options.unregister_watcher(*this);
}
@@ -66,7 +68,7 @@ void Window::scroll(CharCount offset)
void Window::update_display_buffer(const Context& context)
{
kak_assert(&buffer() == &context.buffer());
- scroll_to_keep_selection_visible_ifn(context.selections().main());
+ scroll_to_keep_selection_visible_ifn(context);
DisplayBuffer::LineList& lines = m_display_buffer.lines();
lines.clear();
@@ -143,8 +145,9 @@ static CharCount adapt_view_pos(const DisplayBuffer& display_buffer,
return view_pos;
}
-void Window::scroll_to_keep_selection_visible_ifn(const Range& selection)
+void Window::scroll_to_keep_selection_visible_ifn(const Context& context)
{
+ auto& selection = context.selections().main();
const auto& first = selection.first();
const auto& last = selection.last();
@@ -163,8 +166,8 @@ void Window::scroll_to_keep_selection_visible_ifn(const Range& selection)
lines.emplace_back(AtomList{ {buffer(), last.line, last.line+1} });
display_buffer.compute_range();
- m_highlighters(*this, display_buffer);
- m_builtin_highlighters(*this, display_buffer);
+ m_highlighters(context, display_buffer);
+ m_builtin_highlighters(context, display_buffer);
// now we can compute where the cursor is in display columns
// (this is only valid if highlighting one line and multiple lines put
@@ -245,9 +248,10 @@ BufferCoord Window::offset_coord(BufferCoord coord, LineCount offset)
lines.emplace_back(AtomList{ {buffer(), line, line+1} });
display_buffer.compute_range();
- Context context(*this);
- m_highlighters(*this, display_buffer);
- m_builtin_highlighters(*this, display_buffer);
+ InputHandler hook_handler{*m_buffer, SelectionList{ {} } };
+ hook_handler.context().set_window(*this);
+ m_highlighters(hook_handler.context(), display_buffer);
+ m_builtin_highlighters(hook_handler.context(), display_buffer);
CharCount column = find_display_column(lines[0], buffer(), coord);
return find_buffer_coord(lines[1], buffer(), column);
@@ -256,7 +260,8 @@ BufferCoord Window::offset_coord(BufferCoord coord, LineCount offset)
void Window::on_option_changed(const Option& option)
{
String desc = option.name() + "=" + option.get_as_string();
- InputHandler hook_handler{*this};
+ InputHandler hook_handler{*m_buffer, SelectionList{ {} } };
+ hook_handler.context().set_window(*this);
m_hooks.run_hook("WinSetOption", desc, hook_handler.context());
// an highlighter might depend on the option, so we need to redraw
diff --git a/src/window.hh b/src/window.hh
index 33fed537..3b8928db 100644
--- a/src/window.hh
+++ b/src/window.hh
@@ -3,9 +3,8 @@
#include "completion.hh"
#include "display_buffer.hh"
-#include "editor.hh"
-#include "highlighter.hh"
#include "highlighter.hh"
+#include "selection.hh"
#include "hook_manager.hh"
#include "option_manager.hh"
#include "keymap_manager.hh"
@@ -13,13 +12,8 @@
namespace Kakoune
{
-// A Window is an editing view onto a Buffer
-//
-// The Window class is an interactive Editor adding display functionalities
-// to the editing ones already provided by the Editor class.
-// Display can be customized through the use of highlighters handled by
-// the window's HighlighterGroup
-class Window : public Editor, public OptionManagerWatcher
+// A Window is a view onto a Buffer
+class Window : public SafeCountable, public OptionManagerWatcher
{
public:
Window(Buffer& buffer);
@@ -50,6 +44,8 @@ public:
KeymapManager& keymaps() { return m_keymaps; }
const KeymapManager& keymaps() const { return m_keymaps; }
+ Buffer& buffer() const { return *m_buffer; }
+
size_t timestamp() const { return m_timestamp; }
void forget_timestamp() { m_timestamp = -1; }
@@ -59,8 +55,9 @@ private:
Window(const Window&) = delete;
void on_option_changed(const Option& option) override;
+ void scroll_to_keep_selection_visible_ifn(const Context& context);
- void scroll_to_keep_selection_visible_ifn(const Range& selection);
+ safe_ptr<Buffer> m_buffer;
DisplayCoord m_position;
DisplayCoord m_dimensions;