Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sheet: use entire screen width #257

Merged
merged 3 commits into from
Nov 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 38 additions & 33 deletions app/sheet.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,6 @@
/* TODO: move this somewhere else like common or utils */
#define UNUSED(X) ((void)X)

#define ZSVSHEET_CELL_DISPLAY_WIDTH 10

struct zsvsheet_opts {
char hide_row_nums; // if 1, will load row nums
const char *find;
Expand All @@ -63,16 +61,22 @@ struct zsvsheet_opts {
#include "sheet/read-data.c"
#include "sheet/key-bindings.c"

void display_buffer_subtable(struct zsvsheet_ui_buffer *ui_buffer, size_t rownum_col_offset, size_t input_header_span,
struct zsvsheet_display_dimensions *ddims);
#define ZSVSHEET_CELL_DISPLAY_MIN_WIDTH 10
static size_t zsvsheet_cell_display_width(struct zsvsheet_ui_buffer *ui_buffer,
struct zsvsheet_display_dimensions *ddims) {
size_t width = ddims->columns / (ui_buffer->dimensions.col_count + (ui_buffer->rownum_col_offset ? 1 : 0));
return width < ZSVSHEET_CELL_DISPLAY_MIN_WIDTH ? ZSVSHEET_CELL_DISPLAY_MIN_WIDTH : width;
}

static void display_buffer_subtable(struct zsvsheet_ui_buffer *ui_buffer, size_t input_header_span,
struct zsvsheet_display_dimensions *ddims);

void zsvsheet_set_status(const struct zsvsheet_display_dimensions *ddims, int overwrite, const char *fmt, ...);

struct zsvsheet_display_info {
int update_buffer;
struct zsvsheet_display_dimensions *dimensions;
size_t header_span;
size_t rownum_col_offset;
struct {
struct zsvsheet_ui_buffer **base;
struct zsvsheet_ui_buffer **current;
Expand Down Expand Up @@ -298,11 +302,11 @@ static zsvsheet_handler_status zsvsheet_move_hor(struct zsvsheet_display_info *d
struct zsvsheet_ui_buffer *current_ui_buffer = *(di->ui_buffers.current);

if (right) {
cursor_right(di->dimensions->columns, ZSVSHEET_CELL_DISPLAY_WIDTH,
current_ui_buffer->dimensions.col_count + di->rownum_col_offset >
cursor_right(di->dimensions->columns, zsvsheet_cell_display_width(current_ui_buffer, di->dimensions),
current_ui_buffer->dimensions.col_count + current_ui_buffer->rownum_col_offset >
zsvsheet_buffer_cols(current_ui_buffer->buffer)
? zsvsheet_buffer_cols(current_ui_buffer->buffer)
: current_ui_buffer->dimensions.col_count + di->rownum_col_offset,
: current_ui_buffer->dimensions.col_count + current_ui_buffer->rownum_col_offset,
&current_ui_buffer->cursor_col, &current_ui_buffer->buff_offset.col);
} else {
if (current_ui_buffer->cursor_col > 0) {
Expand Down Expand Up @@ -346,11 +350,11 @@ static zsvsheet_handler_status zsvsheet_move_hor_end(struct zsvsheet_display_inf

if (right) {
// to do: directly set current_ui_buffer->cursor_col and buff_offset.col
while (cursor_right(di->dimensions->columns, ZSVSHEET_CELL_DISPLAY_WIDTH,
current_ui_buffer->dimensions.col_count + di->rownum_col_offset >
while (cursor_right(di->dimensions->columns, zsvsheet_cell_display_width(current_ui_buffer, di->dimensions),
current_ui_buffer->dimensions.col_count + current_ui_buffer->rownum_col_offset >
zsvsheet_buffer_cols(current_ui_buffer->buffer)
? zsvsheet_buffer_cols(current_ui_buffer->buffer)
: current_ui_buffer->dimensions.col_count + di->rownum_col_offset,
: current_ui_buffer->dimensions.col_count + current_ui_buffer->rownum_col_offset,
&current_ui_buffer->cursor_col, &current_ui_buffer->buff_offset.col) > 0)
;
{}
Expand Down Expand Up @@ -610,8 +614,7 @@ int ZSV_MAIN_FUNC(ZSV_COMMAND)(int argc, const char *argv[], struct zsv_opts *op
keypad(stdscr, TRUE);
cbreak();
struct zsvsheet_display_dimensions display_dims = get_display_dimensions(1, 1);
size_t rownum_col_offset = 1;
display_buffer_subtable(current_ui_buffer, rownum_col_offset, header_span, &display_dims);
display_buffer_subtable(current_ui_buffer, header_span, &display_dims);

zsvsheet_register_builtin_procedures();

Expand All @@ -627,7 +630,6 @@ int ZSV_MAIN_FUNC(ZSV_COMMAND)(int argc, const char *argv[], struct zsv_opts *op
.display_info.ui_buffers.current = &current_ui_buffer,
.display_info.dimensions = &display_dims,
.display_info.header_span = header_span,
.display_info.rownum_col_offset = rownum_col_offset,
.find = NULL,
.custom_prop_handler = custom_prop_handler,
.opts_used = opts_used,
Expand Down Expand Up @@ -657,7 +659,7 @@ int ZSV_MAIN_FUNC(ZSV_COMMAND)(int argc, const char *argv[], struct zsv_opts *op
}
if (current_ui_buffer->status)
zsvsheet_set_status(&display_dims, 1, current_ui_buffer->status);
display_buffer_subtable(current_ui_buffer, rownum_col_offset, header_span, &display_dims);
display_buffer_subtable(current_ui_buffer, header_span, &display_dims);
}

endwin();
Expand All @@ -667,18 +669,17 @@ int ZSV_MAIN_FUNC(ZSV_COMMAND)(int argc, const char *argv[], struct zsv_opts *op
return 0;
}

const char *display_cell(struct zsvsheet_buffer *buff, size_t data_row, size_t data_col, int row, int col) {
const char *display_cell(struct zsvsheet_buffer *buff, size_t data_row, size_t data_col, int row, int col,
size_t cell_display_width) {
char *str = (char *)zsvsheet_buffer_cell_display(buff, data_row, data_col);
size_t len = str ? strlen(str) : 0;
if (len == 0 || has_multibyte_char(str, len < ZSVSHEET_CELL_DISPLAY_WIDTH ? len : ZSVSHEET_CELL_DISPLAY_WIDTH) == 0)
mvprintw(row, col * ZSVSHEET_CELL_DISPLAY_WIDTH, "%-*.*s", ZSVSHEET_CELL_DISPLAY_WIDTH,
ZSVSHEET_CELL_DISPLAY_WIDTH - 1, str);
if (len == 0 || has_multibyte_char(str, len < cell_display_width ? len : cell_display_width) == 0)
mvprintw(row, col * cell_display_width, "%-*.*s", cell_display_width, cell_display_width - 1, str);
else {
size_t used_width;
int err = 0;
unsigned char *s = (unsigned char *)str;
size_t nbytes =
utf8_bytes_up_to_max_width_and_replace_newlines(s, len, ZSVSHEET_CELL_DISPLAY_WIDTH - 2, &used_width, &err);
size_t nbytes = utf8_bytes_up_to_max_width_and_replace_newlines(s, len, cell_display_width - 2, &used_width, &err);

// convert the substring to wide characters
wchar_t wsubstring[256]; // Ensure this buffer is large enough
Expand All @@ -699,25 +700,28 @@ const char *display_cell(struct zsvsheet_buffer *buff, size_t data_row, size_t d
}

// move to the desired position
move(row, col * ZSVSHEET_CELL_DISPLAY_WIDTH);
move(row, col * cell_display_width);

// print the wide-character string with right padding
addnwstr(wsubstring, wlen);
for (size_t k = used_width; k < ZSVSHEET_CELL_DISPLAY_WIDTH; k++)
for (size_t k = used_width; k < cell_display_width; k++)
addch(' ');
}
return str;
}

void display_buffer_subtable(struct zsvsheet_ui_buffer *ui_buffer, size_t rownum_col_offset, size_t input_header_span,
struct zsvsheet_display_dimensions *ddims) {
static size_t zsvsheet_max_buffer_cols(struct zsvsheet_ui_buffer *ui_buffer) {
size_t col_count = ui_buffer->dimensions.col_count + (ui_buffer->rownum_col_offset ? 1 : 0);
return col_count > zsvsheet_buffer_cols(ui_buffer->buffer) ? zsvsheet_buffer_cols(ui_buffer->buffer) : col_count;
}

static void display_buffer_subtable(struct zsvsheet_ui_buffer *ui_buffer, size_t input_header_span,
struct zsvsheet_display_dimensions *ddims) {
struct zsvsheet_buffer *buffer = ui_buffer->buffer;
size_t start_row = ui_buffer->buff_offset.row;
size_t buffer_used_row_count = ui_buffer->buff_used_rows;
size_t start_col = ui_buffer->buff_offset.col;
size_t max_col_count = ui_buffer->dimensions.col_count + rownum_col_offset > zsvsheet_buffer_cols(ui_buffer->buffer)
? zsvsheet_buffer_cols(ui_buffer->buffer)
: ui_buffer->dimensions.col_count + rownum_col_offset;
size_t max_col_count = zsvsheet_max_buffer_cols(ui_buffer);
size_t cursor_row = ui_buffer->cursor_row;
size_t cursor_col = ui_buffer->cursor_col;

Expand All @@ -732,7 +736,8 @@ void display_buffer_subtable(struct zsvsheet_ui_buffer *ui_buffer, size_t rownum
if (end_row > buffer_used_row_count)
end_row = buffer_used_row_count;

size_t end_col = start_col + ddims->columns / ZSVSHEET_CELL_DISPLAY_WIDTH;
size_t cell_display_width = zsvsheet_cell_display_width(ui_buffer, ddims);
size_t end_col = start_col + ddims->columns / cell_display_width;
if (end_col > max_col_count)
end_col = max_col_count;

Expand All @@ -742,10 +747,10 @@ void display_buffer_subtable(struct zsvsheet_ui_buffer *ui_buffer, size_t rownum
for (size_t j = start_col; j < end_col; j++) {
if (cursor_row == 0 && cursor_col + start_col == j) {
attroff(A_REVERSE);
cursor_value = display_cell(buffer, 0, j, 0, j - start_col);
cursor_value = display_cell(buffer, 0, j, 0, j - start_col, cell_display_width);
attron(A_REVERSE);
} else
display_cell(buffer, 0, j, 0, j - start_col);
display_cell(buffer, 0, j, 0, j - start_col, cell_display_width);
}
attroff(A_REVERSE);

Expand All @@ -755,10 +760,10 @@ void display_buffer_subtable(struct zsvsheet_ui_buffer *ui_buffer, size_t rownum
for (size_t j = start_col; j < end_col; j++) {
if (screen_row == cursor_row && j == cursor_col + start_col) {
attron(A_REVERSE);
cursor_value = display_cell(buffer, i, j, screen_row, j - start_col);
cursor_value = display_cell(buffer, i, j, screen_row, j - start_col, cell_display_width);
attroff(A_REVERSE);
} else {
display_cell(buffer, i, j, screen_row, j - start_col);
display_cell(buffer, i, j, screen_row, j - start_col, cell_display_width);
}
}
}
Expand Down
6 changes: 5 additions & 1 deletion app/sheet/ui_buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ struct zsvsheet_ui_buffer {
char *row_filter;

unsigned char indexed : 1;
unsigned char _ : 7;
unsigned char rownum_col_offset : 1;
unsigned char _ : 6;
};

void zsvsheet_ui_buffer_delete(struct zsvsheet_ui_buffer *ub) {
Expand All @@ -46,12 +47,15 @@ struct zsvsheet_ui_buffer_opts {
const char *row_filter;
const char *filename;
struct zsv_opts zsv_opts; // options to use when opening this file
char no_rownum_col_offset;
};

struct zsvsheet_ui_buffer *zsvsheet_ui_buffer_new(zsvsheet_buffer_t buffer, struct zsvsheet_ui_buffer_opts *uibopts) {
struct zsvsheet_ui_buffer *uib = calloc(1, sizeof(*uib));
if (uib) {
uib->buffer = buffer;
if (!(uibopts && uibopts->no_rownum_col_offset))
uib->rownum_col_offset = 1;
#ifdef ZSVSHEET_USE_THREADS
uib->mutex = PTHREAD_MUTEX_INITIALIZER;
#endif
Expand Down
19 changes: 14 additions & 5 deletions app/test/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -578,21 +578,21 @@ test-compare: test-%: ${BUILD_DIR}/bin/zsv_%${EXE}

test-sheet: test-%: ${BUILD_DIR}/bin/zsv_%${EXE} worldcitiespop_mil.csv test-sheet-all

test-sheet-all: test-sheet-1 test-sheet-2 test-sheet-3 test-sheet-4
test-sheet-all: test-sheet-1 test-sheet-2 test-sheet-3 test-sheet-4 test-sheet-5
@(for SESSION in $^; do ! tmux kill-session -t "$$SESSION" 2>/dev/null; done && ${TEST_PASS} || ${TEST_FAIL})

test-sheet-1: ${BUILD_DIR}/bin/zsv_sheet${EXE}
@${TEST_INIT}
@echo 'set-option default-terminal "tmux-256color"' > ~/.tmux.conf
@(tmux new-session -x 1000 -y 5 -d -s $@ "${PREFIX} $< worldcitiespop_mil.csv" && \
@(tmux new-session -x 80 -y 5 -d -s $@ "${PREFIX} $< worldcitiespop_mil.csv" && \
sleep 0.5 && \
tmux capture-pane -t $@ -p ${REDIRECT1} ${TMP_DIR}/[email protected] && \
tmux send-keys -t $@ "q" && \
${CMP} ${TMP_DIR}/[email protected] expected/[email protected] && ${TEST_PASS} || ${TEST_FAIL})

test-sheet-2: ${BUILD_DIR}/bin/zsv_sheet${EXE}
@${TEST_INIT}
@(tmux new-session -x 1000 -y 5 -d -s $@ "${PREFIX} $< worldcitiespop_mil.csv" && \
@(tmux new-session -x 80 -y 5 -d -s $@ "${PREFIX} $< worldcitiespop_mil.csv" && \
sleep 0.5 && \
tmux send-keys -t $@ "C-d" && \
tmux capture-pane -t $@ -p ${REDIRECT1} ${TMP_DIR}/[email protected] && \
Expand All @@ -601,7 +601,7 @@ test-sheet-2: ${BUILD_DIR}/bin/zsv_sheet${EXE}

test-sheet-3: ${BUILD_DIR}/bin/zsv_sheet${EXE}
@${TEST_INIT}
@(tmux new-session -x 1000 -y 5 -d -s $@ "${PREFIX} $< worldcitiespop_mil.csv" && \
@(tmux new-session -x 80 -y 5 -d -s $@ "${PREFIX} $< worldcitiespop_mil.csv" && \
sleep 0.5 && \
tmux send-keys -t $@ "f" "sarmaj" Enter && \
sleep 0.5 && \
Expand All @@ -611,9 +611,18 @@ test-sheet-3: ${BUILD_DIR}/bin/zsv_sheet${EXE}

test-sheet-4: ${BUILD_DIR}/bin/zsv_sheet${EXE}
@${TEST_INIT}
@(tmux new-session -x 1000 -y 5 -d -s $@ "${PREFIX} $< worldcitiespop_mil.csv" && \
@(tmux new-session -x 80 -y 5 -d -s $@ "${PREFIX} $< worldcitiespop_mil.csv" && \
sleep 0.5 && \
tmux send-keys -t $@ "C-d" "C-d" "C-u" && \
tmux capture-pane -t $@ -p ${REDIRECT1} ${TMP_DIR}/[email protected] && \
tmux send-keys -t $@ "q" && \
${CMP} ${TMP_DIR}/[email protected] expected/[email protected] && ${TEST_PASS} || ${TEST_FAIL})

test-sheet-5: ${BUILD_DIR}/bin/zsv_sheet${EXE}
@${TEST_INIT}
@echo 'set-option default-terminal "tmux-256color"' > ~/.tmux.conf
@(tmux new-session -x 160 -y 5 -d -s $@ "${PREFIX} $< worldcitiespop_mil.csv" && \
sleep 0.5 && \
tmux capture-pane -t $@ -p ${REDIRECT1} ${TMP_DIR}/[email protected] && \
tmux send-keys -t $@ "q" && \
${CMP} ${TMP_DIR}/[email protected] expected/[email protected] && ${TEST_PASS} || ${TEST_FAIL})
5 changes: 5 additions & 0 deletions app/test/expected/test-sheet-5.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Row # Country City AccentCity Region Population Latitude Longitude
1 ir sarmaj-e hoseynkhan Sarmaj-e Hoseynkhan 13 34.3578 47.5207
2 ad aixirivali Aixirivali 06 42.4666667 1.5
3 mm mokho-atwinywa Mokho-atwinywa 09 18.0333333 96.75
? for help 1