void term_redisplay (void) { /* Calculate the start column if the line at point has to be truncated. */ Buffer bp = get_window_bp (cur_wp); size_t lastcol = 0, t = tab_width (bp); size_t o = window_o (cur_wp); size_t lineo = o - get_buffer_line_o (bp); col = 0; o -= lineo; set_window_start_column (cur_wp, 0); size_t ew = get_window_ewidth (cur_wp); for (size_t lp = lineo; lp != SIZE_MAX; --lp) { col = 0; for (size_t p = lp; p < lineo; ++p) { char c = get_buffer_char (bp, o + p); if (isprint (c)) col++; else col += strlen (make_char_printable (get_buffer_char (bp, o + p), col, t)); } if (col >= ew - 1 || (lp / (ew / 3)) + 2 < lineo / (ew / 3)) { set_window_start_column (cur_wp, lp + 1); col = lastcol; break; } lastcol = col; } /* Draw the windows. */ cur_topline = 0; size_t topline = 0; for (Window wp = head_wp; wp != NULL; wp = get_window_next (wp)) { if (wp == cur_wp) cur_topline = topline; draw_window (topline, wp); topline += get_window_fheight (wp); } term_redraw_cursor (); }
static void draw_window (size_t topline, Window wp) { size_t i, o; Region r; int highlight = calculate_highlight_region (wp, &r); /* Find the first line to display on the first screen line. */ for (o = buffer_start_of_line (get_window_bp (wp), window_o (wp)), i = get_window_topdelta (wp); i > 0 && o > 0; assert ((o = buffer_prev_line (get_window_bp (wp), o)) != SIZE_MAX), --i) ; /* Draw the window lines. */ size_t cur_tab_width = tab_width (get_window_bp (wp)); for (i = topline; i < get_window_eheight (wp) + topline; ++i) { /* Clear the line. */ term_move (i, 0); term_clrtoeol (); /* If at the end of the buffer, don't write any text. */ if (o == SIZE_MAX) continue; draw_line (i, get_window_start_column (wp), wp, o, r, highlight, cur_tab_width); if (get_window_start_column (wp) > 0) { term_move (i, 0); term_addstr("$"); } o = buffer_next_line (get_window_bp (wp), o); } set_window_all_displayed (wp, o >= get_buffer_size (get_window_bp (wp))); /* Draw the status line only if there is available space after the buffer text space. */ if (get_window_fheight (wp) - get_window_eheight (wp) > 0) draw_status_line (topline + get_window_eheight (wp), wp); }
static void draw_window(size_t topline, Window *wp) { size_t i, startcol, lineno; Line *lp; Region r; int highlight; Point pt = window_pt(wp); calculate_highlight_region(wp, &r, &highlight); /* Find the first line to display on the first screen line. */ for (lp = pt.p, lineno = pt.n, i = wp->topdelta; i > 0 && list_prev(lp) != wp->bp->lines; lp = list_prev(lp), --i, --lineno) ; cur_tab_width = tab_width(wp->bp); /* Draw the window lines. */ for (i = topline; i < wp->eheight + topline; ++i, ++lineno) { /* Clear the line. */ term_move(i, 0); term_clrtoeol(); /* If at the end of the buffer, don't write any text. */ if (lp == wp->bp->lines) continue; startcol = wp->start_column; draw_line(i, startcol, wp, lp, lineno, &r, highlight); if (wp->start_column > 0) { term_move(i, 0); term_addch('$'); } lp = list_next(lp); } }
/* * This function calculates the best start column to draw if the line * needs to get truncated. * Called only for the line where is the point. */ static void calculate_start_column(Window *wp) { size_t col = 0, lastcol = 0, t = tab_width(wp->bp); int rpfact, lpfact; char *buf, *rp, *lp, *p; Point pt = window_pt(wp); rp = astr_char(pt.p->item, (ptrdiff_t)pt.o); rpfact = pt.o / (wp->ewidth / 3); for (lp = rp; lp >= astr_cstr(pt.p->item); --lp) { for (col = 0, p = lp; p < rp; ++p) if (*p == '\t') { col |= t - 1; ++col; } else if (isprint(*p)) ++col; else { col += make_char_printable(&buf, (size_t)*p); free(buf); } lpfact = (lp - astr_cstr(pt.p->item)) / (wp->ewidth / 3); if (col >= wp->ewidth - 1 || lpfact < (rpfact - 2)) { wp->start_column = lp + 1 - astr_cstr(pt.p->item); point_screen_column = lastcol; return; } lastcol = col; } wp->start_column = 0; point_screen_column = col; }
static void insert_expanded_tab (void) { size_t t = tab_width (cur_bp); bprintf ("%*s", (int) (t - get_goalc () % t), ""); }