strbuffer: fix issue with order of properties with the same position
This commit is contained in:
@@ -205,21 +205,21 @@ void writeCyclicBuffer(const NC::WBuffer &buf, NC::Window &w, size_t &start_pos,
|
|||||||
auto p = ps.begin();
|
auto p = ps.begin();
|
||||||
|
|
||||||
// load attributes from before starting pos
|
// load attributes from before starting pos
|
||||||
for (; p != ps.end() && p->position() < start_pos; ++p)
|
for (; p != ps.end() && p->first < start_pos; ++p)
|
||||||
w << *p;
|
w << p->second;
|
||||||
|
|
||||||
auto write_buffer = [&](size_t start) {
|
auto write_buffer = [&](size_t start) {
|
||||||
for (size_t i = start; i < s.length() && len < width; ++i)
|
for (size_t i = start; i < s.length() && len < width; ++i)
|
||||||
{
|
{
|
||||||
for (; p != ps.end() && p->position() == i; ++p)
|
for (; p != ps.end() && p->first == i; ++p)
|
||||||
w << *p;
|
w << p->second;
|
||||||
len += wcwidth(s[i]);
|
len += wcwidth(s[i]);
|
||||||
if (len > width)
|
if (len > width)
|
||||||
break;
|
break;
|
||||||
w << s[i];
|
w << s[i];
|
||||||
}
|
}
|
||||||
for (; p != ps.end(); ++p)
|
for (; p != ps.end(); ++p)
|
||||||
w << *p;
|
w << p->second;
|
||||||
p = ps.begin();
|
p = ps.begin();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -36,8 +36,8 @@ bool regexSearch(NC::Buffer &buf, PropT begin, const std::string &ws, PropT end,
|
|||||||
bool success = first != last;
|
bool success = first != last;
|
||||||
for (; first != last; ++first)
|
for (; first != last; ++first)
|
||||||
{
|
{
|
||||||
buf.setProperty(first->position(), begin, id);
|
buf.addProperty(first->position(), begin, id);
|
||||||
buf.setProperty(first->position() + first->length(), end, id);
|
buf.addProperty(first->position() + first->length(), end, id);
|
||||||
}
|
}
|
||||||
return success;
|
return success;
|
||||||
} catch (boost::bad_expression &e) {
|
} catch (boost::bad_expression &e) {
|
||||||
@@ -147,8 +147,8 @@ void Scrollpad::flush()
|
|||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
|
|
||||||
auto load_properties = [&]() {
|
auto load_properties = [&]() {
|
||||||
for (; p != ps.end() && p->position() == i; ++p)
|
for (; p != ps.end() && p->first == i; ++p)
|
||||||
w << *p;
|
w << p->second;
|
||||||
};
|
};
|
||||||
auto write_whitespace = [&]() {
|
auto write_whitespace = [&]() {
|
||||||
for (; i < s.length() && iswspace(s[i]); ++i)
|
for (; i < s.length() && iswspace(s[i]); ++i)
|
||||||
@@ -257,7 +257,7 @@ void Scrollpad::flush()
|
|||||||
}
|
}
|
||||||
// load remaining properties if there are any
|
// load remaining properties if there are any
|
||||||
for (; p != ps.end(); ++p)
|
for (; p != ps.end(); ++p)
|
||||||
w << *p;
|
w << p->second;
|
||||||
return height;
|
return height;
|
||||||
};
|
};
|
||||||
m_real_height = std::max(write_buffer(true), m_height);
|
m_real_height = std::max(write_buffer(true), m_height);
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
#define NCMPCPP_STRBUFFER_H
|
#define NCMPCPP_STRBUFFER_H
|
||||||
|
|
||||||
#include <boost/lexical_cast.hpp>
|
#include <boost/lexical_cast.hpp>
|
||||||
#include <set>
|
#include <map>
|
||||||
#include "window.h"
|
#include "window.h"
|
||||||
|
|
||||||
namespace NC {
|
namespace NC {
|
||||||
@@ -35,34 +35,13 @@ template <typename CharT> class BasicBuffer
|
|||||||
{
|
{
|
||||||
enum class Type { Color, Format };
|
enum class Type { Color, Format };
|
||||||
|
|
||||||
Property(size_t position_, NC::Color color_, int id_)
|
Property(NC::Color color_, size_t id_)
|
||||||
: m_type(Type::Color), m_position(position_), m_color(std::move(color_)), m_id(id_) { }
|
: m_type(Type::Color), m_color(std::move(color_)), m_id(id_) { }
|
||||||
Property(size_t position_, NC::Format format_, int id_)
|
Property(NC::Format format_, size_t id_)
|
||||||
: m_type(Type::Format), m_position(position_), m_format(format_), m_id(id_) { }
|
: m_type(Type::Format), m_format(format_), m_id(id_) { }
|
||||||
|
|
||||||
size_t position() const { return m_position; }
|
|
||||||
size_t id() const { return m_id; }
|
size_t id() const { return m_id; }
|
||||||
|
|
||||||
bool operator<(const Property &rhs) const
|
|
||||||
{
|
|
||||||
if (m_position != rhs.m_position)
|
|
||||||
return m_position < rhs.m_position;
|
|
||||||
if (m_type != rhs.m_type)
|
|
||||||
return m_type < rhs.m_type;
|
|
||||||
switch (m_type)
|
|
||||||
{
|
|
||||||
case Type::Color:
|
|
||||||
if (m_color != rhs.m_color)
|
|
||||||
return m_color < rhs.m_color;
|
|
||||||
break;
|
|
||||||
case Type::Format:
|
|
||||||
if (m_format != rhs.m_format)
|
|
||||||
return m_format < rhs.m_format;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return m_id < rhs.m_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename OutputStreamT>
|
template <typename OutputStreamT>
|
||||||
friend OutputStreamT &operator<<(OutputStreamT &os, const Property &p)
|
friend OutputStreamT &operator<<(OutputStreamT &os, const Property &p)
|
||||||
{
|
{
|
||||||
@@ -80,7 +59,6 @@ template <typename CharT> class BasicBuffer
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
Type m_type;
|
Type m_type;
|
||||||
size_t m_position;
|
|
||||||
Color m_color;
|
Color m_color;
|
||||||
Format m_format;
|
Format m_format;
|
||||||
size_t m_id;
|
size_t m_id;
|
||||||
@@ -88,25 +66,16 @@ template <typename CharT> class BasicBuffer
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
typedef std::basic_string<CharT> StringType;
|
typedef std::basic_string<CharT> StringType;
|
||||||
typedef std::multiset<Property> Properties;
|
typedef std::multimap<size_t, Property> Properties;
|
||||||
|
|
||||||
const StringType &str() const { return m_string; }
|
const StringType &str() const { return m_string; }
|
||||||
const Properties &properties() const { return m_properties; }
|
const Properties &properties() const { return m_properties; }
|
||||||
|
|
||||||
template <typename PropertyT>
|
template <typename PropertyT>
|
||||||
void setProperty(size_t position, PropertyT &&property, size_t id = -1)
|
void addProperty(size_t position, PropertyT &&property, size_t id = -1)
|
||||||
{
|
{
|
||||||
m_properties.insert(Property(position, std::forward<PropertyT>(property), id));
|
assert(position <= m_string.size());
|
||||||
}
|
m_properties.emplace(position, Property(std::forward<PropertyT>(property), id));
|
||||||
|
|
||||||
template <typename PropertyT>
|
|
||||||
bool removeProperty(size_t position, PropertyT &&property, size_t id = -1)
|
|
||||||
{
|
|
||||||
auto it = m_properties.find(Property(position, std::forward<PropertyT>(property), id));
|
|
||||||
bool found = it != m_properties.end();
|
|
||||||
if (found)
|
|
||||||
m_properties.erase(it);
|
|
||||||
return found;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void removeProperties(size_t id = -1)
|
void removeProperties(size_t id = -1)
|
||||||
@@ -114,7 +83,7 @@ public:
|
|||||||
auto it = m_properties.begin();
|
auto it = m_properties.begin();
|
||||||
while (it != m_properties.end())
|
while (it != m_properties.end())
|
||||||
{
|
{
|
||||||
if (it->id() == id)
|
if (it->second.id() == id)
|
||||||
m_properties.erase(it++);
|
m_properties.erase(it++);
|
||||||
else
|
else
|
||||||
++it;
|
++it;
|
||||||
@@ -171,13 +140,13 @@ public:
|
|||||||
|
|
||||||
BasicBuffer<CharT> &operator<<(Color color)
|
BasicBuffer<CharT> &operator<<(Color color)
|
||||||
{
|
{
|
||||||
setProperty(m_string.size(), color);
|
addProperty(m_string.size(), color);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
BasicBuffer<CharT> &operator<<(Format format)
|
BasicBuffer<CharT> &operator<<(Format format)
|
||||||
{
|
{
|
||||||
setProperty(m_string.size(), format);
|
addProperty(m_string.size(), format);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -217,15 +186,15 @@ OutputStreamT &operator<<(OutputStreamT &os, const BasicBuffer<CharT> &buffer)
|
|||||||
auto &s = buffer.str();
|
auto &s = buffer.str();
|
||||||
auto &ps = buffer.properties();
|
auto &ps = buffer.properties();
|
||||||
auto p = ps.begin();
|
auto p = ps.begin();
|
||||||
for (size_t i = 0; i < s.size(); ++i)
|
for (size_t i = 0;; ++i)
|
||||||
{
|
{
|
||||||
for (; p != ps.end() && p->position() == i; ++p)
|
for (; p != ps.end() && p->first == i; ++p)
|
||||||
os << *p;
|
os << p->second;
|
||||||
os << s[i];
|
if (i < s.size())
|
||||||
|
os << s[i];
|
||||||
|
else
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
// load remaining properties
|
|
||||||
for (; p != ps.end(); ++p)
|
|
||||||
os << *p;
|
|
||||||
}
|
}
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user