line-ed: add unicode support
This commit is contained in:
@@ -1,12 +1,15 @@
|
|||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
|
|
||||||
#include "line-ed.h"
|
#include "line-ed.h"
|
||||||
|
|
||||||
const char *line_start(struct line_ed *ed, size_t y)
|
#include <fx/cstr.h>
|
||||||
|
|
||||||
|
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++) {
|
for (size_t i = 0; i < y; i++) {
|
||||||
line += strcspn(line, "\n");
|
line += fx_wstrcspn(line, L"\n");
|
||||||
|
|
||||||
if (*line == '\n') {
|
if (*line == '\n') {
|
||||||
line++;
|
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)
|
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++) {
|
for (size_t i = 0; i < y; i++) {
|
||||||
line += strcspn(line, "\n");
|
line += fx_wstrcspn(line, L"\n");
|
||||||
if (*line == '\n') {
|
if (*line == '\n') {
|
||||||
line++;
|
line++;
|
||||||
}
|
}
|
||||||
@@ -31,7 +34,7 @@ size_t line_length(struct line_ed *ed, size_t y)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t len = strcspn(line, "\n");
|
size_t len = fx_wstrcspn(line, L"\n");
|
||||||
if (line[len] == '\n') {
|
if (line[len] == '\n') {
|
||||||
len++;
|
len++;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
#ifndef LINE_ED_BUFFER_H_
|
#ifndef LINE_ED_BUFFER_H_
|
||||||
#define LINE_ED_BUFFER_H_
|
#define LINE_ED_BUFFER_H_
|
||||||
|
|
||||||
|
#include <fx/encoding.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
struct line_ed;
|
struct line_ed;
|
||||||
|
|
||||||
/* returns a pointer to the start of the line based on the given `y`
|
/* returns a pointer to the start of the line based on the given `y`
|
||||||
* coordinate */
|
* 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.
|
/* 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
|
* for any line other than the last line in the buffer, this length
|
||||||
* INCLUDES the trailing linefeed. */
|
* INCLUDES the trailing linefeed. */
|
||||||
|
|||||||
+22
-12
@@ -19,29 +19,39 @@ void alloc_empty_history_entry(struct line_ed *ed)
|
|||||||
|
|
||||||
void save_buf_to_history(struct line_ed *ed)
|
void save_buf_to_history(struct line_ed *ed)
|
||||||
{
|
{
|
||||||
fx_string *cur
|
fx_string *cur = (fx_string *)fx_array_get(
|
||||||
= (fx_string *)fx_array_get(ed->l_history, ed->l_history_pos);
|
ed->l_history,
|
||||||
fx_string_replace_all(cur, ed->l_buf);
|
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)
|
void append_buf_to_history(struct line_ed *ed)
|
||||||
{
|
{
|
||||||
fx_string *cur
|
fx_string *cur = (fx_string *)fx_array_get(
|
||||||
= (fx_string *)fx_array_get(ed->l_history, ed->l_history_pos);
|
ed->l_history,
|
||||||
|
ed->l_history_pos);
|
||||||
char s[] = {'\n', 0};
|
char s[] = {'\n', 0};
|
||||||
fx_string_append_cstr(cur, s);
|
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)
|
void load_buf_from_history(struct line_ed *ed)
|
||||||
{
|
{
|
||||||
fx_string *cur
|
fx_string *cur = (fx_string *)fx_array_at(
|
||||||
= (fx_string *)fx_array_at(ed->l_history, ed->l_history_pos);
|
ed->l_history,
|
||||||
size_t len
|
ed->l_history_pos);
|
||||||
= MIN((size_t)(ed->l_buf_end - ed->l_buf - 1),
|
size_t len = MIN(
|
||||||
fx_string_get_size(cur, FX_STRLEN_NORMAL));
|
(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';
|
ed->l_buf[len] = '\0';
|
||||||
|
|
||||||
unsigned int x = 0, y = 0;
|
unsigned int x = 0, y = 0;
|
||||||
|
|||||||
+35
-21
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
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) {
|
if (ed->l_buf_ptr > ed->l_line_end + 1) {
|
||||||
return;
|
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;
|
size_t prev_cursor = ed->l_buf_ptr - ed->l_buf;
|
||||||
|
|
||||||
char *dest = ed->l_buf_ptr;
|
fx_wchar *dest = ed->l_buf_ptr;
|
||||||
size_t len = ed->l_line_end - ed->l_buf_ptr + 1;
|
size_t len = (ed->l_line_end - ed->l_buf_ptr + 1) * sizeof *dest;
|
||||||
|
|
||||||
if (dest < ed->l_line_end) {
|
if (dest < ed->l_line_end) {
|
||||||
memmove(dest + 1, dest, len);
|
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;
|
size_t prev_cursor = ed->l_buf_ptr - ed->l_buf;
|
||||||
|
|
||||||
char *dest = ed->l_buf_ptr;
|
fx_wchar *dest = ed->l_buf_ptr;
|
||||||
size_t len = ed->l_line_end - ed->l_buf_ptr + 1;
|
size_t len = (ed->l_line_end - ed->l_buf_ptr + 1) * sizeof *dest;
|
||||||
memmove(dest - 1, dest, len);
|
memmove(dest - 1, dest, len);
|
||||||
|
|
||||||
ed->l_cursor_x--;
|
ed->l_cursor_x--;
|
||||||
@@ -78,8 +78,8 @@ static void backspace_nl(struct line_ed *ed)
|
|||||||
.r_prev_line_len = prev_line_len,
|
.r_prev_line_len = prev_line_len,
|
||||||
};
|
};
|
||||||
|
|
||||||
char *dest = ed->l_buf_ptr;
|
fx_wchar *dest = ed->l_buf_ptr;
|
||||||
size_t len = ed->l_line_end - ed->l_buf_ptr + 1;
|
size_t len = (ed->l_line_end - ed->l_buf_ptr + 1) * sizeof *dest;
|
||||||
memmove(dest - 1, dest, len);
|
memmove(dest - 1, dest, len);
|
||||||
|
|
||||||
ed->l_cursor_x = prev_line_len - 1;
|
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)
|
void cursor_left(struct line_ed *ed)
|
||||||
{
|
{
|
||||||
if (ed->l_cursor_x != 0) {
|
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);
|
fx_tty_move_cursor_x(ed->l_tty, FX_TTY_POS_CURSOR, -1);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
ed->l_cursor_x--;
|
ed->l_cursor_x--;
|
||||||
@@ -120,7 +120,8 @@ void cursor_left(struct line_ed *ed)
|
|||||||
return;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,9 +135,12 @@ void cursor_left(struct line_ed *ed)
|
|||||||
size_t len = line_length(ed, ed->l_cursor_y);
|
size_t len = line_length(ed, ed->l_cursor_y);
|
||||||
ed->l_cursor_x = len - 1;
|
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_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);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
@@ -150,7 +154,7 @@ void cursor_right(struct line_ed *ed)
|
|||||||
if (*ed->l_buf_ptr != '\n') {
|
if (*ed->l_buf_ptr != '\n') {
|
||||||
ed->l_cursor_x++;
|
ed->l_cursor_x++;
|
||||||
ed->l_buf_ptr++;
|
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);
|
fx_tty_move_cursor_x(ed->l_tty, FX_TTY_POS_CURSOR, 1);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
return;
|
return;
|
||||||
@@ -164,7 +168,7 @@ void cursor_right(struct line_ed *ed)
|
|||||||
ed->l_cursor_x = 0;
|
ed->l_cursor_x = 0;
|
||||||
ed->l_buf_ptr++;
|
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_y(ed->l_tty, FX_TTY_POS_CURSOR, 1);
|
||||||
fx_tty_move_cursor_x(ed->l_tty, FX_TTY_POS_START, 0);
|
fx_tty_move_cursor_x(ed->l_tty, FX_TTY_POS_START, 0);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
@@ -177,13 +181,18 @@ void arrow_up(struct line_ed *ed)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ed->l_cursor_y > 0) {
|
if (ed->l_cursor_y > 0) {
|
||||||
//printf("\033[%uA", 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);
|
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(
|
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);
|
fx_tty_clear(ed->l_tty, FX_TTY_CLEAR_SCREEN | FX_TTY_CLEAR_FROM_CURSOR);
|
||||||
|
|
||||||
save_buf_to_history(ed);
|
save_buf_to_history(ed);
|
||||||
@@ -201,13 +210,18 @@ void arrow_down(struct line_ed *ed)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ed->l_cursor_y > 0) {
|
if (ed->l_cursor_y > 0) {
|
||||||
//printf("\033[%uA", 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);
|
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(
|
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);
|
save_buf_to_history(ed);
|
||||||
ed->l_history_pos++;
|
ed->l_history_pos++;
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
#ifndef LINE_ED_INPUT_H_
|
#ifndef LINE_ED_INPUT_H_
|
||||||
#define LINE_ED_INPUT_H_
|
#define LINE_ED_INPUT_H_
|
||||||
|
|
||||||
|
#include <fx/encoding.h>
|
||||||
|
|
||||||
struct line_ed;
|
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 backspace(struct line_ed *ed);
|
||||||
extern void cursor_left(struct line_ed *ed);
|
extern void cursor_left(struct line_ed *ed);
|
||||||
extern void cursor_right(struct line_ed *ed);
|
extern void cursor_right(struct line_ed *ed);
|
||||||
|
|||||||
+15
-14
@@ -6,6 +6,7 @@
|
|||||||
#include "prompt.h"
|
#include "prompt.h"
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <fx/cstr.h>
|
||||||
#include <fx/term/tty.h>
|
#include <fx/term/tty.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@@ -98,13 +99,13 @@ static void clear_buffer(struct line_ed *ed)
|
|||||||
ed->l_continuations = 0;
|
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;
|
fx_wchar *end = s + max;
|
||||||
size_t len = strlen(s);
|
size_t len = fx_wstrlen(s);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
size_t r = strcspn(s, "\\");
|
size_t r = fx_wstrcspn(s, L"\\");
|
||||||
if (s + r > end) {
|
if (s + r > end) {
|
||||||
break;
|
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;
|
fx_wchar *end = s + max;
|
||||||
size_t len = strlen(s);
|
size_t len = fx_wstrlen(s);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
size_t r = strcspn(s, "\\");
|
size_t r = fx_wstrcspn(s, L"\\");
|
||||||
if (s + r > end) {
|
if (s + r > end) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -156,9 +157,9 @@ static void remove_continuation_feeds(char *s, size_t max)
|
|||||||
|
|
||||||
static bool input_is_empty(struct line_ed *ed)
|
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) {
|
while (p < ed->l_line_end) {
|
||||||
if (!isspace(*p)) {
|
if (!fx_wchar_is_space(*p)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -188,7 +189,7 @@ size_t line_ed_readline(struct line_ed *ed, fx_stringstream *out)
|
|||||||
fputc('\r', stdout);
|
fputc('\r', stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
fputc(ed->l_buf[i], stdout);
|
fx_stream_write_char(fx_stdout, ed->l_buf[i]);
|
||||||
}
|
}
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
|
||||||
@@ -257,7 +258,7 @@ size_t line_ed_readline(struct line_ed *ed, fx_stringstream *out)
|
|||||||
arrow_down(ed);
|
arrow_down(ed);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (iswgraph(key) || key == ' ') {
|
if (fx_wchar_is_graph(key) || key == ' ') {
|
||||||
put_char(ed, key);
|
put_char(ed, key);
|
||||||
}
|
}
|
||||||
break;
|
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;
|
ed->l_history_pos = fx_array_size(ed->l_history) - 1;
|
||||||
|
|
||||||
const char *last = last_history_line(ed);
|
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);
|
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);
|
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');
|
fx_stream_write_char(out, '\n');
|
||||||
|
|
||||||
return sz;
|
return sz;
|
||||||
|
|||||||
@@ -49,9 +49,9 @@ struct line_ed {
|
|||||||
/* input buffer, pointer to the buffer cell that corresponds to
|
/* input buffer, pointer to the buffer cell that corresponds to
|
||||||
* the current cursor position, and pointer to the byte AFTER the last
|
* the current cursor position, and pointer to the byte AFTER the last
|
||||||
* usable byte in the buffer */
|
* 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 */
|
/* 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.
|
/* 2-dimensional coordinates of the current cursor position.
|
||||||
* this does NOT include any prompts that are visible on the terminal */
|
* this does NOT include any prompts that are visible on the terminal */
|
||||||
size_t l_cursor_x, l_cursor_y;
|
size_t l_cursor_x, l_cursor_y;
|
||||||
|
|||||||
+13
-12
@@ -4,6 +4,7 @@
|
|||||||
#include "cursor.h"
|
#include "cursor.h"
|
||||||
#include "line-ed.h"
|
#include "line-ed.h"
|
||||||
|
|
||||||
|
#include <fx/cstr.h>
|
||||||
#include <fx/term/tty.h>
|
#include <fx/term/tty.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@@ -15,19 +16,19 @@
|
|||||||
* the (x, y) coordinates provided should be the data coordinates of the
|
* the (x, y) coordinates provided should be the data coordinates of the
|
||||||
* first character in `s`.
|
* 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;
|
fx_tty *tty = ed->l_tty;
|
||||||
|
|
||||||
for (size_t i = 0; s[i] != '\n' && s[i] != '\0'; i++) {
|
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)
|
void print_buffer(struct line_ed *ed)
|
||||||
{
|
{
|
||||||
const char *line_buf = ed->l_buf;
|
const fx_wchar *line_buf = ed->l_buf;
|
||||||
size_t line_len = strcspn(line_buf, "\n");
|
size_t line_len = fx_wstrcspn(line_buf, L"\n");
|
||||||
|
|
||||||
unsigned int y = 0;
|
unsigned int y = 0;
|
||||||
|
|
||||||
@@ -44,7 +45,7 @@ void print_buffer(struct line_ed *ed)
|
|||||||
}
|
}
|
||||||
|
|
||||||
y++;
|
y++;
|
||||||
line_len = strcspn(line_buf, "\n");
|
line_len = fx_wstrcspn(line_buf, L"\n");
|
||||||
|
|
||||||
fputc('\r', stdout);
|
fputc('\r', stdout);
|
||||||
fputc('\n', 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)
|
void put_refresh(struct line_ed *ed, struct refresh_state *state)
|
||||||
{
|
{
|
||||||
/* get the data for the line that is being refreshed */
|
/* get the data for the line that is being refreshed */
|
||||||
const char *line_buf = line_start(ed, ed->l_cursor_y);
|
const fx_wchar *line_buf = line_start(ed, ed->l_cursor_y);
|
||||||
size_t line_len = strcspn(line_buf, "\n");
|
size_t line_len = fx_wstrcspn(line_buf, L"\n");
|
||||||
|
|
||||||
/* the index of the first char in line_buf that needs to be reprinted */
|
/* the index of the first char in line_buf that needs to be reprinted */
|
||||||
size_t start_x = state->r_prev_cursor_x;
|
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.
|
/* get the data for the line that is being refreshed.
|
||||||
* relative to where the cursor was before the linefeed was deleted,
|
* relative to where the cursor was before the linefeed was deleted,
|
||||||
* this is the PREVIOUS line. */
|
* this is the PREVIOUS line. */
|
||||||
const char *line_buf = line_start(ed, ed->l_cursor_y);
|
const fx_wchar *line_buf = line_start(ed, ed->l_cursor_y);
|
||||||
size_t line_len = strcspn(line_buf, "\n");
|
size_t line_len = fx_wstrcspn(line_buf, L"\n");
|
||||||
|
|
||||||
/* the index of the first char in line_buf that needs to be reprinted.
|
/* 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.
|
* 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 + start_x);
|
||||||
|
|
||||||
line_buf += line_len + 1;
|
line_buf += line_len + 1;
|
||||||
line_len = strcspn(line_buf, "\n");
|
line_len = fx_wstrcspn(line_buf, L"\n");
|
||||||
start_x = 0;
|
start_x = 0;
|
||||||
|
|
||||||
if (*line_buf == '\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)
|
void backspace_simple_refresh(struct line_ed *ed, struct refresh_state *state)
|
||||||
{
|
{
|
||||||
/* get the data for the line that is being refreshed */
|
/* get the data for the line that is being refreshed */
|
||||||
const char *line_buf = line_start(ed, ed->l_cursor_y);
|
const fx_wchar *line_buf = line_start(ed, ed->l_cursor_y);
|
||||||
size_t line_len = strcspn(line_buf, "\n");
|
size_t line_len = fx_wstrcspn(line_buf, L"\n");
|
||||||
|
|
||||||
/* the index of the first char in line_buf that needs to be reprinted */
|
/* the index of the first char in line_buf that needs to be reprinted */
|
||||||
size_t start_x = ed->l_cursor_x;
|
size_t start_x = ed->l_cursor_x;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#ifndef LINE_ED_REFRESH_H_
|
#ifndef LINE_ED_REFRESH_H_
|
||||||
#define LINE_ED_REFRESH_H_
|
#define LINE_ED_REFRESH_H_
|
||||||
|
|
||||||
|
#include <fx/encoding.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
struct line_ed;
|
struct line_ed;
|
||||||
@@ -15,7 +16,11 @@ struct refresh_state {
|
|||||||
size_t r_prev_line_len;
|
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 print_buffer(struct line_ed *ed);
|
||||||
extern void put_refresh(struct line_ed *ed, struct refresh_state *state);
|
extern void put_refresh(struct line_ed *ed, struct refresh_state *state);
|
||||||
extern void backspace_nl_refresh(
|
extern void backspace_nl_refresh(
|
||||||
|
|||||||
Reference in New Issue
Block a user