parent
e3a04dfa65
commit
d470bd2cc9
|
@ -1487,32 +1487,24 @@ private:
|
||||||
class RegisterRestorer
|
class RegisterRestorer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RegisterRestorer(char name, const Context& context)
|
RegisterRestorer(char name, Context& context)
|
||||||
: m_name(name)
|
: m_context{context}, m_name{name}
|
||||||
{
|
{
|
||||||
ConstArrayView<String> save = RegisterManager::instance()[name].values(context);
|
ConstArrayView<String> save = RegisterManager::instance()[name].get(context);
|
||||||
m_save = Vector<String>(save.begin(), save.end());
|
m_save = Vector<String>(save.begin(), save.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
RegisterRestorer(RegisterRestorer&& other) noexcept
|
RegisterRestorer(RegisterRestorer&& other) noexcept
|
||||||
: m_save(std::move(other.m_save)), m_name(other.m_name)
|
: m_context{other.m_context}, m_save{std::move(other.m_save)}, m_name{other.m_name}
|
||||||
{
|
{
|
||||||
other.m_name = 0;
|
other.m_name = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
RegisterRestorer& operator=(RegisterRestorer&& other) noexcept
|
|
||||||
{
|
|
||||||
m_save = std::move(other.m_save);
|
|
||||||
m_name = other.m_name;
|
|
||||||
other.m_name = 0;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
~RegisterRestorer()
|
~RegisterRestorer()
|
||||||
{
|
{
|
||||||
if (m_name != 0) try
|
if (m_name != 0) try
|
||||||
{
|
{
|
||||||
RegisterManager::instance()[m_name] = m_save;
|
RegisterManager::instance()[m_name].set(m_context, m_save);
|
||||||
}
|
}
|
||||||
catch (runtime_error& e)
|
catch (runtime_error& e)
|
||||||
{
|
{
|
||||||
|
@ -1523,6 +1515,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Vector<String> m_save;
|
Vector<String> m_save;
|
||||||
|
Context& m_context;
|
||||||
char m_name;
|
char m_name;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2012,7 +2005,7 @@ const CommandDesc set_register_cmd = {
|
||||||
CommandCompleter{},
|
CommandCompleter{},
|
||||||
[](const ParametersParser& parser, Context& context, const ShellContext&)
|
[](const ParametersParser& parser, Context& context, const ShellContext&)
|
||||||
{
|
{
|
||||||
RegisterManager::instance()[parser[0]] = ConstArrayView<String>(parser[1]);
|
RegisterManager::instance()[parser[0]].set(context, {parser[1]});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -211,7 +211,7 @@ void Context::end_edition()
|
||||||
|
|
||||||
StringView Context::main_sel_register_value(StringView reg) const
|
StringView Context::main_sel_register_value(StringView reg) const
|
||||||
{
|
{
|
||||||
auto strings = RegisterManager::instance()[reg].values(*this);
|
auto strings = RegisterManager::instance()[reg].get(*this);
|
||||||
size_t index = m_selections ? (*m_selections).main_index() : 0;
|
size_t index = m_selections ? (*m_selections).main_index() : 0;
|
||||||
if (strings.size() <= index)
|
if (strings.size() <= index)
|
||||||
index = strings.size() - 1;
|
index = strings.size() - 1;
|
||||||
|
|
|
@ -1124,7 +1124,7 @@ public:
|
||||||
on_next_key_with_autoinfo(context(), KeymapMode::None,
|
on_next_key_with_autoinfo(context(), KeymapMode::None,
|
||||||
[this](Key key, Context&) {
|
[this](Key key, Context&) {
|
||||||
if (auto cp = key.codepoint())
|
if (auto cp = key.codepoint())
|
||||||
insert(RegisterManager::instance()[*cp].values(context()));
|
insert(RegisterManager::instance()[*cp].get(context()));
|
||||||
}, "Enter register name", register_doc);
|
}, "Enter register name", register_doc);
|
||||||
update_completions = false;
|
update_completions = false;
|
||||||
}
|
}
|
||||||
|
@ -1491,7 +1491,8 @@ void InputHandler::stop_recording()
|
||||||
kak_assert(m_recording_reg != 0);
|
kak_assert(m_recording_reg != 0);
|
||||||
|
|
||||||
if (not m_recorded_keys.empty())
|
if (not m_recorded_keys.empty())
|
||||||
RegisterManager::instance()[m_recording_reg] = {m_recorded_keys};
|
RegisterManager::instance()[m_recording_reg].set(
|
||||||
|
context(), {m_recorded_keys});
|
||||||
|
|
||||||
m_recording_reg = 0;
|
m_recording_reg = 0;
|
||||||
m_recording_level = -1;
|
m_recording_level = -1;
|
||||||
|
|
13
src/main.cc
13
src/main.cc
|
@ -186,6 +186,19 @@ void register_registers()
|
||||||
for (auto& sel : context.selections())
|
for (auto& sel : context.selections())
|
||||||
result.emplace_back(i < sel.captures().size() ? sel.captures()[i] : "");
|
result.emplace_back(i < sel.captures().size() ? sel.captures()[i] : "");
|
||||||
return result;
|
return result;
|
||||||
|
},
|
||||||
|
[i](Context& context, ConstArrayView<String> values) {
|
||||||
|
if (values.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto& sels = context.selections();
|
||||||
|
for (size_t sel_index = 0; sel_index < sels.size(); ++sel_index)
|
||||||
|
{
|
||||||
|
auto& sel = sels[sel_index];
|
||||||
|
if (sel.captures().size() < i+1)
|
||||||
|
sel.captures().resize(i+1);
|
||||||
|
sel.captures()[i] = values[std::min(sel_index, values.size()-1)];
|
||||||
|
}
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -417,7 +417,7 @@ void pipe(Context& context, NormalParams)
|
||||||
real_cmd = context.main_sel_register_value("|");
|
real_cmd = context.main_sel_register_value("|");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
RegisterManager::instance()['|'] = cmdline.str();
|
RegisterManager::instance()['|'].set(context, cmdline.str());
|
||||||
real_cmd = cmdline;
|
real_cmd = cmdline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -479,7 +479,7 @@ void insert_output(Context& context, NormalParams)
|
||||||
real_cmd = context.main_sel_register_value("|");
|
real_cmd = context.main_sel_register_value("|");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
RegisterManager::instance()['|'] = cmdline.str();
|
RegisterManager::instance()['|'].set(context, cmdline.str());
|
||||||
real_cmd = cmdline;
|
real_cmd = cmdline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -496,7 +496,7 @@ void insert_output(Context& context, NormalParams)
|
||||||
void yank(Context& context, NormalParams params)
|
void yank(Context& context, NormalParams params)
|
||||||
{
|
{
|
||||||
const char reg = params.reg ? params.reg : '"';
|
const char reg = params.reg ? params.reg : '"';
|
||||||
RegisterManager::instance()[reg] = context.selections_content();
|
RegisterManager::instance()[reg].set(context, context.selections_content());
|
||||||
context.print_status({ format("yanked {} selections to register {}",
|
context.print_status({ format("yanked {} selections to register {}",
|
||||||
context.selections().size(), reg),
|
context.selections().size(), reg),
|
||||||
get_face("Information") });
|
get_face("Information") });
|
||||||
|
@ -505,7 +505,7 @@ void yank(Context& context, NormalParams params)
|
||||||
void erase_selections(Context& context, NormalParams params)
|
void erase_selections(Context& context, NormalParams params)
|
||||||
{
|
{
|
||||||
const char reg = params.reg ? params.reg : '"';
|
const char reg = params.reg ? params.reg : '"';
|
||||||
RegisterManager::instance()[reg] = context.selections_content();
|
RegisterManager::instance()[reg].set(context, context.selections_content());
|
||||||
ScopedEdition edition(context);
|
ScopedEdition edition(context);
|
||||||
context.selections().erase();
|
context.selections().erase();
|
||||||
context.selections().avoid_eol();
|
context.selections().avoid_eol();
|
||||||
|
@ -514,7 +514,7 @@ void erase_selections(Context& context, NormalParams params)
|
||||||
void change(Context& context, NormalParams params)
|
void change(Context& context, NormalParams params)
|
||||||
{
|
{
|
||||||
const char reg = params.reg ? params.reg : '"';
|
const char reg = params.reg ? params.reg : '"';
|
||||||
RegisterManager::instance()[reg] = context.selections_content();
|
RegisterManager::instance()[reg].set(context, context.selections_content());
|
||||||
enter_insert_mode<InsertMode::Replace>(context, params);
|
enter_insert_mode<InsertMode::Replace>(context, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -533,7 +533,7 @@ template<InsertMode mode>
|
||||||
void paste(Context& context, NormalParams params)
|
void paste(Context& context, NormalParams params)
|
||||||
{
|
{
|
||||||
const char reg = params.reg ? params.reg : '"';
|
const char reg = params.reg ? params.reg : '"';
|
||||||
auto strings = RegisterManager::instance()[reg].values(context);
|
auto strings = RegisterManager::instance()[reg].get(context);
|
||||||
const bool linewise = contains_that(strings, [](StringView str) {
|
const bool linewise = contains_that(strings, [](StringView str) {
|
||||||
return not str.empty() and str.back() == '\n';
|
return not str.empty() and str.back() == '\n';
|
||||||
});
|
});
|
||||||
|
@ -547,7 +547,7 @@ template<InsertMode mode>
|
||||||
void paste_all(Context& context, NormalParams params)
|
void paste_all(Context& context, NormalParams params)
|
||||||
{
|
{
|
||||||
const char reg = params.reg ? params.reg : '"';
|
const char reg = params.reg ? params.reg : '"';
|
||||||
auto strings = RegisterManager::instance()[reg].values(context);
|
auto strings = RegisterManager::instance()[reg].get(context);
|
||||||
InsertMode effective_mode = mode;
|
InsertMode effective_mode = mode;
|
||||||
String all;
|
String all;
|
||||||
Vector<ByteCount> offsets;
|
Vector<ByteCount> offsets;
|
||||||
|
@ -645,7 +645,7 @@ void search(Context& context, NormalParams params)
|
||||||
const char reg = to_lower(params.reg ? params.reg : '/');
|
const char reg = to_lower(params.reg ? params.reg : '/');
|
||||||
const int count = params.count;
|
const int count = params.count;
|
||||||
|
|
||||||
auto reg_content = RegisterManager::instance()[reg].values(context);
|
auto reg_content = RegisterManager::instance()[reg].get(context);
|
||||||
Vector<String> saved_reg{reg_content.begin(), reg_content.end()};
|
Vector<String> saved_reg{reg_content.begin(), reg_content.end()};
|
||||||
const int main_index = std::min(context.selections().main_index(), saved_reg.size()-1);
|
const int main_index = std::min(context.selections().main_index(), saved_reg.size()-1);
|
||||||
|
|
||||||
|
@ -654,13 +654,13 @@ void search(Context& context, NormalParams params)
|
||||||
(Regex regex, PromptEvent event, Context& context) {
|
(Regex regex, PromptEvent event, Context& context) {
|
||||||
if (event == PromptEvent::Abort)
|
if (event == PromptEvent::Abort)
|
||||||
{
|
{
|
||||||
RegisterManager::instance()[reg] = saved_reg;
|
RegisterManager::instance()[reg].set(context, saved_reg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (regex.empty())
|
if (regex.empty())
|
||||||
regex = Regex{saved_reg[main_index]};
|
regex = Regex{saved_reg[main_index]};
|
||||||
RegisterManager::instance()[reg] = regex.str();
|
RegisterManager::instance()[reg].set(context, regex.str());
|
||||||
|
|
||||||
if (not regex.empty() and not regex.str().empty())
|
if (not regex.empty() and not regex.str().empty())
|
||||||
{
|
{
|
||||||
|
@ -741,7 +741,7 @@ void use_selection_as_search_pattern(Context& context, NormalParams params)
|
||||||
format("register '{}' set to '{}'", reg, patterns[sels.main_index()]),
|
format("register '{}' set to '{}'", reg, patterns[sels.main_index()]),
|
||||||
get_face("Information") });
|
get_face("Information") });
|
||||||
|
|
||||||
RegisterManager::instance()[reg] = patterns;
|
RegisterManager::instance()[reg].set(context, patterns);
|
||||||
|
|
||||||
// Hack, as Window do not take register state into account
|
// Hack, as Window do not take register state into account
|
||||||
if (context.has_window())
|
if (context.has_window())
|
||||||
|
@ -754,7 +754,7 @@ void select_regex(Context& context, NormalParams params)
|
||||||
const int capture = params.count;
|
const int capture = params.count;
|
||||||
auto prompt = capture ? format("select (capture {}):", capture) : "select:"_str;
|
auto prompt = capture ? format("select (capture {}):", capture) : "select:"_str;
|
||||||
|
|
||||||
auto reg_content = RegisterManager::instance()[reg].values(context);
|
auto reg_content = RegisterManager::instance()[reg].get(context);
|
||||||
Vector<String> saved_reg{reg_content.begin(), reg_content.end()};
|
Vector<String> saved_reg{reg_content.begin(), reg_content.end()};
|
||||||
const int main_index = std::min(context.selections().main_index(), saved_reg.size()-1);
|
const int main_index = std::min(context.selections().main_index(), saved_reg.size()-1);
|
||||||
|
|
||||||
|
@ -762,13 +762,13 @@ void select_regex(Context& context, NormalParams params)
|
||||||
[reg, capture, saved_reg, main_index](Regex ex, PromptEvent event, Context& context) {
|
[reg, capture, saved_reg, main_index](Regex ex, PromptEvent event, Context& context) {
|
||||||
if (event == PromptEvent::Abort)
|
if (event == PromptEvent::Abort)
|
||||||
{
|
{
|
||||||
RegisterManager::instance()[reg] = saved_reg;
|
RegisterManager::instance()[reg].set(context, saved_reg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ex.empty())
|
if (ex.empty())
|
||||||
ex = Regex{saved_reg[main_index]};
|
ex = Regex{saved_reg[main_index]};
|
||||||
RegisterManager::instance()[reg] = ex.str();
|
RegisterManager::instance()[reg].set(context, ex.str());
|
||||||
|
|
||||||
if (not ex.empty() and not ex.str().empty())
|
if (not ex.empty() and not ex.str().empty())
|
||||||
select_all_matches(context.selections(), ex, capture);
|
select_all_matches(context.selections(), ex, capture);
|
||||||
|
@ -781,7 +781,7 @@ void split_regex(Context& context, NormalParams params)
|
||||||
const int capture = params.count;
|
const int capture = params.count;
|
||||||
auto prompt = capture ? format("split (on capture {}):", (int)capture) : "split:"_str;
|
auto prompt = capture ? format("split (on capture {}):", (int)capture) : "split:"_str;
|
||||||
|
|
||||||
auto reg_content = RegisterManager::instance()[reg].values(context);
|
auto reg_content = RegisterManager::instance()[reg].get(context);
|
||||||
Vector<String> saved_reg{reg_content.begin(), reg_content.end()};
|
Vector<String> saved_reg{reg_content.begin(), reg_content.end()};
|
||||||
const int main_index = std::min(context.selections().main_index(), saved_reg.size()-1);
|
const int main_index = std::min(context.selections().main_index(), saved_reg.size()-1);
|
||||||
|
|
||||||
|
@ -789,13 +789,13 @@ void split_regex(Context& context, NormalParams params)
|
||||||
[reg, capture, saved_reg, main_index](Regex ex, PromptEvent event, Context& context) {
|
[reg, capture, saved_reg, main_index](Regex ex, PromptEvent event, Context& context) {
|
||||||
if (event == PromptEvent::Abort)
|
if (event == PromptEvent::Abort)
|
||||||
{
|
{
|
||||||
RegisterManager::instance()[reg] = saved_reg;
|
RegisterManager::instance()[reg].set(context, saved_reg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ex.empty())
|
if (ex.empty())
|
||||||
ex = Regex{saved_reg[main_index]};
|
ex = Regex{saved_reg[main_index]};
|
||||||
RegisterManager::instance()[reg] = ex.str();
|
RegisterManager::instance()[reg].set(context, ex.str());
|
||||||
|
|
||||||
if (not ex.empty() and not ex.str().empty())
|
if (not ex.empty() and not ex.str().empty())
|
||||||
split_selections(context.selections(), ex, capture);
|
split_selections(context.selections(), ex, capture);
|
||||||
|
@ -1254,7 +1254,7 @@ void replay_macro(Context& context, NormalParams params)
|
||||||
if (running_macros[idx])
|
if (running_macros[idx])
|
||||||
throw runtime_error("recursive macros call detected");
|
throw runtime_error("recursive macros call detected");
|
||||||
|
|
||||||
ConstArrayView<String> reg_val = RegisterManager::instance()[reg].values(context);
|
ConstArrayView<String> reg_val = RegisterManager::instance()[reg].get(context);
|
||||||
if (reg_val.empty() or reg_val[0].empty())
|
if (reg_val.empty() or reg_val[0].empty())
|
||||||
throw runtime_error(format("Register '{}' is empty", reg));
|
throw runtime_error(format("Register '{}' is empty", reg));
|
||||||
|
|
||||||
|
@ -1445,7 +1445,7 @@ SelectionList read_selections_from_register(char reg, Context& context)
|
||||||
if (not is_basic_alpha(reg) and reg != '^')
|
if (not is_basic_alpha(reg) and reg != '^')
|
||||||
throw runtime_error("selections can only be saved to the '^' and alphabetic registers");
|
throw runtime_error("selections can only be saved to the '^' and alphabetic registers");
|
||||||
|
|
||||||
auto content = RegisterManager::instance()[reg].values(context);
|
auto content = RegisterManager::instance()[reg].get(context);
|
||||||
|
|
||||||
if (content.size() != 1)
|
if (content.size() != 1)
|
||||||
throw runtime_error(format("Register {} does not contain a selections desc", reg));
|
throw runtime_error(format("Register {} does not contain a selections desc", reg));
|
||||||
|
@ -1496,7 +1496,7 @@ void save_selections(Context& context, NormalParams params)
|
||||||
context.buffer().name(),
|
context.buffer().name(),
|
||||||
context.buffer().timestamp());
|
context.buffer().timestamp());
|
||||||
|
|
||||||
RegisterManager::instance()[reg] = desc;
|
RegisterManager::instance()[reg].set(context, desc);
|
||||||
|
|
||||||
context.print_status({format("{} selections to register '{}'", add ? "Added" : "Saved", reg), get_face("Information")});
|
context.print_status({format("{} selections to register '{}'", add ? "Added" : "Saved", reg), get_face("Information")});
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,9 +17,9 @@ class Register
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~Register() = default;
|
virtual ~Register() = default;
|
||||||
virtual Register& operator=(ConstArrayView<String> values) = 0;
|
|
||||||
|
|
||||||
virtual ConstArrayView<String> values(const Context& context) = 0;
|
virtual void set(Context& context, ConstArrayView<String> values) = 0;
|
||||||
|
virtual ConstArrayView<String> get(const Context& context) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
// static value register, which can be modified
|
// static value register, which can be modified
|
||||||
|
@ -27,13 +27,12 @@ public:
|
||||||
class StaticRegister : public Register
|
class StaticRegister : public Register
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Register& operator=(ConstArrayView<String> values) override
|
void set(Context&, ConstArrayView<String> values) override
|
||||||
{
|
{
|
||||||
m_content = Vector<String, MemoryDomain::Registers>(values.begin(), values.end());
|
m_content = Vector<String, MemoryDomain::Registers>(values.begin(), values.end());
|
||||||
return *this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ConstArrayView<String> values(const Context&) override
|
ConstArrayView<String> get(const Context&) override
|
||||||
{
|
{
|
||||||
if (m_content.empty())
|
if (m_content.empty())
|
||||||
return ConstArrayView<String>(String::ms_empty);
|
return ConstArrayView<String>(String::ms_empty);
|
||||||
|
@ -46,43 +45,51 @@ protected:
|
||||||
|
|
||||||
// Dynamic value register, use it's RegisterRetriever
|
// Dynamic value register, use it's RegisterRetriever
|
||||||
// to get it's value when needed.
|
// to get it's value when needed.
|
||||||
template<typename Func>
|
template<typename Getter, typename Setter>
|
||||||
class DynamicRegister : public StaticRegister
|
class DynamicRegister : public StaticRegister
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DynamicRegister(Func function)
|
DynamicRegister(Getter getter, Setter setter)
|
||||||
: m_function(std::move(function)) {}
|
: m_getter{std::move(getter)}, m_setter{std::move(setter)} {}
|
||||||
|
|
||||||
Register& operator=(ConstArrayView<String> values) override
|
void set(Context& context, ConstArrayView<String> values) override
|
||||||
{
|
{
|
||||||
throw runtime_error("this register is not assignable");
|
m_setter(context, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
ConstArrayView<String> values(const Context& context) override
|
ConstArrayView<String> get(const Context& context) override
|
||||||
{
|
{
|
||||||
m_content = m_function(context);
|
m_content = m_getter(context);
|
||||||
return StaticRegister::values(context);
|
return StaticRegister::get(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Func m_function;
|
Getter m_getter;
|
||||||
|
Setter m_setter;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Func>
|
template<typename Func>
|
||||||
std::unique_ptr<Register> make_dyn_reg(Func func)
|
std::unique_ptr<Register> make_dyn_reg(Func func)
|
||||||
{
|
{
|
||||||
return make_unique<DynamicRegister<Func>>(std::move(func));
|
auto setter = [](Context&, ConstArrayView<String>)
|
||||||
|
{
|
||||||
|
throw runtime_error("this register is not assignable");
|
||||||
|
};
|
||||||
|
return make_unique<DynamicRegister<Func, decltype(setter)>>(std::move(func), setter);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Getter, typename Setter>
|
||||||
|
std::unique_ptr<Register> make_dyn_reg(Getter getter, Setter setter)
|
||||||
|
{
|
||||||
|
return make_unique<DynamicRegister<Getter, Setter>>(std::move(getter), std::move(setter));
|
||||||
}
|
}
|
||||||
|
|
||||||
class NullRegister : public Register
|
class NullRegister : public Register
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Register& operator=(ConstArrayView<String> values) override
|
void set(Context&, ConstArrayView<String>) override {}
|
||||||
{
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
ConstArrayView<String> values(const Context& context) override
|
ConstArrayView<String> get(const Context&) override
|
||||||
{
|
{
|
||||||
return ConstArrayView<String>(String::ms_empty);
|
return ConstArrayView<String>(String::ms_empty);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user