static void print_str(char *buf, int *idx, const char *str) { int d = *idx; if (width) { int ws_len; int i = 0; if (align_left) { i = width; d += u_copy_chars(buf + d, str, &i); ws_len = width - i; memset(buf + d, ' ', ws_len); d += ws_len; } else { int s = 0; ws_len = width - u_str_width(str); if (ws_len > 0) { memset(buf + d, ' ', ws_len); d += ws_len; i += ws_len; } if (ws_len < 0) { int w, c = -ws_len; uchar u; while (c > 0) { u = u_get_char(str, &s); w = u_char_width(u); c -= w; } if (c < 0) { /* gaah, skipped too much */ if (u_char_width(u) == 2) { /* double-byte */ buf[d++] = ' '; } else { /* <xx> */ if (c == -3) buf[d++] = hex_tab[(u >> 4) & 0xf]; if (c <= -2) buf[d++] = hex_tab[u & 0xf]; buf[d++] = '>'; } } } if (width - i > 0) { int w = width - i; d += u_copy_chars(buf + d, str + s, &w); } } } else {
void update_status_line(struct window *win) { struct formatter f; char lbuf[256]; char rbuf[256]; int lw, rw; sf_init(&f, win); f.misc_status = format_misc_status(win); sf_format(&f, lbuf, sizeof(lbuf), options.statusline_left); sf_format(&f, rbuf, sizeof(rbuf), options.statusline_right); buf_reset(win->x, win->w, 0); buf_move_cursor(win->x, win->y + win->h - 1); set_builtin_color(BC_STATUSLINE); lw = u_str_width(lbuf); rw = u_str_width(rbuf); if (lw + rw <= win->w) { // both fit buf_add_str(lbuf); buf_set_bytes(' ', win->w - lw - rw); buf_add_str(rbuf); } else if (lw <= win->w && rw <= win->w) { // both would fit separately, draw overlapping buf_add_str(lbuf); obuf.x = win->w - rw; buf_move_cursor(win->x + win->w - rw, win->y + win->h - 1); buf_add_str(rbuf); } else if (lw <= win->w) { // left fits buf_add_str(lbuf); buf_clear_eol(); } else if (rw <= win->w) { // right fits buf_set_bytes(' ', win->w - rw); buf_add_str(rbuf); } else { buf_clear_eol(); } }
static void print_vertical_tab_title(struct view *v, int idx, int width) { const char *orig_filename = buffer_filename(v->buffer); const char *filename = orig_filename; int max = options.tab_bar_max_components; char buf[16]; int skip; snprintf(buf, sizeof(buf), "%2d%s", idx + 1, buffer_modified(v->buffer) ? "+" : " "); if (max) { int i, count = 1; for (i = 0; filename[i]; i++) { if (filename[i] == '/') count++; } // ignore first slash because it does not separate components if (filename[0] == '/') count--; if (count > max) { // skip possible first slash for (i = 1; ; i++) { if (filename[i] == '/' && --count == max) { i++; break; } } filename += i; } } else { skip = strlen(buf) + u_str_width(filename) - width + 1; if (skip > 0) filename += u_skip_chars(filename, &skip); } if (filename != orig_filename) { // filename was shortened. add "<<" symbol long i = strlen(buf); u_set_char(buf, &i, 0xab); buf[i] = 0; } if (v == v->window->view) set_builtin_color(BC_ACTIVETAB); else set_builtin_color(BC_INACTIVETAB); buf_add_str(buf); buf_add_str(filename); buf_clear_eol(); }
static int tab_title_width(int number, const char *filename) { return 3 + number_width(number) + u_str_width(filename); }