99 lines
2.7 KiB
C++
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 */
|