Beispiel #1
0
static bool ui_window_draw_sidebar(UiCursesWin *win) {
    if (!win->winside)
        return true;
    const Line *line = view_lines_get(win->view);
    int sidebar_width = snprintf(NULL, 0, "%zd", line->lineno + win->height - 2) + 1;
    if (win->sidebar_width != sidebar_width) {
        win->sidebar_width = sidebar_width;
        ui_window_resize(win, win->width, win->height);
        ui_window_move(win, win->x, win->y);
        return false;
    } else {
        int i = 0;
        size_t prev_lineno = 0;
        const Line *cursor_line = view_line_get(win->view);
        size_t cursor_lineno = cursor_line->lineno;
        werase(win->winside);
        wbkgd(win->winside, style_to_attr(&win->styles[UI_STYLE_DEFAULT]));
        wattrset(win->winside, style_to_attr(&win->styles[UI_STYLE_LINENUMBER]));
        for (const Line *l = line; l; l = l->next, i++) {
            if (l->lineno && l->lineno != prev_lineno) {
                if (win->options & UI_OPTION_LINE_NUMBERS_ABSOLUTE) {
                    mvwprintw(win->winside, i, 0, "%*u", sidebar_width-1, l->lineno);
                } else if (win->options & UI_OPTION_LINE_NUMBERS_RELATIVE) {
                    size_t rel = (win->options & UI_OPTION_LARGE_FILE) ? 0 : l->lineno;
                    if (l->lineno > cursor_lineno)
                        rel = l->lineno - cursor_lineno;
                    else if (l->lineno < cursor_lineno)
                        rel = cursor_lineno - l->lineno;
                    mvwprintw(win->winside, i, 0, "%*u", sidebar_width-1, rel);
                }
            }
            prev_lineno = l->lineno;
        }
        mvwvline(win->winside, 0, sidebar_width-1, ACS_VLINE, win->height-1);
        return true;
    }
}
Beispiel #2
0
static void ui_window_draw(UiWin *w) {
	UiCursesWin *win = (UiCursesWin*)w;
	if (!ui_window_draw_sidebar(win))
		return;

	wbkgd(win->win, style_to_attr(&win->styles[UI_STYLE_DEFAULT]));
	wmove(win->win, 0, 0);
	int width = view_width_get(win->view);
	CellStyle *prev_style = NULL;
	size_t cursor_lineno = -1;

	if (win->options & UI_OPTION_CURSOR_LINE && win->ui->selwin == win) {
		Cursor *cursor = view_cursors(win->view);
		Filerange selection = view_cursors_selection_get(cursor);
		if (!view_cursors_next(cursor) && !text_range_valid(&selection))
			cursor_lineno = view_cursor_getpos(win->view).line;
	}

	short selection_bg = win->styles[UI_STYLE_SELECTION].bg;
	short cursor_line_bg = win->styles[UI_STYLE_CURSOR_LINE].bg;
	bool multiple_cursors = view_cursors_multiple(win->view);
	attr_t attr = A_NORMAL;

	for (const Line *l = view_lines_get(win->view); l; l = l->next) {
		bool cursor_line = l->lineno == cursor_lineno;
		for (int x = 0; x < width; x++) {
			enum UiStyles style_id = l->cells[x].style;
			if (style_id == 0)
				style_id = UI_STYLE_DEFAULT;
			CellStyle *style = &win->styles[style_id];

			if (l->cells[x].cursor && win->ui->selwin == win) {
				if (multiple_cursors && l->cells[x].cursor_primary)
					attr = style_to_attr(&win->styles[UI_STYLE_CURSOR_PRIMARY]);
				else
					attr = style_to_attr(&win->styles[UI_STYLE_CURSOR]);
				prev_style = NULL;
			} else if (l->cells[x].selected) {
				if (style->fg == selection_bg)
					attr |= A_REVERSE;
				else
					attr = style->attr | COLOR_PAIR(color_pair_get(style->fg, selection_bg));
				prev_style = NULL;
			} else if (cursor_line) {
				attr = style->attr | COLOR_PAIR(color_pair_get(style->fg, cursor_line_bg));
				prev_style = NULL;
			} else if (style != prev_style) {
				attr = style_to_attr(style);
				prev_style = style;
			}
			wattrset(win->win, attr);
			waddstr(win->win, l->cells[x].data);
		}
		/* try to fixup display issues, in theory we should always output a full line */
		int x, y;
		getyx(win->win, y, x);
		(void)y;
		wattrset(win->win, A_NORMAL);
		for (; 0 < x && x < width; x++)
			waddstr(win->win, " ");
	}

	wclrtobot(win->win);

	if (win->winstatus)
		ui_window_draw_status(w);
}