Added argument text object
This commit is contained in:
parent
6689bf0b46
commit
13d212f445
|
@ -925,6 +925,11 @@ void select_object(Context& context, NormalParams params)
|
||||||
return select<mode>(context, std::bind(sel.func, _1, _2, flags));
|
return select<mode>(context, std::bind(sel.func, _1, _2, flags));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (c == 'u')
|
||||||
|
{
|
||||||
|
return select<mode>(context, std::bind(select_argument, _1, _2, level, flags));
|
||||||
|
}
|
||||||
|
|
||||||
static constexpr struct
|
static constexpr struct
|
||||||
{
|
{
|
||||||
MatchingPair pair;
|
MatchingPair pair;
|
||||||
|
@ -958,7 +963,8 @@ void select_object(Context& context, NormalParams params)
|
||||||
"s: sentence \n"
|
"s: sentence \n"
|
||||||
"p: paragraph \n"
|
"p: paragraph \n"
|
||||||
"␣: whitespaces \n"
|
"␣: whitespaces \n"
|
||||||
"i: indent \n");
|
"i: indent \n"
|
||||||
|
"u: argument \n");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<Key::NamedKey key>
|
template<Key::NamedKey key>
|
||||||
|
|
133
src/selectors.cc
133
src/selectors.cc
|
@ -431,6 +431,139 @@ Selection select_indent(const Buffer& buffer, const Selection& selection, Object
|
||||||
return Selection{begin_line, {end_line, buffer[end_line].length() - 1}};
|
return Selection{begin_line, {end_line, buffer[end_line].length() - 1}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Selection select_argument(const Buffer& buffer, const Selection& selection,
|
||||||
|
int level, ObjectFlags flags)
|
||||||
|
{
|
||||||
|
auto is_whitespace = [](Codepoint c) {
|
||||||
|
return c == ' ' or c == '\t' or c == '\n';
|
||||||
|
};
|
||||||
|
auto get_kind = [](Codepoint c) -> int {
|
||||||
|
switch (c)
|
||||||
|
{
|
||||||
|
case '(': case ')': return 1;
|
||||||
|
case '[': case ']': return 2;
|
||||||
|
case '{': case '}': return 3;
|
||||||
|
case '<': case '>': return 4;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
enum Class { None, Opening, Closing };
|
||||||
|
auto classify = [](Codepoint c) {
|
||||||
|
switch (c)
|
||||||
|
{
|
||||||
|
case '(': case '[': case '{': case '<': return Opening;
|
||||||
|
case ')': case ']': case '}': case '>': return Closing;
|
||||||
|
default: return None;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
auto pairs = std::vector<int>();
|
||||||
|
|
||||||
|
Utf8Iterator pos = buffer.iterator_at(selection.cursor());
|
||||||
|
if (classify(*pos) == Closing)
|
||||||
|
++pos;
|
||||||
|
Utf8Iterator begin = pos;
|
||||||
|
Utf8Iterator end = begin;
|
||||||
|
bool fail = false;
|
||||||
|
|
||||||
|
skip_while(end, buffer.end(), [&](Codepoint cur)
|
||||||
|
{
|
||||||
|
if (cur == ',' && level == 0)
|
||||||
|
{
|
||||||
|
pairs.push_back(0);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
auto c = classify(cur);
|
||||||
|
if (c == Opening)
|
||||||
|
{
|
||||||
|
pairs.push_back(get_kind(cur));
|
||||||
|
++level;
|
||||||
|
}
|
||||||
|
else if (c == Closing)
|
||||||
|
{
|
||||||
|
--level;
|
||||||
|
if (pairs.empty() || pairs.back() < 0)
|
||||||
|
{
|
||||||
|
pairs.push_back(-get_kind(cur));
|
||||||
|
return level >= 0;
|
||||||
|
}
|
||||||
|
else if (pairs.back() == get_kind(cur))
|
||||||
|
{
|
||||||
|
pairs.pop_back();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
fail = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
if (fail || end == buffer.end())
|
||||||
|
return selection;
|
||||||
|
|
||||||
|
write_to_debug_buffer("before reverse:");
|
||||||
|
for (auto it = pairs.begin(); it != pairs.end(); ++it)
|
||||||
|
write_to_debug_buffer(format("{}", *it));
|
||||||
|
std::reverse(pairs.begin(), pairs.end());
|
||||||
|
write_to_debug_buffer("before reverse:");
|
||||||
|
for (auto it = pairs.begin(); it != pairs.end(); ++it)
|
||||||
|
write_to_debug_buffer(format("{}", *it));
|
||||||
|
|
||||||
|
--begin;
|
||||||
|
skip_while_reverse(begin, buffer.begin(), [&](Codepoint cur)
|
||||||
|
{
|
||||||
|
if (cur == ',' && pairs.size() == 1)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
auto c = classify(cur);
|
||||||
|
if (c == Closing)
|
||||||
|
{
|
||||||
|
pairs.push_back(-get_kind(cur));
|
||||||
|
}
|
||||||
|
else if (c == Opening)
|
||||||
|
{
|
||||||
|
if (pairs.back() == 0 || pairs.back() == -get_kind(cur))
|
||||||
|
{
|
||||||
|
pairs.pop_back();
|
||||||
|
return !pairs.empty();
|
||||||
|
}
|
||||||
|
fail = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
if (fail || begin == buffer.begin())
|
||||||
|
return selection;
|
||||||
|
|
||||||
|
if (flags & ObjectFlags::Inner)
|
||||||
|
{
|
||||||
|
++begin;
|
||||||
|
skip_while(begin, end, is_whitespace);
|
||||||
|
--end;
|
||||||
|
skip_while_reverse(end, begin, is_whitespace);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (classify(*end) == Closing)
|
||||||
|
{
|
||||||
|
--end;
|
||||||
|
if (classify(*begin) == Opening)
|
||||||
|
++begin;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
++begin;
|
||||||
|
skip_while(begin, end, is_whitespace);
|
||||||
|
++end;
|
||||||
|
skip_while(end, buffer.end(), is_whitespace);
|
||||||
|
--end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags & ObjectFlags::ToBegin and not (flags & ObjectFlags::ToEnd))
|
||||||
|
return utf8_range(pos, begin);
|
||||||
|
return utf8_range(flags & ObjectFlags::ToBegin ? begin : pos, end);
|
||||||
|
}
|
||||||
|
|
||||||
Selection select_lines(const Buffer& buffer, const Selection& selection)
|
Selection select_lines(const Buffer& buffer, const Selection& selection)
|
||||||
{
|
{
|
||||||
// no need to be utf8 aware for is_eol as we only use \n as line seperator
|
// no need to be utf8 aware for is_eol as we only use \n as line seperator
|
||||||
|
|
|
@ -219,6 +219,10 @@ Selection select_indent(const Buffer& buffer,
|
||||||
const Selection& selection,
|
const Selection& selection,
|
||||||
ObjectFlags flags);
|
ObjectFlags flags);
|
||||||
|
|
||||||
|
Selection select_argument(const Buffer& buffer,
|
||||||
|
const Selection& selection,
|
||||||
|
int level, ObjectFlags flags);
|
||||||
|
|
||||||
Selection select_lines(const Buffer& buffer, const Selection& selection);
|
Selection select_lines(const Buffer& buffer, const Selection& selection);
|
||||||
|
|
||||||
Selection trim_partial_lines(const Buffer& buffer, const Selection& selection);
|
Selection trim_partial_lines(const Buffer& buffer, const Selection& selection);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user