summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMaxime Coste <frrrwww@gmail.com>2014-10-30 14:00:42 +0000
committerMaxime Coste <frrrwww@gmail.com>2014-10-30 14:04:57 +0000
commite38ba6ce3d62c2629ebdaad41258d5e4b48f5296 (patch)
tree609ef5d7df44e7222ab961634b7c81c97102881a /src
parent8649371ff23df34c0bf6ca34c1d8b61d7482821e (diff)
Add scope class and encapsulate Options, Keymaps, Aliases and Hooks in it
Diffstat (limited to 'src')
-rw-r--r--src/alias_registry.hh5
-rw-r--r--src/buffer.cc17
-rw-r--r--src/buffer.hh21
-rw-r--r--src/commands.cc113
-rw-r--r--src/context.cc31
-rw-r--r--src/context.hh3
-rw-r--r--src/highlighters.cc6
-rw-r--r--src/hook_manager.hh7
-rw-r--r--src/keymap_manager.hh7
-rw-r--r--src/main.cc68
-rw-r--r--src/option_manager.cc49
-rw-r--r--src/option_manager.hh22
-rw-r--r--src/scope.hh53
-rw-r--r--src/window.cc19
-rw-r--r--src/window.hh21
15 files changed, 201 insertions, 241 deletions
diff --git a/src/alias_registry.hh b/src/alias_registry.hh
index 97f52ee3..ae879eef 100644
--- a/src/alias_registry.hh
+++ b/src/alias_registry.hh
@@ -21,16 +21,13 @@ public:
std::vector<StringView> aliases_for(StringView command) const;
private:
- friend class GlobalAliases;
+ friend class Scope;
AliasRegistry() {}
safe_ptr<AliasRegistry> m_parent;
std::unordered_map<String, String> m_aliases;
};
-class GlobalAliases : public AliasRegistry, public Singleton<GlobalAliases>
-{};
-
}
#endif // alias_registry_hh_INCLUDED
diff --git a/src/buffer.cc b/src/buffer.cc
index 9bdc76df..6956c121 100644
--- a/src/buffer.cc
+++ b/src/buffer.cc
@@ -16,18 +16,15 @@ namespace Kakoune
Buffer::Buffer(String name, Flags flags, std::vector<String> lines,
time_t fs_timestamp)
- : m_name(flags & Flags::File ? real_path(parse_filename(name)) : std::move(name)),
+ : Scope(GlobalScope::instance()),
+ m_name(flags & Flags::File ? real_path(parse_filename(name)) : std::move(name)),
m_flags(flags | Flags::NoUndo),
m_history(), m_history_cursor(m_history.begin()),
m_last_save_undo_index(0),
- m_fs_timestamp(fs_timestamp),
- m_hooks(GlobalHooks::instance()),
- m_options(GlobalOptions::instance()),
- m_keymaps(GlobalKeymaps::instance()),
- m_aliases(GlobalAliases::instance())
+ m_fs_timestamp(fs_timestamp)
{
BufferManager::instance().register_buffer(*this);
- m_options.register_watcher(*this);
+ options().register_watcher(*this);
if (lines.empty())
lines.emplace_back("\n");
@@ -57,7 +54,7 @@ Buffer::Buffer(String name, Flags flags, std::vector<String> lines,
// now we may begin to record undo data
m_flags = flags;
- for (auto& option : m_options.flatten_options())
+ for (auto& option : options().flatten_options())
on_option_changed(*option);
}
@@ -65,7 +62,7 @@ Buffer::~Buffer()
{
run_hook_in_own_context("BufClose", m_name);
- m_options.unregister_watcher(*this);
+ options().unregister_watcher(*this);
BufferManager::instance().unregister_buffer(*this);
m_values.clear();
}
@@ -520,7 +517,7 @@ void Buffer::on_option_changed(const Option& option)
void Buffer::run_hook_in_own_context(const String& hook_name, StringView param)
{
InputHandler hook_handler({ *this, Selection{} });
- m_hooks.run_hook(hook_name, param, hook_handler.context());
+ hooks().run_hook(hook_name, param, hook_handler.context());
}
ByteCoord Buffer::last_modification_coord() const
diff --git a/src/buffer.hh b/src/buffer.hh
index 63b2e7cd..4715ddc1 100644
--- a/src/buffer.hh
+++ b/src/buffer.hh
@@ -1,13 +1,10 @@
#ifndef buffer_hh_INCLUDED
#define buffer_hh_INCLUDED
-#include "alias_registry.hh"
#include "coord.hh"
#include "flags.hh"
-#include "hook_manager.hh"
-#include "option_manager.hh"
-#include "keymap_manager.hh"
#include "safe_ptr.hh"
+#include "scope.hh"
#include "interned_string.hh"
#include "value.hh"
@@ -71,7 +68,7 @@ private:
// The Buffer class permits to read and mutate this file
// representation. It also manage modifications undo/redo and
// provides tools to deal with the line/column nature of text.
-class Buffer : public SafeCountable, public OptionManagerWatcher
+class Buffer : public SafeCountable, public OptionManagerWatcher, public Scope
{
public:
enum class Flags
@@ -150,15 +147,6 @@ public:
// notify the buffer that it was saved in the current state
void notify_saved();
- OptionManager& options() { return m_options; }
- const OptionManager& options() const { return m_options; }
- HookManager& hooks() { return m_hooks; }
- const HookManager& hooks() const { return m_hooks; }
- KeymapManager& keymaps() { return m_keymaps; }
- const KeymapManager& keymaps() const { return m_keymaps; }
- AliasRegistry& aliases() { return m_aliases; }
- const AliasRegistry& aliases() const { return m_aliases; }
-
ValueMap& values() const { return m_values; }
void run_hook_in_own_context(const String& hook_name, StringView param);
@@ -217,11 +205,6 @@ private:
time_t m_fs_timestamp;
- OptionManager m_options;
- HookManager m_hooks;
- KeymapManager m_keymaps;
- AliasRegistry m_aliases;
-
// Values are just data holding by the buffer, so it is part of its
// observable state
mutable ValueMap m_values;
diff --git a/src/commands.cc b/src/commands.cc
index 9bb6d8e1..240daea1 100644
--- a/src/commands.cc
+++ b/src/commands.cc
@@ -84,6 +84,26 @@ const ParameterDesc single_optional_name_param{
static constexpr auto scopes = { "global", "buffer", "window" };
+Scope* get_scope_ifp(const String& scope, const Context& context)
+{
+ if (prefix_match("global", scope))
+ return &GlobalScope::instance();
+ else if (prefix_match("buffer", scope))
+ return &context.buffer();
+ else if (prefix_match("window", scope))
+ return &context.window();
+ else if (prefix_match(scope, "buffer="))
+ return &BufferManager::instance().get_buffer(scope.substr(7_byte));
+ return nullptr;
+}
+
+Scope& get_scope(const String& scope, const Context& context)
+{
+ if (auto s = get_scope_ifp(scope, context))
+ return *s;
+ throw runtime_error("error: no such scope " + scope);
+}
+
struct CommandDesc
{
const char* name;
@@ -495,24 +515,6 @@ const CommandDesc rm_highlighter_cmd = {
}
};
-HookManager* get_hook_manager_ifp(const String& scope, const Context& context)
-{
- if (prefix_match("global", scope))
- return &GlobalHooks::instance();
- else if (prefix_match("buffer", scope))
- return &context.buffer().hooks();
- else if (prefix_match("window", scope))
- return &context.window().hooks();
- return nullptr;
-}
-
-HookManager& get_hook_manager(const String& scope, const Context& context)
-{
- if (auto manager = get_hook_manager_ifp(scope, context))
- return *manager;
- throw runtime_error("error: no such hook container " + scope);
-}
-
const CommandDesc add_hook_cmd = {
"hook",
nullptr,
@@ -557,14 +559,14 @@ const CommandDesc add_hook_cmd = {
StringView group;
if (parser.has_option("group"))
group = parser.option_value("group");
- get_hook_manager(parser[0], context).add_hook(parser[1], group, hook_func);
+ get_scope(parser[0], context).hooks().add_hook(parser[1], group, hook_func);
}
};
const CommandDesc rm_hook_cmd = {
"rmhooks",
nullptr,
- "rmhooks <group>: remove all hooks whose group is <group>",
+ "rmhooks <scope> <group>: remove all hooks whose group is <group>",
ParameterDesc{ SwitchMap{}, ParameterDesc::Flags::None, 2, 2 },
CommandFlags::None,
[](const Context& context, CompletionFlags flags,
@@ -576,15 +578,15 @@ const CommandDesc rm_hook_cmd = {
prefix_complete(params[0].substr(0_byte, pos_in_token), scopes) };
else if (token_to_complete == 1)
{
- if (auto manager = get_hook_manager_ifp(params[0], context))
+ if (auto scope = get_scope_ifp(params[0], context))
return { 0_byte, params[0].length(),
- manager->complete_hook_group(params[1], pos_in_token) };
+ scope->hooks().complete_hook_group(params[1], pos_in_token) };
}
return {};
},
[](const ParametersParser& parser, Context& context)
{
- get_hook_manager(parser[0], context).remove_hooks(parser[1]);
+ get_scope(parser[0], context).hooks().remove_hooks(parser[1]);
}
};
@@ -712,17 +714,6 @@ const CommandDesc define_command_cmd = {
define_command
};
-AliasRegistry& get_aliases(const String& scope, const Context& context)
-{
- if (prefix_match("global", scope))
- return GlobalAliases::instance();
- else if (prefix_match("buffer", scope))
- return context.buffer().aliases();
- else if (prefix_match("window", scope))
- return context.window().aliases();
- throw runtime_error("error: no such scope " + scope);
-}
-
const CommandDesc alias_cmd = {
"alias",
nullptr,
@@ -732,7 +723,7 @@ const CommandDesc alias_cmd = {
CommandCompleter{},
[](const ParametersParser& parser, Context& context)
{
- AliasRegistry& aliases = get_aliases(parser[0], context);
+ AliasRegistry& aliases = get_scope(parser[0], context).aliases();
aliases.add_alias(parser[1], parser[2]);
}
};
@@ -747,7 +738,7 @@ const CommandDesc unalias_cmd = {
CommandCompleter{},
[](const ParametersParser& parser, Context& context)
{
- AliasRegistry& aliases = get_aliases(parser[0], context);
+ AliasRegistry& aliases = get_scope(parser[0], context).aliases();
if (parser.positional_count() == 3 and
aliases[parser[1]] != parser[2])
return;
@@ -831,19 +822,6 @@ const CommandDesc source_cmd = {
}
};
-OptionManager& get_options(const String& scope, const Context& context)
-{
- if (prefix_match("global", scope))
- return GlobalOptions::instance();
- else if (prefix_match("buffer", scope))
- return context.buffer().options();
- else if (prefix_match("window", scope))
- return context.window().options();
- else if (prefix_match(scope, "buffer="))
- return BufferManager::instance().get_buffer(scope.substr(7_byte)).options();
- throw runtime_error("error: no such option container " + scope);
-}
-
const CommandDesc set_option_cmd = {
"set",
nullptr,
@@ -863,14 +841,14 @@ const CommandDesc set_option_cmd = {
prefix_complete(params[0].substr(0_byte, pos_in_token), scopes) };
else if (token_to_complete == 1)
{
- OptionManager& options = get_options(params[0], context);
+ OptionManager& options = get_scope(params[0], context).options();
return { 0_byte, params[1].length(),
options.complete_option_name(params[1], pos_in_token) };
}
else if (token_to_complete == 2 and
- GlobalOptions::instance().option_exists(params[1]))
+ GlobalScope::instance().option_registry().option_exists(params[1]))
{
- OptionManager& options = get_options(params[0], context);
+ OptionManager& options = get_scope(params[0], context).options();
String val = options[params[1]].get_as_string();
if (prefix_match(val, params[2]))
return { 0_byte, params[2].length(), { std::move(val) } };
@@ -879,7 +857,7 @@ const CommandDesc set_option_cmd = {
},
[](const ParametersParser& parser, Context& context)
{
- Option& opt = get_options(parser[0], context).get_local_option(parser[1]);
+ Option& opt = get_scope(parser[0], context).options().get_local_option(parser[1]);
if (parser.has_option("add"))
opt.add_from_string(parser[2]);
else
@@ -920,22 +898,22 @@ const CommandDesc declare_option_cmd = {
if (parser.has_option("docstring"))
docstring = parser.option_value("docstring");
- GlobalOptions& opts = GlobalOptions::instance();
+ OptionsRegistry& reg = GlobalScope::instance().option_registry();
if (parser[0] == "int")
- opt = &opts.declare_option<int>(parser[1], docstring, 0, flags);
+ opt = &reg.declare_option<int>(parser[1], docstring, 0, flags);
else if (parser[0] == "bool")
- opt = &opts.declare_option<bool>(parser[1], docstring, 0, flags);
+ opt = &reg.declare_option<bool>(parser[1], docstring, 0, flags);
else if (parser[0] == "str")
- opt = &opts.declare_option<String>(parser[1], docstring, "", flags);
+ opt = &reg.declare_option<String>(parser[1], docstring, "", flags);
else if (parser[0] == "regex")
- opt = &opts.declare_option<Regex>(parser[1], docstring, Regex{}, flags);
+ opt = &reg.declare_option<Regex>(parser[1], docstring, Regex{}, flags);
else if (parser[0] == "int-list")
- opt = &opts.declare_option<std::vector<int>>(parser[1], docstring, {}, flags);
+ opt = &reg.declare_option<std::vector<int>>(parser[1], docstring, {}, flags);
else if (parser[0] == "str-list")
- opt = &opts.declare_option<std::vector<String>>(parser[1], docstring, {}, flags);
+ opt = &reg.declare_option<std::vector<String>>(parser[1], docstring, {}, flags);
else if (parser[0] == "line-flag-list")
- opt = &opts.declare_option<std::vector<LineAndFlag>>(parser[1], docstring, {}, flags);
+ opt = &reg.declare_option<std::vector<LineAndFlag>>(parser[1], docstring, {}, flags);
else
throw runtime_error("unknown type " + parser[0]);
@@ -944,15 +922,6 @@ const CommandDesc declare_option_cmd = {
}
};
-KeymapManager& get_keymap_manager(const String& scope, Context& context)
-{
- if (prefix_match("global", scope)) return GlobalKeymaps::instance();
- if (prefix_match("buffer", scope)) return context.buffer().keymaps();
- if (prefix_match("window", scope)) return context.window().keymaps();
-
- throw runtime_error("error: no such keymap container " + scope);
-}
-
KeymapMode parse_keymap_mode(const String& str)
{
if (prefix_match("normal", str)) return KeymapMode::Normal;
@@ -997,7 +966,7 @@ const CommandDesc map_key_cmd = {
},
[](const ParametersParser& parser, Context& context)
{
- KeymapManager& keymaps = get_keymap_manager(parser[0], context);
+ KeymapManager& keymaps = get_scope(parser[0], context).keymaps();
KeymapMode keymap_mode = parse_keymap_mode(parser[1]);
KeyList key = parse_keys(parser[2]);
@@ -1419,7 +1388,7 @@ static void register_command(CommandManager& cm, const CommandDesc& c)
{
cm.register_command(c.name, c.func, c.docstring, c.params, c.flags, c.completer);
if (c.alias)
- GlobalAliases::instance().add_alias(c.alias, c.name);
+ GlobalScope::instance().aliases().add_alias(c.alias, c.name);
}
void register_commands()
diff --git a/src/context.cc b/src/context.cc
index 883df5ee..4c72c2bf 100644
--- a/src/context.cc
+++ b/src/context.cc
@@ -54,40 +54,33 @@ UserInterface& Context::ui() const
return client().ui();
}
-OptionManager& Context::options() const
+Scope& Context::scope() const
{
if (has_window())
- return window().options();
+ return window();
if (has_buffer())
- return buffer().options();
- return GlobalOptions::instance();
+ return buffer();
+ return GlobalScope::instance();
+}
+
+OptionManager& Context::options() const
+{
+ return scope().options();
}
HookManager& Context::hooks() const
{
- if (has_window())
- return window().hooks();
- if (has_buffer())
- return buffer().hooks();
- return GlobalHooks::instance();
+ return scope().hooks();
}
KeymapManager& Context::keymaps() const
{
- if (has_window())
- return window().keymaps();
- if (has_buffer())
- return buffer().keymaps();
- return GlobalKeymaps::instance();
+ return scope().keymaps();
}
AliasRegistry& Context::aliases() const
{
- if (has_window())
- return window().aliases();
- if (has_buffer())
- return buffer().aliases();
- return GlobalAliases::instance();
+ return scope().aliases();
}
void Context::set_client(Client& client)
diff --git a/src/context.hh b/src/context.hh
index ad54773f..cd7abb23 100644
--- a/src/context.hh
+++ b/src/context.hh
@@ -10,6 +10,7 @@ namespace Kakoune
class Window;
class Buffer;
class Client;
+class Scope;
class InputHandler;
class UserInterface;
class DisplayLine;
@@ -58,6 +59,8 @@ public:
void set_client(Client& client);
void set_window(Window& window);
+ Scope& scope() const;
+
OptionManager& options() const;
HookManager& hooks() const;
KeymapManager& keymaps() const;
diff --git a/src/highlighters.cc b/src/highlighters.cc
index 8acd83c8..be795e4f 100644
--- a/src/highlighters.cc
+++ b/src/highlighters.cc
@@ -395,7 +395,7 @@ HighlighterAndId create_regex_option_highlighter(HighlighterParameters params)
String option_name = params[0];
// verify option type now
- GlobalOptions::instance()[option_name].get<Regex>();
+ GlobalScope::instance().options()[option_name].get<Regex>();
auto get_regex = [option_name](const Context& context){
return context.options()[option_name].get<Regex>();
@@ -412,7 +412,7 @@ HighlighterAndId create_line_option_highlighter(HighlighterParameters params)
String option_name = params[0];
get_face(facespec); // validate facespec
- GlobalOptions::instance()[option_name].get<int>(); // verify option type now
+ GlobalScope::instance().options()[option_name].get<int>(); // verify option type now
auto func = [=](const Context& context, HighlightFlags flags,
DisplayBuffer& display_buffer)
@@ -645,7 +645,7 @@ HighlighterAndId create_flag_lines_highlighter(HighlighterParameters params)
Color bg = str_to_color(params[0]);
// throw if wrong option type
- GlobalOptions::instance()[option_name].get<std::vector<LineAndFlag>>();
+ GlobalScope::instance().options()[option_name].get<std::vector<LineAndFlag>>();
auto func = [=](const Context& context, HighlightFlags flags,
DisplayBuffer& display_buffer)
diff --git a/src/hook_manager.hh b/src/hook_manager.hh
index dd1c6eeb..21aade05 100644
--- a/src/hook_manager.hh
+++ b/src/hook_manager.hh
@@ -27,17 +27,12 @@ private:
HookManager()
: m_parent(nullptr) {}
// the only one allowed to construct a root hook manager
- friend class GlobalHooks;
+ friend class Scope;
HookManager* m_parent;
std::unordered_map<String, id_map<HookFunc>> m_hook;
};
-class GlobalHooks : public HookManager,
- public Singleton<GlobalHooks>
-{
-};
-
}
#endif // hook_manager_hh_INCLUDED
diff --git a/src/keymap_manager.hh b/src/keymap_manager.hh
index 489ad301..6521f69c 100644
--- a/src/keymap_manager.hh
+++ b/src/keymap_manager.hh
@@ -34,7 +34,7 @@ private:
KeymapManager()
: m_parent(nullptr) {}
// the only one allowed to construct a root map manager
- friend class GlobalKeymaps;
+ friend class Scope;
KeymapManager* m_parent;
@@ -43,11 +43,6 @@ private:
Keymap m_mapping;
};
-class GlobalKeymaps : public KeymapManager,
- public Singleton<GlobalKeymaps>
-{
-};
-
}
#endif // keymap_manager_hh_INCLUDED
diff --git a/src/main.cc b/src/main.cc
index 4402d53c..f6154404 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -1,5 +1,4 @@
#include "assert.hh"
-#include "alias_registry.hh"
#include "buffer.hh"
#include "buffer_manager.hh"
#include "buffer_utils.hh"
@@ -12,15 +11,14 @@
#include "face_registry.hh"
#include "file.hh"
#include "highlighters.hh"
-#include "hook_manager.hh"
-#include "keymap_manager.hh"
#include "ncurses.hh"
-#include "option_manager.hh"
#include "parameters_parser.hh"
#include "register_manager.hh"
#include "remote.hh"
#include "shell_manager.hh"
+#include "scope.hh"
#include "string.hh"
+#include "insert_completer.hh"
#include "interned_string.hh"
#include "window.hh"
@@ -187,6 +185,52 @@ void register_registers()
}
}
+void register_options()
+{
+ OptionsRegistry& reg = GlobalScope::instance().option_registry();
+
+ reg.declare_option("tabstop", "size of a tab character", 8);
+ reg.declare_option("indentwidth", "indentation width", 4);
+ reg.declare_option("scrolloff",
+ "number of lines and columns to keep visible main cursor when scrolling",
+ CharCoord{0,0});
+ reg.declare_option("eolformat", "end of line format: 'crlf' or 'lf'", "lf"_str);
+ reg.declare_option("BOM", "insert a byte order mark when writing buffer",
+ "no"_str);
+ reg.declare_option("complete_prefix",
+ "complete up to common prefix in tab completion",
+ true);
+ reg.declare_option("incsearch",
+ "incrementaly apply search/select/split regex",
+ true);
+ reg.declare_option("autoinfo",
+ "automatically display contextual help",
+ 1);
+ reg.declare_option("autoshowcompl",
+ "automatically display possible completions for prompts",
+ true);
+ reg.declare_option("aligntab",
+ "use tab characters when possible for alignement",
+ false);
+ reg.declare_option("ignored_files",
+ "patterns to ignore when completing filenames",
+ Regex{R"(^(\..*|.*\.(o|so|a))$)"});
+ reg.declare_option("disabled_hooks",
+ "patterns to disable hooks whose group is matched",
+ Regex{});
+ reg.declare_option("filetype", "buffer filetype", ""_str);
+ reg.declare_option("path", "path to consider when trying to find a file",
+ std::vector<String>({ "./", "/usr/include" }));
+ reg.declare_option("completers", "insert mode completers to execute.",
+ std::vector<InsertCompleterDesc>({
+ InsertCompleterDesc{ InsertCompleterDesc::Filename },
+ InsertCompleterDesc{ InsertCompleterDesc::Word, "all"_str }
+ }), OptionFlags::None);
+ reg.declare_option("autoreload",
+ "autoreload buffer when a filesystem modification is detected",
+ Ask);
+}
+
void create_local_client(const String& init_command)
{
class LocalNCursesUI : public NCursesUI
@@ -298,10 +342,7 @@ int run_server(StringView session, StringView init_command,
StringRegistry string_registry;
EventManager event_manager;
- GlobalOptions global_options;
- GlobalHooks global_hooks;
- GlobalKeymaps global_keymaps;
- GlobalAliases global_aliases;
+ GlobalScope global_scope;
ShellManager shell_manager;
CommandManager command_manager;
BufferManager buffer_manager;
@@ -313,6 +354,7 @@ int run_server(StringView session, StringView init_command,
run_unit_tests();
+ register_options();
register_env_vars();
register_registers();
register_commands();
@@ -339,7 +381,7 @@ int run_server(StringView session, StringView init_command,
{
Context empty_context;
- global_hooks.run_hook("KakBegin", "", empty_context);
+ global_scope.hooks().run_hook("KakBegin", "", empty_context);
}
if (not files.empty()) try
@@ -372,7 +414,7 @@ int run_server(StringView session, StringView init_command,
{
Context empty_context;
- global_hooks.run_hook("KakEnd", "", empty_context);
+ global_scope.hooks().run_hook("KakEnd", "", empty_context);
}
return 0;
@@ -381,14 +423,12 @@ int run_server(StringView session, StringView init_command,
int run_filter(StringView keystr, memoryview<StringView> files)
{
StringRegistry string_registry;
- GlobalOptions global_options;
- GlobalHooks global_hooks;
- GlobalKeymaps global_keymaps;
- GlobalAliases global_aliases;
+ GlobalScope global_scope;
ShellManager shell_manager;
BufferManager buffer_manager;
RegisterManager register_manager;
+ register_options();
register_env_vars();
register_registers();
diff --git a/src/option_manager.cc b/src/option_manager.cc
index 8b7c2f76..5330e05a 100644
--- a/src/option_manager.cc
+++ b/src/option_manager.cc
@@ -1,11 +1,7 @@
#include "option_manager.hh"
-#include "insert_completer.hh"
-
#include "assert.hh"
-#include <sstream>
-
namespace Kakoune
{
@@ -128,49 +124,4 @@ void OptionManager::on_option_changed(const Option& option)
watcher->on_option_changed(option);
}
-GlobalOptions::GlobalOptions()
- : OptionManager()
-{
- declare_option("tabstop", "size of a tab character", 8);
- declare_option("indentwidth", "indentation width", 4);
- declare_option("scrolloff",
- "number of lines and columns to keep visible main cursor when scrolling",
- CharCoord{0,0});
- declare_option("eolformat", "end of line format: 'crlf' or 'lf'", "lf"_str);
- declare_option("BOM", "insert a byte order mark when writing buffer",
- "no"_str);
- declare_option("complete_prefix",
- "complete up to common prefix in tab completion",
- true);
- declare_option("incsearch",
- "incrementaly apply search/select/split regex",
- true);
- declare_option("autoinfo",
- "automatically display contextual help",
- 1);
- declare_option("autoshowcompl",
- "automatically display possible completions for prompts",
- true);
- declare_option("aligntab",
- "use tab characters when possible for alignement",
- false);
- declare_option("ignored_files",
- "patterns to ignore when completing filenames",
- Regex{R"(^(\..*|.*\.(o|so|a))$)"});
- declare_option("disabled_hooks",
- "patterns to disable hooks whose group is matched",
- Regex{});
- declare_option("filetype", "buffer filetype", ""_str);
- declare_option("path", "path to consider when trying to find a file",
- std::vector<String>({ "./", "/usr/include" }));
- declare_option("completers", "insert mode completers to execute.",
- std::vector<InsertCompleterDesc>({
- InsertCompleterDesc{ InsertCompleterDesc::Filename },
- InsertCompleterDesc{ InsertCompleterDesc::Word, "all"_str }
- }), OptionFlags::None);
- declare_option("autoreload",
- "autoreload buffer when a filesystem modification is detected",
- Ask);
-}
-
}
diff --git a/src/option_manager.hh b/src/option_manager.hh
index 00cd0370..058c8ea6 100644
--- a/src/option_manager.hh
+++ b/src/option_manager.hh
@@ -104,7 +104,8 @@ private:
OptionManager()
: m_parent(nullptr) {}
// the only one allowed to construct a root option manager
- friend class GlobalOptions;
+ friend class Scope;
+ friend class OptionsRegistry;
template<typename MatchingFunc>
CandidateList get_matching_names(MatchingFunc func);
@@ -186,34 +187,37 @@ auto find_option(T& container, const String& name) -> decltype(container.begin()
return find_if(container, [&name](const ptr_type& opt) { return opt->name() == name; });
}
-class GlobalOptions : public OptionManager,
- public Singleton<GlobalOptions>
+class OptionsRegistry
{
public:
- GlobalOptions();
+ OptionsRegistry(OptionManager& global_manager) : m_global_manager(global_manager) {}
template<typename T>
Option& declare_option(const String& name, const String& docstring,
const T& value,
OptionFlags flags = OptionFlags::None)
{
- auto it = find_option(m_options, name);
- if (it != m_options.end())
+ auto& opts = m_global_manager.m_options;
+ auto it = find_option(opts, name);
+ if (it != opts.end())
{
if ((*it)->is_of_type<T>() and (*it)->flags() == flags)
return **it;
throw runtime_error("option " + name + " already declared with different type or flags");
}
m_descs.emplace_back(new OptionDesc{name, docstring, flags});
- m_options.emplace_back(new TypedOption<T>{*this, *m_descs.back(), value});
- return *m_options.back();
+ opts.emplace_back(new TypedOption<T>{m_global_manager, *m_descs.back(), value});
+ return *opts.back();
}
bool option_exists(const String& name) const
{
- return find_option(m_options, name) != m_options.end();
+ return find_if(m_descs, [&name](const std::unique_ptr<OptionDesc>& opt) {
+ return opt->name() == name;
+ }) != m_descs.end();
}
private:
+ OptionManager& m_global_manager;
std::vector<std::unique_ptr<OptionDesc>> m_descs;
};
diff --git a/src/scope.hh b/src/scope.hh
new file mode 100644
index 00000000..0fb99f8d
--- /dev/null
+++ b/src/scope.hh
@@ -0,0 +1,53 @@
+#ifndef scope_hh_INCLUDED
+#define scope_hh_INCLUDED
+
+#include "alias_registry.hh"
+#include "hook_manager.hh"
+#include "keymap_manager.hh"
+#include "option_manager.hh"
+
+namespace Kakoune
+{
+
+class Scope
+{
+public:
+ Scope(Scope& parent)
+ : m_options(parent.options()),
+ m_hooks(parent.hooks()),
+ m_keymaps(parent.keymaps()),
+ m_aliases(parent.aliases()) {}
+
+ OptionManager& options() { return m_options; }
+ const OptionManager& options() const { return m_options; }
+ HookManager& hooks() { return m_hooks; }
+ const HookManager& hooks() const { return m_hooks; }
+ KeymapManager& keymaps() { return m_keymaps; }
+ const KeymapManager& keymaps() const { return m_keymaps; }
+ AliasRegistry& aliases() { return m_aliases; }
+ const AliasRegistry& aliases() const { return m_aliases; }
+
+private:
+ friend class GlobalScope;
+ Scope() = default;
+
+ OptionManager m_options;
+ HookManager m_hooks;
+ KeymapManager m_keymaps;
+ AliasRegistry m_aliases;
+};
+
+class GlobalScope : public Scope, public Singleton<GlobalScope>
+{
+ public:
+ GlobalScope() : m_option_registry(m_options) {}
+
+ OptionsRegistry& option_registry() { return m_option_registry; }
+ const OptionsRegistry& option_registry() const { return m_option_registry; }
+ private:
+ OptionsRegistry m_option_registry;
+};
+
+}
+
+#endif // scope_hh_INCLUDED
diff --git a/src/window.cc b/src/window.cc
index 5adf685c..c7eaf686 100644
--- a/src/window.cc
+++ b/src/window.cc
@@ -18,22 +18,19 @@ void expand_tabulations(const Context& context, HighlightFlags flags, DisplayBuf
void expand_unprintable(const Context& context, HighlightFlags flags, DisplayBuffer& display_buffer);
Window::Window(Buffer& buffer)
- : m_buffer(&buffer),
- m_hooks(buffer.hooks()),
- m_options(buffer.options()),
- m_keymaps(buffer.keymaps()),
- m_aliases(buffer.aliases())
+ : Scope(buffer),
+ m_buffer(&buffer)
{
InputHandler hook_handler{{ *m_buffer, Selection{} }};
hook_handler.context().set_window(*this);
- m_hooks.run_hook("WinCreate", buffer.name(), hook_handler.context());
- m_options.register_watcher(*this);
+ hooks().run_hook("WinCreate", buffer.name(), hook_handler.context());
+ options().register_watcher(*this);
m_builtin_highlighters.add_child({"tabulations"_str, make_simple_highlighter(expand_tabulations)});
m_builtin_highlighters.add_child({"unprintable"_str, make_simple_highlighter(expand_unprintable)});
m_builtin_highlighters.add_child({"selections"_str, make_simple_highlighter(highlight_selections)});
- for (auto& option : m_options.flatten_options())
+ for (auto& option : options().flatten_options())
on_option_changed(*option);
}
@@ -41,8 +38,8 @@ Window::~Window()
{
InputHandler hook_handler{{ *m_buffer, Selection{} }};
hook_handler.context().set_window(*this);
- m_hooks.run_hook("WinClose", buffer().name(), hook_handler.context());
- m_options.unregister_watcher(*this);
+ hooks().run_hook("WinClose", buffer().name(), hook_handler.context());
+ options().unregister_watcher(*this);
}
void Window::display_line_at(LineCount buffer_line, LineCount display_line)
@@ -279,7 +276,7 @@ void Window::on_option_changed(const Option& option)
String desc = option.name() + "=" + option.get_as_string();
InputHandler hook_handler{{ *m_buffer, Selection{} }};
hook_handler.context().set_window(*this);
- m_hooks.run_hook("WinSetOption", desc, hook_handler.context());
+ hooks().run_hook("WinSetOption", desc, hook_handler.context());
// an highlighter might depend on the option, so we need to redraw
forget_timestamp();
diff --git a/src/window.hh b/src/window.hh
index 8a51ad4a..e2bb91b1 100644
--- a/src/window.hh
+++ b/src/window.hh
@@ -1,21 +1,18 @@
#ifndef window_hh_INCLUDED
#define window_hh_INCLUDED
-#include "alias_registry.hh"
#include "completion.hh"
#include "display_buffer.hh"
#include "highlighter_group.hh"
#include "selection.hh"
-#include "hook_manager.hh"
-#include "option_manager.hh"
-#include "keymap_manager.hh"
#include "safe_ptr.hh"
+#include "scope.hh"
namespace Kakoune
{
// A Window is a view onto a Buffer
-class Window : public SafeCountable, public OptionManagerWatcher
+class Window : public SafeCountable, public OptionManagerWatcher, public Scope
{
public:
Window(Buffer& buffer);
@@ -39,15 +36,6 @@ public:
Highlighter& highlighters() { return m_highlighters; }
- OptionManager& options() { return m_options; }
- const OptionManager& options() const { return m_options; }
- HookManager& hooks() { return m_hooks; }
- const HookManager& hooks() const { return m_hooks; }
- KeymapManager& keymaps() { return m_keymaps; }
- const KeymapManager& keymaps() const { return m_keymaps; }
- AliasRegistry& aliases() { return m_aliases; }
- const AliasRegistry& aliases() const { return m_aliases; }
-
Buffer& buffer() const { return *m_buffer; }
size_t timestamp() const { return m_timestamp; }
@@ -67,11 +55,6 @@ private:
CharCoord m_dimensions;
DisplayBuffer m_display_buffer;
- HookManager m_hooks;
- OptionManager m_options;
- KeymapManager m_keymaps;
- AliasRegistry m_aliases;
-
HighlighterGroup m_highlighters;
HighlighterGroup m_builtin_highlighters;