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:
parent
ac1960495c
commit
d6522213a4
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user