add an OptionManager class and use it to manage tabstops
OptionManager map names to options, and may delegate option resolution to it's parent if it does not contains the asked for option. That way Buffers can override global options, and Windows can override Buffer options.
This commit is contained in:
parent
c8447658c0
commit
f3dd65fbf1
|
@ -26,7 +26,8 @@ Buffer::Buffer(const std::string& name, Type type,
|
||||||
const String& initial_content)
|
const String& initial_content)
|
||||||
: m_name(name), m_type(type),
|
: m_name(name), m_type(type),
|
||||||
m_history(1), m_history_cursor(m_history.begin()),
|
m_history(1), m_history_cursor(m_history.begin()),
|
||||||
m_last_save_undo_index(0)
|
m_last_save_undo_index(0),
|
||||||
|
m_option_manager(GlobalOptionManager::instance())
|
||||||
{
|
{
|
||||||
BufferManager::instance().register_buffer(this);
|
BufferManager::instance().register_buffer(this);
|
||||||
if (not initial_content.empty())
|
if (not initial_content.empty())
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "line_and_column.hh"
|
#include "line_and_column.hh"
|
||||||
|
#include "option_manager.hh"
|
||||||
|
|
||||||
namespace Kakoune
|
namespace Kakoune
|
||||||
{
|
{
|
||||||
|
@ -173,6 +174,8 @@ public:
|
||||||
|
|
||||||
const String& line_content(size_t l) const { return m_lines[l].content; }
|
const String& line_content(size_t l) const { return m_lines[l].content; }
|
||||||
|
|
||||||
|
OptionManager& option_manager() { return m_option_manager; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class BufferIterator;
|
friend class BufferIterator;
|
||||||
|
|
||||||
|
@ -210,6 +213,8 @@ private:
|
||||||
size_t m_last_save_undo_index;
|
size_t m_last_save_undo_index;
|
||||||
|
|
||||||
std::vector<ModificationListener*> m_modification_listeners;
|
std::vector<ModificationListener*> m_modification_listeners;
|
||||||
|
|
||||||
|
OptionManager m_option_manager;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline Modification Modification::make_erase(BufferIterator begin,
|
inline Modification Modification::make_erase(BufferIterator begin,
|
||||||
|
|
|
@ -39,7 +39,7 @@ void cleanup_whitespaces(Buffer& buffer, Modification& modification)
|
||||||
|
|
||||||
void expand_tabulations(Buffer& buffer, Modification& modification)
|
void expand_tabulations(Buffer& buffer, Modification& modification)
|
||||||
{
|
{
|
||||||
const int tabstop = 8;
|
const int tabstop = buffer.option_manager()["tabstop"];
|
||||||
if (modification.type == Modification::Insert and
|
if (modification.type == Modification::Insert and
|
||||||
modification.content == "\t")
|
modification.content == "\t")
|
||||||
{
|
{
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
namespace Kakoune
|
namespace Kakoune
|
||||||
{
|
{
|
||||||
|
|
||||||
|
using namespace std::placeholders;
|
||||||
|
|
||||||
void colorize_regex_range(DisplayBuffer& display_buffer,
|
void colorize_regex_range(DisplayBuffer& display_buffer,
|
||||||
const BufferIterator& range_begin,
|
const BufferIterator& range_begin,
|
||||||
const BufferIterator& range_end,
|
const BufferIterator& range_end,
|
||||||
|
@ -97,13 +99,13 @@ HighlighterAndId colorize_regex_factory(Window& window,
|
||||||
|
|
||||||
std::string id = "colre'" + params[0] + "'";
|
std::string id = "colre'" + params[0] + "'";
|
||||||
|
|
||||||
return HighlighterAndId(id, std::bind(colorize_regex, std::placeholders::_1,
|
return HighlighterAndId(id, std::bind(colorize_regex, _1,
|
||||||
ex, fg_color, bg_color));
|
ex, fg_color, bg_color));
|
||||||
}
|
}
|
||||||
|
|
||||||
void expand_tabulations(DisplayBuffer& display_buffer)
|
void expand_tabulations(Window& window, DisplayBuffer& display_buffer)
|
||||||
{
|
{
|
||||||
const int tabstop = 8;
|
const int tabstop = window.option_manager()["tabstop"];
|
||||||
for (auto atom_it = display_buffer.begin();
|
for (auto atom_it = display_buffer.begin();
|
||||||
atom_it != display_buffer.end(); ++atom_it)
|
atom_it != display_buffer.end(); ++atom_it)
|
||||||
{
|
{
|
||||||
|
@ -289,7 +291,6 @@ public:
|
||||||
HighlighterAndId operator()(Window& window,
|
HighlighterAndId operator()(Window& window,
|
||||||
const HighlighterParameters& params) const
|
const HighlighterParameters& params) const
|
||||||
{
|
{
|
||||||
using namespace std::placeholders;
|
|
||||||
return HighlighterAndId(m_id, std::bind(highlighter_func, std::ref(window), _1));
|
return HighlighterAndId(m_id, std::bind(highlighter_func, std::ref(window), _1));
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
|
@ -310,7 +311,7 @@ void register_highlighters()
|
||||||
HighlighterRegistry& registry = HighlighterRegistry::instance();
|
HighlighterRegistry& registry = HighlighterRegistry::instance();
|
||||||
|
|
||||||
registry.register_factory("highlight_selections", WindowHighlighterFactory<highlight_selections>("highlight_selections"));
|
registry.register_factory("highlight_selections", WindowHighlighterFactory<highlight_selections>("highlight_selections"));
|
||||||
registry.register_factory("expand_tabs", SimpleHighlighterFactory<expand_tabulations>("expand_tabs"));
|
registry.register_factory("expand_tabs", WindowHighlighterFactory<expand_tabulations>("expand_tabs"));
|
||||||
registry.register_factory("number_lines", SimpleHighlighterFactory<show_line_numbers>("number_lines"));
|
registry.register_factory("number_lines", SimpleHighlighterFactory<show_line_numbers>("number_lines"));
|
||||||
registry.register_factory("regex", colorize_regex_factory);
|
registry.register_factory("regex", colorize_regex_factory);
|
||||||
registry.register_factory("group", highlighter_group_factory);
|
registry.register_factory("group", highlighter_group_factory);
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include "filters.hh"
|
#include "filters.hh"
|
||||||
#include "filter_registry.hh"
|
#include "filter_registry.hh"
|
||||||
#include "hook_manager.hh"
|
#include "hook_manager.hh"
|
||||||
|
#include "option_manager.hh"
|
||||||
#include "context.hh"
|
#include "context.hh"
|
||||||
#include "ncurses.hh"
|
#include "ncurses.hh"
|
||||||
|
|
||||||
|
@ -918,6 +919,7 @@ int main(int argc, char* argv[])
|
||||||
HighlighterRegistry highlighter_registry;
|
HighlighterRegistry highlighter_registry;
|
||||||
FilterRegistry filter_registry;
|
FilterRegistry filter_registry;
|
||||||
GlobalHookManager hook_manager;
|
GlobalHookManager hook_manager;
|
||||||
|
GlobalOptionManager option_manager;
|
||||||
|
|
||||||
run_unit_tests();
|
run_unit_tests();
|
||||||
|
|
||||||
|
|
21
src/option_manager.cc
Normal file
21
src/option_manager.cc
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
#include "option_manager.hh"
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
namespace Kakoune
|
||||||
|
{
|
||||||
|
|
||||||
|
std::string int_to_str(int value)
|
||||||
|
{
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << value;
|
||||||
|
return oss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
GlobalOptionManager::GlobalOptionManager()
|
||||||
|
: OptionManager()
|
||||||
|
{
|
||||||
|
(*this)["tabstop"] = 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
84
src/option_manager.hh
Normal file
84
src/option_manager.hh
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
#ifndef option_manager_hh_INCLUDED
|
||||||
|
#define option_manager_hh_INCLUDED
|
||||||
|
|
||||||
|
#include "utils.hh"
|
||||||
|
#include "exception.hh"
|
||||||
|
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
namespace Kakoune
|
||||||
|
{
|
||||||
|
|
||||||
|
struct option_not_found : public runtime_error
|
||||||
|
{
|
||||||
|
option_not_found(const std::string& name)
|
||||||
|
: runtime_error("option not found: " + name) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::string int_to_str(int value);
|
||||||
|
|
||||||
|
class Option
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Option() {}
|
||||||
|
explicit Option(int value) : m_value(int_to_str(value)) {}
|
||||||
|
explicit Option(const std::string& value) : m_value(value) {}
|
||||||
|
|
||||||
|
Option& operator=(int value) { m_value = int_to_str(value); return *this; }
|
||||||
|
Option& operator=(const std::string& value) { m_value = value; return *this; }
|
||||||
|
|
||||||
|
operator int() const { return atoi(m_value.c_str()); }
|
||||||
|
operator std::string() const { return m_value; }
|
||||||
|
private:
|
||||||
|
std::string m_value;
|
||||||
|
};
|
||||||
|
|
||||||
|
class OptionManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
OptionManager(OptionManager& parent)
|
||||||
|
: m_parent(&parent) {}
|
||||||
|
|
||||||
|
Option& operator[] (const std::string& name)
|
||||||
|
{
|
||||||
|
auto it = m_options.find(name);
|
||||||
|
if (it != m_options.end())
|
||||||
|
return it->second;
|
||||||
|
else if (m_parent)
|
||||||
|
return (*m_parent)[name];
|
||||||
|
else
|
||||||
|
return m_options[name];
|
||||||
|
}
|
||||||
|
|
||||||
|
const Option& operator[] (const std::string& name) const
|
||||||
|
{
|
||||||
|
auto it = m_options.find(name);
|
||||||
|
if (it != m_options.end())
|
||||||
|
return it->second;
|
||||||
|
else if (m_parent)
|
||||||
|
return (*m_parent)[name];
|
||||||
|
else
|
||||||
|
throw option_not_found(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
OptionManager()
|
||||||
|
: m_parent(nullptr) {}
|
||||||
|
// the only one allowed to construct a root option manager
|
||||||
|
friend class GlobalOptionManager;
|
||||||
|
|
||||||
|
std::unordered_map<std::string, Option> m_options;
|
||||||
|
OptionManager* m_parent;
|
||||||
|
};
|
||||||
|
|
||||||
|
class GlobalOptionManager : public OptionManager,
|
||||||
|
public Singleton<GlobalOptionManager>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GlobalOptionManager();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // option_manager_hh_INCLUDED
|
|
@ -14,7 +14,8 @@ namespace Kakoune
|
||||||
Window::Window(Buffer& buffer)
|
Window::Window(Buffer& buffer)
|
||||||
: Editor(buffer),
|
: Editor(buffer),
|
||||||
m_position(0, 0),
|
m_position(0, 0),
|
||||||
m_dimensions(0, 0)
|
m_dimensions(0, 0),
|
||||||
|
m_option_manager(buffer.option_manager())
|
||||||
{
|
{
|
||||||
HighlighterRegistry& registry = HighlighterRegistry::instance();
|
HighlighterRegistry& registry = HighlighterRegistry::instance();
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include "highlighter.hh"
|
#include "highlighter.hh"
|
||||||
#include "highlighter_group.hh"
|
#include "highlighter_group.hh"
|
||||||
#include "hook_manager.hh"
|
#include "hook_manager.hh"
|
||||||
|
#include "option_manager.hh"
|
||||||
|
|
||||||
namespace Kakoune
|
namespace Kakoune
|
||||||
{
|
{
|
||||||
|
@ -39,6 +40,7 @@ public:
|
||||||
HighlighterGroup& highlighters() { return m_highlighters; }
|
HighlighterGroup& highlighters() { return m_highlighters; }
|
||||||
|
|
||||||
HookManager& hook_manager() { return m_hook_manager; }
|
HookManager& hook_manager() { return m_hook_manager; }
|
||||||
|
OptionManager& option_manager() { return m_option_manager; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class Buffer;
|
friend class Buffer;
|
||||||
|
@ -57,6 +59,7 @@ private:
|
||||||
HighlighterGroup m_highlighters;
|
HighlighterGroup m_highlighters;
|
||||||
|
|
||||||
HookManager m_hook_manager;
|
HookManager m_hook_manager;
|
||||||
|
OptionManager m_option_manager;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user