summaryrefslogtreecommitdiffstats
path: root/src/shared/format-table.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/shared/format-table.c')
-rw-r--r--src/shared/format-table.c133
1 files changed, 115 insertions, 18 deletions
diff --git a/src/shared/format-table.c b/src/shared/format-table.c
index 9a19177..9146444 100644
--- a/src/shared/format-table.c
+++ b/src/shared/format-table.c
@@ -77,7 +77,9 @@ typedef struct TableData {
unsigned ellipsize_percent; /* 0 … 100, where to place the ellipsis when compression is needed */
unsigned align_percent; /* 0 … 100, where to pad with spaces when expanding is needed. 0: left-aligned, 100: right-aligned */
- bool uppercase; /* Uppercase string on display */
+ bool uppercase:1; /* Uppercase string on display */
+ bool underline:1;
+ bool rgap_underline:1;
const char *color; /* ANSI color string to use for this cell. When written to terminal should not move cursor. Will automatically be reset after the cell */
const char *rgap_color; /* The ANSI color to use for the gap right of this cell. Usually used to underline entire rows in a gapless fashion */
@@ -401,7 +403,7 @@ static bool table_data_matches(
return false;
/* If a color/url is set, refuse to merge */
- if (d->color || d->rgap_color)
+ if (d->color || d->rgap_color || d->underline || d->rgap_underline)
return false;
if (d->url)
return false;
@@ -617,6 +619,8 @@ static int table_dedup_cell(Table *t, TableCell *cell) {
nd->color = od->color;
nd->rgap_color = od->rgap_color;
+ nd->underline = od->underline;
+ nd->rgap_underline = od->rgap_underline;
nd->url = TAKE_PTR(curl);
table_data_unref(od);
@@ -759,6 +763,46 @@ int table_set_rgap_color(Table *t, TableCell *cell, const char *color) {
return 0;
}
+int table_set_underline(Table *t, TableCell *cell, bool b) {
+ TableData *d;
+ int r;
+
+ assert(t);
+ assert(cell);
+
+ r = table_dedup_cell(t, cell);
+ if (r < 0)
+ return r;
+
+ assert_se(d = table_get_data(t, cell));
+
+ if (d->underline == b)
+ return 0;
+
+ d->underline = b;
+ return 1;
+}
+
+int table_set_rgap_underline(Table *t, TableCell *cell, bool b) {
+ TableData *d;
+ int r;
+
+ assert(t);
+ assert(cell);
+
+ r = table_dedup_cell(t, cell);
+ if (r < 0)
+ return r;
+
+ assert_se(d = table_get_data(t, cell));
+
+ if (d->rgap_underline == b)
+ return 0;
+
+ d->rgap_underline = b;
+ return 1;
+}
+
int table_set_url(Table *t, TableCell *cell, const char *url) {
_cleanup_free_ char *copy = NULL;
int r;
@@ -834,6 +878,8 @@ int table_update(Table *t, TableCell *cell, TableDataType type, const void *data
nd->color = od->color;
nd->rgap_color = od->rgap_color;
+ nd->underline = od->underline;
+ nd->rgap_underline = od->rgap_underline;
nd->url = TAKE_PTR(curl);
table_data_unref(od);
@@ -1101,6 +1147,31 @@ int table_add_many_internal(Table *t, TableDataType first_type, ...) {
goto check;
}
+ case TABLE_SET_UNDERLINE: {
+ int u = va_arg(ap, int);
+ r = table_set_underline(t, last_cell, u);
+ goto check;
+ }
+
+ case TABLE_SET_RGAP_UNDERLINE: {
+ int u = va_arg(ap, int);
+ r = table_set_rgap_underline(t, last_cell, u);
+ goto check;
+ }
+
+ case TABLE_SET_BOTH_UNDERLINES: {
+ int u = va_arg(ap, int);
+
+ r = table_set_underline(t, last_cell, u);
+ if (r < 0) {
+ va_end(ap);
+ return r;
+ }
+
+ r = table_set_rgap_underline(t, last_cell, u);
+ goto check;
+ }
+
case TABLE_SET_URL: {
const char *u = va_arg(ap, const char*);
r = table_set_url(t, last_cell, u);
@@ -1641,7 +1712,7 @@ static const char *table_data_format(Table *t, TableData *d, bool avoid_uppercas
if (!p)
return NULL;
- if (!format_bytes_full(p, FORMAT_BYTES_MAX, d->size, 0))
+ if (!format_bytes_full(p, FORMAT_BYTES_MAX, d->size, FORMAT_BYTES_BELOW_POINT))
return table_ersatz_string(t);
n = strlen(p);
@@ -1932,7 +2003,7 @@ static const char *table_data_format(Table *t, TableData *d, bool avoid_uppercas
if (d->mode == MODE_INVALID)
return table_ersatz_string(t);
- return inode_type_to_string(d->mode);
+ return inode_type_to_string(d->mode) ?: table_ersatz_string(t);
case TABLE_DEVNUM:
if (devnum_is_zero(d->devnum))
@@ -2130,8 +2201,6 @@ static const char* table_data_color(TableData *d) {
if (d->type == TABLE_FIELD)
return ansi_bright_blue();
- if (d->type == TABLE_HEADER)
- return ansi_underline();
return NULL;
}
@@ -2139,11 +2208,29 @@ static const char* table_data_color(TableData *d) {
static const char* table_data_rgap_color(TableData *d) {
assert(d);
- if (d->rgap_color)
- return d->rgap_color;
+ return d->rgap_color ?: d->rgap_color;
+}
+
+static const char* table_data_underline(TableData *d) {
+ assert(d);
+
+ if (d->underline)
+ return /* cescape( */ansi_add_underline_grey()/* ) */;
if (d->type == TABLE_HEADER)
- return ansi_underline();
+ return ansi_add_underline();
+
+ return NULL;
+}
+
+static const char* table_data_rgap_underline(TableData *d) {
+ assert(d);
+
+ if (d->rgap_underline)
+ return ansi_add_underline_grey();
+
+ if (d->type == TABLE_HEADER)
+ return ansi_add_underline();
return NULL;
}
@@ -2418,13 +2505,13 @@ int table_print(Table *t, FILE *f) {
row = t->data + i * t->n_columns;
do {
- const char *gap_color = NULL;
+ const char *gap_color = NULL, *gap_underline = NULL;
more_sublines = false;
for (size_t j = 0; j < display_columns; j++) {
_cleanup_free_ char *buffer = NULL, *extracted = NULL;
bool lines_truncated = false;
- const char *field, *color = NULL;
+ const char *field, *color = NULL, *underline = NULL;
TableData *d;
size_t l;
@@ -2490,6 +2577,7 @@ int table_print(Table *t, FILE *f) {
/* Drop trailing white spaces of last column when no cosmetics is set. */
if (j == display_columns - 1 &&
(!colors_enabled() || !table_data_color(d)) &&
+ (!underline_enabled() || !table_data_underline(d)) &&
(!urlify_enabled() || !d->url))
delete_trailing_chars(aligned, NULL);
@@ -2511,31 +2599,40 @@ int table_print(Table *t, FILE *f) {
if (colors_enabled() && gap_color)
fputs(gap_color, f);
+ if (underline_enabled() && gap_underline)
+ fputs(gap_underline, f);
if (j > 0)
fputc(' ', f); /* column separator left of cell */
+ /* Undo gap color/underline */
+ if ((colors_enabled() && gap_color) ||
+ (underline_enabled() && gap_underline))
+ fputs(ANSI_NORMAL, f);
+
if (colors_enabled()) {
color = table_data_color(d);
-
- /* Undo gap color */
- if (gap_color)
- fputs(ANSI_NORMAL, f);
-
if (color)
fputs(color, f);
}
+ if (underline_enabled()) {
+ underline = table_data_underline(d);
+ if (underline)
+ fputs(underline, f);
+ }
+
fputs(field, f);
- if (colors_enabled() && color)
+ if (color || underline)
fputs(ANSI_NORMAL, f);
gap_color = table_data_rgap_color(d);
+ gap_underline = table_data_rgap_underline(d);
}
fputc('\n', f);
- n_subline ++;
+ n_subline++;
} while (more_sublines);
}