Refactor LineAndColumn coordinates
BufferCoord -> ByteCoord DisplayCoord -> CharCoord Moved their definition along with LineAndColumn into coord.hh
This commit is contained in:
parent
54ceb3a0d0
commit
8546788b43
|
@ -123,15 +123,15 @@ bool Buffer::set_name(String name)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
BufferIterator Buffer::iterator_at(BufferCoord coord) const
|
BufferIterator Buffer::iterator_at(ByteCoord coord) const
|
||||||
{
|
{
|
||||||
return is_end(coord) ? end() : BufferIterator(*this, clamp(coord));
|
return is_end(coord) ? end() : BufferIterator(*this, clamp(coord));
|
||||||
}
|
}
|
||||||
|
|
||||||
BufferCoord Buffer::clamp(BufferCoord coord) const
|
ByteCoord Buffer::clamp(ByteCoord coord) const
|
||||||
{
|
{
|
||||||
if (m_lines.empty())
|
if (m_lines.empty())
|
||||||
return BufferCoord{};
|
return ByteCoord{};
|
||||||
|
|
||||||
coord.line = Kakoune::clamp(coord.line, 0_line, line_count() - 1);
|
coord.line = Kakoune::clamp(coord.line, 0_line, line_count() - 1);
|
||||||
ByteCount max_col = std::max(0_byte, m_lines[coord.line].length() - 1);
|
ByteCount max_col = std::max(0_byte, m_lines[coord.line].length() - 1);
|
||||||
|
@ -139,7 +139,7 @@ BufferCoord Buffer::clamp(BufferCoord coord) const
|
||||||
return coord;
|
return coord;
|
||||||
}
|
}
|
||||||
|
|
||||||
BufferCoord Buffer::offset_coord(BufferCoord coord, CharCount offset)
|
ByteCoord Buffer::offset_coord(ByteCoord coord, CharCount offset)
|
||||||
{
|
{
|
||||||
auto& line = m_lines[coord.line].content;
|
auto& line = m_lines[coord.line].content;
|
||||||
auto character = std::max(0_char, std::min(line.char_count_to(coord.column) + offset,
|
auto character = std::max(0_char, std::min(line.char_count_to(coord.column) + offset,
|
||||||
|
@ -147,7 +147,7 @@ BufferCoord Buffer::offset_coord(BufferCoord coord, CharCount offset)
|
||||||
return {coord.line, line.byte_count_to(character)};
|
return {coord.line, line.byte_count_to(character)};
|
||||||
}
|
}
|
||||||
|
|
||||||
BufferCoord Buffer::offset_coord(BufferCoord coord, LineCount offset)
|
ByteCoord Buffer::offset_coord(ByteCoord coord, LineCount offset)
|
||||||
{
|
{
|
||||||
auto character = m_lines[coord.line].content.char_count_to(coord.column);
|
auto character = m_lines[coord.line].content.char_count_to(coord.column);
|
||||||
auto line = Kakoune::clamp(coord.line + offset, 0_line, line_count()-1);
|
auto line = Kakoune::clamp(coord.line + offset, 0_line, line_count()-1);
|
||||||
|
@ -157,7 +157,7 @@ BufferCoord Buffer::offset_coord(BufferCoord coord, LineCount offset)
|
||||||
return {line, content.byte_count_to(character)};
|
return {line, content.byte_count_to(character)};
|
||||||
}
|
}
|
||||||
|
|
||||||
String Buffer::string(BufferCoord begin, BufferCoord end) const
|
String Buffer::string(ByteCoord begin, ByteCoord end) const
|
||||||
{
|
{
|
||||||
String res;
|
String res;
|
||||||
for (auto line = begin.line; line <= end.line and line < line_count(); ++line)
|
for (auto line = begin.line; line <= end.line and line < line_count(); ++line)
|
||||||
|
@ -179,10 +179,10 @@ struct Buffer::Modification
|
||||||
enum Type { Insert, Erase };
|
enum Type { Insert, Erase };
|
||||||
|
|
||||||
Type type;
|
Type type;
|
||||||
BufferCoord coord;
|
ByteCoord coord;
|
||||||
String content;
|
String content;
|
||||||
|
|
||||||
Modification(Type type, BufferCoord coord, String content)
|
Modification(Type type, ByteCoord coord, String content)
|
||||||
: type(type), coord(coord), content(std::move(content)) {}
|
: type(type), coord(coord), content(std::move(content)) {}
|
||||||
|
|
||||||
Modification inverse() const
|
Modification inverse() const
|
||||||
|
@ -203,7 +203,7 @@ class UndoGroupOptimizer
|
||||||
static constexpr auto Insert = Buffer::Modification::Type::Insert;
|
static constexpr auto Insert = Buffer::Modification::Type::Insert;
|
||||||
static constexpr auto Erase = Buffer::Modification::Type::Erase;
|
static constexpr auto Erase = Buffer::Modification::Type::Erase;
|
||||||
|
|
||||||
static BufferCoord advance(BufferCoord coord, const String& str)
|
static ByteCoord advance(ByteCoord coord, const String& str)
|
||||||
{
|
{
|
||||||
for (auto c : str)
|
for (auto c : str)
|
||||||
{
|
{
|
||||||
|
@ -218,7 +218,7 @@ class UndoGroupOptimizer
|
||||||
return coord;
|
return coord;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ByteCount count_byte_to(BufferCoord pos, BufferCoord endpos, const String& str)
|
static ByteCount count_byte_to(ByteCoord pos, ByteCoord endpos, const String& str)
|
||||||
{
|
{
|
||||||
ByteCount count = 0;
|
ByteCount count = 0;
|
||||||
for (auto it = str.begin(); it != str.end() and pos != endpos; ++it)
|
for (auto it = str.begin(); it != str.end() and pos != endpos; ++it)
|
||||||
|
@ -270,7 +270,7 @@ class UndoGroupOptimizer
|
||||||
// so we have a O(n²) worst case complexity of the undo group optimization
|
// so we have a O(n²) worst case complexity of the undo group optimization
|
||||||
if (next_coord < coord)
|
if (next_coord < coord)
|
||||||
{
|
{
|
||||||
BufferCoord next_end = advance(next_coord, it_next->content);
|
ByteCoord next_end = advance(next_coord, it_next->content);
|
||||||
if (it_next->type == Insert)
|
if (it_next->type == Insert)
|
||||||
{
|
{
|
||||||
if (coord.line == next_coord.line)
|
if (coord.line == next_coord.line)
|
||||||
|
@ -448,7 +448,7 @@ void Buffer::check_invariant() const
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
BufferCoord Buffer::do_insert(BufferCoord pos, const String& content)
|
ByteCoord Buffer::do_insert(ByteCoord pos, const String& content)
|
||||||
{
|
{
|
||||||
kak_assert(is_valid(pos));
|
kak_assert(is_valid(pos));
|
||||||
|
|
||||||
|
@ -462,8 +462,8 @@ BufferCoord Buffer::do_insert(BufferCoord pos, const String& content)
|
||||||
for (LineCount i = pos.line+1; i < line_count(); ++i)
|
for (LineCount i = pos.line+1; i < line_count(); ++i)
|
||||||
m_lines[i].start += content.length();
|
m_lines[i].start += content.length();
|
||||||
|
|
||||||
BufferCoord begin;
|
ByteCoord begin;
|
||||||
BufferCoord end;
|
ByteCoord end;
|
||||||
// if we inserted at the end of the buffer, we have created a new
|
// if we inserted at the end of the buffer, we have created a new
|
||||||
// line without inserting a '\n'
|
// line without inserting a '\n'
|
||||||
if (is_end(pos))
|
if (is_end(pos))
|
||||||
|
@ -480,8 +480,8 @@ BufferCoord Buffer::do_insert(BufferCoord pos, const String& content)
|
||||||
if (start != content.length())
|
if (start != content.length())
|
||||||
m_lines.push_back({ m_timestamp, offset + start, content.substr(start) });
|
m_lines.push_back({ m_timestamp, offset + start, content.substr(start) });
|
||||||
|
|
||||||
begin = pos.column == 0 ? pos : BufferCoord{ pos.line + 1, 0 };
|
begin = pos.column == 0 ? pos : ByteCoord{ pos.line + 1, 0 };
|
||||||
end = BufferCoord{ line_count()-1, m_lines.back().length() };
|
end = ByteCoord{ line_count()-1, m_lines.back().length() };
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -521,7 +521,7 @@ BufferCoord Buffer::do_insert(BufferCoord pos, const String& content)
|
||||||
std::make_move_iterator(new_lines.end()));
|
std::make_move_iterator(new_lines.end()));
|
||||||
|
|
||||||
begin = pos;
|
begin = pos;
|
||||||
end = BufferCoord{ last_line, m_lines[last_line].length() - suffix.length() };
|
end = ByteCoord{ last_line, m_lines[last_line].length() - suffix.length() };
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto listener : m_change_listeners)
|
for (auto listener : m_change_listeners)
|
||||||
|
@ -529,7 +529,7 @@ BufferCoord Buffer::do_insert(BufferCoord pos, const String& content)
|
||||||
return begin;
|
return begin;
|
||||||
}
|
}
|
||||||
|
|
||||||
BufferCoord Buffer::do_erase(BufferCoord begin, BufferCoord end)
|
ByteCoord Buffer::do_erase(ByteCoord begin, ByteCoord end)
|
||||||
{
|
{
|
||||||
kak_assert(is_valid(begin));
|
kak_assert(is_valid(begin));
|
||||||
kak_assert(is_valid(end));
|
kak_assert(is_valid(end));
|
||||||
|
@ -539,7 +539,7 @@ BufferCoord Buffer::do_erase(BufferCoord begin, BufferCoord end)
|
||||||
String suffix = m_lines[end.line].content.substr(end.column);
|
String suffix = m_lines[end.line].content.substr(end.column);
|
||||||
Line new_line = { m_timestamp, m_lines[begin.line].start, prefix + suffix };
|
Line new_line = { m_timestamp, m_lines[begin.line].start, prefix + suffix };
|
||||||
|
|
||||||
BufferCoord next;
|
ByteCoord next;
|
||||||
if (new_line.length() != 0)
|
if (new_line.length() != 0)
|
||||||
{
|
{
|
||||||
m_lines.erase(m_lines.begin() + (int)begin.line, m_lines.begin() + (int)end.line);
|
m_lines.erase(m_lines.begin() + (int)begin.line, m_lines.begin() + (int)end.line);
|
||||||
|
@ -549,7 +549,7 @@ BufferCoord Buffer::do_erase(BufferCoord begin, BufferCoord end)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_lines.erase(m_lines.begin() + (int)begin.line, m_lines.begin() + (int)end.line + 1);
|
m_lines.erase(m_lines.begin() + (int)begin.line, m_lines.begin() + (int)end.line + 1);
|
||||||
next = is_end(begin) ? end_coord() : BufferCoord{begin.line, 0};
|
next = is_end(begin) ? end_coord() : ByteCoord{begin.line, 0};
|
||||||
}
|
}
|
||||||
|
|
||||||
for (LineCount i = begin.line+1; i < line_count(); ++i)
|
for (LineCount i = begin.line+1; i < line_count(); ++i)
|
||||||
|
@ -563,11 +563,11 @@ BufferCoord Buffer::do_erase(BufferCoord begin, BufferCoord end)
|
||||||
void Buffer::apply_modification(const Modification& modification)
|
void Buffer::apply_modification(const Modification& modification)
|
||||||
{
|
{
|
||||||
const String& content = modification.content;
|
const String& content = modification.content;
|
||||||
BufferCoord coord = modification.coord;
|
ByteCoord coord = modification.coord;
|
||||||
|
|
||||||
kak_assert(is_valid(coord));
|
kak_assert(is_valid(coord));
|
||||||
// in modifications, end coords should be {line_count(), 0}
|
// in modifications, end coords should be {line_count(), 0}
|
||||||
kak_assert(coord != BufferCoord(line_count()-1, m_lines.back().length()));
|
kak_assert(coord != ByteCoord(line_count()-1, m_lines.back().length()));
|
||||||
switch (modification.type)
|
switch (modification.type)
|
||||||
{
|
{
|
||||||
case Modification::Insert:
|
case Modification::Insert:
|
||||||
|
@ -578,7 +578,7 @@ void Buffer::apply_modification(const Modification& modification)
|
||||||
case Modification::Erase:
|
case Modification::Erase:
|
||||||
{
|
{
|
||||||
ByteCount count = content.length();
|
ByteCount count = content.length();
|
||||||
BufferCoord end = advance(coord, count);
|
ByteCoord end = advance(coord, count);
|
||||||
kak_assert(string(coord, end) == content);
|
kak_assert(string(coord, end) == content);
|
||||||
do_erase(coord, end);
|
do_erase(coord, end);
|
||||||
break;
|
break;
|
||||||
|
@ -599,7 +599,7 @@ BufferIterator Buffer::insert(const BufferIterator& pos, String content)
|
||||||
|
|
||||||
// for undo and redo purpose it is better to use one past last line rather
|
// for undo and redo purpose it is better to use one past last line rather
|
||||||
// than one past last char coord.
|
// than one past last char coord.
|
||||||
auto coord = pos == end() ? BufferCoord{line_count()} : pos.coord();
|
auto coord = pos == end() ? ByteCoord{line_count()} : pos.coord();
|
||||||
if (not (m_flags & Flags::NoUndo))
|
if (not (m_flags & Flags::NoUndo))
|
||||||
m_current_undo_group.emplace_back(Modification::Insert, coord, content);
|
m_current_undo_group.emplace_back(Modification::Insert, coord, content);
|
||||||
return {*this, do_insert(pos.coord(), content)};
|
return {*this, do_insert(pos.coord(), content)};
|
||||||
|
@ -642,7 +642,7 @@ void Buffer::notify_saved()
|
||||||
m_fs_timestamp = get_fs_timestamp(m_name);
|
m_fs_timestamp = get_fs_timestamp(m_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
BufferCoord Buffer::advance(BufferCoord coord, ByteCount count) const
|
ByteCoord Buffer::advance(ByteCoord coord, ByteCount count) const
|
||||||
{
|
{
|
||||||
ByteCount off = Kakoune::clamp(offset(coord) + count, 0_byte, byte_count());
|
ByteCount off = Kakoune::clamp(offset(coord) + count, 0_byte, byte_count());
|
||||||
auto it = std::upper_bound(m_lines.begin(), m_lines.end(), off,
|
auto it = std::upper_bound(m_lines.begin(), m_lines.end(), off,
|
||||||
|
@ -650,7 +650,7 @@ BufferCoord Buffer::advance(BufferCoord coord, ByteCount count) const
|
||||||
return { LineCount{ (int)(it - m_lines.begin()) }, off - it->start };
|
return { LineCount{ (int)(it - m_lines.begin()) }, off - it->start };
|
||||||
}
|
}
|
||||||
|
|
||||||
BufferCoord Buffer::char_next(BufferCoord coord) const
|
ByteCoord Buffer::char_next(ByteCoord coord) const
|
||||||
{
|
{
|
||||||
if (coord.column < m_lines[coord.line].length() - 1)
|
if (coord.column < m_lines[coord.line].length() - 1)
|
||||||
{
|
{
|
||||||
|
@ -673,7 +673,7 @@ BufferCoord Buffer::char_next(BufferCoord coord) const
|
||||||
return coord;
|
return coord;
|
||||||
}
|
}
|
||||||
|
|
||||||
BufferCoord Buffer::char_prev(BufferCoord coord) const
|
ByteCoord Buffer::char_prev(ByteCoord coord) const
|
||||||
{
|
{
|
||||||
kak_assert(is_valid(coord));
|
kak_assert(is_valid(coord));
|
||||||
if (is_end(coord))
|
if (is_end(coord))
|
||||||
|
@ -715,7 +715,7 @@ void Buffer::run_hook_in_own_context(const String& hook_name, const String& para
|
||||||
m_hooks.run_hook(hook_name, param, hook_handler.context());
|
m_hooks.run_hook(hook_name, param, hook_handler.context());
|
||||||
}
|
}
|
||||||
|
|
||||||
BufferCoord Buffer::last_modification_coord() const
|
ByteCoord Buffer::last_modification_coord() const
|
||||||
{
|
{
|
||||||
if (m_history.empty())
|
if (m_history.empty())
|
||||||
return {};
|
return {};
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef buffer_hh_INCLUDED
|
#ifndef buffer_hh_INCLUDED
|
||||||
#define buffer_hh_INCLUDED
|
#define buffer_hh_INCLUDED
|
||||||
|
|
||||||
#include "line_and_column.hh"
|
#include "coord.hh"
|
||||||
#include "hook_manager.hh"
|
#include "hook_manager.hh"
|
||||||
#include "option_manager.hh"
|
#include "option_manager.hh"
|
||||||
#include "keymap_manager.hh"
|
#include "keymap_manager.hh"
|
||||||
|
@ -20,12 +20,6 @@ class Buffer;
|
||||||
|
|
||||||
constexpr time_t InvalidTime = 0;
|
constexpr time_t InvalidTime = 0;
|
||||||
|
|
||||||
struct BufferCoord : LineAndColumn<BufferCoord, LineCount, ByteCount>
|
|
||||||
{
|
|
||||||
constexpr BufferCoord(LineCount line = 0, ByteCount column = 0)
|
|
||||||
: LineAndColumn(line, column) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
// A BufferIterator permits to iterate over the characters of a buffer
|
// A BufferIterator permits to iterate over the characters of a buffer
|
||||||
class BufferIterator
|
class BufferIterator
|
||||||
{
|
{
|
||||||
|
@ -37,7 +31,7 @@ public:
|
||||||
using iterator_category = std::random_access_iterator_tag;
|
using iterator_category = std::random_access_iterator_tag;
|
||||||
|
|
||||||
BufferIterator() : m_buffer(nullptr) {}
|
BufferIterator() : m_buffer(nullptr) {}
|
||||||
BufferIterator(const Buffer& buffer, BufferCoord coord);
|
BufferIterator(const Buffer& buffer, ByteCoord coord);
|
||||||
|
|
||||||
bool operator== (const BufferIterator& iterator) const;
|
bool operator== (const BufferIterator& iterator) const;
|
||||||
bool operator!= (const BufferIterator& iterator) const;
|
bool operator!= (const BufferIterator& iterator) const;
|
||||||
|
@ -62,20 +56,20 @@ public:
|
||||||
BufferIterator operator++ (int);
|
BufferIterator operator++ (int);
|
||||||
BufferIterator operator-- (int);
|
BufferIterator operator-- (int);
|
||||||
|
|
||||||
const BufferCoord& coord() const { return m_coord; }
|
const ByteCoord& coord() const { return m_coord; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
safe_ptr<const Buffer> m_buffer;
|
safe_ptr<const Buffer> m_buffer;
|
||||||
BufferCoord m_coord;
|
ByteCoord m_coord;
|
||||||
};
|
};
|
||||||
|
|
||||||
class BufferChangeListener
|
class BufferChangeListener
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual void on_insert(const Buffer& buffer,
|
virtual void on_insert(const Buffer& buffer,
|
||||||
BufferCoord begin, BufferCoord end) = 0;
|
ByteCoord begin, ByteCoord end) = 0;
|
||||||
virtual void on_erase(const Buffer& buffer,
|
virtual void on_erase(const Buffer& buffer,
|
||||||
BufferCoord begin, BufferCoord end) = 0;
|
ByteCoord begin, ByteCoord end) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
// A Buffer is a in-memory representation of a file
|
// A Buffer is a in-memory representation of a file
|
||||||
|
@ -118,25 +112,25 @@ public:
|
||||||
bool undo();
|
bool undo();
|
||||||
bool redo();
|
bool redo();
|
||||||
|
|
||||||
String string(BufferCoord begin, BufferCoord end) const;
|
String string(ByteCoord begin, ByteCoord end) const;
|
||||||
|
|
||||||
char byte_at(BufferCoord c) const;
|
char byte_at(ByteCoord c) const;
|
||||||
ByteCount offset(BufferCoord c) const;
|
ByteCount offset(ByteCoord c) const;
|
||||||
ByteCount distance(BufferCoord begin, BufferCoord end) const;
|
ByteCount distance(ByteCoord begin, ByteCoord end) const;
|
||||||
BufferCoord advance(BufferCoord coord, ByteCount count) const;
|
ByteCoord advance(ByteCoord coord, ByteCount count) const;
|
||||||
BufferCoord next(BufferCoord coord) const;
|
ByteCoord next(ByteCoord coord) const;
|
||||||
BufferCoord prev(BufferCoord coord) const;
|
ByteCoord prev(ByteCoord coord) const;
|
||||||
|
|
||||||
BufferCoord char_next(BufferCoord coord) const;
|
ByteCoord char_next(ByteCoord coord) const;
|
||||||
BufferCoord char_prev(BufferCoord coord) const;
|
ByteCoord char_prev(ByteCoord coord) const;
|
||||||
|
|
||||||
BufferCoord back_coord() const;
|
ByteCoord back_coord() const;
|
||||||
BufferCoord end_coord() const;
|
ByteCoord end_coord() const;
|
||||||
|
|
||||||
bool is_valid(BufferCoord c) const;
|
bool is_valid(ByteCoord c) const;
|
||||||
bool is_end(BufferCoord c) const;
|
bool is_end(ByteCoord c) const;
|
||||||
|
|
||||||
BufferCoord last_modification_coord() const;
|
ByteCoord last_modification_coord() const;
|
||||||
|
|
||||||
BufferIterator begin() const;
|
BufferIterator begin() const;
|
||||||
BufferIterator end() const;
|
BufferIterator end() const;
|
||||||
|
@ -147,13 +141,13 @@ public:
|
||||||
{ return m_lines[line].content; }
|
{ return m_lines[line].content; }
|
||||||
|
|
||||||
// returns an iterator at given coordinates. clamp line_and_column
|
// returns an iterator at given coordinates. clamp line_and_column
|
||||||
BufferIterator iterator_at(BufferCoord coord) const;
|
BufferIterator iterator_at(ByteCoord coord) const;
|
||||||
|
|
||||||
// returns nearest valid coordinates from given ones
|
// returns nearest valid coordinates from given ones
|
||||||
BufferCoord clamp(BufferCoord coord) const;
|
ByteCoord clamp(ByteCoord coord) const;
|
||||||
|
|
||||||
BufferCoord offset_coord(BufferCoord coord, CharCount offset);
|
ByteCoord offset_coord(ByteCoord coord, CharCount offset);
|
||||||
BufferCoord offset_coord(BufferCoord coord, LineCount offset);
|
ByteCoord offset_coord(ByteCoord coord, LineCount offset);
|
||||||
|
|
||||||
const String& name() const { return m_name; }
|
const String& name() const { return m_name; }
|
||||||
String display_name() const;
|
String display_name() const;
|
||||||
|
@ -203,8 +197,8 @@ private:
|
||||||
};
|
};
|
||||||
LineList m_lines;
|
LineList m_lines;
|
||||||
|
|
||||||
BufferCoord do_insert(BufferCoord pos, const String& content);
|
ByteCoord do_insert(ByteCoord pos, const String& content);
|
||||||
BufferCoord do_erase(BufferCoord begin, BufferCoord end);
|
ByteCoord do_erase(ByteCoord begin, ByteCoord end);
|
||||||
|
|
||||||
String m_name;
|
String m_name;
|
||||||
Flags m_flags;
|
Flags m_flags;
|
||||||
|
|
|
@ -6,13 +6,13 @@
|
||||||
namespace Kakoune
|
namespace Kakoune
|
||||||
{
|
{
|
||||||
|
|
||||||
inline char Buffer::byte_at(BufferCoord c) const
|
inline char Buffer::byte_at(ByteCoord c) const
|
||||||
{
|
{
|
||||||
kak_assert(c.line < line_count() and c.column < m_lines[c.line].length());
|
kak_assert(c.line < line_count() and c.column < m_lines[c.line].length());
|
||||||
return m_lines[c.line].content[c.column];
|
return m_lines[c.line].content[c.column];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline BufferCoord Buffer::next(BufferCoord coord) const
|
inline ByteCoord Buffer::next(ByteCoord coord) const
|
||||||
{
|
{
|
||||||
if (coord.column < m_lines[coord.line].length() - 1)
|
if (coord.column < m_lines[coord.line].length() - 1)
|
||||||
++coord.column;
|
++coord.column;
|
||||||
|
@ -26,7 +26,7 @@ inline BufferCoord Buffer::next(BufferCoord coord) const
|
||||||
return coord;
|
return coord;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline BufferCoord Buffer::prev(BufferCoord coord) const
|
inline ByteCoord Buffer::prev(ByteCoord coord) const
|
||||||
{
|
{
|
||||||
if (coord.column == 0)
|
if (coord.column == 0)
|
||||||
{
|
{
|
||||||
|
@ -38,28 +38,28 @@ inline BufferCoord Buffer::prev(BufferCoord coord) const
|
||||||
return coord;
|
return coord;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline ByteCount Buffer::distance(BufferCoord begin, BufferCoord end) const
|
inline ByteCount Buffer::distance(ByteCoord begin, ByteCoord end) const
|
||||||
{
|
{
|
||||||
return offset(end) - offset(begin);
|
return offset(end) - offset(begin);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline ByteCount Buffer::offset(BufferCoord c) const
|
inline ByteCount Buffer::offset(ByteCoord c) const
|
||||||
{
|
{
|
||||||
if (c.line == line_count())
|
if (c.line == line_count())
|
||||||
return m_lines.back().start + m_lines.back().length();
|
return m_lines.back().start + m_lines.back().length();
|
||||||
return m_lines[c.line].start + c.column;
|
return m_lines[c.line].start + c.column;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool Buffer::is_valid(BufferCoord c) const
|
inline bool Buffer::is_valid(ByteCoord c) const
|
||||||
{
|
{
|
||||||
return (c.line < line_count() and c.column < m_lines[c.line].length()) or
|
return (c.line < line_count() and c.column < m_lines[c.line].length()) or
|
||||||
(c.line == line_count() - 1 and c.column == m_lines.back().length()) or
|
(c.line == line_count() - 1 and c.column == m_lines.back().length()) or
|
||||||
(c.line == line_count() and c.column == 0);
|
(c.line == line_count() and c.column == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool Buffer::is_end(BufferCoord c) const
|
inline bool Buffer::is_end(ByteCoord c) const
|
||||||
{
|
{
|
||||||
return c >= BufferCoord{line_count() - 1, m_lines.back().length()};
|
return c >= ByteCoord{line_count() - 1, m_lines.back().length()};
|
||||||
}
|
}
|
||||||
|
|
||||||
inline BufferIterator Buffer::begin() const
|
inline BufferIterator Buffer::begin() const
|
||||||
|
@ -96,17 +96,17 @@ inline size_t Buffer::line_timestamp(LineCount line) const
|
||||||
return m_lines[line].timestamp;
|
return m_lines[line].timestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline BufferCoord Buffer::back_coord() const
|
inline ByteCoord Buffer::back_coord() const
|
||||||
{
|
{
|
||||||
return { line_count() - 1, m_lines.back().length() - 1 };
|
return { line_count() - 1, m_lines.back().length() - 1 };
|
||||||
}
|
}
|
||||||
|
|
||||||
inline BufferCoord Buffer::end_coord() const
|
inline ByteCoord Buffer::end_coord() const
|
||||||
{
|
{
|
||||||
return { line_count() - 1, m_lines.back().length() };
|
return { line_count() - 1, m_lines.back().length() };
|
||||||
}
|
}
|
||||||
|
|
||||||
inline BufferIterator::BufferIterator(const Buffer& buffer, BufferCoord coord)
|
inline BufferIterator::BufferIterator(const Buffer& buffer, ByteCoord coord)
|
||||||
: m_buffer(&buffer), m_coord(coord)
|
: m_buffer(&buffer), m_coord(coord)
|
||||||
{
|
{
|
||||||
kak_assert(m_buffer and m_buffer->is_valid(m_coord));
|
kak_assert(m_buffer and m_buffer->is_valid(m_coord));
|
||||||
|
|
|
@ -6,7 +6,7 @@ namespace Kakoune
|
||||||
{
|
{
|
||||||
|
|
||||||
CharCount get_column(const Buffer& buffer,
|
CharCount get_column(const Buffer& buffer,
|
||||||
CharCount tabstop, BufferCoord coord)
|
CharCount tabstop, ByteCoord coord)
|
||||||
{
|
{
|
||||||
auto& line = buffer[coord.line];
|
auto& line = buffer[coord.line];
|
||||||
auto col = 0_char;
|
auto col = 0_char;
|
||||||
|
|
|
@ -24,7 +24,7 @@ inline CharCount char_length(const Buffer& buffer, const Selection& range)
|
||||||
utf8::next(buffer.iterator_at(range.max())));
|
utf8::next(buffer.iterator_at(range.max())));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void avoid_eol(const Buffer& buffer, BufferCoord& coord)
|
inline void avoid_eol(const Buffer& buffer, ByteCoord& coord)
|
||||||
{
|
{
|
||||||
const auto column = coord.column;
|
const auto column = coord.column;
|
||||||
const auto& line = buffer[coord.line];
|
const auto& line = buffer[coord.line];
|
||||||
|
@ -39,7 +39,7 @@ inline void avoid_eol(const Buffer& buffer, Selection& sel)
|
||||||
}
|
}
|
||||||
|
|
||||||
CharCount get_column(const Buffer& buffer,
|
CharCount get_column(const Buffer& buffer,
|
||||||
CharCount tabstop, BufferCoord coord);
|
CharCount tabstop, ByteCoord coord);
|
||||||
|
|
||||||
Buffer* create_fifo_buffer(String name, int fd, bool scroll = false);
|
Buffer* create_fifo_buffer(String name, int fd, bool scroll = false);
|
||||||
|
|
||||||
|
|
|
@ -82,8 +82,8 @@ void Client::redraw_ifn()
|
||||||
{
|
{
|
||||||
if (context().window().timestamp() != context().buffer().timestamp())
|
if (context().window().timestamp() != context().buffer().timestamp())
|
||||||
{
|
{
|
||||||
DisplayCoord dimensions = context().ui().dimensions();
|
CharCoord dimensions = context().ui().dimensions();
|
||||||
if (dimensions == DisplayCoord{0,0})
|
if (dimensions == CharCoord{0,0})
|
||||||
return;
|
return;
|
||||||
context().window().set_dimensions(dimensions);
|
context().window().set_dimensions(dimensions);
|
||||||
context().window().update_display_buffer(context());
|
context().window().update_display_buffer(context());
|
||||||
|
@ -96,8 +96,8 @@ void Client::redraw_ifn()
|
||||||
|
|
||||||
static void reload_buffer(Context& context, const String& filename)
|
static void reload_buffer(Context& context, const String& filename)
|
||||||
{
|
{
|
||||||
DisplayCoord view_pos = context.window().position();
|
CharCoord view_pos = context.window().position();
|
||||||
BufferCoord cursor_pos = context.selections().main().cursor();
|
ByteCoord cursor_pos = context.selections().main().cursor();
|
||||||
Buffer* buf = create_buffer_from_file(filename);
|
Buffer* buf = create_buffer_from_file(filename);
|
||||||
if (not buf)
|
if (not buf)
|
||||||
return;
|
return;
|
||||||
|
@ -121,7 +121,7 @@ void Client::check_buffer_fs_timestamp()
|
||||||
return;
|
return;
|
||||||
if (reload == Ask)
|
if (reload == Ask)
|
||||||
{
|
{
|
||||||
DisplayCoord pos = context().window().dimensions();
|
CharCoord pos = context().window().dimensions();
|
||||||
pos.column -= 1;
|
pos.column -= 1;
|
||||||
m_ui->info_show(
|
m_ui->info_show(
|
||||||
"reload '" + buffer.display_name() + "' ?",
|
"reload '" + buffer.display_name() + "' ?",
|
||||||
|
|
|
@ -1150,7 +1150,7 @@ const CommandDesc info_cmd = {
|
||||||
if (parser.positional_count() > 0)
|
if (parser.positional_count() > 0)
|
||||||
{
|
{
|
||||||
MenuStyle style = MenuStyle::Prompt;
|
MenuStyle style = MenuStyle::Prompt;
|
||||||
DisplayCoord pos = context.ui().dimensions();
|
CharCoord pos = context.ui().dimensions();
|
||||||
pos.column -= 1;
|
pos.column -= 1;
|
||||||
if (parser.has_option("anchor"))
|
if (parser.has_option("anchor"))
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#ifndef line_and_column_hh_INCLUDED
|
#ifndef coord_hh_INCLUDED
|
||||||
#define line_and_column_hh_INCLUDED
|
#define coord_hh_INCLUDED
|
||||||
|
|
||||||
|
#include "units.hh"
|
||||||
|
|
||||||
namespace Kakoune
|
namespace Kakoune
|
||||||
{
|
{
|
||||||
|
@ -72,6 +74,18 @@ struct LineAndColumn
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ByteCoord : LineAndColumn<ByteCoord, LineCount, ByteCount>
|
||||||
|
{
|
||||||
|
constexpr ByteCoord(LineCount line = 0, ByteCount column = 0)
|
||||||
|
: LineAndColumn(line, column) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CharCoord : LineAndColumn<CharCoord, LineCount, CharCount>
|
||||||
|
{
|
||||||
|
constexpr CharCoord(LineCount line = 0, CharCount column = 0)
|
||||||
|
: LineAndColumn(line, column) {}
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // line_and_column_hh_INCLUDED
|
#endif // coord_hh_INCLUDED
|
|
@ -42,7 +42,7 @@ DisplayLine::DisplayLine(AtomList atoms)
|
||||||
compute_range();
|
compute_range();
|
||||||
}
|
}
|
||||||
|
|
||||||
DisplayLine::iterator DisplayLine::split(iterator it, BufferCoord pos)
|
DisplayLine::iterator DisplayLine::split(iterator it, ByteCoord pos)
|
||||||
{
|
{
|
||||||
kak_assert(it->type() == DisplayAtom::BufferRange);
|
kak_assert(it->type() == DisplayAtom::BufferRange);
|
||||||
kak_assert(it->begin() < pos);
|
kak_assert(it->begin() < pos);
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
#include "buffer.hh"
|
#include "buffer.hh"
|
||||||
#include "color.hh"
|
#include "color.hh"
|
||||||
#include "line_and_column.hh"
|
#include "coord.hh"
|
||||||
#include "string.hh"
|
#include "string.hh"
|
||||||
#include "utf8.hh"
|
#include "utf8.hh"
|
||||||
|
|
||||||
|
@ -12,12 +12,6 @@
|
||||||
namespace Kakoune
|
namespace Kakoune
|
||||||
{
|
{
|
||||||
|
|
||||||
struct DisplayCoord : LineAndColumn<DisplayCoord, LineCount, CharCount>
|
|
||||||
{
|
|
||||||
constexpr DisplayCoord(LineCount line = 0, CharCount column = 0)
|
|
||||||
: LineAndColumn(line, column) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
using Attribute = char;
|
using Attribute = char;
|
||||||
|
|
||||||
enum Attributes
|
enum Attributes
|
||||||
|
@ -34,7 +28,7 @@ struct DisplayAtom
|
||||||
public:
|
public:
|
||||||
enum Type { BufferRange, ReplacedBufferRange, Text };
|
enum Type { BufferRange, ReplacedBufferRange, Text };
|
||||||
|
|
||||||
DisplayAtom(const Buffer& buffer, BufferCoord begin, BufferCoord end)
|
DisplayAtom(const Buffer& buffer, ByteCoord begin, ByteCoord end)
|
||||||
: m_type(BufferRange), m_buffer(&buffer), m_begin(begin), m_end(end)
|
: m_type(BufferRange), m_buffer(&buffer), m_begin(begin), m_end(end)
|
||||||
{ check_invariant(); }
|
{ check_invariant(); }
|
||||||
|
|
||||||
|
@ -72,13 +66,13 @@ public:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const BufferCoord& begin() const
|
const ByteCoord& begin() const
|
||||||
{
|
{
|
||||||
kak_assert(has_buffer_range());
|
kak_assert(has_buffer_range());
|
||||||
return m_begin;
|
return m_begin;
|
||||||
}
|
}
|
||||||
|
|
||||||
const BufferCoord& end() const
|
const ByteCoord& end() const
|
||||||
{
|
{
|
||||||
kak_assert(has_buffer_range());
|
kak_assert(has_buffer_range());
|
||||||
return m_end;
|
return m_end;
|
||||||
|
@ -114,12 +108,12 @@ private:
|
||||||
Type m_type;
|
Type m_type;
|
||||||
|
|
||||||
const Buffer* m_buffer = nullptr;
|
const Buffer* m_buffer = nullptr;
|
||||||
BufferCoord m_begin;
|
ByteCoord m_begin;
|
||||||
BufferCoord m_end;
|
ByteCoord m_end;
|
||||||
String m_text;
|
String m_text;
|
||||||
};
|
};
|
||||||
|
|
||||||
using BufferRange = std::pair<BufferCoord, BufferCoord>;
|
using BufferRange = std::pair<ByteCoord, ByteCoord>;
|
||||||
using AtomList = std::vector<DisplayAtom>;
|
using AtomList = std::vector<DisplayAtom>;
|
||||||
|
|
||||||
class DisplayLine
|
class DisplayLine
|
||||||
|
@ -146,7 +140,7 @@ public:
|
||||||
const BufferRange& range() const { return m_range; }
|
const BufferRange& range() const { return m_range; }
|
||||||
|
|
||||||
// Split atom pointed by it at pos, returns an iterator to the first atom
|
// Split atom pointed by it at pos, returns an iterator to the first atom
|
||||||
iterator split(iterator it, BufferCoord pos);
|
iterator split(iterator it, ByteCoord pos);
|
||||||
|
|
||||||
iterator insert(iterator it, DisplayAtom atom);
|
iterator insert(iterator it, DisplayAtom atom);
|
||||||
iterator erase(iterator beg, iterator end);
|
iterator erase(iterator beg, iterator end);
|
||||||
|
|
|
@ -36,12 +36,12 @@ void DynamicSelectionList::check_invariant() const
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void DynamicSelectionList::on_insert(const Buffer& buffer, BufferCoord begin, BufferCoord end)
|
void DynamicSelectionList::on_insert(const Buffer& buffer, ByteCoord begin, ByteCoord end)
|
||||||
{
|
{
|
||||||
update_insert(buffer, begin, end);
|
update_insert(buffer, begin, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DynamicSelectionList::on_erase(const Buffer& buffer, BufferCoord begin, BufferCoord end)
|
void DynamicSelectionList::on_erase(const Buffer& buffer, ByteCoord begin, ByteCoord end)
|
||||||
{
|
{
|
||||||
update_erase(buffer, begin, end);
|
update_erase(buffer, begin, end);
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,8 +19,8 @@ public:
|
||||||
void check_invariant() const;
|
void check_invariant() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void on_insert(const Buffer& buffer, BufferCoord begin, BufferCoord end) override;
|
void on_insert(const Buffer& buffer, ByteCoord begin, ByteCoord end) override;
|
||||||
void on_erase(const Buffer& buffer, BufferCoord begin, BufferCoord end) override;
|
void on_erase(const Buffer& buffer, ByteCoord begin, ByteCoord end) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ using RegexIterator = boost::regex_iterator<BufferIterator>;
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void highlight_range(DisplayBuffer& display_buffer,
|
void highlight_range(DisplayBuffer& display_buffer,
|
||||||
BufferCoord begin, BufferCoord end,
|
ByteCoord begin, ByteCoord end,
|
||||||
bool skip_replaced, T func)
|
bool skip_replaced, T func)
|
||||||
{
|
{
|
||||||
if (begin == end or end <= display_buffer.range().first
|
if (begin == end or end <= display_buffer.range().first
|
||||||
|
@ -66,7 +66,7 @@ template<typename T>
|
||||||
void apply_highlighter(const Context& context,
|
void apply_highlighter(const Context& context,
|
||||||
HighlightFlags flags,
|
HighlightFlags flags,
|
||||||
DisplayBuffer& display_buffer,
|
DisplayBuffer& display_buffer,
|
||||||
BufferCoord begin, BufferCoord end,
|
ByteCoord begin, ByteCoord end,
|
||||||
T&& highlighter)
|
T&& highlighter)
|
||||||
{
|
{
|
||||||
using LineIterator = DisplayBuffer::LineList::iterator;
|
using LineIterator = DisplayBuffer::LineList::iterator;
|
||||||
|
@ -197,7 +197,7 @@ private:
|
||||||
Cache(const Buffer&){}
|
Cache(const Buffer&){}
|
||||||
BufferRange m_range;
|
BufferRange m_range;
|
||||||
size_t m_timestamp = 0;
|
size_t m_timestamp = 0;
|
||||||
std::vector<std::vector<std::pair<BufferCoord, BufferCoord>>> m_matches;
|
std::vector<std::vector<std::pair<ByteCoord, ByteCoord>>> m_matches;
|
||||||
};
|
};
|
||||||
BufferSideCache<Cache> m_cache;
|
BufferSideCache<Cache> m_cache;
|
||||||
|
|
||||||
|
@ -455,8 +455,8 @@ void highlight_selections(const Context& context, HighlightFlags flags, DisplayB
|
||||||
{
|
{
|
||||||
auto& sel = context.selections()[i];
|
auto& sel = context.selections()[i];
|
||||||
const bool forward = sel.anchor() <= sel.cursor();
|
const bool forward = sel.anchor() <= sel.cursor();
|
||||||
BufferCoord begin = forward ? sel.anchor() : buffer.char_next(sel.cursor());
|
ByteCoord begin = forward ? sel.anchor() : buffer.char_next(sel.cursor());
|
||||||
BufferCoord end = forward ? sel.cursor() : buffer.char_next(sel.anchor());
|
ByteCoord end = forward ? sel.cursor() : buffer.char_next(sel.anchor());
|
||||||
|
|
||||||
const bool primary = (i == context.selections().main_index());
|
const bool primary = (i == context.selections().main_index());
|
||||||
ColorPair sel_colors = get_color(primary ? "PrimarySelection" : "SecondarySelection");
|
ColorPair sel_colors = get_color(primary ? "PrimarySelection" : "SecondarySelection");
|
||||||
|
@ -592,10 +592,10 @@ public:
|
||||||
const auto& buffer = context.buffer();
|
const auto& buffer = context.buffer();
|
||||||
auto& regions = update_cache_ifn(buffer);
|
auto& regions = update_cache_ifn(buffer);
|
||||||
auto begin = std::lower_bound(regions.begin(), regions.end(), range.first,
|
auto begin = std::lower_bound(regions.begin(), regions.end(), range.first,
|
||||||
[](const Region& r, const BufferCoord& c) { return r.end < c; });
|
[](const Region& r, const ByteCoord& c) { return r.end < c; });
|
||||||
auto end = std::lower_bound(begin, regions.end(), range.second,
|
auto end = std::lower_bound(begin, regions.end(), range.second,
|
||||||
[](const Region& r, const BufferCoord& c) { return r.begin < c; });
|
[](const Region& r, const ByteCoord& c) { return r.begin < c; });
|
||||||
auto correct = [&](const BufferCoord& c) -> BufferCoord {
|
auto correct = [&](const ByteCoord& c) -> ByteCoord {
|
||||||
if (buffer[c.line].length() == c.column)
|
if (buffer[c.line].length() == c.column)
|
||||||
return {c.line+1, 0};
|
return {c.line+1, 0};
|
||||||
return c;
|
return c;
|
||||||
|
@ -611,8 +611,8 @@ private:
|
||||||
|
|
||||||
struct Region
|
struct Region
|
||||||
{
|
{
|
||||||
BufferCoord begin;
|
ByteCoord begin;
|
||||||
BufferCoord end;
|
ByteCoord end;
|
||||||
};
|
};
|
||||||
using RegionList = std::vector<Region>;
|
using RegionList = std::vector<Region>;
|
||||||
|
|
||||||
|
@ -778,7 +778,7 @@ HighlighterAndId region_factory(HighlighterParameters params)
|
||||||
const ColorPair colors = get_color(params[2]);
|
const ColorPair colors = get_color(params[2]);
|
||||||
|
|
||||||
auto func = [colors](const Context&, HighlightFlags flags, DisplayBuffer& display_buffer,
|
auto func = [colors](const Context&, HighlightFlags flags, DisplayBuffer& display_buffer,
|
||||||
BufferCoord begin, BufferCoord end)
|
ByteCoord begin, ByteCoord end)
|
||||||
{
|
{
|
||||||
highlight_range(display_buffer, begin, end, true,
|
highlight_range(display_buffer, begin, end, true,
|
||||||
[&colors](DisplayAtom& atom) { atom.colors = colors; });
|
[&colors](DisplayAtom& atom) { atom.colors = colors; });
|
||||||
|
@ -805,7 +805,7 @@ HighlighterAndId region_ref_factory(HighlighterParameters params)
|
||||||
const String& name = params[2];
|
const String& name = params[2];
|
||||||
|
|
||||||
auto func = [name](const Context& context, HighlightFlags flags, DisplayBuffer& display_buffer,
|
auto func = [name](const Context& context, HighlightFlags flags, DisplayBuffer& display_buffer,
|
||||||
BufferCoord begin, BufferCoord end)
|
ByteCoord begin, ByteCoord end)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
|
@ -207,7 +207,7 @@ public:
|
||||||
{
|
{
|
||||||
if (not context().has_ui())
|
if (not context().has_ui())
|
||||||
return;
|
return;
|
||||||
DisplayCoord menu_pos{ context().ui().dimensions().line, 0_char };
|
CharCoord menu_pos{ context().ui().dimensions().line, 0_char };
|
||||||
context().ui().menu_show(choices, menu_pos, get_color("MenuForeground"),
|
context().ui().menu_show(choices, menu_pos, get_color("MenuForeground"),
|
||||||
get_color("MenuBackground"), MenuStyle::Prompt);
|
get_color("MenuBackground"), MenuStyle::Prompt);
|
||||||
context().ui().menu_select(0);
|
context().ui().menu_select(0);
|
||||||
|
@ -549,7 +549,7 @@ private:
|
||||||
CandidateList& candidates = m_completions.candidates;
|
CandidateList& candidates = m_completions.candidates;
|
||||||
if (context().has_ui() and not candidates.empty())
|
if (context().has_ui() and not candidates.empty())
|
||||||
{
|
{
|
||||||
DisplayCoord menu_pos{ context().ui().dimensions().line, 0_char };
|
CharCoord menu_pos{ context().ui().dimensions().line, 0_char };
|
||||||
context().ui().menu_show(candidates, menu_pos, get_color("MenuForeground"),
|
context().ui().menu_show(candidates, menu_pos, get_color("MenuForeground"),
|
||||||
get_color("MenuBackground"), MenuStyle::Prompt);
|
get_color("MenuBackground"), MenuStyle::Prompt);
|
||||||
}
|
}
|
||||||
|
@ -669,7 +669,7 @@ public:
|
||||||
{
|
{
|
||||||
for (auto& sel : context().selections())
|
for (auto& sel : context().selections())
|
||||||
{
|
{
|
||||||
if (sel.cursor() == BufferCoord{0,0})
|
if (sel.cursor() == ByteCoord{0,0})
|
||||||
continue;
|
continue;
|
||||||
auto pos = buffer.iterator_at(sel.cursor());
|
auto pos = buffer.iterator_at(sel.cursor());
|
||||||
buffer.erase(utf8::previous(pos), pos);
|
buffer.erase(utf8::previous(pos), pos);
|
||||||
|
@ -783,7 +783,7 @@ private:
|
||||||
|
|
||||||
for (auto& sel : selections)
|
for (auto& sel : selections)
|
||||||
{
|
{
|
||||||
BufferCoord anchor, cursor;
|
ByteCoord anchor, cursor;
|
||||||
switch (mode)
|
switch (mode)
|
||||||
{
|
{
|
||||||
case InsertMode::Insert:
|
case InsertMode::Insert:
|
||||||
|
@ -803,7 +803,7 @@ private:
|
||||||
|
|
||||||
case InsertMode::OpenLineBelow:
|
case InsertMode::OpenLineBelow:
|
||||||
case InsertMode::AppendAtLineEnd:
|
case InsertMode::AppendAtLineEnd:
|
||||||
anchor = cursor = BufferCoord{sel.max().line, buffer[sel.max().line].length() - 1};
|
anchor = cursor = ByteCoord{sel.max().line, buffer[sel.max().line].length() - 1};
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case InsertMode::OpenLineAbove:
|
case InsertMode::OpenLineAbove:
|
||||||
|
@ -841,7 +841,7 @@ private:
|
||||||
{
|
{
|
||||||
// special case, the --first line above did nothing, so we need to compensate now
|
// special case, the --first line above did nothing, so we need to compensate now
|
||||||
if (sel.anchor() == buffer.char_next({0,0}))
|
if (sel.anchor() == buffer.char_next({0,0}))
|
||||||
sel.anchor() = sel.cursor() = BufferCoord{0,0};
|
sel.anchor() = sel.cursor() = ByteCoord{0,0};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ WordDB& get_word_db(const Buffer& buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
template<bool other_buffers>
|
template<bool other_buffers>
|
||||||
InsertCompletion complete_word(const Buffer& buffer, BufferCoord cursor_pos)
|
InsertCompletion complete_word(const Buffer& buffer, ByteCoord cursor_pos)
|
||||||
{
|
{
|
||||||
auto pos = buffer.iterator_at(cursor_pos);
|
auto pos = buffer.iterator_at(cursor_pos);
|
||||||
if (pos == buffer.begin() or not is_word(*utf8::previous(pos)))
|
if (pos == buffer.begin() or not is_word(*utf8::previous(pos)))
|
||||||
|
@ -76,7 +76,7 @@ InsertCompletion complete_word(const Buffer& buffer, BufferCoord cursor_pos)
|
||||||
}
|
}
|
||||||
|
|
||||||
template<bool require_slash>
|
template<bool require_slash>
|
||||||
InsertCompletion complete_filename(const Buffer& buffer, BufferCoord cursor_pos,
|
InsertCompletion complete_filename(const Buffer& buffer, ByteCoord cursor_pos,
|
||||||
OptionManager& options)
|
OptionManager& options)
|
||||||
{
|
{
|
||||||
auto pos = buffer.iterator_at(cursor_pos);
|
auto pos = buffer.iterator_at(cursor_pos);
|
||||||
|
@ -114,7 +114,7 @@ InsertCompletion complete_filename(const Buffer& buffer, BufferCoord cursor_pos,
|
||||||
return { begin.coord(), pos.coord(), std::move(res), buffer.timestamp() };
|
return { begin.coord(), pos.coord(), std::move(res), buffer.timestamp() };
|
||||||
}
|
}
|
||||||
|
|
||||||
InsertCompletion complete_option(const Buffer& buffer, BufferCoord cursor_pos,
|
InsertCompletion complete_option(const Buffer& buffer, ByteCoord cursor_pos,
|
||||||
OptionManager& options, const String& option_name)
|
OptionManager& options, const String& option_name)
|
||||||
{
|
{
|
||||||
const StringList& opt = options[option_name].get<StringList>();;
|
const StringList& opt = options[option_name].get<StringList>();;
|
||||||
|
@ -126,7 +126,7 @@ InsertCompletion complete_option(const Buffer& buffer, BufferCoord cursor_pos,
|
||||||
boost::smatch match;
|
boost::smatch match;
|
||||||
if (boost::regex_match(desc.begin(), desc.end(), match, re))
|
if (boost::regex_match(desc.begin(), desc.end(), match, re))
|
||||||
{
|
{
|
||||||
BufferCoord coord{ str_to_int(match[1].str()) - 1, str_to_int(match[2].str()) - 1 };
|
ByteCoord coord{ str_to_int(match[1].str()) - 1, str_to_int(match[2].str()) - 1 };
|
||||||
if (not buffer.is_valid(coord))
|
if (not buffer.is_valid(coord))
|
||||||
return {};
|
return {};
|
||||||
auto end = coord;
|
auto end = coord;
|
||||||
|
@ -149,7 +149,7 @@ InsertCompletion complete_option(const Buffer& buffer, BufferCoord cursor_pos,
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
InsertCompletion complete_line(const Buffer& buffer, BufferCoord cursor_pos)
|
InsertCompletion complete_line(const Buffer& buffer, ByteCoord cursor_pos)
|
||||||
{
|
{
|
||||||
String prefix = buffer[cursor_pos.line].substr(0_byte, cursor_pos.column);
|
String prefix = buffer[cursor_pos.line].substr(0_byte, cursor_pos.column);
|
||||||
StringList res;
|
StringList res;
|
||||||
|
@ -223,8 +223,8 @@ void InsertCompleter::update()
|
||||||
for (auto& candidate : m_completions.candidates)
|
for (auto& candidate : m_completions.candidates)
|
||||||
longest_completion = std::max(longest_completion, candidate.length());
|
longest_completion = std::max(longest_completion, candidate.length());
|
||||||
|
|
||||||
BufferCoord cursor = m_context.selections().main().cursor();
|
ByteCoord cursor = m_context.selections().main().cursor();
|
||||||
BufferCoord compl_beg = m_completions.begin;
|
ByteCoord compl_beg = m_completions.begin;
|
||||||
if (cursor.line == compl_beg.line and
|
if (cursor.line == compl_beg.line and
|
||||||
is_in_range(cursor.column - compl_beg.column,
|
is_in_range(cursor.column - compl_beg.column,
|
||||||
ByteCount{0}, longest_completion-1))
|
ByteCount{0}, longest_completion-1))
|
||||||
|
@ -272,24 +272,24 @@ bool InsertCompleter::setup_ifn()
|
||||||
for (auto& completer : completers)
|
for (auto& completer : completers)
|
||||||
{
|
{
|
||||||
if (completer == "filename" and
|
if (completer == "filename" and
|
||||||
try_complete([this](const Buffer& buffer, BufferCoord cursor_pos) {
|
try_complete([this](const Buffer& buffer, ByteCoord cursor_pos) {
|
||||||
return complete_filename<true>(buffer, cursor_pos,
|
return complete_filename<true>(buffer, cursor_pos,
|
||||||
options());
|
options());
|
||||||
}))
|
}))
|
||||||
return true;
|
return true;
|
||||||
if (completer.substr(0_byte, 7_byte) == "option=" and
|
if (completer.substr(0_byte, 7_byte) == "option=" and
|
||||||
try_complete([&,this](const Buffer& buffer, BufferCoord cursor_pos) {
|
try_complete([&,this](const Buffer& buffer, ByteCoord cursor_pos) {
|
||||||
return complete_option(buffer, cursor_pos,
|
return complete_option(buffer, cursor_pos,
|
||||||
options(), completer.substr(7_byte));
|
options(), completer.substr(7_byte));
|
||||||
}))
|
}))
|
||||||
return true;
|
return true;
|
||||||
if (completer == "word=buffer" and
|
if (completer == "word=buffer" and
|
||||||
try_complete([this](const Buffer& buffer, BufferCoord cursor_pos) {
|
try_complete([this](const Buffer& buffer, ByteCoord cursor_pos) {
|
||||||
return complete_word<false>(buffer, cursor_pos);
|
return complete_word<false>(buffer, cursor_pos);
|
||||||
}))
|
}))
|
||||||
return true;
|
return true;
|
||||||
if (completer == "word=all" and
|
if (completer == "word=all" and
|
||||||
try_complete([this](const Buffer& buffer, BufferCoord cursor_pos) {
|
try_complete([this](const Buffer& buffer, ByteCoord cursor_pos) {
|
||||||
return complete_word<true>(buffer, cursor_pos);
|
return complete_word<true>(buffer, cursor_pos);
|
||||||
}))
|
}))
|
||||||
return true;
|
return true;
|
||||||
|
@ -303,7 +303,7 @@ void InsertCompleter::menu_show()
|
||||||
{
|
{
|
||||||
if (not m_context.has_ui())
|
if (not m_context.has_ui())
|
||||||
return;
|
return;
|
||||||
DisplayCoord menu_pos = m_context.window().display_position(m_completions.begin);
|
CharCoord menu_pos = m_context.window().display_position(m_completions.begin);
|
||||||
|
|
||||||
const CharCount tabstop = m_context.options()["tabstop"].get<int>();
|
const CharCount tabstop = m_context.options()["tabstop"].get<int>();
|
||||||
const CharCount column = get_column(m_context.buffer(), tabstop,
|
const CharCount column = get_column(m_context.buffer(), tabstop,
|
||||||
|
@ -339,7 +339,7 @@ template<typename CompleteFunc>
|
||||||
bool InsertCompleter::try_complete(CompleteFunc complete_func)
|
bool InsertCompleter::try_complete(CompleteFunc complete_func)
|
||||||
{
|
{
|
||||||
auto& buffer = m_context.buffer();
|
auto& buffer = m_context.buffer();
|
||||||
BufferCoord cursor_pos = m_context.selections().main().cursor();
|
ByteCoord cursor_pos = m_context.selections().main().cursor();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
m_completions = complete_func(buffer, cursor_pos);
|
m_completions = complete_func(buffer, cursor_pos);
|
||||||
|
@ -362,21 +362,21 @@ bool InsertCompleter::try_complete(CompleteFunc complete_func)
|
||||||
|
|
||||||
void InsertCompleter::explicit_file_complete()
|
void InsertCompleter::explicit_file_complete()
|
||||||
{
|
{
|
||||||
try_complete([this](const Buffer& buffer, BufferCoord cursor_pos) {
|
try_complete([this](const Buffer& buffer, ByteCoord cursor_pos) {
|
||||||
return complete_filename<false>(buffer, cursor_pos, options());
|
return complete_filename<false>(buffer, cursor_pos, options());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void InsertCompleter::explicit_word_complete()
|
void InsertCompleter::explicit_word_complete()
|
||||||
{
|
{
|
||||||
try_complete([this](const Buffer& buffer, BufferCoord cursor_pos) {
|
try_complete([this](const Buffer& buffer, ByteCoord cursor_pos) {
|
||||||
return complete_word<true>(buffer, cursor_pos);
|
return complete_word<true>(buffer, cursor_pos);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void InsertCompleter::explicit_line_complete()
|
void InsertCompleter::explicit_line_complete()
|
||||||
{
|
{
|
||||||
try_complete([this](const Buffer& buffer, BufferCoord cursor_pos) {
|
try_complete([this](const Buffer& buffer, ByteCoord cursor_pos) {
|
||||||
return complete_line(buffer, cursor_pos);
|
return complete_line(buffer, cursor_pos);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,10 +9,10 @@ namespace Kakoune
|
||||||
|
|
||||||
struct InsertCompletion
|
struct InsertCompletion
|
||||||
{
|
{
|
||||||
BufferCoord begin;
|
ByteCoord begin;
|
||||||
BufferCoord end;
|
ByteCoord end;
|
||||||
CandidateList candidates;
|
CandidateList candidates;
|
||||||
size_t timestamp;
|
size_t timestamp;
|
||||||
|
|
||||||
bool is_valid() const { return not candidates.empty(); }
|
bool is_valid() const { return not candidates.empty(); }
|
||||||
};
|
};
|
||||||
|
|
|
@ -62,7 +62,7 @@ std::vector<LineModification> LineChangeWatcher::compute_modifications()
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LineChangeWatcher::on_insert(const Buffer& buffer, BufferCoord begin, BufferCoord end)
|
void LineChangeWatcher::on_insert(const Buffer& buffer, ByteCoord begin, ByteCoord end)
|
||||||
{
|
{
|
||||||
if (buffer.is_end(end))
|
if (buffer.is_end(end))
|
||||||
{
|
{
|
||||||
|
@ -72,7 +72,7 @@ void LineChangeWatcher::on_insert(const Buffer& buffer, BufferCoord begin, Buffe
|
||||||
m_changes.push_back({begin.line, end.line - begin.line});
|
m_changes.push_back({begin.line, end.line - begin.line});
|
||||||
}
|
}
|
||||||
|
|
||||||
void LineChangeWatcher::on_erase(const Buffer& buffer, BufferCoord begin, BufferCoord end)
|
void LineChangeWatcher::on_erase(const Buffer& buffer, ByteCoord begin, ByteCoord end)
|
||||||
{
|
{
|
||||||
if (begin.line == buffer.line_count())
|
if (begin.line == buffer.line_count())
|
||||||
{
|
{
|
||||||
|
|
|
@ -24,8 +24,8 @@ public:
|
||||||
|
|
||||||
std::vector<LineModification> compute_modifications();
|
std::vector<LineModification> compute_modifications();
|
||||||
private:
|
private:
|
||||||
void on_insert(const Buffer& buffer, BufferCoord begin, BufferCoord end) override;
|
void on_insert(const Buffer& buffer, ByteCoord begin, ByteCoord end) override;
|
||||||
void on_erase(const Buffer& buffer, BufferCoord begin, BufferCoord end) override;
|
void on_erase(const Buffer& buffer, ByteCoord begin, ByteCoord end) override;
|
||||||
|
|
||||||
struct Change
|
struct Change
|
||||||
{
|
{
|
||||||
|
|
|
@ -210,16 +210,16 @@ void addutf8str(WINDOW* win, Utf8Iterator begin, Utf8Iterator end)
|
||||||
waddstr(win, std::string(begin.base(), end.base()).c_str());
|
waddstr(win, std::string(begin.base(), end.base()).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
static DisplayCoord window_size(WINDOW* win)
|
static CharCoord window_size(WINDOW* win)
|
||||||
{
|
{
|
||||||
DisplayCoord size;
|
CharCoord size;
|
||||||
getmaxyx(win, (int&)size.line, (int&)size.column);
|
getmaxyx(win, (int&)size.line, (int&)size.column);
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static DisplayCoord window_pos(WINDOW* win)
|
static CharCoord window_pos(WINDOW* win)
|
||||||
{
|
{
|
||||||
DisplayCoord pos;
|
CharCoord pos;
|
||||||
getbegyx(win, (int&)pos.line, (int&)pos.column);
|
getbegyx(win, (int&)pos.line, (int&)pos.column);
|
||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
|
@ -410,7 +410,7 @@ void NCursesUI::draw_menu()
|
||||||
|
|
||||||
const int item_count = (int)m_items.size();
|
const int item_count = (int)m_items.size();
|
||||||
const LineCount menu_lines = div_round_up(item_count, m_menu_columns);
|
const LineCount menu_lines = div_round_up(item_count, m_menu_columns);
|
||||||
const DisplayCoord win_size = window_size(m_menu_win);
|
const CharCoord win_size = window_size(m_menu_win);
|
||||||
const LineCount& win_height = win_size.line;
|
const LineCount& win_height = win_size.line;
|
||||||
kak_assert(win_height <= menu_lines);
|
kak_assert(win_height <= menu_lines);
|
||||||
|
|
||||||
|
@ -451,7 +451,7 @@ void NCursesUI::draw_menu()
|
||||||
}
|
}
|
||||||
|
|
||||||
void NCursesUI::menu_show(memoryview<String> items,
|
void NCursesUI::menu_show(memoryview<String> items,
|
||||||
DisplayCoord anchor, ColorPair fg, ColorPair bg,
|
CharCoord anchor, ColorPair fg, ColorPair bg,
|
||||||
MenuStyle style)
|
MenuStyle style)
|
||||||
{
|
{
|
||||||
if (m_menu_win)
|
if (m_menu_win)
|
||||||
|
@ -465,7 +465,7 @@ void NCursesUI::menu_show(memoryview<String> items,
|
||||||
m_menu_fg = fg;
|
m_menu_fg = fg;
|
||||||
m_menu_bg = bg;
|
m_menu_bg = bg;
|
||||||
|
|
||||||
DisplayCoord maxsize = window_size(stdscr);
|
CharCoord maxsize = window_size(stdscr);
|
||||||
maxsize.column -= anchor.column;
|
maxsize.column -= anchor.column;
|
||||||
if (maxsize.column <= 2)
|
if (maxsize.column <= 2)
|
||||||
return;
|
return;
|
||||||
|
@ -532,9 +532,9 @@ void NCursesUI::menu_hide()
|
||||||
m_dirty = true;
|
m_dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static DisplayCoord compute_needed_size(StringView str)
|
static CharCoord compute_needed_size(StringView str)
|
||||||
{
|
{
|
||||||
DisplayCoord res{1,0};
|
CharCoord res{1,0};
|
||||||
CharCount line_len = 0;
|
CharCount line_len = 0;
|
||||||
for (Utf8Iterator begin{str.begin()}, end{str.end()};
|
for (Utf8Iterator begin{str.begin()}, end{str.end()};
|
||||||
begin != end; ++begin)
|
begin != end; ++begin)
|
||||||
|
@ -558,12 +558,11 @@ static DisplayCoord compute_needed_size(StringView str)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static DisplayCoord compute_pos(DisplayCoord anchor,
|
static CharCoord compute_pos(CharCoord anchor, CharCoord size,
|
||||||
DisplayCoord size,
|
WINDOW* opt_window_to_avoid = nullptr)
|
||||||
WINDOW* opt_window_to_avoid = nullptr)
|
|
||||||
{
|
{
|
||||||
DisplayCoord scrsize = window_size(stdscr);
|
CharCoord scrsize = window_size(stdscr);
|
||||||
DisplayCoord pos = { anchor.line+1, anchor.column };
|
CharCoord pos = { anchor.line+1, anchor.column };
|
||||||
if (pos.line + size.line >= scrsize.line)
|
if (pos.line + size.line >= scrsize.line)
|
||||||
pos.line = max(0_line, anchor.line - size.line);
|
pos.line = max(0_line, anchor.line - size.line);
|
||||||
if (pos.column + size.column >= scrsize.column)
|
if (pos.column + size.column >= scrsize.column)
|
||||||
|
@ -571,10 +570,10 @@ static DisplayCoord compute_pos(DisplayCoord anchor,
|
||||||
|
|
||||||
if (opt_window_to_avoid)
|
if (opt_window_to_avoid)
|
||||||
{
|
{
|
||||||
DisplayCoord winbeg = window_pos(opt_window_to_avoid);
|
CharCoord winbeg = window_pos(opt_window_to_avoid);
|
||||||
DisplayCoord winend = winbeg + window_size(opt_window_to_avoid);
|
CharCoord winend = winbeg + window_size(opt_window_to_avoid);
|
||||||
|
|
||||||
DisplayCoord end = pos + size;
|
CharCoord end = pos + size;
|
||||||
|
|
||||||
// check intersection
|
// check intersection
|
||||||
if (not (end.line < winbeg.line or end.column < winbeg.column or
|
if (not (end.line < winbeg.line or end.column < winbeg.column or
|
||||||
|
@ -642,7 +641,7 @@ static String make_info_box(StringView title, StringView message,
|
||||||
" │╰─╯│ ",
|
" │╰─╯│ ",
|
||||||
" ╰───╯ ",
|
" ╰───╯ ",
|
||||||
" " };
|
" " };
|
||||||
DisplayCoord assistant_size;
|
CharCoord assistant_size;
|
||||||
if (assist)
|
if (assist)
|
||||||
assistant_size = { (int)assistant.size(), assistant[0].char_length() };
|
assistant_size = { (int)assistant.size(), assistant[0].char_length() };
|
||||||
|
|
||||||
|
@ -688,7 +687,7 @@ static String make_info_box(StringView title, StringView message,
|
||||||
}
|
}
|
||||||
|
|
||||||
void NCursesUI::info_show(StringView title, StringView content,
|
void NCursesUI::info_show(StringView title, StringView content,
|
||||||
DisplayCoord anchor, ColorPair colors,
|
CharCoord anchor, ColorPair colors,
|
||||||
MenuStyle style)
|
MenuStyle style)
|
||||||
{
|
{
|
||||||
if (m_info_win)
|
if (m_info_win)
|
||||||
|
@ -706,9 +705,9 @@ void NCursesUI::info_show(StringView title, StringView content,
|
||||||
info_box = fancy_info_box;
|
info_box = fancy_info_box;
|
||||||
}
|
}
|
||||||
|
|
||||||
DisplayCoord size = compute_needed_size(info_box);
|
CharCoord size = compute_needed_size(info_box);
|
||||||
|
|
||||||
DisplayCoord pos = compute_pos(anchor, size, m_menu_win);
|
CharCoord pos = compute_pos(anchor, size, m_menu_win);
|
||||||
|
|
||||||
m_info_win = (NCursesWin*)newwin((int)size.line, (int)size.column,
|
m_info_win = (NCursesWin*)newwin((int)size.line, (int)size.column,
|
||||||
(int)pos.line, (int)pos.column);
|
(int)pos.line, (int)pos.column);
|
||||||
|
@ -739,7 +738,7 @@ void NCursesUI::info_hide()
|
||||||
m_dirty = true;
|
m_dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
DisplayCoord NCursesUI::dimensions()
|
CharCoord NCursesUI::dimensions()
|
||||||
{
|
{
|
||||||
return m_dimensions;
|
return m_dimensions;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,13 +27,13 @@ public:
|
||||||
Key get_key() override;
|
Key get_key() override;
|
||||||
|
|
||||||
void menu_show(memoryview<String> items,
|
void menu_show(memoryview<String> items,
|
||||||
DisplayCoord anchor, ColorPair fg, ColorPair bg,
|
CharCoord anchor, ColorPair fg, ColorPair bg,
|
||||||
MenuStyle style) override;
|
MenuStyle style) override;
|
||||||
void menu_select(int selected) override;
|
void menu_select(int selected) override;
|
||||||
void menu_hide() override;
|
void menu_hide() override;
|
||||||
|
|
||||||
void info_show(StringView title, StringView content,
|
void info_show(StringView title, StringView content,
|
||||||
DisplayCoord anchor, ColorPair colors,
|
CharCoord anchor, ColorPair colors,
|
||||||
MenuStyle style) override;
|
MenuStyle style) override;
|
||||||
void info_hide() override;
|
void info_hide() override;
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ public:
|
||||||
|
|
||||||
void set_input_callback(InputCallback callback) override;
|
void set_input_callback(InputCallback callback) override;
|
||||||
|
|
||||||
DisplayCoord dimensions() override;
|
CharCoord dimensions() override;
|
||||||
|
|
||||||
static void abort();
|
static void abort();
|
||||||
private:
|
private:
|
||||||
|
@ -49,7 +49,7 @@ private:
|
||||||
void redraw();
|
void redraw();
|
||||||
void draw_line(const DisplayLine& line, CharCount col_index) const;
|
void draw_line(const DisplayLine& line, CharCount col_index) const;
|
||||||
|
|
||||||
DisplayCoord m_dimensions;
|
CharCoord m_dimensions;
|
||||||
void update_dimensions();
|
void update_dimensions();
|
||||||
|
|
||||||
NCursesWin* m_menu_win = nullptr;
|
NCursesWin* m_menu_win = nullptr;
|
||||||
|
|
|
@ -174,7 +174,7 @@ constexpr Select<mode, T> make_select(T func)
|
||||||
}
|
}
|
||||||
|
|
||||||
template<SelectMode mode = SelectMode::Replace>
|
template<SelectMode mode = SelectMode::Replace>
|
||||||
void select_coord(const Buffer& buffer, BufferCoord coord, SelectionList& selections)
|
void select_coord(const Buffer& buffer, ByteCoord coord, SelectionList& selections)
|
||||||
{
|
{
|
||||||
coord = buffer.clamp(coord);
|
coord = buffer.clamp(coord);
|
||||||
if (mode == SelectMode::Replace)
|
if (mode == SelectMode::Replace)
|
||||||
|
@ -204,7 +204,7 @@ bool show_auto_info_ifn(const String& title, const String& info,
|
||||||
if (not context.options()["autoinfo"].get<bool>() or not context.has_ui())
|
if (not context.options()["autoinfo"].get<bool>() or not context.has_ui())
|
||||||
return false;
|
return false;
|
||||||
ColorPair col = get_color("Information");
|
ColorPair col = get_color("Information");
|
||||||
DisplayCoord pos = context.window().dimensions();
|
CharCoord pos = context.window().dimensions();
|
||||||
pos.column -= 1;
|
pos.column -= 1;
|
||||||
context.ui().info_show(title, info, pos , col, MenuStyle::Prompt);
|
context.ui().info_show(title, info, pos , col, MenuStyle::Prompt);
|
||||||
return true;
|
return true;
|
||||||
|
@ -243,7 +243,7 @@ void goto_commands(Context& context, int line)
|
||||||
case 'g':
|
case 'g':
|
||||||
case 'k':
|
case 'k':
|
||||||
context.push_jump();
|
context.push_jump();
|
||||||
select_coord<mode>(buffer, BufferCoord{0,0}, context.selections());
|
select_coord<mode>(buffer, ByteCoord{0,0}, context.selections());
|
||||||
break;
|
break;
|
||||||
case 'l':
|
case 'l':
|
||||||
select<mode>(context, select_to_eol);
|
select<mode>(context, select_to_eol);
|
||||||
|
@ -330,7 +330,7 @@ void goto_commands(Context& context, int line)
|
||||||
context.push_jump();
|
context.push_jump();
|
||||||
auto pos = buffer.last_modification_coord();
|
auto pos = buffer.last_modification_coord();
|
||||||
if (buffer[pos.line].length() == pos.column + 1)
|
if (buffer[pos.line].length() == pos.column + 1)
|
||||||
pos = BufferCoord{ pos.line+1, 0 };
|
pos = ByteCoord{ pos.line+1, 0 };
|
||||||
select_coord<mode>(buffer, pos, context.selections());
|
select_coord<mode>(buffer, pos, context.selections());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -446,7 +446,7 @@ void command(Context& context, int)
|
||||||
{
|
{
|
||||||
auto info = CommandManager::instance().command_info(cmdline);
|
auto info = CommandManager::instance().command_info(cmdline);
|
||||||
ColorPair col = get_color("Information");
|
ColorPair col = get_color("Information");
|
||||||
DisplayCoord pos = context.window().dimensions();
|
CharCoord pos = context.window().dimensions();
|
||||||
pos.column -= 1;
|
pos.column -= 1;
|
||||||
if (not info.first.empty() and not info.second.empty())
|
if (not info.first.empty() and not info.second.empty())
|
||||||
context.ui().info_show(info.first, info.second, pos , col, MenuStyle::Prompt);
|
context.ui().info_show(info.first, info.second, pos , col, MenuStyle::Prompt);
|
||||||
|
@ -863,12 +863,12 @@ void deindent(Context& context, int)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (deindent_incomplete and width != 0)
|
if (deindent_incomplete and width != 0)
|
||||||
sels.emplace_back(line, BufferCoord{line, column-1});
|
sels.emplace_back(line, ByteCoord{line, column-1});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (width == indent_width)
|
if (width == indent_width)
|
||||||
{
|
{
|
||||||
sels.emplace_back(line, BufferCoord{line, column});
|
sels.emplace_back(line, ByteCoord{line, column});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -949,7 +949,7 @@ void scroll(Context& context, int)
|
||||||
"scrool only implements PageUp and PageDown");
|
"scrool only implements PageUp and PageDown");
|
||||||
Window& window = context.window();
|
Window& window = context.window();
|
||||||
Buffer& buffer = context.buffer();
|
Buffer& buffer = context.buffer();
|
||||||
DisplayCoord position = window.position();
|
CharCoord position = window.position();
|
||||||
LineCount cursor_line = 0;
|
LineCount cursor_line = 0;
|
||||||
|
|
||||||
if (key == Key::PageUp)
|
if (key == Key::PageUp)
|
||||||
|
@ -1219,21 +1219,21 @@ public:
|
||||||
ModifiedRangesListener(Buffer& buffer)
|
ModifiedRangesListener(Buffer& buffer)
|
||||||
: BufferChangeListener_AutoRegister(buffer) {}
|
: BufferChangeListener_AutoRegister(buffer) {}
|
||||||
|
|
||||||
void on_insert(const Buffer& buffer, BufferCoord begin, BufferCoord end)
|
void on_insert(const Buffer& buffer, ByteCoord begin, ByteCoord end)
|
||||||
{
|
{
|
||||||
m_ranges.update_insert(buffer, begin, end);
|
m_ranges.update_insert(buffer, begin, end);
|
||||||
auto it = std::upper_bound(m_ranges.begin(), m_ranges.end(), begin,
|
auto it = std::upper_bound(m_ranges.begin(), m_ranges.end(), begin,
|
||||||
[](BufferCoord c, const Selection& sel)
|
[](ByteCoord c, const Selection& sel)
|
||||||
{ return c < sel.min(); });
|
{ return c < sel.min(); });
|
||||||
m_ranges.emplace(it, begin, buffer.char_prev(end));
|
m_ranges.emplace(it, begin, buffer.char_prev(end));
|
||||||
}
|
}
|
||||||
|
|
||||||
void on_erase(const Buffer& buffer, BufferCoord begin, BufferCoord end)
|
void on_erase(const Buffer& buffer, ByteCoord begin, ByteCoord end)
|
||||||
{
|
{
|
||||||
m_ranges.update_erase(buffer, begin, end);
|
m_ranges.update_erase(buffer, begin, end);
|
||||||
auto pos = std::min(begin, buffer.back_coord());
|
auto pos = std::min(begin, buffer.back_coord());
|
||||||
auto it = std::upper_bound(m_ranges.begin(), m_ranges.end(), pos,
|
auto it = std::upper_bound(m_ranges.begin(), m_ranges.end(), pos,
|
||||||
[](BufferCoord c, const Selection& sel)
|
[](ByteCoord c, const Selection& sel)
|
||||||
{ return c < sel.min(); });
|
{ return c < sel.min(); });
|
||||||
m_ranges.emplace(it, pos, pos);
|
m_ranges.emplace(it, pos, pos);
|
||||||
}
|
}
|
||||||
|
|
|
@ -249,13 +249,13 @@ public:
|
||||||
~RemoteUI();
|
~RemoteUI();
|
||||||
|
|
||||||
void menu_show(memoryview<String> choices,
|
void menu_show(memoryview<String> choices,
|
||||||
DisplayCoord anchor, ColorPair fg, ColorPair bg,
|
CharCoord anchor, ColorPair fg, ColorPair bg,
|
||||||
MenuStyle style) override;
|
MenuStyle style) override;
|
||||||
void menu_select(int selected) override;
|
void menu_select(int selected) override;
|
||||||
void menu_hide() override;
|
void menu_hide() override;
|
||||||
|
|
||||||
void info_show(StringView title, StringView content,
|
void info_show(StringView title, StringView content,
|
||||||
DisplayCoord anchor, ColorPair colors,
|
CharCoord anchor, ColorPair colors,
|
||||||
MenuStyle style) override;
|
MenuStyle style) override;
|
||||||
void info_hide() override;
|
void info_hide() override;
|
||||||
|
|
||||||
|
@ -267,13 +267,13 @@ public:
|
||||||
|
|
||||||
bool is_key_available() override;
|
bool is_key_available() override;
|
||||||
Key get_key() override;
|
Key get_key() override;
|
||||||
DisplayCoord dimensions() override;
|
CharCoord dimensions() override;
|
||||||
|
|
||||||
void set_input_callback(InputCallback callback) override;
|
void set_input_callback(InputCallback callback) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FDWatcher m_socket_watcher;
|
FDWatcher m_socket_watcher;
|
||||||
DisplayCoord m_dimensions;
|
CharCoord m_dimensions;
|
||||||
InputCallback m_input_callback;
|
InputCallback m_input_callback;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -296,7 +296,7 @@ RemoteUI::~RemoteUI()
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteUI::menu_show(memoryview<String> choices,
|
void RemoteUI::menu_show(memoryview<String> choices,
|
||||||
DisplayCoord anchor, ColorPair fg, ColorPair bg,
|
CharCoord anchor, ColorPair fg, ColorPair bg,
|
||||||
MenuStyle style)
|
MenuStyle style)
|
||||||
{
|
{
|
||||||
Message msg(m_socket_watcher.fd());
|
Message msg(m_socket_watcher.fd());
|
||||||
|
@ -322,7 +322,7 @@ void RemoteUI::menu_hide()
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteUI::info_show(StringView title, StringView content,
|
void RemoteUI::info_show(StringView title, StringView content,
|
||||||
DisplayCoord anchor, ColorPair colors,
|
CharCoord anchor, ColorPair colors,
|
||||||
MenuStyle style)
|
MenuStyle style)
|
||||||
{
|
{
|
||||||
Message msg(m_socket_watcher.fd());
|
Message msg(m_socket_watcher.fd());
|
||||||
|
@ -397,7 +397,7 @@ Key RemoteUI::get_key()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DisplayCoord RemoteUI::dimensions()
|
CharCoord RemoteUI::dimensions()
|
||||||
{
|
{
|
||||||
return m_dimensions;
|
return m_dimensions;
|
||||||
}
|
}
|
||||||
|
@ -447,7 +447,7 @@ void RemoteClient::process_next_message()
|
||||||
case RemoteUIMsg::MenuShow:
|
case RemoteUIMsg::MenuShow:
|
||||||
{
|
{
|
||||||
auto choices = read_vector<String>(socket);
|
auto choices = read_vector<String>(socket);
|
||||||
auto anchor = read<DisplayCoord>(socket);
|
auto anchor = read<CharCoord>(socket);
|
||||||
auto fg = read<ColorPair>(socket);
|
auto fg = read<ColorPair>(socket);
|
||||||
auto bg = read<ColorPair>(socket);
|
auto bg = read<ColorPair>(socket);
|
||||||
auto style = read<MenuStyle>(socket);
|
auto style = read<MenuStyle>(socket);
|
||||||
|
@ -464,7 +464,7 @@ void RemoteClient::process_next_message()
|
||||||
{
|
{
|
||||||
auto title = read<String>(socket);
|
auto title = read<String>(socket);
|
||||||
auto content = read<String>(socket);
|
auto content = read<String>(socket);
|
||||||
auto anchor = read<DisplayCoord>(socket);
|
auto anchor = read<CharCoord>(socket);
|
||||||
auto colors = read<ColorPair>(socket);
|
auto colors = read<ColorPair>(socket);
|
||||||
auto style = read<MenuStyle>(socket);
|
auto style = read<MenuStyle>(socket);
|
||||||
m_ui->info_show(title, content, anchor, colors, style);
|
m_ui->info_show(title, content, anchor, colors, style);
|
||||||
|
@ -494,7 +494,7 @@ void RemoteClient::write_next_key()
|
||||||
// handle a resize event.
|
// handle a resize event.
|
||||||
msg.write(m_ui->get_key());
|
msg.write(m_ui->get_key());
|
||||||
|
|
||||||
DisplayCoord dimensions = m_ui->dimensions();
|
CharCoord dimensions = m_ui->dimensions();
|
||||||
if (dimensions != m_dimensions)
|
if (dimensions != m_dimensions)
|
||||||
{
|
{
|
||||||
m_dimensions = dimensions;
|
m_dimensions = dimensions;
|
||||||
|
|
|
@ -32,7 +32,7 @@ private:
|
||||||
void write_next_key();
|
void write_next_key();
|
||||||
|
|
||||||
std::unique_ptr<UserInterface> m_ui;
|
std::unique_ptr<UserInterface> m_ui;
|
||||||
DisplayCoord m_dimensions;
|
CharCoord m_dimensions;
|
||||||
FDWatcher m_socket_watcher;
|
FDWatcher m_socket_watcher;
|
||||||
};
|
};
|
||||||
std::unique_ptr<RemoteClient> connect_to(const String& session,
|
std::unique_ptr<RemoteClient> connect_to(const String& session,
|
||||||
|
|
|
@ -19,10 +19,10 @@ namespace
|
||||||
|
|
||||||
template<template <bool, bool> class UpdateFunc>
|
template<template <bool, bool> class UpdateFunc>
|
||||||
void on_buffer_change(const Buffer& buffer, SelectionList& sels,
|
void on_buffer_change(const Buffer& buffer, SelectionList& sels,
|
||||||
BufferCoord begin, BufferCoord end, LineCount end_line)
|
ByteCoord begin, ByteCoord end, LineCount end_line)
|
||||||
{
|
{
|
||||||
auto update_beg = std::lower_bound(sels.begin(), sels.end(), begin,
|
auto update_beg = std::lower_bound(sels.begin(), sels.end(), begin,
|
||||||
[](const Selection& s, BufferCoord c)
|
[](const Selection& s, ByteCoord c)
|
||||||
{ return s.max() < c; });
|
{ return s.max() < c; });
|
||||||
auto update_only_line_beg = std::upper_bound(sels.begin(), sels.end(), end_line,
|
auto update_only_line_beg = std::upper_bound(sels.begin(), sels.end(), end_line,
|
||||||
[](LineCount l, const Selection& s)
|
[](LineCount l, const Selection& s)
|
||||||
|
@ -52,8 +52,8 @@ void on_buffer_change(const Buffer& buffer, SelectionList& sels,
|
||||||
template<bool assume_different_line, bool assume_greater_than_begin>
|
template<bool assume_different_line, bool assume_greater_than_begin>
|
||||||
struct UpdateInsert
|
struct UpdateInsert
|
||||||
{
|
{
|
||||||
void operator()(const Buffer& buffer, BufferCoord& coord,
|
void operator()(const Buffer& buffer, ByteCoord& coord,
|
||||||
BufferCoord begin, BufferCoord end) const
|
ByteCoord begin, ByteCoord end) const
|
||||||
{
|
{
|
||||||
if (assume_different_line)
|
if (assume_different_line)
|
||||||
kak_assert(begin.line < coord.line);
|
kak_assert(begin.line < coord.line);
|
||||||
|
@ -69,8 +69,8 @@ struct UpdateInsert
|
||||||
template<bool assume_different_line, bool assume_greater_than_begin>
|
template<bool assume_different_line, bool assume_greater_than_begin>
|
||||||
struct UpdateErase
|
struct UpdateErase
|
||||||
{
|
{
|
||||||
void operator()(const Buffer& buffer, BufferCoord& coord,
|
void operator()(const Buffer& buffer, ByteCoord& coord,
|
||||||
BufferCoord begin, BufferCoord end) const
|
ByteCoord begin, ByteCoord end) const
|
||||||
{
|
{
|
||||||
if (not assume_greater_than_begin and coord < begin)
|
if (not assume_greater_than_begin and coord < begin)
|
||||||
return;
|
return;
|
||||||
|
@ -93,12 +93,12 @@ struct UpdateErase
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SelectionList::update_insert(const Buffer& buffer, BufferCoord begin, BufferCoord end)
|
void SelectionList::update_insert(const Buffer& buffer, ByteCoord begin, ByteCoord end)
|
||||||
{
|
{
|
||||||
on_buffer_change<UpdateInsert>(buffer, *this, begin, end, begin.line);
|
on_buffer_change<UpdateInsert>(buffer, *this, begin, end, begin.line);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SelectionList::update_erase(const Buffer& buffer, BufferCoord begin, BufferCoord end)
|
void SelectionList::update_erase(const Buffer& buffer, ByteCoord begin, ByteCoord end)
|
||||||
{
|
{
|
||||||
on_buffer_change<UpdateErase>(buffer, *this, begin, end, end.line);
|
on_buffer_change<UpdateErase>(buffer, *this, begin, end, end.line);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,19 +12,19 @@ using CaptureList = std::vector<String>;
|
||||||
struct Selection
|
struct Selection
|
||||||
{
|
{
|
||||||
Selection() = default;
|
Selection() = default;
|
||||||
explicit Selection(BufferCoord pos) : Selection(pos,pos) {}
|
explicit Selection(ByteCoord pos) : Selection(pos,pos) {}
|
||||||
Selection(BufferCoord anchor, BufferCoord cursor,
|
Selection(ByteCoord anchor, ByteCoord cursor,
|
||||||
CaptureList captures = {})
|
CaptureList captures = {})
|
||||||
: m_anchor{anchor}, m_cursor{cursor},
|
: m_anchor{anchor}, m_cursor{cursor},
|
||||||
m_captures(std::move(captures)) {}
|
m_captures(std::move(captures)) {}
|
||||||
|
|
||||||
void merge_with(const Selection& range);
|
void merge_with(const Selection& range);
|
||||||
|
|
||||||
BufferCoord& anchor() { return m_anchor; }
|
ByteCoord& anchor() { return m_anchor; }
|
||||||
BufferCoord& cursor() { return m_cursor; }
|
ByteCoord& cursor() { return m_cursor; }
|
||||||
|
|
||||||
const BufferCoord& anchor() const { return m_anchor; }
|
const ByteCoord& anchor() const { return m_anchor; }
|
||||||
const BufferCoord& cursor() const { return m_cursor; }
|
const ByteCoord& cursor() const { return m_cursor; }
|
||||||
|
|
||||||
CaptureList& captures() { return m_captures; }
|
CaptureList& captures() { return m_captures; }
|
||||||
const CaptureList& captures() const { return m_captures; }
|
const CaptureList& captures() const { return m_captures; }
|
||||||
|
@ -34,12 +34,12 @@ struct Selection
|
||||||
return m_anchor == other.m_anchor and m_cursor == other.m_cursor;
|
return m_anchor == other.m_anchor and m_cursor == other.m_cursor;
|
||||||
}
|
}
|
||||||
|
|
||||||
const BufferCoord& min() const { return std::min(m_anchor, m_cursor); }
|
const ByteCoord& min() const { return std::min(m_anchor, m_cursor); }
|
||||||
const BufferCoord& max() const { return std::max(m_anchor, m_cursor); }
|
const ByteCoord& max() const { return std::max(m_anchor, m_cursor); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BufferCoord m_anchor;
|
ByteCoord m_anchor;
|
||||||
BufferCoord m_cursor;
|
ByteCoord m_cursor;
|
||||||
|
|
||||||
CaptureList m_captures;
|
CaptureList m_captures;
|
||||||
};
|
};
|
||||||
|
@ -58,11 +58,11 @@ static bool compare_selections(const Selection& lhs, const Selection& rhs)
|
||||||
struct SelectionList : std::vector<Selection>
|
struct SelectionList : std::vector<Selection>
|
||||||
{
|
{
|
||||||
SelectionList() = default;
|
SelectionList() = default;
|
||||||
SelectionList(BufferCoord c) : std::vector<Selection>{Selection{c,c}} {}
|
SelectionList(ByteCoord c) : std::vector<Selection>{Selection{c,c}} {}
|
||||||
SelectionList(Selection s) : std::vector<Selection>{s} {}
|
SelectionList(Selection s) : std::vector<Selection>{s} {}
|
||||||
|
|
||||||
void update_insert(const Buffer& buffer, BufferCoord begin, BufferCoord end);
|
void update_insert(const Buffer& buffer, ByteCoord begin, ByteCoord end);
|
||||||
void update_erase(const Buffer& buffer, BufferCoord begin, BufferCoord end);
|
void update_erase(const Buffer& buffer, ByteCoord begin, ByteCoord end);
|
||||||
|
|
||||||
void check_invariant() const;
|
void check_invariant() const;
|
||||||
|
|
||||||
|
|
|
@ -77,7 +77,7 @@ Selection select_matching(const Buffer& buffer, const Selection& selection)
|
||||||
// c++14 will add std::optional, so we use boost::optional until then
|
// c++14 will add std::optional, so we use boost::optional until then
|
||||||
using boost::optional;
|
using boost::optional;
|
||||||
static optional<Selection> find_surrounding(const Buffer& buffer,
|
static optional<Selection> find_surrounding(const Buffer& buffer,
|
||||||
BufferCoord coord,
|
ByteCoord coord,
|
||||||
CodepointPair matching,
|
CodepointPair matching,
|
||||||
ObjectFlags flags, int init_level)
|
ObjectFlags flags, int init_level)
|
||||||
{
|
{
|
||||||
|
@ -373,7 +373,7 @@ Selection select_whole_indent(const Buffer& buffer, const Selection& selection,
|
||||||
++end_line;
|
++end_line;
|
||||||
}
|
}
|
||||||
--end_line;
|
--end_line;
|
||||||
BufferCoord first = begin_line;
|
ByteCoord first = begin_line;
|
||||||
// keep the first line indent in inner mode
|
// keep the first line indent in inner mode
|
||||||
if (flags & ObjectFlags::Inner)
|
if (flags & ObjectFlags::Inner)
|
||||||
{
|
{
|
||||||
|
|
|
@ -16,13 +16,13 @@ void test_buffer()
|
||||||
BufferIterator pos = buffer.begin();
|
BufferIterator pos = buffer.begin();
|
||||||
kak_assert(*pos == 'a');
|
kak_assert(*pos == 'a');
|
||||||
pos += 6;
|
pos += 6;
|
||||||
kak_assert(pos.coord() == BufferCoord{0 COMMA 6});
|
kak_assert(pos.coord() == ByteCoord{0 COMMA 6});
|
||||||
++pos;
|
++pos;
|
||||||
kak_assert(pos.coord() == BufferCoord{1 COMMA 0});
|
kak_assert(pos.coord() == ByteCoord{1 COMMA 0});
|
||||||
--pos;
|
--pos;
|
||||||
kak_assert(pos.coord() == BufferCoord{0 COMMA 6});
|
kak_assert(pos.coord() == ByteCoord{0 COMMA 6});
|
||||||
pos += 1;
|
pos += 1;
|
||||||
kak_assert(pos.coord() == BufferCoord{1 COMMA 0});
|
kak_assert(pos.coord() == ByteCoord{1 COMMA 0});
|
||||||
buffer.insert(pos, "tchou kanaky\n");
|
buffer.insert(pos, "tchou kanaky\n");
|
||||||
kak_assert(buffer.line_count() == 5);
|
kak_assert(buffer.line_count() == 5);
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ namespace Kakoune
|
||||||
class String;
|
class String;
|
||||||
class DisplayBuffer;
|
class DisplayBuffer;
|
||||||
class DisplayLine;
|
class DisplayLine;
|
||||||
struct DisplayCoord;
|
struct CharCoord;
|
||||||
|
|
||||||
enum class MenuStyle
|
enum class MenuStyle
|
||||||
{
|
{
|
||||||
|
@ -28,20 +28,20 @@ public:
|
||||||
virtual ~UserInterface() {}
|
virtual ~UserInterface() {}
|
||||||
|
|
||||||
virtual void menu_show(memoryview<String> choices,
|
virtual void menu_show(memoryview<String> choices,
|
||||||
DisplayCoord anchor, ColorPair fg, ColorPair bg,
|
CharCoord anchor, ColorPair fg, ColorPair bg,
|
||||||
MenuStyle style) = 0;
|
MenuStyle style) = 0;
|
||||||
virtual void menu_select(int selected) = 0;
|
virtual void menu_select(int selected) = 0;
|
||||||
virtual void menu_hide() = 0;
|
virtual void menu_hide() = 0;
|
||||||
|
|
||||||
virtual void info_show(StringView title, StringView content,
|
virtual void info_show(StringView title, StringView content,
|
||||||
DisplayCoord anchor, ColorPair colors,
|
CharCoord anchor, ColorPair colors,
|
||||||
MenuStyle style) = 0;
|
MenuStyle style) = 0;
|
||||||
virtual void info_hide() = 0;
|
virtual void info_hide() = 0;
|
||||||
|
|
||||||
virtual void draw(const DisplayBuffer& display_buffer,
|
virtual void draw(const DisplayBuffer& display_buffer,
|
||||||
const DisplayLine& status_line,
|
const DisplayLine& status_line,
|
||||||
const DisplayLine& mode_line) = 0;
|
const DisplayLine& mode_line) = 0;
|
||||||
virtual DisplayCoord dimensions() = 0;
|
virtual CharCoord dimensions() = 0;
|
||||||
virtual bool is_key_available() = 0;
|
virtual bool is_key_available() = 0;
|
||||||
virtual Key get_key() = 0;
|
virtual Key get_key() = 0;
|
||||||
|
|
||||||
|
|
|
@ -93,13 +93,13 @@ void Window::update_display_buffer(const Context& context)
|
||||||
m_timestamp = buffer().timestamp();
|
m_timestamp = buffer().timestamp();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::set_position(DisplayCoord position)
|
void Window::set_position(CharCoord position)
|
||||||
{
|
{
|
||||||
m_position.line = std::max(0_line, position.line);
|
m_position.line = std::max(0_line, position.line);
|
||||||
m_position.column = std::max(0_char, position.column);
|
m_position.column = std::max(0_char, position.column);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::set_dimensions(DisplayCoord dimensions)
|
void Window::set_dimensions(CharCoord dimensions)
|
||||||
{
|
{
|
||||||
m_dimensions = dimensions;
|
m_dimensions = dimensions;
|
||||||
}
|
}
|
||||||
|
@ -117,7 +117,7 @@ static LineCount adapt_view_pos(LineCount line, LineCount offset,
|
||||||
}
|
}
|
||||||
|
|
||||||
static CharCount adapt_view_pos(const DisplayBuffer& display_buffer,
|
static CharCount adapt_view_pos(const DisplayBuffer& display_buffer,
|
||||||
BufferCoord pos, CharCount view_pos, CharCount view_size)
|
ByteCoord pos, CharCount view_pos, CharCount view_size)
|
||||||
{
|
{
|
||||||
CharCount buffer_column = 0;
|
CharCount buffer_column = 0;
|
||||||
CharCount non_buffer_column = 0;
|
CharCount non_buffer_column = 0;
|
||||||
|
@ -197,7 +197,7 @@ void Window::scroll_to_keep_selection_visible_ifn(const Context& context)
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
CharCount find_display_column(const DisplayLine& line, const Buffer& buffer,
|
CharCount find_display_column(const DisplayLine& line, const Buffer& buffer,
|
||||||
BufferCoord coord)
|
ByteCoord coord)
|
||||||
{
|
{
|
||||||
CharCount column = 0;
|
CharCount column = 0;
|
||||||
for (auto& atom : line)
|
for (auto& atom : line)
|
||||||
|
@ -215,8 +215,8 @@ CharCount find_display_column(const DisplayLine& line, const Buffer& buffer,
|
||||||
return column;
|
return column;
|
||||||
}
|
}
|
||||||
|
|
||||||
BufferCoord find_buffer_coord(const DisplayLine& line, const Buffer& buffer,
|
ByteCoord find_buffer_coord(const DisplayLine& line, const Buffer& buffer,
|
||||||
CharCount column)
|
CharCount column)
|
||||||
{
|
{
|
||||||
auto& range = line.range();
|
auto& range = line.range();
|
||||||
for (auto& atom : line)
|
for (auto& atom : line)
|
||||||
|
@ -235,7 +235,7 @@ BufferCoord find_buffer_coord(const DisplayLine& line, const Buffer& buffer,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DisplayCoord Window::display_position(BufferCoord coord)
|
CharCoord Window::display_position(ByteCoord coord)
|
||||||
{
|
{
|
||||||
LineCount l = 0;
|
LineCount l = 0;
|
||||||
for (auto& line : m_display_buffer.lines())
|
for (auto& line : m_display_buffer.lines())
|
||||||
|
@ -248,12 +248,12 @@ DisplayCoord Window::display_position(BufferCoord coord)
|
||||||
return { 0, 0 };
|
return { 0, 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
BufferCoord Window::offset_coord(BufferCoord coord, CharCount offset)
|
ByteCoord Window::offset_coord(ByteCoord coord, CharCount offset)
|
||||||
{
|
{
|
||||||
return buffer().offset_coord(coord, offset);
|
return buffer().offset_coord(coord, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
BufferCoord Window::offset_coord(BufferCoord coord, LineCount offset)
|
ByteCoord Window::offset_coord(ByteCoord coord, LineCount offset)
|
||||||
{
|
{
|
||||||
auto line = clamp(coord.line + offset, 0_line, buffer().line_count()-1);
|
auto line = clamp(coord.line + offset, 0_line, buffer().line_count()-1);
|
||||||
DisplayBuffer display_buffer;
|
DisplayBuffer display_buffer;
|
||||||
|
|
|
@ -19,11 +19,11 @@ public:
|
||||||
Window(Buffer& buffer);
|
Window(Buffer& buffer);
|
||||||
~Window();
|
~Window();
|
||||||
|
|
||||||
const DisplayCoord& position() const { return m_position; }
|
const CharCoord& position() const { return m_position; }
|
||||||
void set_position(DisplayCoord position);
|
void set_position(CharCoord position);
|
||||||
|
|
||||||
const DisplayCoord& dimensions() const { return m_dimensions; }
|
const CharCoord& dimensions() const { return m_dimensions; }
|
||||||
void set_dimensions(DisplayCoord dimensions);
|
void set_dimensions(CharCoord dimensions);
|
||||||
|
|
||||||
const DisplayBuffer& display_buffer() const { return m_display_buffer; }
|
const DisplayBuffer& display_buffer() const { return m_display_buffer; }
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ public:
|
||||||
void scroll(CharCount offset);
|
void scroll(CharCount offset);
|
||||||
void update_display_buffer(const Context& context);
|
void update_display_buffer(const Context& context);
|
||||||
|
|
||||||
DisplayCoord display_position(BufferCoord coord);
|
CharCoord display_position(ByteCoord coord);
|
||||||
|
|
||||||
HighlighterGroup& highlighters() { return m_highlighters; }
|
HighlighterGroup& highlighters() { return m_highlighters; }
|
||||||
|
|
||||||
|
@ -49,8 +49,8 @@ public:
|
||||||
size_t timestamp() const { return m_timestamp; }
|
size_t timestamp() const { return m_timestamp; }
|
||||||
void forget_timestamp() { m_timestamp = -1; }
|
void forget_timestamp() { m_timestamp = -1; }
|
||||||
|
|
||||||
BufferCoord offset_coord(BufferCoord coord, CharCount offset);
|
ByteCoord offset_coord(ByteCoord coord, CharCount offset);
|
||||||
BufferCoord offset_coord(BufferCoord coord, LineCount offset);
|
ByteCoord offset_coord(ByteCoord coord, LineCount offset);
|
||||||
private:
|
private:
|
||||||
Window(const Window&) = delete;
|
Window(const Window&) = delete;
|
||||||
|
|
||||||
|
@ -59,8 +59,8 @@ private:
|
||||||
|
|
||||||
safe_ptr<Buffer> m_buffer;
|
safe_ptr<Buffer> m_buffer;
|
||||||
|
|
||||||
DisplayCoord m_position;
|
CharCoord m_position;
|
||||||
DisplayCoord m_dimensions;
|
CharCoord m_dimensions;
|
||||||
DisplayBuffer m_display_buffer;
|
DisplayBuffer m_display_buffer;
|
||||||
|
|
||||||
HookManager m_hooks;
|
HookManager m_hooks;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user