/* Picks window to use for suggestion box and prepares it for displaying data. * Sets *height to number of suggestions to display. Returns picked window. */ static WINDOW * prepare_suggestion_box(int *height) { WINDOW *win; const col_attr_t col = cfg.cs.color[SUGGEST_BOX_COLOR]; const int count = vle_compl_get_count(); if((cfg.sug.flags & SF_OTHERPANE) && curr_stats.number_of_windows == 2) { win = other_view->win; *height = MIN(count, getmaxy(win)); } else { const int max_height = getmaxy(stdscr) - getmaxy(status_bar) - ui_stat_job_bar_height() - 2; *height = MIN(count, max_height); wresize(stat_win, *height, getmaxx(stdscr)); ui_stat_reposition(getmaxy(status_bar), 1); win = stat_win; } wbkgdset(win, COLOR_PAIR(colmgr_get_pair(col.fg, col.bg)) | col.attr); werase(win); return win; }
/* Prints line onto a window highlighting it according to attrs, which should * specify 0-9 color groups for every character in line. */ static void print_with_attrs(WINDOW *win, const char line[], const char attrs[], const cchar_t *default_attr) { cchar_t attr = *default_attr; while(*line != '\0') { if(*attrs == '0') { attr = *default_attr; } else if(*attrs != ' ') { const int color = (USER1_COLOR + (*attrs - '1')); col_attr_t col = cfg.cs.color[STATUS_LINE_COLOR]; cs_mix_colors(&col, &cfg.cs.color[color]); setcchar(&attr, L" ", col.attr, colmgr_get_pair(col.fg, col.bg), NULL); } const size_t len = utf8_chrw(line); char char_buf[len + 1]; copy_str(char_buf, sizeof(char_buf), line); wprinta(win, char_buf, &attr, 0); line += len; attrs += utf8_chrsw(char_buf); } }
/* Loads color scheme settings into color pairs. */ static void load_color_pairs(col_scheme_t *cs) { int i; for(i = 0; i < MAXNUM_COLOR; i++) { cs->pair[i] = colmgr_get_pair(cs->color[i].fg, cs->color[i].bg); } }
static int count_available_pairs(int seed, int max) { int i = 0; while(i < max && colmgr_get_pair(seed, i) != 0) { ++i; } return i; }
/* Prints the leading character of the str to the win window parsing terminal * escape sequences. */ static void print_char_esc(WINDOW *win, const char str[], esc_state *state) { if(str[0] == '\033') { esc_state_update(state, str); wattrset(win, COLOR_PAIR(colmgr_get_pair(state->fg, state->bg)) | state->attrs); } else { wprint(win, str); } }
static void status_bar_message_i(const char message[], int error) { /* TODO: Refactor this function status_bar_message_i() */ static char *msg; static int err; int len; const char *p, *q; int lines; int status_bar_lines; size_t screen_length; const char *out_msg; char truncated_msg[2048]; if(curr_stats.load_stage == 0) { return; } if(message != NULL) { if(replace_string(&msg, message)) { return; } err = error; save_status_bar_msg(msg); } if(msg == NULL || vle_mode_is(CMDLINE_MODE)) { return; } p = msg; q = msg - 1; status_bar_lines = 0; len = getmaxx(stdscr); while((q = strchr(q + 1, '\n')) != NULL) { status_bar_lines += DIV_ROUND_UP(q - p, len ); if(q == p) { ++status_bar_lines; } p = q + 1; } if(*p == '\0') { ++status_bar_lines; } screen_length = utf8_strsw(p); status_bar_lines += DIV_ROUND_UP(screen_length, len); if(status_bar_lines == 0) { status_bar_lines = 1; } lines = status_bar_lines; if(status_bar_lines > 1 || screen_length > (size_t)getmaxx(status_bar)) { ++lines; } out_msg = msg; if(lines > 1) { if(cfg.trunc_normal_sb_msgs && !err && curr_stats.allow_sb_msg_truncation) { truncate_with_ellipsis(msg, getmaxx(stdscr) - FIELDS_WIDTH(), truncated_msg); out_msg = truncated_msg; lines = 1; } else { const int extra = DIV_ROUND_UP(ARRAY_LEN(PRESS_ENTER_MSG) - 1, len) - 1; lines += extra; } } if(lines > getmaxy(stdscr)) { lines = getmaxy(stdscr); } (void)ui_stat_reposition(lines); mvwin(status_bar, getmaxy(stdscr) - lines, 0); if(lines == 1) { wresize(status_bar, lines, getmaxx(stdscr) - FIELDS_WIDTH()); } else { wresize(status_bar, lines, getmaxx(stdscr)); } checked_wmove(status_bar, 0, 0); if(err) { col_attr_t col = cfg.cs.color[CMD_LINE_COLOR]; mix_colors(&col, &cfg.cs.color[ERROR_MSG_COLOR]); wattron(status_bar, COLOR_PAIR(colmgr_get_pair(col.fg, col.bg)) | col.attr); } else { int attr = cfg.cs.color[CMD_LINE_COLOR].attr; wattron(status_bar, COLOR_PAIR(cfg.cs.pair[CMD_LINE_COLOR]) | attr); } werase(status_bar); wprint(status_bar, out_msg); multiline_status_bar = lines > 1; if(multiline_status_bar) { checked_wmove(status_bar, lines - DIV_ROUND_UP(ARRAY_LEN(PRESS_ENTER_MSG), len), 0); wclrtoeol(status_bar); if(lines < status_bar_lines) wprintw(status_bar, "%d of %d lines. ", lines, status_bar_lines); wprintw(status_bar, "%s", PRESS_ENTER_MSG); } wattrset(status_bar, 0); update_all_windows(); /* This is needed because update_all_windows() doesn't call doupdate() if * curr_stats.load_stage == 1. */ doupdate(); }
/* Draws single menu item at position specified by line argument. Non-zero * clear argument suppresses drawing current items in different color. */ static void draw_menu_item(menu_state_t *ms, int pos, int line, int clear) { menu_data_t *const m = ms->d; int i; int off; char *item_tail; const int width = (curr_stats.load_stage == 0) ? 100 : getmaxx(menu_win) - 2; /* Calculate color for the line. */ int attrs; col_attr_t col = cfg.cs.color[WIN_COLOR]; if(cfg.hl_search && ms->search_highlight && ms->matches != NULL && ms->matches[pos][0] >= 0) { cs_mix_colors(&col, &cfg.cs.color[SELECTED_COLOR]); } if(!clear && pos == m->pos) { cs_mix_colors(&col, &cfg.cs.color[CURR_LINE_COLOR]); } attrs = COLOR_PAIR(colmgr_get_pair(col.fg, col.bg)) | col.attr; /* Calculate offset of m->hor_pos's character in item text. */ off = 0; i = m->hor_pos; while(i-- > 0 && m->items[pos][off] != '\0') { off += utf8_chrw(m->items[pos] + off); } item_tail = strdup(m->items[pos] + off); replace_char(item_tail, '\t', ' '); wattron(menu_win, attrs); /* Clear the area. */ checked_wmove(menu_win, line, 1); if(curr_stats.load_stage != 0) { wprintw(menu_win, "%*s", width, ""); } /* Draw visible part of item. */ checked_wmove(menu_win, line, 2); if(utf8_strsw(item_tail) > (size_t)(width - 2)) { void *p; const size_t len = utf8_nstrsnlen(item_tail, width - 3 - 2 + 1); memset(item_tail + len, ' ', strlen(item_tail) - len); p = realloc(item_tail, len + 4); if(p != NULL) { item_tail = p; strcpy(item_tail + len - 1, "..."); } wprint(menu_win, item_tail); } else { const size_t len = utf8_nstrsnlen(item_tail, width - 2 + 1); item_tail[len] = '\0'; wprint(menu_win, item_tail); } wattroff(menu_win, attrs); if(ms->search_highlight && ms->matches != NULL && ms->matches[pos][0] >= 0) { draw_search_match(item_tail, ms->matches[pos][0] - m->hor_pos, ms->matches[pos][1] - m->hor_pos, line, width, attrs); } free(item_tail); }