1
1
mirror of https://github.com/mawww/kakoune.git synced 2024-11-22 05:03:56 +03:00

WIP shared scopes

This commit is contained in:
Maxime Coste 2020-09-09 18:43:36 +10:00
parent ac1960495c
commit d6522213a4
7 changed files with 140 additions and 38 deletions

View File

@ -27,39 +27,10 @@ hook global BufCreate .*\.m %{
hook global WinSetOption filetype=(c|cpp|objc) %[
require-module c-family
evaluate-commands "set-option window static_words %%opt{%val{hook_param_capture_1}_static_words}"
hook -group "%val{hook_param_capture_1}-trim-indent" window ModeChange pop:insert:.* c-family-trim-indent
hook -group "%val{hook_param_capture_1}-insert" window InsertChar \n c-family-insert-on-newline
hook -group "%val{hook_param_capture_1}-indent" window InsertChar \n c-family-indent-on-newline
hook -group "%val{hook_param_capture_1}-indent" window InsertChar \{ c-family-indent-on-opening-curly-brace
hook -group "%val{hook_param_capture_1}-indent" window InsertChar \} c-family-indent-on-closing-curly-brace
hook -group "%val{hook_param_capture_1}-insert" window InsertChar \} c-family-insert-on-closing-curly-brace
alias window alt "%val{hook_param_capture_1}-alternative-file"
hook -once -always window WinSetOption filetype=.* "
remove-hooks window %val{hook_param_capture_1}-.+
unalias window alt %val{hook_param_capture_1}-alternative-file
"
link-shared-scope buffer %val{hook_param_capture_1}
hook -once -always window WinSetOption filetype=.* "unlink-shared-scope window %val{hook_param_capture_1}"
]
hook -group c-highlight global WinSetOption filetype=c %{
add-highlighter window/c ref c
hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/c }
}
hook -group cpp-highlight global WinSetOption filetype=cpp %{
add-highlighter window/cpp ref cpp
hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/cpp }
}
hook -group objc-highlight global WinSetOption filetype=objc %{
add-highlighter window/objc ref objc
hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/objc }
}
provide-module c-family %§
define-command -hidden c-family-trim-indent %{
@ -459,6 +430,27 @@ define-command objc-alternative-file -docstring "Jump to the alternate objc file
c-family-alternative-file
}
evaluate-commands %sh[
for ft in c cpp objc; do
cat <<-EOF
declare-shared-scope $ft
add-highlighter shared/$ft/ ref $ft
evaluate-commands "set-option shared/$ft static_words %%opt{${ft}_static_words}"
hook -group "${ft}-trim-indent" shared/${ft} ModeChange pop:insert:.* c-family-trim-indent
hook -group "${ft}-insert" shared/${ft} InsertChar \n c-family-insert-on-newline
hook -group "${ft}-indent" shared/${ft} InsertChar \n c-family-indent-on-newline
hook -group "${ft}-indent" shared/${ft} InsertChar \{ c-family-indent-on-opening-curly-brace
hook -group "${ft}-indent" shared/${ft} InsertChar \} c-family-indent-on-closing-curly-brace
hook -group "${ft}-insert" shared/${ft} InsertChar \} c-family-insert-on-closing-curly-brace
alias shared/${ft} alt "${ft}-alternative-file"
EOF
done
]
§
# Module aliases

View File

