version 1.281, 2020/05/16 15:01:31 |
version 1.282, 2020/05/16 15:11:52 |
|
|
int searchtype; |
int searchtype; |
int searchregex; |
int searchregex; |
char *searchstr; |
char *searchstr; |
bitstr_t *searchmark; |
u_char *searchmark; |
u_int searchcount; |
u_int searchcount; |
int searchthis; |
int searchthis; |
int searchx; |
int searchx; |
int searchy; |
int searchy; |
int searcho; |
int searcho; |
|
u_char searchgen; |
|
|
int timeout; /* search has timed out */ |
int timeout; /* search has timed out */ |
#define WINDOW_COPY_SEARCH_TIMEOUT 10 |
#define WINDOW_COPY_SEARCH_TIMEOUT 10 |
|
|
data->searchregex = 0; |
data->searchregex = 0; |
data->searchstr = NULL; |
data->searchstr = NULL; |
} |
} |
data->searchmark = NULL; |
|
data->searchx = data->searchy = data->searcho = -1; |
data->searchx = data->searchy = data->searcho = -1; |
data->timeout = 0; |
|
data->viewmode = 0; |
|
|
|
data->jumptype = WINDOW_COPY_OFF; |
data->jumptype = WINDOW_COPY_OFF; |
data->jumpchar = '\0'; |
data->jumpchar = '\0'; |
|
|
const struct grid_line *gl; |
const struct grid_line *gl; |
int found, cis, which = -1; |
int found, cis, which = -1; |
int cflags = REG_EXTENDED; |
int cflags = REG_EXTENDED; |
u_int px, py, b, nfound = 0, width; |
u_int px, py, i, b, nfound = 0, width; |
u_int ssize = 1; |
u_int ssize = 1; |
char *sbuf; |
char *sbuf; |
regex_t reg; |
regex_t reg; |
|
|
cis = window_copy_is_lowercase(data->searchstr); |
cis = window_copy_is_lowercase(data->searchstr); |
|
|
free(data->searchmark); |
free(data->searchmark); |
data->searchmark = bit_alloc((gd->hsize + gd->sy) * gd->sx); |
data->searchmark = xcalloc(gd->hsize + gd->sy, gd->sx); |
|
data->searchgen = 1; |
|
|
if (regex) { |
if (regex) { |
sbuf = xmalloc(ssize); |
sbuf = xmalloc(ssize); |
|
|
which = nfound; |
which = nfound; |
|
|
b = (py * gd->sx) + px; |
b = (py * gd->sx) + px; |
bit_nset(data->searchmark, b, b + width - 1); |
for (i = b; i < b + width; i++) |
|
data->searchmark[i] = data->searchgen; |
|
if (data->searchgen == UCHAR_MAX) |
|
data->searchgen = 1; |
|
else |
|
data->searchgen++; |
|
|
px++; |
px++; |
} |
} |
|
|
} |
} |
|
|
static void |
static void |
|
window_copy_match_start_end(struct window_copy_mode_data *data, u_int at, |
|
u_int *start, u_int *end) |
|
{ |
|
struct grid *gd = data->backing->grid; |
|
u_int last = (gd->hsize + gd->sy) * gd->sx - 1; |
|
u_char mark = data->searchmark[at]; |
|
|
|
*start = *end = at; |
|
while (*start != 0 && data->searchmark[*start] == mark) |
|
(*start)--; |
|
if (data->searchmark[*start] != mark) |
|
(*start)++; |
|
while (*end != last && data->searchmark[*end] == mark) |
|
(*end)++; |
|
if (data->searchmark[*end] != mark) |
|
(*end)--; |
|
} |
|
|
|
static char * |
|
window_copy_match_at_cursor(struct window_copy_mode_data *data) |
|
{ |
|
struct grid *gd = data->backing->grid; |
|
struct grid_cell gc; |
|
u_int at, start, end, cy, px, py; |
|
u_int sx = screen_size_x(data->backing); |
|
char *buf = NULL; |
|
size_t len = 0; |
|
|
|
if (data->searchmark == NULL) |
|
return (NULL); |
|
|
|
cy = screen_hsize(data->backing) - data->oy + data->cy; |
|
at = (cy * sx) + data->cx; |
|
if (data->searchmark[at] == 0) |
|
return (NULL); |
|
window_copy_match_start_end(data, at, &start, &end); |
|
|
|
/* |
|
* Cells will not be set in the marked array unless they are valid text |
|
* and wrapping will be taken care of, so we can just copy. |
|
*/ |
|
for (at = start; at <= end; at++) { |
|
py = at / sx; |
|
px = at % (py * sx); |
|
|
|
grid_get_cell(gd, px, py, &gc); |
|
buf = xrealloc(buf, len + gc.data.size + 1); |
|
memcpy(buf + len, gc.data.data, gc.data.size); |
|
len += gc.data.size; |
|
} |
|
if (len != 0) |
|
buf[len] = '\0'; |
|
return (buf); |
|
} |
|
|
|
static void |
|
window_copy_update_style(struct window_mode_entry *wme, u_int fx, u_int fy, |
|
struct grid_cell *gc, const struct grid_cell *mgc, |
|
const struct grid_cell *cgc) |
|
{ |
|
struct window_copy_mode_data *data = wme->data; |
|
u_int mark, at, start, end, cy; |
|
u_int sx = screen_size_x(data->backing); |
|
|
|
if (data->searchmark == NULL) |
|
return; |
|
mark = data->searchmark[(fy * sx) + fx]; |
|
if (mark == 0) |
|
return; |
|
|
|
cy = screen_hsize(data->backing) - data->oy + data->cy; |
|
at = (cy * sx) + data->cx; |
|
if (data->searchmark[at] == mark) { |
|
window_copy_match_start_end(data, at, &start, &end); |
|
if (at >= start && at <= end) { |
|
gc->attr = cgc->attr; |
|
gc->fg = cgc->fg; |
|
gc->bg = cgc->bg; |
|
} |
|
return; |
|
} |
|
|
|
gc->attr = mgc->attr; |
|
gc->fg = mgc->fg; |
|
gc->bg = mgc->bg; |
|
} |
|
|
|
static void |
|
window_copy_write_one(struct window_mode_entry *wme, |
|
struct screen_write_ctx *ctx, u_int py, u_int fy, u_int nx, |
|
const struct grid_cell *mgc, const struct grid_cell *cgc) |
|
{ |
|
struct window_copy_mode_data *data = wme->data; |
|
struct grid *gd = data->backing->grid; |
|
struct grid_cell gc; |
|
u_int fx; |
|
|
|
screen_write_cursormove(ctx, 0, py, 0); |
|
for (fx = 0; fx < nx; fx++) { |
|
grid_get_cell(gd, fx, fy, &gc); |
|
if (fx + gc.data.width <= nx) { |
|
window_copy_update_style(wme, fx, fy, &gc, mgc, cgc); |
|
screen_write_cell(ctx, &gc); |
|
} |
|
} |
|
} |
|
|
|
static void |
window_copy_write_line(struct window_mode_entry *wme, |
window_copy_write_line(struct window_mode_entry *wme, |
struct screen_write_ctx *ctx, u_int py) |
struct screen_write_ctx *ctx, u_int py) |
{ |
{ |
|
|
struct window_copy_mode_data *data = wme->data; |
struct window_copy_mode_data *data = wme->data; |
struct screen *s = &data->screen; |
struct screen *s = &data->screen; |
struct options *oo = wp->window->options; |
struct options *oo = wp->window->options; |
struct grid_cell gc; |
struct grid_cell gc, mgc, cgc; |
char hdr[512]; |
char hdr[512]; |
size_t size = 0; |
size_t size = 0; |
u_int hsize = screen_hsize(data->backing); |
u_int hsize = screen_hsize(data->backing); |
|
|
style_apply(&gc, oo, "mode-style", NULL); |
style_apply(&gc, oo, "mode-style", NULL); |
gc.flags |= GRID_FLAG_NOPALETTE; |
gc.flags |= GRID_FLAG_NOPALETTE; |
|
style_apply(&mgc, oo, "copy-mode-match-style", NULL); |
|
mgc.flags |= GRID_FLAG_NOPALETTE; |
|
style_apply(&cgc, oo, "copy-mode-current-match-style", NULL); |
|
cgc.flags |= GRID_FLAG_NOPALETTE; |
|
|
if (py == 0 && s->rupper < s->rlower && !data->hide_position) { |
if (py == 0 && s->rupper < s->rlower && !data->hide_position) { |
if (data->searchmark == NULL) { |
if (data->searchmark == NULL) { |
|
|
size = 0; |
size = 0; |
|
|
if (size < screen_size_x(s)) { |
if (size < screen_size_x(s)) { |
screen_write_cursormove(ctx, 0, py, 0); |
window_copy_write_one(wme, ctx, py, hsize - data->oy + py, |
screen_write_copy(ctx, data->backing, 0, hsize - data->oy + py, |
screen_size_x(s) - size, &mgc, &cgc); |
screen_size_x(s) - size, 1, data->searchmark, &gc); |
|
} |
} |
|
|
if (py == data->cy && data->cx == screen_size_x(s)) { |
if (py == data->cy && data->cx == screen_size_x(s)) { |
memcpy(&gc, &grid_default_cell, sizeof gc); |
|
screen_write_cursormove(ctx, screen_size_x(s) - 1, py, 0); |
screen_write_cursormove(ctx, screen_size_x(s) - 1, py, 0); |
screen_write_putc(ctx, &gc, '$'); |
screen_write_putc(ctx, &grid_default_cell, '$'); |
} |
} |
} |
} |
|
|
|
|
u_int firstsx, lastex, restex, restsx, selx; |
u_int firstsx, lastex, restex, restsx, selx; |
int keys; |
int keys; |
|
|
if (data->screen.sel == NULL && data->lineflag == LINE_SEL_NONE) |
if (data->screen.sel == NULL && data->lineflag == LINE_SEL_NONE) { |
return (NULL); |
buf = window_copy_match_at_cursor(data); |
|
if (buf != NULL) |
|
*len = strlen(buf); |
|
return (buf); |
|
} |
|
|
buf = xmalloc(1); |
buf = xmalloc(1); |
off = 0; |
off = 0; |