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 edit open #223

Merged
merged 3 commits into from
Oct 12, 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
147 changes: 86 additions & 61 deletions app/sheet.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <string.h>
#include <stdarg.h>
#include <ctype.h>
#include <errno.h>

#include <zsv.h>
#include "sheet/sheet_internal.h"
Expand All @@ -31,6 +32,9 @@
#include <pthread.h>
#endif

#define ZSV_COMMAND sheet
#include "zsv_command.h"

#include "sheet/buffer.h"
#include "sheet/buffer.c"

Expand Down Expand Up @@ -98,12 +102,11 @@ size_t zsvsheet_get_input_raw_row(struct zsvsheet_rowcol *input_offset, struct z
#include "sheet/cursor.c"

// zsvsheet_handle_find_next: return non-zero if a result was found
char zsvsheet_handle_find_next(struct zsvsheet_ui_buffer *uib, const char *filename, const char *needle,
struct zsv_opts *zsv_opts, struct zsvsheet_opts *zsvsheet_opts, size_t header_span,
char zsvsheet_handle_find_next(struct zsvsheet_ui_buffer *uib, const char *needle, const struct zsv_opts *zsv_opts,
struct zsvsheet_opts *zsvsheet_opts, size_t header_span,
struct zsvsheet_display_dimensions *ddims, int *update_buffer,
struct zsv_prop_handler *custom_prop_handler, const char *opts_used) {
if (zsvsheet_find_next(uib, filename, needle, zsv_opts, zsvsheet_opts, header_span, custom_prop_handler, opts_used) >
0) {
if (zsvsheet_find_next(uib, needle, zsv_opts, zsvsheet_opts, header_span, custom_prop_handler, opts_used) > 0) {
*update_buffer = zsvsheet_goto_input_raw_row(uib, zsvsheet_opts->found_rownum, header_span, ddims, (size_t)-1);
return 1;
}
Expand Down Expand Up @@ -153,8 +156,32 @@ void zsvsheet_set_status(struct zsvsheet_display_dimensions *ddims, int overwrit

#include "sheet/terminfo.c"

#define ZSV_COMMAND sheet
#include "zsv_command.h"
int zsvsheet_ui_buffer_open_file(const char *filename, const struct zsv_opts *zsv_optsp, const char *row_filter,
struct zsv_prop_handler *custom_prop_handler, const char *opts_used,
struct zsvsheet_ui_buffer **ui_buffer_stack_bottom,
struct zsvsheet_ui_buffer **ui_buffer_stack_top) {
struct zsvsheet_buffer_opts bopts = {0};
struct zsvsheet_ui_buffer_opts uibopts = {0};
uibopts.filename = filename;
uibopts.buff_opts = &bopts;
struct zsvsheet_opts zsvsheet_opts = {0};
struct zsv_opts opts = *zsv_optsp;
int err = 0;
struct zsvsheet_ui_buffer *tmp_ui_buffer = NULL;
uibopts.row_filter = row_filter;
if ((err = read_data(&tmp_ui_buffer, &uibopts, &opts, 0, 0, 0, NULL, &zsvsheet_opts, custom_prop_handler,
opts_used)) != 0 ||
!tmp_ui_buffer || !tmp_ui_buffer->buff_used_rows) {
zsvsheet_ui_buffer_delete(tmp_ui_buffer);
if (err)
return err;
return -1;
}
tmp_ui_buffer->cursor_row = 1; // first row is header
zsvsheet_ui_buffer_push(ui_buffer_stack_bottom, ui_buffer_stack_top, tmp_ui_buffer);
return 0;
}

#include "sheet/usage.c"

int ZSV_MAIN_FUNC(ZSV_COMMAND)(int argc, const char *argv[], struct zsv_opts *optsp,
Expand All @@ -164,11 +191,6 @@ int ZSV_MAIN_FUNC(ZSV_COMMAND)(int argc, const char *argv[], struct zsv_opts *op
return zsv_status_ok;
}

if (argc < 2) {
fprintf(stderr, "Please specify an input file\n");
return 1;
}

const char *locale = setlocale(LC_ALL, "C.UTF-8");
if (!locale || strstr(locale, "UTF-8") == NULL)
locale = setlocale(LC_ALL, "");
Expand All @@ -182,31 +204,33 @@ int ZSV_MAIN_FUNC(ZSV_COMMAND)(int argc, const char *argv[], struct zsv_opts *op
return 1;
}

const char *filename = argv[1];
char *find = NULL;
struct zsvsheet_ui_buffer *ui_buffers = NULL;
struct zsvsheet_ui_buffer *current_ui_buffer = NULL;
struct zsvsheet_ui_buffer *tmp_ui_buffer;
struct zsv_opts opts = *optsp;

size_t header_span = 0; // number of rows that comprise the header
struct zsvsheet_opts zsvsheet_opts = {0};
int err;
struct zsvsheet_buffer_opts bopts = {0};
tmp_ui_buffer = NULL;
struct zsvsheet_ui_buffer_opts uibopts = {0};
uibopts.buff_opts = &bopts;
if ((err = read_data(&tmp_ui_buffer, &uibopts, filename, &opts, 0, 0, 0, NULL, &zsvsheet_opts, custom_prop_handler,
opts_used)) != 0 ||
!tmp_ui_buffer || !tmp_ui_buffer->buff_used_rows) {
if (err)
perror(filename);
else
fprintf(stderr, "%s: no data found", filename);
zsvsheet_ui_buffer_delete(tmp_ui_buffer);
return -1;
{
struct zsvsheet_ui_buffer *tmp_ui_buffer;
zsvsheet_ui_buffer_new_blank(&tmp_ui_buffer);
if (!tmp_ui_buffer) {
fprintf(stderr, "Out of memory!\n");
return ENOMEM;
}
zsvsheet_ui_buffer_push(&ui_buffers, &current_ui_buffer, tmp_ui_buffer);
}

if (argc > 1) {
const char *filename = argv[1];
if ((err = zsvsheet_ui_buffer_open_file(filename, optsp, NULL, custom_prop_handler, opts_used, &ui_buffers,
&current_ui_buffer))) {
if (err > 0)
perror(filename);
else
fprintf(stderr, "%s: no data found", filename); // to do: change this to a base-buff status msg
return -1;
}
}
zsvsheet_ui_buffer_push(&ui_buffers, &current_ui_buffer, tmp_ui_buffer);

header_span = 1;
initscr();
Expand All @@ -216,7 +240,6 @@ int ZSV_MAIN_FUNC(ZSV_COMMAND)(int argc, const char *argv[], struct zsv_opts *op
struct zsvsheet_display_dimensions display_dims = get_display_dimensions(1, 1);

int zsvsheetch;
current_ui_buffer->cursor_row = 1; // first row is header
size_t rownum_col_offset = 1;
display_buffer_subtable(current_ui_buffer, rownum_col_offset, header_span, &display_dims);
char cmdbuff[256]; // subcommand buffer
Expand Down Expand Up @@ -316,18 +339,19 @@ int ZSV_MAIN_FUNC(ZSV_COMMAND)(int argc, const char *argv[], struct zsv_opts *op
: current_ui_buffer->dimensions.col_count + rownum_col_offset,
&current_ui_buffer->cursor_col, &current_ui_buffer->buff_offset.col);
break;
case zsvsheet_key_escape: // escape
tmp_ui_buffer = zsvsheet_ui_buffer_pop(&ui_buffers, &current_ui_buffer);
if (tmp_ui_buffer) {
zsvsheet_ui_buffer_delete(tmp_ui_buffer);
update_buffer = 1;
break;
case zsvsheet_key_escape: // escape
if (current_ui_buffer->prior) { // current_ui_buffer is not the base/blank buffer
if (zsvsheet_ui_buffer_pop(&ui_buffers, &current_ui_buffer, NULL)) {
update_buffer = 1;
break;
}
}
continue;
case zsvsheet_key_find_next:
if (find) {
if (!zsvsheet_handle_find_next(current_ui_buffer, filename, find, &opts, &zsvsheet_opts, header_span,
&display_dims, &update_buffer, custom_prop_handler, opts_used))
struct zsvsheet_opts zsvsheet_opts = {0};
if (!zsvsheet_handle_find_next(current_ui_buffer, find, optsp, &zsvsheet_opts, header_span, &display_dims,
&update_buffer, custom_prop_handler, opts_used))
continue;
}
break;
Expand All @@ -336,44 +360,45 @@ int ZSV_MAIN_FUNC(ZSV_COMMAND)(int argc, const char *argv[], struct zsv_opts *op
if (*cmdbuff != '\0') {
free(find);
find = strdup(cmdbuff);
if (!zsvsheet_handle_find_next(current_ui_buffer, filename, find, &opts, &zsvsheet_opts, header_span,
&display_dims, &update_buffer, custom_prop_handler, opts_used))
struct zsvsheet_opts zsvsheet_opts = {0};
if (!zsvsheet_handle_find_next(current_ui_buffer, find, optsp, &zsvsheet_opts, header_span, &display_dims,
&update_buffer, custom_prop_handler, opts_used))
continue;
}
break;
case zsvsheet_key_open_file:
case zsvsheet_key_filter:
get_subcommand("Filter", cmdbuff, sizeof(cmdbuff), (int)(display_dims.rows - display_dims.footer_span));
if (*cmdbuff != '\0') {
tmp_ui_buffer = NULL;
uibopts.row_filter = cmdbuff;
if ((err = read_data(&tmp_ui_buffer, &uibopts, filename, &opts, 0, 0, 0, NULL, // header_span, NULL,
&zsvsheet_opts, custom_prop_handler, opts_used)) != 0) {
zsvsheet_set_status(&display_dims, 1, "Unexpected error!"); // to do: better error message
zsvsheet_ui_buffer_delete(tmp_ui_buffer);
continue;
} else if (tmp_ui_buffer->buff_used_rows > 1) {
zsvsheet_ui_buffer_push(&ui_buffers, &current_ui_buffer, tmp_ui_buffer);
current_ui_buffer->cursor_row = 1;
// not sure why but using ncurses, erase() and refresh() needed for screen to properly redraw
erase();
refresh();
} else {
zsvsheet_ui_buffer_delete(tmp_ui_buffer);
get_subcommand(zsvsheetch == zsvsheet_key_filter ? "Filter" : "File to open", cmdbuff, sizeof(cmdbuff),
(int)(display_dims.rows - display_dims.footer_span));
if (*cmdbuff == '\0')
continue;

if ((err = zsvsheet_ui_buffer_open_file(zsvsheetch == zsvsheet_key_filter ? current_ui_buffer->filename : cmdbuff,
optsp, zsvsheetch == zsvsheet_key_filter ? cmdbuff : NULL,
custom_prop_handler, opts_used, &ui_buffers, &current_ui_buffer))) {
if (err > 0)
zsvsheet_set_status(&display_dims, 1, "%s: %s", current_ui_buffer->filename, strerror(err));
else if (err < 0)
zsvsheet_set_status(&display_dims, 1, "Unexpected error");
else
zsvsheet_set_status(&display_dims, 1, "Not found: %s", cmdbuff);
continue;
}
continue;
} else if (zsvsheetch == zsvsheet_key_filter && current_ui_buffer->dimensions.row_count < 2) {
zsvsheet_ui_buffer_pop(&ui_buffers, &current_ui_buffer, NULL);
zsvsheet_set_status(&display_dims, 1, "Not found: %s", cmdbuff);
}
break;
}
if (update_buffer) {
if (read_data(&current_ui_buffer, NULL, filename, &opts, current_ui_buffer->input_offset.row,
struct zsvsheet_opts zsvsheet_opts = {0};
if (read_data(&current_ui_buffer, NULL, optsp, current_ui_buffer->input_offset.row,
current_ui_buffer->input_offset.col, header_span, current_ui_buffer->dimensions.index,
&zsvsheet_opts, custom_prop_handler, opts_used)) {
zsvsheet_set_status(&display_dims, 1, "Unexpected error!"); // to do: better error message
continue;
}
}
if (current_ui_buffer->status) // filter_dimensions.row_count)
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);
}
Expand Down
28 changes: 15 additions & 13 deletions app/sheet/buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,11 @@ void zsvsheet_buffer_delete(zsvsheet_buffer_t buff) {
}
}

zsvsheet_buffer_t zsvsheet_buffer_new(size_t cols, struct zsvsheet_buffer_opts *opts,
enum zsvsheet_buffer_status *stat) {
*stat = zsvsheet_buffer_status_ok;
zsvsheet_buffer_t zsvsheet_buffer_new(size_t cols, struct zsvsheet_buffer_opts *opts, enum zsvsheet_status *stat) {
struct zsvsheet_buffer_opts bopts = {0};
if (!opts)
opts = &bopts;
*stat = zsvsheet_status_ok;
if (opts->rows == 0)
opts->rows = ZSVSHEET_BUFFER_DEFAULT_ROW_COUNT;
else if (opts->rows < 256)
Expand All @@ -73,17 +75,17 @@ zsvsheet_buffer_t zsvsheet_buffer_new(size_t cols, struct zsvsheet_buffer_opts *
if (opts->max_cell_len == 0)
opts->max_cell_len = ZSVSHEET_BUFFER_DEFAULT_MAX_CELL_LEN;
if (opts->cell_buff_len < sizeof(void *) * 2)
*stat = zsvsheet_buffer_status_error;
*stat = zsvsheet_status_error;
else {
if (!opts->no_rownum_column)
cols++;
void *data = calloc(opts->rows, cols * opts->cell_buff_len);
if (!data)
*stat = zsvsheet_buffer_status_memory;
*stat = zsvsheet_status_memory;
else {
struct zsvsheet_buffer *buff = calloc(1, sizeof(*buff));
if (!buff)
*stat = zsvsheet_buffer_status_memory;
*stat = zsvsheet_status_memory;
else {
buff->opts.rows = opts->rows;
buff->cols = cols;
Expand All @@ -101,9 +103,9 @@ zsvsheet_buffer_t zsvsheet_buffer_new(size_t cols, struct zsvsheet_buffer_opts *
#define UTF8_NOT_FIRST_CHAR(x) ((x & 0xC0) == 0x80)
#endif

enum zsvsheet_buffer_status zsvsheet_buffer_write_cell_w_len(zsvsheet_buffer_t buff, size_t row, size_t col,
const unsigned char *value, size_t len) {
enum zsvsheet_buffer_status stat = zsvsheet_buffer_status_ok;
enum zsvsheet_status zsvsheet_buffer_write_cell_w_len(zsvsheet_buffer_t buff, size_t row, size_t col,
const unsigned char *value, size_t len) {
enum zsvsheet_status stat = zsvsheet_status_ok;
size_t offset = buffer_data_offset(buff, row, col);
free_long_cell(buff, offset);
if (len < buff->opts.cell_buff_len) {
Expand All @@ -120,7 +122,7 @@ enum zsvsheet_buffer_status zsvsheet_buffer_write_cell_w_len(zsvsheet_buffer_t b
len--;
}
if (!len) // the only reason len could be 0 is if our input was not valid utf8, but check to make sure anyway
stat = zsvsheet_buffer_status_utf8;
stat = zsvsheet_status_utf8;
else {
char *value_copy = malloc(1 + len);
if (value_copy) {
Expand All @@ -129,14 +131,14 @@ enum zsvsheet_buffer_status zsvsheet_buffer_write_cell_w_len(zsvsheet_buffer_t b
set_long_cell(buff, offset, value_copy);
buff->long_cell_count++;
} else
stat = zsvsheet_buffer_status_memory;
stat = zsvsheet_status_memory;
}
}
return stat;
}

enum zsvsheet_buffer_status zsvsheet_buffer_write_cell(zsvsheet_buffer_t buff, size_t row, size_t col,
const unsigned char *value) {
enum zsvsheet_status zsvsheet_buffer_write_cell(zsvsheet_buffer_t buff, size_t row, size_t col,
const unsigned char *value) {
return zsvsheet_buffer_write_cell_w_len(buff, row, col, value, strlen((void *)value));
}

Expand Down
18 changes: 5 additions & 13 deletions app/sheet/buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,20 @@

typedef struct zsvsheet_buffer *zsvsheet_buffer_t;

enum zsvsheet_buffer_status {
zsvsheet_buffer_status_ok = 0,
zsvsheet_buffer_status_memory,
zsvsheet_buffer_status_error, // generic error
zsvsheet_buffer_status_utf8
};

struct zsvsheet_buffer_opts {
size_t cell_buff_len; // default = 16. must be >= 2 * sizeof(void *)
size_t max_cell_len; // length in bytes; defaults to 32767
size_t rows; // rows to buffer. cannot be < 256
char no_rownum_column; // reserved. TO DO: if set, omit row num column
};

zsvsheet_buffer_t zsvsheet_buffer_new(size_t cols, struct zsvsheet_buffer_opts *opts,
enum zsvsheet_buffer_status *stat);
zsvsheet_buffer_t zsvsheet_buffer_new(size_t cols, struct zsvsheet_buffer_opts *opts, enum zsvsheet_status *stat);

enum zsvsheet_buffer_status zsvsheet_buffer_write_cell(zsvsheet_buffer_t buff, size_t row, size_t col,
const unsigned char *value);
enum zsvsheet_status zsvsheet_buffer_write_cell(zsvsheet_buffer_t buff, size_t row, size_t col,
const unsigned char *value);

enum zsvsheet_buffer_status zsvsheet_buffer_write_cell_w_len(zsvsheet_buffer_t buff, size_t row, size_t col,
const unsigned char *value, size_t len);
enum zsvsheet_status zsvsheet_buffer_write_cell_w_len(zsvsheet_buffer_t buff, size_t row, size_t col,
const unsigned char *value, size_t len);

const unsigned char *zsvsheet_buffer_cell_display(zsvsheet_buffer_t buff, size_t row, size_t col);

Expand Down
2 changes: 2 additions & 0 deletions app/sheet/key-bindings.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
static enum zsvsheet_key zsvsheet_key_binding(int ch) {
if (ch == 27) // escape
return zsvsheet_key_escape;
if (ch == 'e') // edit / open
return zsvsheet_key_open_file;
if (ch == KEY_SF) // shift + down
return zsvsheet_key_move_bottom;
if (ch == KEY_SR) // shift + up
Expand Down
3 changes: 2 additions & 1 deletion app/sheet/key-bindings.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ enum zsvsheet_key {
zsvsheet_key_move_right,
zsvsheet_key_filter,
zsvsheet_key_find,
zsvsheet_key_find_next
zsvsheet_key_find_next,
zsvsheet_key_open_file
};

#endif
Loading