diff --git a/bshell/line-ed/buffer.c b/bshell/line-ed/buffer.c index 1b46fcb..f2453bd 100644 --- a/bshell/line-ed/buffer.c +++ b/bshell/line-ed/buffer.c @@ -1,12 +1,15 @@ #include "buffer.h" + #include "line-ed.h" -const char *line_start(struct line_ed *ed, size_t y) +#include + +const fx_wchar *line_start(struct line_ed *ed, size_t y) { - const char *line = ed->l_buf; + const fx_wchar *line = ed->l_buf; for (size_t i = 0; i < y; i++) { - line += strcspn(line, "\n"); + line += fx_wstrcspn(line, L"\n"); if (*line == '\n') { line++; @@ -18,10 +21,10 @@ const char *line_start(struct line_ed *ed, size_t y) size_t line_length(struct line_ed *ed, size_t y) { - const char *line = ed->l_buf; + const fx_wchar *line = ed->l_buf; for (size_t i = 0; i < y; i++) { - line += strcspn(line, "\n"); + line += fx_wstrcspn(line, L"\n"); if (*line == '\n') { line++; } @@ -31,7 +34,7 @@ size_t line_length(struct line_ed *ed, size_t y) return 0; } - size_t len = strcspn(line, "\n"); + size_t len = fx_wstrcspn(line, L"\n"); if (line[len] == '\n') { len++; } diff --git a/bshell/line-ed/buffer.h b/bshell/line-ed/buffer.h index d70956e..a77af4c 100644 --- a/bshell/line-ed/buffer.h +++ b/bshell/line-ed/buffer.h @@ -1,13 +1,14 @@ #ifndef LINE_ED_BUFFER_H_ #define LINE_ED_BUFFER_H_ +#include #include struct line_ed; /* returns a pointer to the start of the line based on the given `y` * coordinate */ -extern const char *line_start(struct line_ed *ed, size_t y); +extern const fx_wchar *line_start(struct line_ed *ed, size_t y); /* returns the length of the line based on the given `y` coordinate. * for any line other than the last line in the buffer, this length * INCLUDES the trailing linefeed. */ diff --git a/bshell/line-ed/history.c b/bshell/line-ed/history.c index 5caa728..eba4660 100644 --- a/bshell/line-ed/history.c +++ b/bshell/line-ed/history.c @@ -19,29 +19,39 @@ void alloc_empty_history_entry(struct line_ed *ed) void save_buf_to_history(struct line_ed *ed) { - fx_string *cur - = (fx_string *)fx_array_get(ed->l_history, ed->l_history_pos); - fx_string_replace_all(cur, ed->l_buf); + fx_string *cur = (fx_string *)fx_array_get( + ed->l_history, + ed->l_history_pos); + fx_string_clear(cur); + fx_string_append_wstr(cur, ed->l_buf); } void append_buf_to_history(struct line_ed *ed) { - fx_string *cur - = (fx_string *)fx_array_get(ed->l_history, ed->l_history_pos); + fx_string *cur = (fx_string *)fx_array_get( + ed->l_history, + ed->l_history_pos); char s[] = {'\n', 0}; fx_string_append_cstr(cur, s); - fx_string_append_cstr(cur, ed->l_buf); + fx_string_append_wstr(cur, ed->l_buf); } void load_buf_from_history(struct line_ed *ed) { - fx_string *cur - = (fx_string *)fx_array_at(ed->l_history, ed->l_history_pos); - size_t len - = MIN((size_t)(ed->l_buf_end - ed->l_buf - 1), - fx_string_get_size(cur, FX_STRLEN_NORMAL)); + fx_string *cur = (fx_string *)fx_array_at( + ed->l_history, + ed->l_history_pos); + size_t len = MIN( + (size_t)(ed->l_buf_end - ed->l_buf - 1), + fx_string_get_size(cur, FX_STRLEN_CODEPOINTS)); + + const char *src = fx_string_get_cstr(cur); + for (size_t i = 0; i < len; i++) { + fx_wchar ch_src = fx_wchar_utf8_codepoint_decode(src); + ed->l_buf[i] = ch_src; + src += fx_wchar_utf8_codepoint_stride(src); + } - memcpy(ed->l_buf, fx_string_get_cstr(cur), len); ed->l_buf[len] = '\0'; unsigned int x = 0, y = 0; diff --git a/bshell/line-ed/input.c b/bshell/line-ed/input.c index 5dbae94..70b0f8d 100644 --- a/bshell/line-ed/input.c +++ b/bshell/line-ed/input.c @@ -8,7 +8,7 @@ #include -void put_char(struct line_ed *ed, char c) +void put_char(struct line_ed *ed, fx_wchar c) { if (ed->l_buf_ptr > ed->l_line_end + 1) { return; @@ -21,8 +21,8 @@ void put_char(struct line_ed *ed, char c) size_t prev_cursor = ed->l_buf_ptr - ed->l_buf; - char *dest = ed->l_buf_ptr; - size_t len = ed->l_line_end - ed->l_buf_ptr + 1; + fx_wchar *dest = ed->l_buf_ptr; + size_t len = (ed->l_line_end - ed->l_buf_ptr + 1) * sizeof *dest; if (dest < ed->l_line_end) { memmove(dest + 1, dest, len); @@ -55,8 +55,8 @@ static void backspace_simple(struct line_ed *ed) size_t prev_cursor = ed->l_buf_ptr - ed->l_buf; - char *dest = ed->l_buf_ptr; - size_t len = ed->l_line_end - ed->l_buf_ptr + 1; + fx_wchar *dest = ed->l_buf_ptr; + size_t len = (ed->l_line_end - ed->l_buf_ptr + 1) * sizeof *dest; memmove(dest - 1, dest, len); ed->l_cursor_x--; @@ -78,8 +78,8 @@ static void backspace_nl(struct line_ed *ed) .r_prev_line_len = prev_line_len, }; - char *dest = ed->l_buf_ptr; - size_t len = ed->l_line_end - ed->l_buf_ptr + 1; + fx_wchar *dest = ed->l_buf_ptr; + size_t len = (ed->l_line_end - ed->l_buf_ptr + 1) * sizeof *dest; memmove(dest - 1, dest, len); ed->l_cursor_x = prev_line_len - 1; @@ -112,7 +112,7 @@ void backspace(struct line_ed *ed) void cursor_left(struct line_ed *ed) { if (ed->l_cursor_x != 0) { - //fputs("\010", stdout); + // fputs("\010", stdout); fx_tty_move_cursor_x(ed->l_tty, FX_TTY_POS_CURSOR, -1); fflush(stdout); ed->l_cursor_x--; @@ -120,7 +120,8 @@ void cursor_left(struct line_ed *ed) return; } - if (ed->l_cursor_y <= ed->l_continuations || ed->l_buf_ptr <= ed->l_buf) { + if (ed->l_cursor_y <= ed->l_continuations + || ed->l_buf_ptr <= ed->l_buf) { return; } @@ -134,9 +135,12 @@ void cursor_left(struct line_ed *ed) size_t len = line_length(ed, ed->l_cursor_y); ed->l_cursor_x = len - 1; - //printf("\033[A\033[%dG", len + prompt_len); + // printf("\033[A\033[%dG", len + prompt_len); fx_tty_move_cursor_y(ed->l_tty, FX_TTY_POS_CURSOR, -1); - fx_tty_move_cursor_x(ed->l_tty, FX_TTY_POS_START, (int)(len + prompt_len)); + fx_tty_move_cursor_x( + ed->l_tty, + FX_TTY_POS_START, + (int)(len + prompt_len)); fflush(stdout); } @@ -150,7 +154,7 @@ void cursor_right(struct line_ed *ed) if (*ed->l_buf_ptr != '\n') { ed->l_cursor_x++; ed->l_buf_ptr++; - //fputs("\033[C", stdout); + // fputs("\033[C", stdout); fx_tty_move_cursor_x(ed->l_tty, FX_TTY_POS_CURSOR, 1); fflush(stdout); return; @@ -164,7 +168,7 @@ void cursor_right(struct line_ed *ed) ed->l_cursor_x = 0; ed->l_buf_ptr++; - //printf("\033[B\033[G"); + // printf("\033[B\033[G"); fx_tty_move_cursor_y(ed->l_tty, FX_TTY_POS_CURSOR, 1); fx_tty_move_cursor_x(ed->l_tty, FX_TTY_POS_START, 0); fflush(stdout); @@ -177,13 +181,18 @@ void arrow_up(struct line_ed *ed) } if (ed->l_cursor_y > 0) { - //printf("\033[%uA", ed->l_cursor_y); - fx_tty_move_cursor_y(ed->l_tty, FX_TTY_POS_CURSOR, (long long)ed->l_cursor_y); + // printf("\033[%uA", ed->l_cursor_y); + fx_tty_move_cursor_y( + ed->l_tty, + FX_TTY_POS_CURSOR, + (long long)ed->l_cursor_y); } - //printf("\033[%zuG\033[J", prompt_length(ed, PROMPT_MAIN) + 1); + // printf("\033[%zuG\033[J", prompt_length(ed, PROMPT_MAIN) + 1); fx_tty_move_cursor_x( - ed->l_tty, FX_TTY_POS_START, (long long)prompt_length(ed, PROMPT_MAIN)); + ed->l_tty, + FX_TTY_POS_START, + (long long)prompt_length(ed, PROMPT_MAIN)); fx_tty_clear(ed->l_tty, FX_TTY_CLEAR_SCREEN | FX_TTY_CLEAR_FROM_CURSOR); save_buf_to_history(ed); @@ -201,13 +210,18 @@ void arrow_down(struct line_ed *ed) } if (ed->l_cursor_y > 0) { - //printf("\033[%uA", ed->l_cursor_y); - fx_tty_move_cursor_y(ed->l_tty, FX_TTY_POS_CURSOR, (int)ed->l_cursor_y); + // printf("\033[%uA", ed->l_cursor_y); + fx_tty_move_cursor_y( + ed->l_tty, + FX_TTY_POS_CURSOR, + (int)ed->l_cursor_y); } - //printf("\033[%zuG\033[J", prompt_length(ed, PROMPT_MAIN) + 1); + // printf("\033[%zuG\033[J", prompt_length(ed, PROMPT_MAIN) + 1); fx_tty_move_cursor_x( - ed->l_tty, FX_TTY_POS_START, prompt_length(ed, PROMPT_MAIN) + 1); + ed->l_tty, + FX_TTY_POS_START, + prompt_length(ed, PROMPT_MAIN) + 1); save_buf_to_history(ed); ed->l_history_pos++; diff --git a/bshell/line-ed/input.h b/bshell/line-ed/input.h index bbecf93..26b8255 100644 --- a/bshell/line-ed/input.h +++ b/bshell/line-ed/input.h @@ -1,9 +1,11 @@ #ifndef LINE_ED_INPUT_H_ #define LINE_ED_INPUT_H_ +#include + struct line_ed; -extern void put_char(struct line_ed *ed, char c); +extern void put_char(struct line_ed *ed, fx_wchar c); extern void backspace(struct line_ed *ed); extern void cursor_left(struct line_ed *ed); extern void cursor_right(struct line_ed *ed); diff --git a/bshell/line-ed/line-ed.c b/bshell/line-ed/line-ed.c index 2bf09a1..6d0d5de 100644 --- a/bshell/line-ed/line-ed.c +++ b/bshell/line-ed/line-ed.c @@ -6,6 +6,7 @@ #include "prompt.h" #include +#include #include #include #include @@ -98,13 +99,13 @@ static void clear_buffer(struct line_ed *ed) ed->l_continuations = 0; } -static void convert_continuation_feeds(char *s, size_t max) +static void convert_continuation_feeds(fx_wchar *s, size_t max) { - char *end = s + max; - size_t len = strlen(s); + fx_wchar *end = s + max; + size_t len = fx_wstrlen(s); while (1) { - size_t r = strcspn(s, "\\"); + size_t r = fx_wstrcspn(s, L"\\"); if (s + r > end) { break; } @@ -126,13 +127,13 @@ static void convert_continuation_feeds(char *s, size_t max) } } -static void remove_continuation_feeds(char *s, size_t max) +static void remove_continuation_feeds(fx_wchar *s, size_t max) { - char *end = s + max; - size_t len = strlen(s); + fx_wchar *end = s + max; + size_t len = fx_wstrlen(s); while (1) { - size_t r = strcspn(s, "\\"); + size_t r = fx_wstrcspn(s, L"\\"); if (s + r > end) { break; } @@ -156,9 +157,9 @@ static void remove_continuation_feeds(char *s, size_t max) static bool input_is_empty(struct line_ed *ed) { - const char *p = ed->l_buf; + const fx_wchar *p = ed->l_buf; while (p < ed->l_line_end) { - if (!isspace(*p)) { + if (!fx_wchar_is_space(*p)) { return false; } } @@ -188,7 +189,7 @@ size_t line_ed_readline(struct line_ed *ed, fx_stringstream *out) fputc('\r', stdout); } - fputc(ed->l_buf[i], stdout); + fx_stream_write_char(fx_stdout, ed->l_buf[i]); } fflush(stdout); @@ -257,7 +258,7 @@ size_t line_ed_readline(struct line_ed *ed, fx_stringstream *out) arrow_down(ed); break; default: - if (iswgraph(key) || key == ' ') { + if (fx_wchar_is_graph(key) || key == ' ') { put_char(ed, key); } break; @@ -278,7 +279,7 @@ size_t line_ed_readline(struct line_ed *ed, fx_stringstream *out) ed->l_history_pos = fx_array_size(ed->l_history) - 1; const char *last = last_history_line(ed); - if (!last || strcmp(last, ed->l_buf) != 0) { + if (!last || fx_wastrcmp(last, ed->l_buf) != 0) { save_buf_to_history(ed); } } @@ -294,7 +295,7 @@ size_t line_ed_readline(struct line_ed *ed, fx_stringstream *out) convert_continuation_feeds(ed->l_buf, sz); } - fx_stream_write_cstr(out, ed->l_buf, NULL); + fx_stream_write_wstr(out, ed->l_buf, NULL); fx_stream_write_char(out, '\n'); return sz; diff --git a/bshell/line-ed/line-ed.h b/bshell/line-ed/line-ed.h index f681a1b..68daeb1 100644 --- a/bshell/line-ed/line-ed.h +++ b/bshell/line-ed/line-ed.h @@ -49,9 +49,9 @@ struct line_ed { /* input buffer, pointer to the buffer cell that corresponds to * the current cursor position, and pointer to the byte AFTER the last * usable byte in the buffer */ - char *l_buf, *l_buf_ptr, *l_buf_end; + fx_wchar *l_buf, *l_buf_ptr, *l_buf_end; /* pointer to the byte AFTER the last byte of the user's input */ - char *l_line_end; + fx_wchar *l_line_end; /* 2-dimensional coordinates of the current cursor position. * this does NOT include any prompts that are visible on the terminal */ size_t l_cursor_x, l_cursor_y; diff --git a/bshell/line-ed/refresh.c b/bshell/line-ed/refresh.c index 7167e28..a455963 100644 --- a/bshell/line-ed/refresh.c +++ b/bshell/line-ed/refresh.c @@ -4,6 +4,7 @@ #include "cursor.h" #include "line-ed.h" +#include #include #include #include @@ -15,19 +16,19 @@ * the (x, y) coordinates provided should be the data coordinates of the * first character in `s`. */ -void print_text(struct line_ed *ed, size_t x, size_t y, const char *s) +void print_text(struct line_ed *ed, size_t x, size_t y, const fx_wchar *s) { fx_tty *tty = ed->l_tty; for (size_t i = 0; s[i] != '\n' && s[i] != '\0'; i++) { - fputc(s[i], stdout); + fx_stream_write_char(fx_stdout, s[i]); } } void print_buffer(struct line_ed *ed) { - const char *line_buf = ed->l_buf; - size_t line_len = strcspn(line_buf, "\n"); + const fx_wchar *line_buf = ed->l_buf; + size_t line_len = fx_wstrcspn(line_buf, L"\n"); unsigned int y = 0; @@ -44,7 +45,7 @@ void print_buffer(struct line_ed *ed) } y++; - line_len = strcspn(line_buf, "\n"); + line_len = fx_wstrcspn(line_buf, L"\n"); fputc('\r', stdout); fputc('\n', stdout); @@ -74,8 +75,8 @@ void print_buffer(struct line_ed *ed) void put_refresh(struct line_ed *ed, struct refresh_state *state) { /* get the data for the line that is being refreshed */ - const char *line_buf = line_start(ed, ed->l_cursor_y); - size_t line_len = strcspn(line_buf, "\n"); + const fx_wchar *line_buf = line_start(ed, ed->l_cursor_y); + size_t line_len = fx_wstrcspn(line_buf, L"\n"); /* the index of the first char in line_buf that needs to be reprinted */ size_t start_x = state->r_prev_cursor_x; @@ -128,8 +129,8 @@ void backspace_nl_refresh(struct line_ed *ed, struct refresh_state *state) /* get the data for the line that is being refreshed. * relative to where the cursor was before the linefeed was deleted, * this is the PREVIOUS line. */ - const char *line_buf = line_start(ed, ed->l_cursor_y); - size_t line_len = strcspn(line_buf, "\n"); + const fx_wchar *line_buf = line_start(ed, ed->l_cursor_y); + size_t line_len = fx_wstrcspn(line_buf, L"\n"); /* the index of the first char in line_buf that needs to be reprinted. * subtract one to account for the linefeed that has since been deleted. @@ -188,7 +189,7 @@ void backspace_nl_refresh(struct line_ed *ed, struct refresh_state *state) line_buf + start_x); line_buf += line_len + 1; - line_len = strcspn(line_buf, "\n"); + line_len = fx_wstrcspn(line_buf, L"\n"); start_x = 0; if (*line_buf == '\0') { @@ -218,8 +219,8 @@ void backspace_nl_refresh(struct line_ed *ed, struct refresh_state *state) void backspace_simple_refresh(struct line_ed *ed, struct refresh_state *state) { /* get the data for the line that is being refreshed */ - const char *line_buf = line_start(ed, ed->l_cursor_y); - size_t line_len = strcspn(line_buf, "\n"); + const fx_wchar *line_buf = line_start(ed, ed->l_cursor_y); + size_t line_len = fx_wstrcspn(line_buf, L"\n"); /* the index of the first char in line_buf that needs to be reprinted */ size_t start_x = ed->l_cursor_x; diff --git a/bshell/line-ed/refresh.h b/bshell/line-ed/refresh.h index 94ee3e5..df380c5 100644 --- a/bshell/line-ed/refresh.h +++ b/bshell/line-ed/refresh.h @@ -1,6 +1,7 @@ #ifndef LINE_ED_REFRESH_H_ #define LINE_ED_REFRESH_H_ +#include #include struct line_ed; @@ -15,7 +16,11 @@ struct refresh_state { size_t r_prev_line_len; }; -extern void print_text(struct line_ed *ed, size_t x, size_t y, const char *s); +extern void print_text( + struct line_ed *ed, + size_t x, + size_t y, + const fx_wchar *s); extern void print_buffer(struct line_ed *ed); extern void put_refresh(struct line_ed *ed, struct refresh_state *state); extern void backspace_nl_refresh(