void ui_puts(uint8_t *str) { uint8_t *p = str; uint8_t c; while ((c = *p)) { if (c < 0x20) { abort(); } size_t clen = (size_t)mb_ptr2len(p); ui_call_put((String){ .data = (char *)p, .size = clen }); col++; if (mb_ptr2cells(p) > 1) { // double cell character, blank the next cell ui_call_put((String)STRING_INIT); col++; } if (utf_ambiguous_width(utf_ptr2char(p))) { pending_cursor_update = true; } if (col >= width) { ui_linefeed(); } p += clen; if (p_wd) { // 'writedelay': flush & delay each time. ui_flush(); uint64_t wd = (uint64_t)labs(p_wd); os_delay(wd, false); } }
static void remote_ui_raw_line(UI *ui, Integer grid, Integer row, Integer startcol, Integer endcol, Integer clearcol, Integer clearattr, Boolean wrap, const schar_T *chunk, const sattr_T *attrs) { UIData *data = ui->data; if (ui->ui_ext[kUILinegrid]) { Array args = ARRAY_DICT_INIT; ADD(args, INTEGER_OBJ(grid)); ADD(args, INTEGER_OBJ(row)); ADD(args, INTEGER_OBJ(startcol)); Array cells = ARRAY_DICT_INIT; int repeat = 0; size_t ncells = (size_t)(endcol-startcol); int last_hl = -1; for (size_t i = 0; i < ncells; i++) { repeat++; if (i == ncells-1 || attrs[i] != attrs[i+1] || STRCMP(chunk[i], chunk[i+1])) { Array cell = ARRAY_DICT_INIT; ADD(cell, STRING_OBJ(cstr_to_string((const char *)chunk[i]))); if (attrs[i] != last_hl || repeat > 1) { ADD(cell, INTEGER_OBJ(attrs[i])); last_hl = attrs[i]; } if (repeat > 1) { ADD(cell, INTEGER_OBJ(repeat)); } ADD(cells, ARRAY_OBJ(cell)); repeat = 0; } } if (endcol < clearcol) { Array cell = ARRAY_DICT_INIT; ADD(cell, STRING_OBJ(cstr_to_string(" "))); ADD(cell, INTEGER_OBJ(clearattr)); ADD(cell, INTEGER_OBJ(clearcol-endcol)); ADD(cells, ARRAY_OBJ(cell)); } ADD(args, ARRAY_OBJ(cells)); push_call(ui, "grid_line", args); } else { for (int i = 0; i < endcol-startcol; i++) { remote_ui_cursor_goto(ui, row, startcol+i); remote_ui_highlight_set(ui, attrs[i]); remote_ui_put(ui, (const char *)chunk[i]); if (utf_ambiguous_width(utf_ptr2char(chunk[i]))) { data->client_col = -1; // force cursor update } } if (endcol < clearcol) { remote_ui_cursor_goto(ui, row, endcol); remote_ui_highlight_set(ui, (int)clearattr); // legacy eol_clear was only ever used with cleared attributes // so be on the safe side if (clearattr == 0 && clearcol == Columns) { Array args = ARRAY_DICT_INIT; push_call(ui, "eol_clear", args); } else { for (Integer c = endcol; c < clearcol; c++) { remote_ui_put(ui, " "); } } } } }