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:
Maxime Coste 2012-04-03 13:39:20 +00:00
parent c8447658c0
commit f3dd65fbf1
9 changed files with 127 additions and 9 deletions

View File

@ -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())

View File

@ -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,

View File

@ -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")
{ {

View File

@ -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);

View File

@ -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
View 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
View 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

View File

@ -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();

View File

@ -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
{ {
@ -38,7 +39,8 @@ 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;
}; };
} }