Rename selections first,last to more explicit anchor,cursor
This commit is contained in:
parent
dbd194cea8
commit
2159fc9563
|
@ -44,7 +44,7 @@ void Client::print_status(DisplayLine status_line)
|
|||
|
||||
DisplayLine Client::generate_mode_line() const
|
||||
{
|
||||
auto pos = context().selections().main().last();
|
||||
auto pos = context().selections().main().cursor();
|
||||
auto col = context().buffer()[pos.line].char_count_to(pos.column);
|
||||
|
||||
std::ostringstream oss;
|
||||
|
@ -90,7 +90,7 @@ void Client::redraw_ifn()
|
|||
static void reload_buffer(Context& context, const String& filename)
|
||||
{
|
||||
DisplayCoord view_pos = context.window().position();
|
||||
BufferCoord cursor_pos = context.selections().main().last();
|
||||
BufferCoord cursor_pos = context.selections().main().cursor();
|
||||
Buffer* buf = create_buffer_from_file(filename);
|
||||
if (not buf)
|
||||
return;
|
||||
|
|
|
@ -126,7 +126,7 @@ void edit(CommandParameters params, Context& context)
|
|||
|
||||
context.selections() = context.buffer().clamp({ line, column });
|
||||
if (context.has_window())
|
||||
context.window().center_line(context.selections().main().last().line);
|
||||
context.window().center_line(context.selections().main().cursor().line);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -674,7 +674,7 @@ void info(CommandParameters params, Context& context)
|
|||
{
|
||||
style = MenuStyle::Inline;
|
||||
const auto& sel = context.selections().main();
|
||||
auto it = sel.last();
|
||||
auto it = sel.cursor();
|
||||
String anchor = parser.option_value("anchor");
|
||||
if (anchor == "left")
|
||||
it = sel.min();
|
||||
|
|
|
@ -26,12 +26,12 @@ void DynamicSelectionList::check_invariant() const
|
|||
for (size_t i = 0; i < size(); ++i)
|
||||
{
|
||||
auto& sel = (*this)[i];
|
||||
kak_assert(buffer.is_valid(sel.first()));
|
||||
kak_assert(buffer.is_valid(sel.last()));
|
||||
kak_assert(not buffer.is_end(sel.first()));
|
||||
kak_assert(not buffer.is_end(sel.last()));
|
||||
kak_assert(utf8::is_character_start(buffer.iterator_at(sel.first())));
|
||||
kak_assert(utf8::is_character_start(buffer.iterator_at(sel.last())));
|
||||
kak_assert(buffer.is_valid(sel.anchor()));
|
||||
kak_assert(buffer.is_valid(sel.cursor()));
|
||||
kak_assert(not buffer.is_end(sel.anchor()));
|
||||
kak_assert(not buffer.is_end(sel.cursor()));
|
||||
kak_assert(utf8::is_character_start(buffer.iterator_at(sel.anchor())));
|
||||
kak_assert(utf8::is_character_start(buffer.iterator_at(sel.cursor())));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -403,7 +403,7 @@ void show_matching_char(const Context& context, HighlightFlags flags, DisplayBuf
|
|||
const auto& buffer = context.buffer();
|
||||
for (auto& sel : context.selections())
|
||||
{
|
||||
auto pos = sel.last();
|
||||
auto pos = sel.cursor();
|
||||
if (pos < range.first or pos >= range.second)
|
||||
continue;
|
||||
auto c = buffer.byte_at(pos);
|
||||
|
@ -454,16 +454,16 @@ void highlight_selections(const Context& context, HighlightFlags flags, DisplayB
|
|||
for (size_t i = 0; i < context.selections().size(); ++i)
|
||||
{
|
||||
auto& sel = context.selections()[i];
|
||||
const bool forward = sel.first() <= sel.last();
|
||||
BufferCoord begin = forward ? sel.first() : buffer.char_next(sel.last());
|
||||
BufferCoord end = forward ? sel.last() : buffer.char_next(sel.first());
|
||||
const bool forward = sel.anchor() <= sel.cursor();
|
||||
BufferCoord begin = forward ? sel.anchor() : buffer.char_next(sel.cursor());
|
||||
BufferCoord end = forward ? sel.cursor() : buffer.char_next(sel.anchor());
|
||||
|
||||
const bool primary = (i == context.selections().main_index());
|
||||
ColorPair sel_colors = get_color(primary ? "PrimarySelection" : "SecondarySelection");
|
||||
highlight_range(display_buffer, begin, end, false,
|
||||
[&](DisplayAtom& atom) { atom.colors = sel_colors; });
|
||||
ColorPair cur_colors = get_color(primary ? "PrimaryCursor" : "SecondaryCursor");
|
||||
highlight_range(display_buffer, sel.last(), buffer.char_next(sel.last()), false,
|
||||
highlight_range(display_buffer, sel.cursor(), buffer.char_next(sel.cursor()), false,
|
||||
[&](DisplayAtom& atom) { atom.colors = cur_colors; });
|
||||
}
|
||||
}
|
||||
|
|
|
@ -612,7 +612,7 @@ public:
|
|||
if (m_current_candidate < 0)
|
||||
m_current_candidate += m_matching_candidates.size();
|
||||
const String& candidate = m_matching_candidates[m_current_candidate];
|
||||
const auto& cursor_pos = m_context.selections().main().last();
|
||||
const auto& cursor_pos = m_context.selections().main().cursor();
|
||||
const auto prefix_len = buffer.distance(m_completions.begin, cursor_pos);
|
||||
const auto suffix_len = std::max(0_byte, buffer.distance(cursor_pos, m_completions.end));
|
||||
const auto buffer_len = buffer.byte_count();
|
||||
|
@ -620,8 +620,8 @@ public:
|
|||
auto ref = buffer.string(m_completions.begin, m_completions.end);
|
||||
for (auto& sel : m_context.selections())
|
||||
{
|
||||
auto offset = buffer.offset(sel.last());
|
||||
auto pos = buffer.iterator_at(sel.last());
|
||||
auto offset = buffer.offset(sel.cursor());
|
||||
auto pos = buffer.iterator_at(sel.cursor());
|
||||
if (offset >= prefix_len and offset + suffix_len < buffer_len and
|
||||
std::equal(ref.begin(), ref.end(), pos - prefix_len))
|
||||
{
|
||||
|
@ -650,7 +650,7 @@ public:
|
|||
for (auto& candidate : m_completions.candidates)
|
||||
longest_completion = std::max(longest_completion, candidate.length());
|
||||
|
||||
BufferCoord cursor = m_context.selections().main().last();
|
||||
BufferCoord cursor = m_context.selections().main().cursor();
|
||||
BufferCoord compl_beg = m_completions.begin;
|
||||
if (cursor.line == compl_beg.line and
|
||||
is_in_range(cursor.column - compl_beg.column,
|
||||
|
@ -694,7 +694,7 @@ public:
|
|||
bool try_complete()
|
||||
{
|
||||
auto& buffer = m_context.buffer();
|
||||
BufferCoord cursor_pos = m_context.selections().main().last();
|
||||
BufferCoord cursor_pos = m_context.selections().main().cursor();
|
||||
m_completions = (this->*complete_func)(buffer, cursor_pos);
|
||||
if (not m_completions.is_valid())
|
||||
return false;
|
||||
|
@ -948,9 +948,9 @@ public:
|
|||
{
|
||||
for (auto& sel : context().selections())
|
||||
{
|
||||
if (sel.last() == BufferCoord{0,0})
|
||||
if (sel.cursor() == BufferCoord{0,0})
|
||||
continue;
|
||||
auto pos = buffer.iterator_at(sel.last());
|
||||
auto pos = buffer.iterator_at(sel.cursor());
|
||||
buffer.erase(utf8::previous(pos), pos);
|
||||
}
|
||||
}
|
||||
|
@ -958,7 +958,7 @@ public:
|
|||
{
|
||||
for (auto& sel : context().selections())
|
||||
{
|
||||
auto pos = buffer.iterator_at(sel.last());
|
||||
auto pos = buffer.iterator_at(sel.cursor());
|
||||
buffer.erase(pos, utf8::next(pos));
|
||||
}
|
||||
}
|
||||
|
@ -1027,9 +1027,9 @@ private:
|
|||
auto& selections = context().selections();
|
||||
for (auto& sel : selections)
|
||||
{
|
||||
auto last = context().has_window() ? context().window().offset_coord(sel.last(), offset)
|
||||
: context().buffer().offset_coord(sel.last(), offset);
|
||||
sel.first() = sel.last() = last;
|
||||
auto cursor = context().has_window() ? context().window().offset_coord(sel.cursor(), offset)
|
||||
: context().buffer().offset_coord(sel.cursor(), offset);
|
||||
sel.anchor() = sel.cursor() = cursor;
|
||||
}
|
||||
selections.sort_and_merge_overlapping();
|
||||
}
|
||||
|
@ -1041,7 +1041,7 @@ private:
|
|||
for (size_t i = 0; i < selections.size(); ++i)
|
||||
{
|
||||
size_t index = std::min(i, strings.size()-1);
|
||||
buffer.insert(buffer.iterator_at(selections[i].last()),
|
||||
buffer.insert(buffer.iterator_at(selections[i].cursor()),
|
||||
strings[index]);
|
||||
}
|
||||
}
|
||||
|
@ -1051,7 +1051,7 @@ private:
|
|||
auto str = codepoint_to_str(key);
|
||||
auto& buffer = context().buffer();
|
||||
for (auto& sel : context().selections())
|
||||
buffer.insert(buffer.iterator_at(sel.last()), str);
|
||||
buffer.insert(buffer.iterator_at(sel.cursor()), str);
|
||||
context().hooks().run_hook("InsertChar", str, context());
|
||||
}
|
||||
|
||||
|
@ -1062,54 +1062,54 @@ private:
|
|||
|
||||
for (auto& sel : selections)
|
||||
{
|
||||
BufferCoord first, last;
|
||||
BufferCoord anchor, cursor;
|
||||
switch (mode)
|
||||
{
|
||||
case InsertMode::Insert:
|
||||
first = sel.max();
|
||||
last = sel.min();
|
||||
anchor = sel.max();
|
||||
cursor = sel.min();
|
||||
break;
|
||||
case InsertMode::Replace:
|
||||
first = last = Kakoune::erase(buffer, sel).coord();
|
||||
anchor = cursor = Kakoune::erase(buffer, sel).coord();
|
||||
break;
|
||||
case InsertMode::Append:
|
||||
first = sel.min();
|
||||
last = sel.max();
|
||||
anchor = sel.min();
|
||||
cursor = sel.max();
|
||||
// special case for end of lines, append to current line instead
|
||||
if (last.column != buffer[last.line].length() - 1)
|
||||
last = buffer.char_next(last);
|
||||
if (cursor.column != buffer[cursor.line].length() - 1)
|
||||
cursor = buffer.char_next(cursor);
|
||||
break;
|
||||
|
||||
case InsertMode::OpenLineBelow:
|
||||
case InsertMode::AppendAtLineEnd:
|
||||
first = last = BufferCoord{sel.max().line, buffer[sel.max().line].length() - 1};
|
||||
anchor = cursor = BufferCoord{sel.max().line, buffer[sel.max().line].length() - 1};
|
||||
break;
|
||||
|
||||
case InsertMode::OpenLineAbove:
|
||||
case InsertMode::InsertAtLineBegin:
|
||||
first = sel.min().line;
|
||||
anchor = sel.min().line;
|
||||
if (mode == InsertMode::OpenLineAbove)
|
||||
first = buffer.char_prev(first);
|
||||
anchor = buffer.char_prev(anchor);
|
||||
else
|
||||
{
|
||||
auto first_non_blank = buffer.iterator_at(first);
|
||||
while (*first_non_blank == ' ' or *first_non_blank == '\t')
|
||||
++first_non_blank;
|
||||
if (*first_non_blank != '\n')
|
||||
first = first_non_blank.coord();
|
||||
auto anchor_non_blank = buffer.iterator_at(anchor);
|
||||
while (*anchor_non_blank == ' ' or *anchor_non_blank == '\t')
|
||||
++anchor_non_blank;
|
||||
if (*anchor_non_blank != '\n')
|
||||
anchor = anchor_non_blank.coord();
|
||||
}
|
||||
last = first;
|
||||
cursor = anchor;
|
||||
break;
|
||||
case InsertMode::InsertAtNextLineBegin:
|
||||
kak_assert(false); // not implemented
|
||||
break;
|
||||
}
|
||||
if (buffer.is_end(first))
|
||||
first = buffer.char_prev(first);
|
||||
if (buffer.is_end(last))
|
||||
last = buffer.char_prev(last);
|
||||
sel.first() = first;
|
||||
sel.last() = last;
|
||||
if (buffer.is_end(anchor))
|
||||
anchor = buffer.char_prev(anchor);
|
||||
if (buffer.is_end(cursor))
|
||||
cursor = buffer.char_prev(cursor);
|
||||
sel.anchor() = anchor;
|
||||
sel.cursor() = cursor;
|
||||
}
|
||||
if (mode == InsertMode::OpenLineBelow or mode == InsertMode::OpenLineAbove)
|
||||
{
|
||||
|
@ -1119,8 +1119,8 @@ private:
|
|||
for (auto& sel : selections)
|
||||
{
|
||||
// special case, the --first line above did nothing, so we need to compensate now
|
||||
if (sel.first() == buffer.char_next({0,0}))
|
||||
sel.first() = sel.last() = BufferCoord{0,0};
|
||||
if (sel.anchor() == buffer.char_next({0,0}))
|
||||
sel.anchor() = sel.cursor() = BufferCoord{0,0};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1133,8 +1133,8 @@ private:
|
|||
{
|
||||
for (auto& sel : context().selections())
|
||||
{
|
||||
if (m_insert_mode == InsertMode::Append and sel.last().column > 0)
|
||||
sel.last() = context().buffer().char_prev(sel.last());
|
||||
if (m_insert_mode == InsertMode::Append and sel.cursor().column > 0)
|
||||
sel.cursor() = context().buffer().char_prev(sel.cursor());
|
||||
avoid_eol(context().buffer(), sel);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -108,15 +108,15 @@ void register_env_vars()
|
|||
}, {
|
||||
"cursor_line",
|
||||
[](const String& name, const Context& context)
|
||||
{ return to_string(context.selections().main().last().line + 1); }
|
||||
{ return to_string(context.selections().main().cursor().line + 1); }
|
||||
}, {
|
||||
"cursor_column",
|
||||
[](const String& name, const Context& context)
|
||||
{ return to_string(context.selections().main().last().column + 1); }
|
||||
{ return to_string(context.selections().main().cursor().column + 1); }
|
||||
}, {
|
||||
"cursor_char_column",
|
||||
[](const String& name, const Context& context)
|
||||
{ auto coord = context.selections().main().last();
|
||||
{ auto coord = context.selections().main().cursor();
|
||||
return to_string(context.buffer()[coord.line].char_count_to(coord.column) + 1); }
|
||||
}, {
|
||||
"selection_desc",
|
||||
|
|
|
@ -70,8 +70,8 @@ void insert(Buffer& buffer, SelectionList& selections, const String& str)
|
|||
pos = buffer.insert(pos, str);
|
||||
if (mode == InsertMode::Replace and pos != buffer.end())
|
||||
{
|
||||
sel.first() = pos.coord();
|
||||
sel.last() = str.empty() ?
|
||||
sel.anchor() = pos.coord();
|
||||
sel.cursor() = str.empty() ?
|
||||
pos.coord() : (pos + str.byte_count_to(str.char_length() - 1)).coord();
|
||||
}
|
||||
avoid_eol(buffer, sel);
|
||||
|
@ -93,8 +93,8 @@ void insert(Buffer& buffer, SelectionList& selections, memoryview<String> string
|
|||
pos = buffer.insert(pos, str);
|
||||
if (mode == InsertMode::Replace and pos != buffer.end())
|
||||
{
|
||||
sel.first() = pos.coord();
|
||||
sel.last() = (str.empty() ?
|
||||
sel.anchor() = pos.coord();
|
||||
sel.cursor() = (str.empty() ?
|
||||
pos : pos + str.byte_count_to(str.char_length() - 1)).coord();
|
||||
}
|
||||
avoid_eol(buffer, sel);
|
||||
|
@ -131,8 +131,8 @@ void select(Context& context, Func func)
|
|||
{
|
||||
auto& sel = selections.main();
|
||||
auto res = func(buffer, sel);
|
||||
sel.first() = res.first();
|
||||
sel.last() = res.last();
|
||||
sel.anchor() = res.anchor();
|
||||
sel.cursor() = res.cursor();
|
||||
if (not res.captures().empty())
|
||||
sel.captures() = std::move(res.captures());
|
||||
}
|
||||
|
@ -145,8 +145,8 @@ void select(Context& context, Func func)
|
|||
sel.merge_with(res);
|
||||
else
|
||||
{
|
||||
sel.first() = res.first();
|
||||
sel.last() = res.last();
|
||||
sel.anchor() = res.anchor();
|
||||
sel.cursor() = res.cursor();
|
||||
}
|
||||
if (not res.captures().empty())
|
||||
sel.captures() = std::move(res.captures());
|
||||
|
@ -181,7 +181,7 @@ void select_coord(const Buffer& buffer, BufferCoord coord, SelectionList& select
|
|||
else if (mode == SelectMode::Extend)
|
||||
{
|
||||
for (auto& sel : selections)
|
||||
sel.last() = coord;
|
||||
sel.cursor() = coord;
|
||||
selections.sort_and_merge_overlapping();
|
||||
}
|
||||
}
|
||||
|
@ -335,7 +335,7 @@ void view_commands(Context& context, int param)
|
|||
if (key.modifiers != Key::Modifiers::None or not context.has_window())
|
||||
return;
|
||||
|
||||
LineCount cursor_line = context.selections().main().last().line;
|
||||
LineCount cursor_line = context.selections().main().cursor().line;
|
||||
Window& window = context.window();
|
||||
switch (tolower(key.key))
|
||||
{
|
||||
|
@ -688,7 +688,7 @@ void split_lines(Context& context, int)
|
|||
SelectionList res;
|
||||
for (auto& sel : selections)
|
||||
{
|
||||
if (sel.first().line == sel.last().line)
|
||||
if (sel.anchor().line == sel.cursor().line)
|
||||
{
|
||||
res.push_back(std::move(sel));
|
||||
continue;
|
||||
|
@ -1030,8 +1030,8 @@ void align(Context& context, int)
|
|||
size_t column = 0;
|
||||
for (auto& sel : selections)
|
||||
{
|
||||
auto line = sel.last().line;
|
||||
if (sel.first().line != line)
|
||||
auto line = sel.cursor().line;
|
||||
if (sel.anchor().line != line)
|
||||
throw runtime_error("align cannot work with multi line selections");
|
||||
|
||||
column = (line == last_line) ? column + 1 : 0;
|
||||
|
@ -1046,11 +1046,11 @@ void align(Context& context, int)
|
|||
{
|
||||
CharCount maxcol = 0;
|
||||
for (auto& sel : col)
|
||||
maxcol = std::max(get_column(buffer, tabstop, sel->last()), maxcol);
|
||||
maxcol = std::max(get_column(buffer, tabstop, sel->cursor()), maxcol);
|
||||
for (auto& sel : col)
|
||||
{
|
||||
auto insert_coord = sel->min();
|
||||
auto lastcol = get_column(buffer, tabstop, sel->last());
|
||||
auto lastcol = get_column(buffer, tabstop, sel->cursor());
|
||||
String padstr;
|
||||
if (not use_tabs)
|
||||
padstr = String{ ' ', maxcol - lastcol };
|
||||
|
@ -1196,11 +1196,11 @@ void move(Context& context, int count)
|
|||
auto& selections = context.selections();
|
||||
for (auto& sel : selections)
|
||||
{
|
||||
auto last = context.has_window() ? context.window().offset_coord(sel.last(), offset)
|
||||
: context.buffer().offset_coord(sel.last(), offset);
|
||||
auto cursor = context.has_window() ? context.window().offset_coord(sel.cursor(), offset)
|
||||
: context.buffer().offset_coord(sel.cursor(), offset);
|
||||
|
||||
sel.first() = mode == SelectMode::Extend ? sel.first() : last;
|
||||
sel.last() = last;
|
||||
sel.anchor() = mode == SelectMode::Extend ? sel.anchor() : cursor;
|
||||
sel.cursor() = cursor;
|
||||
avoid_eol(context.buffer(), sel);
|
||||
}
|
||||
selections.sort_and_merge_overlapping();
|
||||
|
|
|
@ -7,11 +7,11 @@ namespace Kakoune
|
|||
|
||||
void Range::merge_with(const Range& range)
|
||||
{
|
||||
m_last = range.m_last;
|
||||
if (m_first < m_last)
|
||||
m_first = std::min(m_first, range.m_first);
|
||||
if (m_first > m_last)
|
||||
m_first = std::max(m_first, range.m_first);
|
||||
m_cursor = range.m_cursor;
|
||||
if (m_anchor < m_cursor)
|
||||
m_anchor = std::min(m_anchor, range.m_anchor);
|
||||
if (m_anchor > m_cursor)
|
||||
m_anchor = std::max(m_anchor, range.m_anchor);
|
||||
}
|
||||
|
||||
namespace
|
||||
|
@ -22,27 +22,27 @@ void on_buffer_change(const Buffer& buffer, SelectionList& sels,
|
|||
BufferCoord begin, BufferCoord end, LineCount end_line)
|
||||
{
|
||||
auto update_beg = std::lower_bound(sels.begin(), sels.end(), begin,
|
||||
[](const Selection& s, BufferCoord c) { return std::max(s.first(), s.last()) < c; });
|
||||
[](const Selection& s, BufferCoord c) { return std::max(s.anchor(), s.cursor()) < c; });
|
||||
auto update_only_line_beg = std::upper_bound(sels.begin(), sels.end(), end_line,
|
||||
[](LineCount l, const Selection& s) { return l < std::min(s.first(), s.last()).line; });
|
||||
[](LineCount l, const Selection& s) { return l < std::min(s.anchor(), s.cursor()).line; });
|
||||
|
||||
if (update_beg != update_only_line_beg)
|
||||
{
|
||||
// for the first one, we are not sure if min < begin
|
||||
UpdateFunc<false, false>{}(buffer, update_beg->first(), begin, end);
|
||||
UpdateFunc<false, false>{}(buffer, update_beg->last(), begin, end);
|
||||
UpdateFunc<false, false>{}(buffer, update_beg->anchor(), begin, end);
|
||||
UpdateFunc<false, false>{}(buffer, update_beg->cursor(), begin, end);
|
||||
}
|
||||
for (auto it = update_beg+1; it < update_only_line_beg; ++it)
|
||||
{
|
||||
UpdateFunc<false, true>{}(buffer, it->first(), begin, end);
|
||||
UpdateFunc<false, true>{}(buffer, it->last(), begin, end);
|
||||
UpdateFunc<false, true>{}(buffer, it->anchor(), begin, end);
|
||||
UpdateFunc<false, true>{}(buffer, it->cursor(), begin, end);
|
||||
}
|
||||
if (end.line > begin.line)
|
||||
{
|
||||
for (auto it = update_only_line_beg; it != sels.end(); ++it)
|
||||
{
|
||||
UpdateFunc<true, true>{}(buffer, it->first(), begin, end);
|
||||
UpdateFunc<true, true>{}(buffer, it->last(), begin, end);
|
||||
UpdateFunc<true, true>{}(buffer, it->anchor(), begin, end);
|
||||
UpdateFunc<true, true>{}(buffer, it->cursor(), begin, end);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,28 +10,28 @@ namespace Kakoune
|
|||
struct Range
|
||||
{
|
||||
public:
|
||||
Range(BufferCoord first, BufferCoord last)
|
||||
: m_first{first}, m_last{last} {}
|
||||
Range(BufferCoord anchor, BufferCoord cursor)
|
||||
: m_anchor{anchor}, m_cursor{cursor} {}
|
||||
|
||||
void merge_with(const Range& range);
|
||||
|
||||
BufferCoord& first() { return m_first; }
|
||||
BufferCoord& last() { return m_last; }
|
||||
BufferCoord& anchor() { return m_anchor; }
|
||||
BufferCoord& cursor() { return m_cursor; }
|
||||
|
||||
const BufferCoord& first() const { return m_first; }
|
||||
const BufferCoord& last() const { return m_last; }
|
||||
const BufferCoord& anchor() const { return m_anchor; }
|
||||
const BufferCoord& cursor() const { return m_cursor; }
|
||||
|
||||
bool operator== (const Range& other) const
|
||||
{
|
||||
return m_first == other.m_first and m_last == other.m_last;
|
||||
return m_anchor == other.m_anchor and m_cursor == other.m_cursor;
|
||||
}
|
||||
|
||||
const BufferCoord& min() const { return std::min(m_first, m_last); }
|
||||
const BufferCoord& max() const { return std::max(m_first, m_last); }
|
||||
const BufferCoord& min() const { return std::min(m_anchor, m_cursor); }
|
||||
const BufferCoord& max() const { return std::max(m_anchor, m_cursor); }
|
||||
|
||||
private:
|
||||
BufferCoord m_first;
|
||||
BufferCoord m_last;
|
||||
BufferCoord m_anchor;
|
||||
BufferCoord m_cursor;
|
||||
};
|
||||
|
||||
inline bool overlaps(const Range& lhs, const Range& rhs)
|
||||
|
@ -68,8 +68,8 @@ inline void avoid_eol(const Buffer& buffer, BufferCoord& coord)
|
|||
|
||||
inline void avoid_eol(const Buffer& buffer, Range& sel)
|
||||
{
|
||||
avoid_eol(buffer, sel.first());
|
||||
avoid_eol(buffer, sel.last());
|
||||
avoid_eol(buffer, sel.anchor());
|
||||
avoid_eol(buffer, sel.cursor());
|
||||
}
|
||||
|
||||
|
||||
|
@ -79,9 +79,9 @@ using CaptureList = std::vector<String>;
|
|||
struct Selection : public Range
|
||||
{
|
||||
explicit Selection(BufferCoord pos) : Range(pos,pos) {}
|
||||
Selection(BufferCoord first, BufferCoord last,
|
||||
Selection(BufferCoord anchor, BufferCoord cursor,
|
||||
CaptureList captures = {})
|
||||
: Range(first, last), m_captures(std::move(captures)) {}
|
||||
: Range(anchor, cursor), m_captures(std::move(captures)) {}
|
||||
|
||||
Selection(const Range& range)
|
||||
: Range(range) {}
|
||||
|
|
|
@ -11,7 +11,7 @@ namespace Kakoune
|
|||
|
||||
Selection select_line(const Buffer& buffer, const Selection& selection)
|
||||
{
|
||||
Utf8Iterator first = buffer.iterator_at(selection.last());
|
||||
Utf8Iterator first = buffer.iterator_at(selection.cursor());
|
||||
if (*first == '\n' and first + 1 != buffer.end())
|
||||
++first;
|
||||
|
||||
|
@ -27,7 +27,7 @@ Selection select_line(const Buffer& buffer, const Selection& selection)
|
|||
Selection select_matching(const Buffer& buffer, const Selection& selection)
|
||||
{
|
||||
std::vector<Codepoint> matching_pairs = { '(', ')', '{', '}', '[', ']', '<', '>' };
|
||||
Utf8Iterator it = buffer.iterator_at(selection.last());
|
||||
Utf8Iterator it = buffer.iterator_at(selection.cursor());
|
||||
std::vector<Codepoint>::iterator match = matching_pairs.end();
|
||||
while (not is_eol(*it))
|
||||
{
|
||||
|
@ -142,7 +142,7 @@ Selection select_surrounding(const Buffer& buffer, const Selection& selection,
|
|||
ObjectFlags flags)
|
||||
{
|
||||
const bool nestable = matching.first != matching.second;
|
||||
auto pos = selection.last();
|
||||
auto pos = selection.cursor();
|
||||
if (not nestable or flags & ObjectFlags::Inner)
|
||||
{
|
||||
if (auto res = find_surrounding(buffer, pos, matching, flags, level))
|
||||
|
@ -171,7 +171,7 @@ Selection select_surrounding(const Buffer& buffer, const Selection& selection,
|
|||
Selection select_to(const Buffer& buffer, const Selection& selection,
|
||||
Codepoint c, int count, bool inclusive)
|
||||
{
|
||||
Utf8Iterator begin = buffer.iterator_at(selection.last());
|
||||
Utf8Iterator begin = buffer.iterator_at(selection.cursor());
|
||||
Utf8Iterator end = begin;
|
||||
do
|
||||
{
|
||||
|
@ -188,7 +188,7 @@ Selection select_to(const Buffer& buffer, const Selection& selection,
|
|||
Selection select_to_reverse(const Buffer& buffer, const Selection& selection,
|
||||
Codepoint c, int count, bool inclusive)
|
||||
{
|
||||
Utf8Iterator begin = buffer.iterator_at(selection.last());
|
||||
Utf8Iterator begin = buffer.iterator_at(selection.cursor());
|
||||
Utf8Iterator end = begin;
|
||||
do
|
||||
{
|
||||
|
@ -204,7 +204,7 @@ Selection select_to_reverse(const Buffer& buffer, const Selection& selection,
|
|||
|
||||
Selection select_to_eol(const Buffer& buffer, const Selection& selection)
|
||||
{
|
||||
Utf8Iterator begin = buffer.iterator_at(selection.last());
|
||||
Utf8Iterator begin = buffer.iterator_at(selection.cursor());
|
||||
Utf8Iterator end = begin;
|
||||
skip_while(end, buffer.end(), [](Codepoint cur) { return not is_eol(cur); });
|
||||
return utf8_range(begin, end != begin ? end-1 : end);
|
||||
|
@ -212,7 +212,7 @@ Selection select_to_eol(const Buffer& buffer, const Selection& selection)
|
|||
|
||||
Selection select_to_eol_reverse(const Buffer& buffer, const Selection& selection)
|
||||
{
|
||||
Utf8Iterator begin = buffer.iterator_at(selection.last());
|
||||
Utf8Iterator begin = buffer.iterator_at(selection.cursor());
|
||||
Utf8Iterator end = begin - 1;
|
||||
skip_while_reverse(end, buffer.begin(), [](Codepoint cur) { return not is_eol(cur); });
|
||||
return utf8_range(begin, end == buffer.begin() ? end : end+1);
|
||||
|
@ -220,7 +220,7 @@ Selection select_to_eol_reverse(const Buffer& buffer, const Selection& selection
|
|||
|
||||
Selection select_whole_sentence(const Buffer& buffer, const Selection& selection, ObjectFlags flags)
|
||||
{
|
||||
BufferIterator first = buffer.iterator_at(selection.last());
|
||||
BufferIterator first = buffer.iterator_at(selection.cursor());
|
||||
BufferIterator last = first;
|
||||
|
||||
if (flags & ObjectFlags::ToBegin)
|
||||
|
@ -271,7 +271,7 @@ Selection select_whole_sentence(const Buffer& buffer, const Selection& selection
|
|||
|
||||
Selection select_whole_paragraph(const Buffer& buffer, const Selection& selection, ObjectFlags flags)
|
||||
{
|
||||
BufferIterator first = buffer.iterator_at(selection.last());
|
||||
BufferIterator first = buffer.iterator_at(selection.cursor());
|
||||
BufferIterator last = first;
|
||||
|
||||
if (flags & ObjectFlags::ToBegin and first != buffer.begin())
|
||||
|
@ -329,7 +329,7 @@ static CharCount get_indent(const String& str, int tabstop)
|
|||
Selection select_whole_indent(const Buffer& buffer, const Selection& selection, ObjectFlags flags)
|
||||
{
|
||||
int tabstop = buffer.options()["tabstop"].get<int>();
|
||||
LineCount line = selection.last().line;
|
||||
LineCount line = selection.cursor().line;
|
||||
auto indent = get_indent(buffer[line], tabstop);
|
||||
|
||||
LineCount begin_line = line - 1;
|
||||
|
@ -367,8 +367,8 @@ Selection select_whole_indent(const Buffer& buffer, const Selection& selection,
|
|||
Selection select_whole_lines(const Buffer& buffer, const Selection& selection)
|
||||
{
|
||||
// no need to be utf8 aware for is_eol as we only use \n as line seperator
|
||||
BufferIterator first = buffer.iterator_at(selection.first());
|
||||
BufferIterator last = buffer.iterator_at(selection.last());
|
||||
BufferIterator first = buffer.iterator_at(selection.anchor());
|
||||
BufferIterator last = buffer.iterator_at(selection.cursor());
|
||||
BufferIterator& to_line_start = first <= last ? first : last;
|
||||
BufferIterator& to_line_end = first <= last ? last : first;
|
||||
|
||||
|
@ -387,8 +387,8 @@ Selection select_whole_lines(const Buffer& buffer, const Selection& selection)
|
|||
Selection trim_partial_lines(const Buffer& buffer, const Selection& selection)
|
||||
{
|
||||
// same as select_whole_lines
|
||||
BufferIterator first = buffer.iterator_at(selection.first());
|
||||
BufferIterator last = buffer.iterator_at(selection.last());
|
||||
BufferIterator first = buffer.iterator_at(selection.anchor());
|
||||
BufferIterator last = buffer.iterator_at(selection.cursor());
|
||||
BufferIterator& to_line_start = first <= last ? first : last;
|
||||
BufferIterator& to_line_end = first <= last ? last : first;
|
||||
|
||||
|
|
|
@ -11,9 +11,9 @@ namespace Kakoune
|
|||
inline void clear_selections(const Buffer& buffer, SelectionList& selections)
|
||||
{
|
||||
auto& sel = selections.main();
|
||||
auto& pos = sel.last();
|
||||
auto& pos = sel.cursor();
|
||||
avoid_eol(buffer, pos);
|
||||
sel.first() = pos;
|
||||
sel.anchor() = pos;
|
||||
|
||||
selections = SelectionList{ std::move(sel) };
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ inline void clear_selections(const Buffer& buffer, SelectionList& selections)
|
|||
inline void flip_selections(SelectionList& selections)
|
||||
{
|
||||
for (auto& sel : selections)
|
||||
std::swap(sel.first(), sel.last());
|
||||
std::swap(sel.anchor(), sel.cursor());
|
||||
selections.check_invariant();
|
||||
}
|
||||
|
||||
|
@ -61,7 +61,7 @@ using RegexIterator = boost::regex_iterator<BufferIterator>;
|
|||
template<WordType word_type>
|
||||
Selection select_to_next_word(const Buffer& buffer, const Selection& selection)
|
||||
{
|
||||
Utf8Iterator begin = buffer.iterator_at(selection.last());
|
||||
Utf8Iterator begin = buffer.iterator_at(selection.cursor());
|
||||
if (begin+1 == buffer.end())
|
||||
return selection;
|
||||
if (categorize<word_type>(*begin) != categorize<word_type>(*(begin+1)))
|
||||
|
@ -85,7 +85,7 @@ Selection select_to_next_word(const Buffer& buffer, const Selection& selection)
|
|||
template<WordType word_type>
|
||||
Selection select_to_next_word_end(const Buffer& buffer, const Selection& selection)
|
||||
{
|
||||
Utf8Iterator begin = buffer.iterator_at(selection.last());
|
||||
Utf8Iterator begin = buffer.iterator_at(selection.cursor());
|
||||
if (begin+1 == buffer.end())
|
||||
return selection;
|
||||
if (categorize<word_type>(*begin) != categorize<word_type>(*(begin+1)))
|
||||
|
@ -108,7 +108,7 @@ Selection select_to_next_word_end(const Buffer& buffer, const Selection& selecti
|
|||
template<WordType word_type>
|
||||
Selection select_to_previous_word(const Buffer& buffer, const Selection& selection)
|
||||
{
|
||||
Utf8Iterator begin = buffer.iterator_at(selection.last());
|
||||
Utf8Iterator begin = buffer.iterator_at(selection.cursor());
|
||||
if (begin == buffer.begin())
|
||||
return selection;
|
||||
if (categorize<word_type>(*begin) != categorize<word_type>(*(begin-1)))
|
||||
|
@ -160,7 +160,7 @@ constexpr ObjectFlags operator|(ObjectFlags lhs, ObjectFlags rhs)
|
|||
template<WordType word_type>
|
||||
Selection select_whole_word(const Buffer& buffer, const Selection& selection, ObjectFlags flags)
|
||||
{
|
||||
Utf8Iterator first = buffer.iterator_at(selection.last());
|
||||
Utf8Iterator first = buffer.iterator_at(selection.cursor());
|
||||
Utf8Iterator last = first;
|
||||
if (is_word<word_type>(*first))
|
||||
{
|
||||
|
@ -242,7 +242,7 @@ bool find_match_in_buffer(const Buffer& buffer, const BufferIterator pos,
|
|||
template<Direction direction>
|
||||
Selection find_next_match(const Buffer& buffer, const Selection& sel, const Regex& regex)
|
||||
{
|
||||
auto begin = buffer.iterator_at(sel.last());
|
||||
auto begin = buffer.iterator_at(sel.cursor());
|
||||
auto end = begin;
|
||||
|
||||
CaptureList captures;
|
||||
|
|
|
@ -162,22 +162,22 @@ static CharCount adapt_view_pos(const DisplayBuffer& display_buffer,
|
|||
void Window::scroll_to_keep_selection_visible_ifn(const Context& context)
|
||||
{
|
||||
auto& selection = context.selections().main();
|
||||
const auto& first = selection.first();
|
||||
const auto& last = selection.last();
|
||||
const auto& anchor = selection.anchor();
|
||||
const auto& cursor = selection.cursor();
|
||||
|
||||
const LineCount offset = std::min<LineCount>(options()["scrolloff"].get<int>(),
|
||||
(m_dimensions.line - 1) / 2);
|
||||
|
||||
// scroll lines if needed, try to get as much of the selection visible as possible
|
||||
m_position.line = adapt_view_pos(first.line, offset, m_position.line,
|
||||
m_position.line = adapt_view_pos(anchor.line, offset, m_position.line,
|
||||
m_dimensions.line, buffer().line_count());
|
||||
m_position.line = adapt_view_pos(last.line, offset, m_position.line,
|
||||
m_position.line = adapt_view_pos(cursor.line, offset, m_position.line,
|
||||
m_dimensions.line, buffer().line_count());
|
||||
|
||||
// highlight only the line containing the cursor
|
||||
DisplayBuffer display_buffer;
|
||||
DisplayBuffer::LineList& lines = display_buffer.lines();
|
||||
lines.emplace_back(AtomList{ {buffer(), last.line, last.line+1} });
|
||||
lines.emplace_back(AtomList{ {buffer(), cursor.line, cursor.line+1} });
|
||||
|
||||
display_buffer.compute_range();
|
||||
m_highlighters(context, HighlightFlags::MoveOnly, display_buffer);
|
||||
|
@ -188,9 +188,9 @@ void Window::scroll_to_keep_selection_visible_ifn(const Context& context)
|
|||
// the cursor in the same position, however I do not find any sane example
|
||||
// of highlighters not doing that)
|
||||
m_position.column = adapt_view_pos(display_buffer,
|
||||
first.line == last.line ? first : last.line,
|
||||
anchor.line == cursor.line ? anchor : cursor.line,
|
||||
m_position.column, m_dimensions.column);
|
||||
m_position.column = adapt_view_pos(display_buffer, last,
|
||||
m_position.column = adapt_view_pos(display_buffer, cursor,
|
||||
m_position.column, m_dimensions.column);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user