@ -190,7 +190,7 @@ const ParameterDesc single_param{ {}, ParameterDesc::Flags::None, 1, 1 };
const ParameterDesc single_optional_param{ {}, ParameterDesc::Flags::None, 0, 1 };
const ParameterDesc double_params{ {}, ParameterDesc::Flags::None, 2, 2 };
static constexpr auto scopes = { "global", "buffer", "window" };
static constexpr auto scopes = { "global", "buffer", "window", "shared" };
static Completions complete_scope(const Context&, CompletionFlags,
const String& prefix, ByteCount cursor_pos)
@ -321,6 +321,12 @@ Scope* get_scope_ifp(StringView scope, const Context& context)
return &context.window();
else if (prefix_match(scope, "buffer="))
return &BufferManager::instance().get_buffer(scope.substr(7_byte));
else if (prefix_match(scope, "shared/"))
{
auto it = SharedScopes::instance().scopes.find(scope.substr(7_byte));
if (it != SharedScopes::instance().scopes.end())
return it->value.get();
}
return nullptr;
}
@ -2649,6 +2655,81 @@ const CommandDesc require_module_cmd = {
}
};
const CommandDesc declare_shared_scope_cmd = {
"declare-shared-scope",
nullptr,
"declare-shared-scope <shared-scope>: declare <shared-scope>",
ParameterDesc{
{},
ParameterDesc::Flags::None,
1, 1
},
CommandFlags::None,
CommandHelper{},
make_completer(complete_scope),
[](const ParametersParser& parser, Context& context, const ShellContext&)
{
auto name = parser[0];
if (name.empty() or not all_of(name, is_identifier))
throw runtime_error(format("invalid shared scope name: '{}'", name));
if (SharedScopes::instance().scopes.contains(name))
throw runtime_error(format("duplicate shared scope name: '{}'", name));
SharedScopes::instance().scopes.insert({name, std::make_unique<SharedScope>()});
}
};
static Completions complete_shared_scope(const Context&, CompletionFlags,
const String& prefix, ByteCount cursor_pos)
{
return { 0_byte, cursor_pos, complete(prefix, cursor_pos, SharedScopes::instance().scopes | transform([](auto&& v) -> const String& { return v.key; })) };
}
SharedScope& get_shared_scope(StringView name)
{
auto it = SharedScopes::instance().scopes.find(name);
if (it == SharedScopes::instance().scopes.end())
throw runtime_error(format("no such shared scope '{}'", name));
return *it->value;
}
const CommandDesc link_shared_scope_cmd = {
"link-shared-scope",
nullptr,
"link-shared-scope <scope> <shared-scope>: link <shared-scope> into <scope>",
ParameterDesc{
{},
ParameterDesc::Flags::None,
2, 2
},
CommandFlags::None,
CommandHelper{},
make_completer(complete_scope, complete_shared_scope),
[](const ParametersParser& parser, Context& context, const ShellContext&)
{
get_scope(parser[0], context).add_shared_scope(get_shared_scope(parser[1]));
}
};
const CommandDesc unlink_shared_scope_cmd = {
"unlink-shared-scope",
nullptr,
"unlink-shared-scope <scope> <shared-scope>: unlink <shared-scope> into <scope>",
ParameterDesc{
{},
ParameterDesc::Flags::None,
2, 2
},
CommandFlags::None,
CommandHelper{},
make_completer(complete_scope, complete_shared_scope),
[](const ParametersParser& parser, Context& context, const ShellContext&)
{
get_scope(parser[0], context).remove_shared_scope(get_shared_scope(parser[1]));
}
};
}
void register_commands()
@ -2718,6 +2799,9 @@ void register_commands()
register_command(enter_user_mode_cmd);
register_command(provide_module_cmd);
register_command(require_module_cmd);
register_command(declare_shared_scope_cmd);
register_command(link_shared_scope_cmd);
register_command(unlink_shared_scope_cmd);
}
}

View File

@ -85,6 +85,8 @@ void Highlighters::highlight(HighlightContext context, DisplayBuffer& display_bu
if (m_parent)
m_parent->highlight({context.context, context.setup, context.pass, disabled_ids}, display_buffer, range);
for (auto& shared : m_shared)
shared->highlight({context.context, context.setup, context.pass, disabled_ids}, display_buffer, range);
m_group.highlight(context, display_buffer, range);
}
@ -95,6 +97,8 @@ void Highlighters::compute_display_setup(HighlightContext context, DisplaySetup&
if (m_parent)
m_parent->compute_display_setup({context.context, context.setup, context.pass, disabled_ids}, setup);
for (auto& shared : m_shared)
shared->compute_display_setup({context.context, context.setup, context.pass, disabled_ids}, setup);
m_group.compute_display_setup(context, setup);
}

View File

@ -79,6 +79,9 @@ void HookManager::run_hook(Hook hook, StringView param, Context& context)
hooks_to_run.push_back({ hook.get(), std::move(captures) });
}
for (auto& shared : m_shared)
m_shared->run_hook(hook, param, context);
if (m_parent)
m_parent->run_hook(hook, param, context);

View File

@ -52,14 +52,14 @@ Option& OptionManager::get_local_option(StringView name)
auto it = m_options.find(name);
if (it != m_options.end())
return *(it->value);
else if (m_parent)
if (m_parent)
{
auto* clone = (*m_parent)[name].clone(*this);
return *m_options.insert({clone->name(), std::unique_ptr<Option>{clone}});
}
else
throw option_not_found(name);
throw option_not_found(name);
}
Option& OptionManager::operator[](StringView name)
@ -67,10 +67,11 @@ Option& OptionManager::operator[](StringView name)
auto it = m_options.find(name);
if (it != m_options.end())
return *it->value;
else if (m_parent)
if (m_parent)
return (*m_parent)[name];
else
throw option_not_found(name);
throw option_not_found(name);
}
const Option& OptionManager::operator[](StringView name) const

View File

@ -60,6 +60,12 @@ public:
SharedScope() = default;
};
class SharedScopes : public Singleton<SharedScopes>
{
public:
HashMap<String, std::unique_ptr<SharedScope>> scopes;
};
class GlobalScope : public Scope, public OptionManagerWatcher, public Singleton<GlobalScope>
{
public:
@ -72,6 +78,7 @@ class GlobalScope : public Scope, public OptionManagerWatcher, public Singleton<
void on_option_changed(const Option& option) override;
OptionsRegistry m_option_registry;
SharedScopes m_shared_scopes;
};
}

View File

@ -4,6 +4,7 @@
#include "safe_ptr.hh"
#include "vector.hh"
#include "ranges.hh"
#include "array_view.hh"
namespace Kakoune
{
@ -27,6 +28,16 @@ protected:
m_shared.erase(it);
}
auto this_then_shared()
{
return concatenated(ArrayView{this, 1}, m_shared);
}
auto shared_then_this()
{
return concatenated(m_shared, ArrayView{this, 1});
}
SafePtr<Derived> m_parent;
Vector<SafePtr<Derived>> m_shared;
};