Take a function SelectionList::insert to get string to insert
This makes it unnecessary to allocate Vector<String> to insert and allows to remove the insert_pos pointer hack by passing it to the callback.
This commit is contained in:
parent
bc11f972c5
commit
33a80e644c
|
@ -414,13 +414,10 @@ void replace_with_char(Context& context, NormalParams)
|
||||||
ScopedEdition edition(context);
|
ScopedEdition edition(context);
|
||||||
Buffer& buffer = context.buffer();
|
Buffer& buffer = context.buffer();
|
||||||
SelectionList& selections = context.selections();
|
SelectionList& selections = context.selections();
|
||||||
Vector<String> strings;
|
selections.insert([&](size_t index, BufferCoord) {
|
||||||
for (auto& sel : selections)
|
CharCount count = char_length(buffer, selections[index]);
|
||||||
{
|
return String{*cp, count};
|
||||||
CharCount count = char_length(buffer, sel);
|
}, InsertMode::Replace);
|
||||||
strings.emplace_back(*cp, count);
|
|
||||||
}
|
|
||||||
selections.insert(strings, InsertMode::Replace);
|
|
||||||
}, "replace with char", "enter char to replace with\n");
|
}, "replace with char", "enter char to replace with\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -438,18 +435,16 @@ void for_each_codepoint(Context& context, NormalParams)
|
||||||
ScopedEdition edition(context);
|
ScopedEdition edition(context);
|
||||||
Buffer& buffer = context.buffer();
|
Buffer& buffer = context.buffer();
|
||||||
SelectionList& selections = context.selections();
|
SelectionList& selections = context.selections();
|
||||||
Vector<String> strings;
|
|
||||||
for (auto& sel : selections)
|
selections.insert([&](size_t index, BufferCoord) {
|
||||||
{
|
auto& sel = selections[index];
|
||||||
String str;
|
String str;
|
||||||
for (auto begin = Utf8It{buffer.iterator_at(sel.min()), buffer},
|
for (auto begin = Utf8It{buffer.iterator_at(sel.min()), buffer},
|
||||||
end = Utf8It{buffer.iterator_at(sel.max()), buffer}+1;
|
end = Utf8It{buffer.iterator_at(sel.max()), buffer}+1;
|
||||||
begin != end; ++begin)
|
begin != end; ++begin)
|
||||||
utf8::dump(std::back_inserter(str), func(*begin));
|
utf8::dump(std::back_inserter(str), func(*begin));
|
||||||
|
return str;
|
||||||
strings.push_back(std::move(str));
|
}, InsertMode::Replace);
|
||||||
}
|
|
||||||
selections.insert(strings, InsertMode::Replace);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void command(const Context& context, EnvVarMap env_vars, char reg = 0)
|
void command(const Context& context, EnvVarMap env_vars, char reg = 0)
|
||||||
|
@ -649,15 +644,15 @@ void insert_output(Context& context, NormalParams params)
|
||||||
auto& selections = context.selections();
|
auto& selections = context.selections();
|
||||||
const size_t old_main = selections.main_index();
|
const size_t old_main = selections.main_index();
|
||||||
|
|
||||||
auto ins = selections | transform([&, i=0](auto& sel) mutable {
|
selections.insert([&](size_t index, BufferCoord) {
|
||||||
selections.set_main_index(i++);
|
selections.set_main_index(index);
|
||||||
return ShellManager::instance().eval(
|
auto [out, status] = ShellManager::instance().eval(
|
||||||
cmdline, context, content(context.buffer(), sel),
|
cmdline, context, content(context.buffer(), selections[index]),
|
||||||
ShellManager::Flags::WaitForStdout).first;
|
ShellManager::Flags::WaitForStdout);
|
||||||
}) | gather<Vector>();
|
return out;
|
||||||
|
}, mode);
|
||||||
|
|
||||||
selections.set_main_index(old_main);
|
selections.set_main_index(old_main);
|
||||||
selections.insert(ins, mode);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -741,7 +736,10 @@ void paste_all(Context& context, NormalParams params)
|
||||||
auto& selections = context.selections();
|
auto& selections = context.selections();
|
||||||
{
|
{
|
||||||
ScopedEdition edition(context);
|
ScopedEdition edition(context);
|
||||||
selections.insert(all, effective_mode, &insert_pos);
|
selections.insert([&](size_t, BufferCoord pos) {
|
||||||
|
insert_pos.push_back(pos);
|
||||||
|
return String::no_copy(all);
|
||||||
|
}, effective_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Buffer& buffer = context.buffer();
|
const Buffer& buffer = context.buffer();
|
||||||
|
|
|
@ -385,12 +385,18 @@ static void fix_overflowing_selections(Vector<Selection>& selections,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SelectionList::insert(ConstArrayView<String> strings, InsertMode mode,
|
void SelectionList::insert(ConstArrayView<String> strings, InsertMode mode)
|
||||||
Vector<BufferCoord>* out_insert_pos)
|
|
||||||
{
|
{
|
||||||
if (strings.empty())
|
if (strings.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
insert([&](size_t index, BufferCoord) {
|
||||||
|
return String::no_copy(strings[std::min(strings.size()-1, index)]);
|
||||||
|
}, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SelectionList::insert(ContentFunc get_content, InsertMode mode)
|
||||||
|
{
|
||||||
update();
|
update();
|
||||||
|
|
||||||
Vector<BufferCoord> insert_pos;
|
Vector<BufferCoord> insert_pos;
|
||||||
|
@ -410,11 +416,11 @@ void SelectionList::insert(ConstArrayView<String> strings, InsertMode mode,
|
||||||
kak_assert(m_buffer->is_valid(sel.anchor()) and
|
kak_assert(m_buffer->is_valid(sel.anchor()) and
|
||||||
m_buffer->is_valid(sel.cursor()));
|
m_buffer->is_valid(sel.cursor()));
|
||||||
|
|
||||||
const String& str = strings[std::min(index, strings.size()-1)];
|
|
||||||
|
|
||||||
const auto pos = (mode == InsertMode::Replace) ?
|
const auto pos = (mode == InsertMode::Replace) ?
|
||||||
sel.min() : changes_tracker.get_new_coord(insert_pos[index]);
|
sel.min() : changes_tracker.get_new_coord(insert_pos[index]);
|
||||||
|
|
||||||
|
String str = get_content(index, pos);
|
||||||
|
|
||||||
if (mode == InsertMode::Replace)
|
if (mode == InsertMode::Replace)
|
||||||
{
|
{
|
||||||
auto range = replace(*m_buffer, sel, str);
|
auto range = replace(*m_buffer, sel, str);
|
||||||
|
@ -432,8 +438,6 @@ void SelectionList::insert(ConstArrayView<String> strings, InsertMode mode,
|
||||||
}
|
}
|
||||||
|
|
||||||
changes_tracker.update(*m_buffer, m_timestamp);
|
changes_tracker.update(*m_buffer, m_timestamp);
|
||||||
if (out_insert_pos)
|
|
||||||
out_insert_pos->push_back(pos);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// We might just have been deleting text if strings were empty,
|
// We might just have been deleting text if strings were empty,
|
||||||
|
|
|
@ -145,8 +145,9 @@ struct SelectionList
|
||||||
size_t timestamp() const { return m_timestamp; }
|
size_t timestamp() const { return m_timestamp; }
|
||||||
void force_timestamp(size_t timestamp) { m_timestamp = timestamp; }
|
void force_timestamp(size_t timestamp) { m_timestamp = timestamp; }
|
||||||
|
|
||||||
void insert(ConstArrayView<String> strings, InsertMode mode,
|
void insert(ConstArrayView<String> strings, InsertMode mode);
|
||||||
Vector<BufferCoord>* out_insert_pos = nullptr);
|
using ContentFunc = FunctionRef<String (size_t index, BufferCoord insert_pos)>;
|
||||||
|
void insert(ContentFunc get_content, InsertMode mode);
|
||||||
void erase();
|
void erase();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -124,6 +124,8 @@ public:
|
||||||
struct NoCopy{};
|
struct NoCopy{};
|
||||||
String(NoCopy, StringView str);
|
String(NoCopy, StringView str);
|
||||||
|
|
||||||
|
static String no_copy(StringView str);
|
||||||
|
|
||||||
[[gnu::always_inline]]
|
[[gnu::always_inline]]
|
||||||
char* data() { return m_data.data(); }
|
char* data() { return m_data.data(); }
|
||||||
|
|
||||||
|
@ -274,6 +276,7 @@ template<> struct HashCompatible<StringView, String> : std::true_type {};
|
||||||
|
|
||||||
inline String::String(StringView str) : String{str.begin(), str.length()} {}
|
inline String::String(StringView str) : String{str.begin(), str.length()} {}
|
||||||
inline String::String(NoCopy, StringView str) : m_data{NoCopy{}, str.begin(), (size_t)str.length()} {}
|
inline String::String(NoCopy, StringView str) : m_data{NoCopy{}, str.begin(), (size_t)str.length()} {}
|
||||||
|
inline String String::no_copy(StringView str) { return {NoCopy{}, str}; }
|
||||||
|
|
||||||
template<typename Type, typename CharType>
|
template<typename Type, typename CharType>
|
||||||
inline StringView StringOps<Type, CharType>::substr(ByteCount from, ByteCount length) const
|
inline StringView StringOps<Type, CharType>::substr(ByteCount from, ByteCount length) const
|
||||||
|
|
|
@ -173,7 +173,11 @@ public:
|
||||||
}}
|
}}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
template<typename Target, typename = std::enable_if_t<!std::is_same_v<FunctionRef, std::decay_t<Target>>>>
|
template<typename Target,
|
||||||
|
typename = std::enable_if_t<
|
||||||
|
not std::is_same_v<FunctionRef, std::decay_t<Target>> and
|
||||||
|
std::is_convertible_v<decltype(std::declval<Target>()(std::declval<Args>()...)), Res>
|
||||||
|
>>
|
||||||
FunctionRef(Target&& target)
|
FunctionRef(Target&& target)
|
||||||
: m_target{&target},
|
: m_target{&target},
|
||||||
m_invoker{[](void* target, Args... args) {
|
m_invoker{[](void* target, Args... args) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user