#include "line-editor.h" #include static void convert_offset_to_xy( struct bshell_line_ed_p *ed, unsigned long offset, unsigned long *out_x, unsigned long *out_y) { unsigned long x = 0, y = 0; unsigned int w = 0, h = 0; fx_tty_get_dimensions(ed->ed_tty, &w, &h); if (!w || !h) { w = 80; h = 25; } fx_string *prompt = line_ed_get_prompt(ed); fx_string *buffer = line_ed_get_buffer(ed); const char *s = fx_string_get_cstr(prompt); size_t len = fx_string_get_size(prompt, FX_STRLEN_CODEPOINTS); fx_wchar prev = FX_WCHAR_INVALID; for (unsigned long i = 0; i < len; i++) { fx_wchar c = fx_wchar_utf8_codepoint_decode(s); if (prev != FX_WCHAR_INVALID) { if (prev == '\n' || x + 1 >= w) { x = 0; y++; } else { x += line_ed_get_char_width(c); } } unsigned int stride = fx_wchar_utf8_codepoint_size(c); if (stride == 0) { break; } s += stride; prev = c; } s = fx_string_get_cstr(buffer); len = fx_string_get_size(buffer, FX_STRLEN_CODEPOINTS); for (unsigned long i = 0; i < offset && i < len; i++) { fx_wchar c = fx_wchar_utf8_codepoint_decode(s); if (prev != FX_WCHAR_INVALID) { if (prev == '\n' || x + 1 >= w) { x = 0; y++; } else { x += line_ed_get_char_width(c); } } unsigned int stride = fx_wchar_utf8_codepoint_size(c); if (stride == 0) { break; } s += stride; prev = c; } if (offset > len) { if (x + 1 >= w) { x = 0; y++; } else { x++; } } if (out_x) { *out_x = x; } if (out_y) { *out_y = y; } } void line_ed_get_points(struct bshell_line_ed_p *ed, struct cursor_points *out) { unsigned long cursor = line_ed_get_cursor(ed); fx_string *buffer = line_ed_get_buffer(ed); convert_offset_to_xy( ed, cursor + 1, &out->c_cursor_x, &out->c_cursor_y); convert_offset_to_xy( ed, fx_string_get_size(buffer, FX_STRLEN_CODEPOINTS), &out->c_render_limit_x, &out->c_render_limit_y); convert_offset_to_xy( ed, fx_string_get_size(buffer, FX_STRLEN_CODEPOINTS) + 1, &out->c_cursor_limit_x, &out->c_cursor_limit_y); }