void window_copy_cursor_jump_back(struct window_pane *wp) { struct window_copy_mode_data *data = wp->modedata; struct screen *back_s = data->backing; const struct grid_cell *gc; uint px, py; px = data->cx; py = screen_hsize(back_s) + data->cy - data->oy; if (px > 0) px--; for (;;) { gc = grid_peek_cell(back_s->grid, px, py); if ((gc->flags & (GRID_FLAG_PADDING|GRID_FLAG_UTF8)) == 0 && gc->data == data->jumpchar) { window_copy_update_cursor(wp, px, data->cy); if (window_copy_update_selection(wp)) window_copy_redraw_lines(wp, data->cy, 1); return; } if (px == 0) break; px--; } }
u_int window_copy_find_length(struct window_pane *wp, u_int py) { const struct grid_cell *gc; u_int px; /* * If the pane has been resized, its grid can contain old overlong * lines. grid_peek_cell does not allow accessing cells beyond the * width of the grid, and screen_write_copy treats them as spaces, so * ignore them here too. */ px = wp->base.grid->linedata[py].cellsize; if (px > screen_size_x(&wp->base)) px = screen_size_x(&wp->base); while (px > 0) { gc = grid_peek_cell(wp->base.grid, px - 1, py); if (gc->flags & GRID_FLAG_UTF8) break; if (gc->data != ' ') break; px--; } return (px); }
void window_copy_cursor_jump(struct window_pane *wp) { struct window_copy_mode_data *data = wp->modedata; struct screen *back_s = data->backing; const struct grid_cell *gc; uint px, py, xx; px = data->cx + 1; py = screen_hsize(back_s) + data->cy - data->oy; xx = window_copy_find_length(wp, py); while (px < xx) { gc = grid_peek_cell(back_s->grid, px, py); if ((gc->flags & (GRID_FLAG_PADDING|GRID_FLAG_UTF8)) == 0 && gc->data == data->jumpchar) { window_copy_update_cursor(wp, px, data->cy); if (window_copy_update_selection(wp)) window_copy_redraw_lines(wp, data->cy, 1); return; } px++; } }
/* Convert cells into a string. */ char * grid_string_cells(struct grid *gd, u_int px, u_int py, u_int nx) { const struct grid_cell *gc; struct utf8_data ud; char *buf; size_t len, off; u_int xx; GRID_DEBUG(gd, "px=%u, py=%u, nx=%u", px, py, nx); len = 128; buf = xmalloc(len); off = 0; for (xx = px; xx < px + nx; xx++) { gc = grid_peek_cell(gd, xx, py); if (gc->flags & GRID_FLAG_PADDING) continue; grid_cell_get(gc, &ud); while (len < off + ud.size + 1) { buf = xrealloc(buf, 2, len); len *= 2; } memcpy(buf + off, ud.data, ud.size); off += ud.size; } while (off > 0 && buf[off - 1] == ' ') off--; buf[off] = '\0'; return (buf); }
void window_copy_copy_line(struct window_pane *wp, char **buf, size_t *off, u_int sy, u_int sx, u_int ex) { struct window_copy_mode_data *data = wp->modedata; struct grid *gd = data->backing->grid; const struct grid_cell *gc; const struct grid_utf8 *gu; struct grid_line *gl; u_int i, xx, wrapped = 0; size_t size; if (sx > ex) return; /* * Work out if the line was wrapped at the screen edge and all of it is * on screen. */ gl = &gd->linedata[sy]; if (gl->flags & GRID_LINE_WRAPPED && gl->cellsize <= gd->sx) wrapped = 1; /* If the line was wrapped, don't strip spaces (use the full length). */ if (wrapped) xx = gl->cellsize; else xx = window_copy_find_length(wp, sy); if (ex > xx) ex = xx; if (sx > xx) sx = xx; if (sx < ex) { for (i = sx; i < ex; i++) { gc = grid_peek_cell(gd, i, sy); if (gc->flags & GRID_FLAG_PADDING) continue; if (!(gc->flags & GRID_FLAG_UTF8)) { *buf = xrealloc(*buf, 1, (*off) + 1); (*buf)[(*off)++] = gc->data; } else { gu = grid_peek_utf8(gd, i, sy); size = grid_utf8_size(gu); *buf = xrealloc(*buf, 1, (*off) + size); *off += grid_utf8_copy(gu, *buf + *off, size); } } } /* Only add a newline if the line wasn't wrapped. */ if (!wrapped || ex != xx) { *buf = xrealloc(*buf, 1, (*off) + 1); (*buf)[(*off)++] = '\n'; } }
int window_copy_in_set(struct window_pane *wp, u_int px, u_int py, const char *set) { const struct grid_cell *gc; gc = grid_peek_cell(wp->base.grid, px, py); if (gc->flags & (GRID_FLAG_PADDING|GRID_FLAG_UTF8)) return (0); if (gc->data == 0x00 || gc->data == 0x7f) return (0); return (strchr(set, gc->data) != NULL); }
int window_copy_search_compare( struct grid *gd, u_int px, u_int py, struct grid *sgd, u_int spx) { const struct grid_cell *gc, *sgc; const struct grid_utf8 *gu, *sgu; gc = grid_peek_cell(gd, px, py); sgc = grid_peek_cell(sgd, spx, 0); if ((gc->flags & GRID_FLAG_UTF8) != (sgc->flags & GRID_FLAG_UTF8)) return (0); if (gc->flags & GRID_FLAG_UTF8) { gu = grid_peek_utf8(gd, px, py); sgu = grid_peek_utf8(sgd, spx, 0); if (grid_utf8_compare(gu, sgu)) return (1); } else { if (gc->data == sgc->data) return (1); } return (0); }
/* Convert cells into a string. */ char * grid_string_cells(struct grid *gd, u_int px, u_int py, u_int nx) { const struct grid_cell *gc; const struct grid_utf8 *gu; char *buf; size_t len, off, size; u_int xx; GRID_DEBUG(gd, "px=%u, py=%u, nx=%u", px, py, nx); len = 128; buf = xmalloc(len); off = 0; for (xx = px; xx < px + nx; xx++) { gc = grid_peek_cell(gd, xx, py); if (gc->flags & GRID_FLAG_PADDING) continue; if (gc->flags & GRID_FLAG_UTF8) { gu = grid_peek_utf8(gd, xx, py); size = grid_utf8_size(gu); while (len < off + size + 1) { buf = xrealloc(buf, 2, len); len *= 2; } off += grid_utf8_copy(gu, buf + off, len - off); } else { while (len < off + 2) { buf = xrealloc(buf, 2, len); len *= 2; } buf[off++] = gc->data; } } while (off > 0 && buf[off - 1] == ' ') off--; buf[off] = '\0'; return (buf); }
void window_copy_cursor_back_to_indentation(struct window_pane *wp) { struct window_copy_mode_data *data = wp->modedata; u_int px, py, xx; const struct grid_cell *gc; px = 0; py = screen_hsize(&wp->base) + data->cy - data->oy; xx = window_copy_find_length(wp, py); while (px < xx) { gc = grid_peek_cell(wp->base.grid, px, py); if (gc->flags & GRID_FLAG_UTF8) break; if (gc->data != ' ') break; px++; } window_copy_update_cursor(wp, px, data->cy); if (window_copy_update_selection(wp)) window_copy_redraw_lines(wp, data->cy, 1); }
/* Get cell for reading. */ const struct grid_cell * grid_view_peek_cell(struct grid *gd, u_int px, u_int py) { return (grid_peek_cell(gd, grid_view_x(gd, px), grid_view_y(gd, py))); }
/* Convert cells into a string. */ char * grid_string_cells(struct grid *gd, u_int px, u_int py, u_int nx, struct grid_cell **lastgc, int with_codes, int escape_c0, int trim) { const struct grid_cell *gc; static struct grid_cell lastgc1; struct utf8_data ud; const char* data; char *buf, code[128]; size_t len, off, size, codelen; u_int xx; GRID_DEBUG(gd, "px=%u, py=%u, nx=%u", px, py, nx); if (lastgc != NULL && *lastgc == NULL) { memcpy(&lastgc1, &grid_default_cell, sizeof lastgc1); *lastgc = &lastgc1; } len = 128; buf = xmalloc(len); off = 0; for (xx = px; xx < px + nx; xx++) { gc = grid_peek_cell(gd, xx, py); if (gc->flags & GRID_FLAG_PADDING) continue; grid_cell_get(gc, &ud); if (with_codes) { grid_string_cells_code(*lastgc, gc, code, sizeof code, escape_c0); codelen = strlen(code); memcpy(*lastgc, gc, sizeof *gc); } else codelen = 0; data = ud.data; size = ud.size; if (escape_c0 && size == 1 && *data == '\\') { data = "\\\\"; size = 2; } while (len < off + size + codelen + 1) { buf = xrealloc(buf, 2, len); len *= 2; } if (codelen != 0) { memcpy(buf + off, code, codelen); off += codelen; } memcpy(buf + off, data, size); off += size; } if (trim) { while (off > 0 && buf[off - 1] == ' ') off--; } buf[off] = '\0'; return (buf); }