fxos/include/fxos/view/util.h

99 lines
2.7 KiB
C++

//---------------------------------------------------------------------------//
// 1100101 |_ mov #0, r4 __ //
// 11 |_ <0xb380 %5c4> / _|_ _____ ___ //
// 0110 |_ 3.50 -> 3.60 | _\ \ / _ (_-< //
// |_ base# + offset |_| /_\_\___/__/ //
//---------------------------------------------------------------------------//
// fxos/view/util
#include <string>
#include <ranges>
#include <iostream>
#include <fmt/core.h>
#include <fmt/color.h>
#ifndef FXOS_VIEW_UTIL_H
#define FXOS_VIEW_UTIL_H
namespace FxOS {
static inline auto fmt_rgb(std::string s, fmt::detail::color_type fg)
{
return fmt::format("{}", fmt::styled(s, fmt::fg(fg)));
}
static inline auto fmt_color(std::string s, fmt::terminal_color fg)
{
return fmt::format("{}", fmt::styled(s, fmt::fg(fg)));
}
static size_t codePointLength(std::string s)
{
size_t len = 0;
for(auto c: s)
len += (c & 0xc0) != 0x80;
return len;
}
/* viewStrings: Display a set of strings with line wrapping */
template<typename R, typename T>
concept range_of
= std::ranges::range<R> && std::same_as<std::ranges::range_value_t<R>, T>;
struct ViewStringsOptions
{
/* Maximum number of columns to print elements in (excluding start) */
int maxColumns = 80;
/* Extra text at the beginning of each line (in addition to maxColumns) */
std::string lineStart = "";
/* Item separator */
std::string separator = ", ";
/* Style for text after lineStart */
fmt::text_style style {};
};
template<typename R>
requires(range_of<R, std::string>)
void viewStrings(R range, ViewStringsOptions const &opts)
{
bool newline = true;
int lineSize = 0;
for(std::string const &str: range) {
int strSize = codePointLength(str);
int lengthNeeded = strSize + (newline ? 0 : opts.separator.size());
/* Allow overflow if that's required for progress */
if(lineSize != 0 && lineSize + lengthNeeded > opts.maxColumns) {
fmt::print("\n");
newline = true;
lineSize = 0;
}
if(newline) {
std::cout << opts.lineStart;
fmt::print(opts.style, "{}", str);
}
else {
fmt::print(opts.style, "{}{}", opts.separator, str);
}
lineSize += strSize + (newline ? 0 : opts.separator.size());
newline = false;
}
if(!newline)
fmt::print("\n");
}
template<typename R, typename F>
void viewStrings(R range, F fun, ViewStringsOptions const &opts)
{
return viewStrings(
std::views::all(range) | std::views::transform(fun), opts);
}
} /* namespace FxOS */
#endif /* FXOS_VIEW_UTIL_H */