mirror of
https://github.com/tmux/tmux.git
synced 2024-12-04 19:58:48 +00:00
Merge branch 'obsd-master'
This commit is contained in:
commit
911d768b71
7
format.c
7
format.c
@ -5277,10 +5277,13 @@ format_grid_line(struct grid *gd, u_int y)
|
|||||||
for (x = 0; x < grid_line_length(gd, y); x++) {
|
for (x = 0; x < grid_line_length(gd, y); x++) {
|
||||||
grid_get_cell(gd, x, y, &gc);
|
grid_get_cell(gd, x, y, &gc);
|
||||||
if (gc.flags & GRID_FLAG_PADDING)
|
if (gc.flags & GRID_FLAG_PADDING)
|
||||||
break;
|
continue;
|
||||||
|
|
||||||
ud = xreallocarray(ud, size + 2, sizeof *ud);
|
ud = xreallocarray(ud, size + 2, sizeof *ud);
|
||||||
memcpy(&ud[size++], &gc.data, sizeof *ud);
|
if (gc.flags & GRID_FLAG_TAB)
|
||||||
|
utf8_set(&ud[size++], '\t');
|
||||||
|
else
|
||||||
|
memcpy(&ud[size++], &gc.data, sizeof *ud);
|
||||||
}
|
}
|
||||||
if (size != 0) {
|
if (size != 0) {
|
||||||
ud[size].size = 0;
|
ud[size].size = 0;
|
||||||
|
@ -345,6 +345,8 @@ grid_reader_cell_equals_data(const struct grid_cell *gc,
|
|||||||
{
|
{
|
||||||
if (gc->flags & GRID_FLAG_PADDING)
|
if (gc->flags & GRID_FLAG_PADDING)
|
||||||
return (0);
|
return (0);
|
||||||
|
if (gc->flags & GRID_FLAG_TAB && ud->size == 1 && *ud->data == '\t')
|
||||||
|
return (1);
|
||||||
if (gc->data.size != ud->size)
|
if (gc->data.size != ud->size)
|
||||||
return (0);
|
return (0);
|
||||||
return (memcmp(gc->data.data, ud->data, gc->data.size) == 0);
|
return (memcmp(gc->data.data, ud->data, gc->data.size) == 0);
|
||||||
|
42
grid.c
42
grid.c
@ -92,6 +92,8 @@ grid_need_extended_cell(const struct grid_cell_entry *gce,
|
|||||||
return (1);
|
return (1);
|
||||||
if (gc->link != 0)
|
if (gc->link != 0)
|
||||||
return (1);
|
return (1);
|
||||||
|
if (gc->flags & GRID_FLAG_TAB)
|
||||||
|
return (1);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,7 +126,10 @@ grid_extended_cell(struct grid_line *gl, struct grid_cell_entry *gce,
|
|||||||
fatalx("offset too big");
|
fatalx("offset too big");
|
||||||
gl->flags |= GRID_LINE_EXTENDED;
|
gl->flags |= GRID_LINE_EXTENDED;
|
||||||
|
|
||||||
utf8_from_data(&gc->data, &uc);
|
if (gc->flags & GRID_FLAG_TAB)
|
||||||
|
uc = gc->data.width;
|
||||||
|
else
|
||||||
|
utf8_from_data(&gc->data, &uc);
|
||||||
|
|
||||||
gee = &gl->extddata[gce->offset];
|
gee = &gl->extddata[gce->offset];
|
||||||
gee->data = uc;
|
gee->data = uc;
|
||||||
@ -252,6 +257,16 @@ grid_cells_equal(const struct grid_cell *gc1, const struct grid_cell *gc2)
|
|||||||
return (memcmp(gc1->data.data, gc2->data.data, gc1->data.size) == 0);
|
return (memcmp(gc1->data.data, gc2->data.data, gc1->data.size) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set grid cell to a tab. */
|
||||||
|
void
|
||||||
|
grid_set_tab(struct grid_cell *gc, u_int width)
|
||||||
|
{
|
||||||
|
memset(&gc->data, 0, sizeof gc->data);
|
||||||
|
gc->flags |= GRID_FLAG_TAB;
|
||||||
|
gc->data.width = gc->data.size = gc->data.have = width;
|
||||||
|
memset(&gc->data, ' ', gc->data.size);
|
||||||
|
}
|
||||||
|
|
||||||
/* Free one line. */
|
/* Free one line. */
|
||||||
static void
|
static void
|
||||||
grid_free_line(struct grid *gd, u_int py)
|
grid_free_line(struct grid *gd, u_int py)
|
||||||
@ -515,7 +530,11 @@ grid_get_cell1(struct grid_line *gl, u_int px, struct grid_cell *gc)
|
|||||||
gc->bg = gee->bg;
|
gc->bg = gee->bg;
|
||||||
gc->us = gee->us;
|
gc->us = gee->us;
|
||||||
gc->link = gee->link;
|
gc->link = gee->link;
|
||||||
utf8_to_data(gee->data, &gc->data);
|
|
||||||
|
if (gc->flags & GRID_FLAG_TAB)
|
||||||
|
grid_set_tab(gc, gee->data);
|
||||||
|
else
|
||||||
|
utf8_to_data(gee->data, &gc->data);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1077,13 +1096,18 @@ grid_string_cells(struct grid *gd, u_int px, u_int py, u_int nx,
|
|||||||
} else
|
} else
|
||||||
codelen = 0;
|
codelen = 0;
|
||||||
|
|
||||||
data = gc.data.data;
|
if (gc.flags & GRID_FLAG_TAB) {
|
||||||
size = gc.data.size;
|
data = "\t";
|
||||||
if ((flags & GRID_STRING_ESCAPE_SEQUENCES) &&
|
size = 1;
|
||||||
size == 1 &&
|
} else {
|
||||||
*data == '\\') {
|
data = gc.data.data;
|
||||||
data = "\\\\";
|
size = gc.data.size;
|
||||||
size = 2;
|
if ((flags & GRID_STRING_ESCAPE_SEQUENCES) &&
|
||||||
|
size == 1 &&
|
||||||
|
*data == '\\') {
|
||||||
|
data = "\\\\";
|
||||||
|
size = 2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (len < off + size + codelen + 1) {
|
while (len < off + size + codelen + 1) {
|
||||||
|
27
input.c
27
input.c
@ -1213,6 +1213,10 @@ input_c0_dispatch(struct input_ctx *ictx)
|
|||||||
struct screen_write_ctx *sctx = &ictx->ctx;
|
struct screen_write_ctx *sctx = &ictx->ctx;
|
||||||
struct window_pane *wp = ictx->wp;
|
struct window_pane *wp = ictx->wp;
|
||||||
struct screen *s = sctx->s;
|
struct screen *s = sctx->s;
|
||||||
|
struct grid_cell gc, first_gc;
|
||||||
|
u_int cx = s->cx, line = s->cy + s->grid->hsize;
|
||||||
|
u_int width;
|
||||||
|
int has_content = 0;
|
||||||
|
|
||||||
ictx->utf8started = 0; /* can't be valid UTF-8 */
|
ictx->utf8started = 0; /* can't be valid UTF-8 */
|
||||||
|
|
||||||
@ -1234,11 +1238,28 @@ input_c0_dispatch(struct input_ctx *ictx)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
/* Find the next tab point, or use the last column if none. */
|
/* Find the next tab point, or use the last column if none. */
|
||||||
|
grid_get_cell(s->grid, s->cx, line, &first_gc);
|
||||||
do {
|
do {
|
||||||
s->cx++;
|
if (!has_content) {
|
||||||
if (bit_test(s->tabs, s->cx))
|
grid_get_cell(s->grid, cx, line, &gc);
|
||||||
|
if (gc.data.size != 1 ||
|
||||||
|
*gc.data.data != ' ' ||
|
||||||
|
!grid_cells_look_equal(&gc, &first_gc))
|
||||||
|
has_content = 1;
|
||||||
|
}
|
||||||
|
cx++;
|
||||||
|
if (bit_test(s->tabs, cx))
|
||||||
break;
|
break;
|
||||||
} while (s->cx < screen_size_x(s) - 1);
|
} while (cx < screen_size_x(s) - 1);
|
||||||
|
|
||||||
|
width = cx - s->cx;
|
||||||
|
if (has_content || width > sizeof gc.data.data)
|
||||||
|
s->cx = cx;
|
||||||
|
else {
|
||||||
|
grid_get_cell(s->grid, s->cx, line, &gc);
|
||||||
|
grid_set_tab(&gc, width);
|
||||||
|
screen_write_collect_add(sctx, &gc);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case '\012': /* LF */
|
case '\012': /* LF */
|
||||||
case '\013': /* VT */
|
case '\013': /* VT */
|
||||||
|
@ -1911,6 +1911,8 @@ screen_write_collect_add(struct screen_write_ctx *ctx,
|
|||||||
collect = 1;
|
collect = 1;
|
||||||
if (gc->data.width != 1 || gc->data.size != 1 || *gc->data.data >= 0x7f)
|
if (gc->data.width != 1 || gc->data.size != 1 || *gc->data.data >= 0x7f)
|
||||||
collect = 0;
|
collect = 0;
|
||||||
|
else if (gc->flags & GRID_FLAG_TAB)
|
||||||
|
collect = 0;
|
||||||
else if (gc->attr & GRID_ATTR_CHARSET)
|
else if (gc->attr & GRID_ATTR_CHARSET)
|
||||||
collect = 0;
|
collect = 0;
|
||||||
else if (~s->mode & MODE_WRAP)
|
else if (~s->mode & MODE_WRAP)
|
||||||
|
39
status.c
39
status.c
@ -740,6 +740,8 @@ status_prompt_redraw(struct client *c)
|
|||||||
u_int pcursor, pwidth, promptline;
|
u_int pcursor, pwidth, promptline;
|
||||||
struct grid_cell gc;
|
struct grid_cell gc;
|
||||||
struct format_tree *ft;
|
struct format_tree *ft;
|
||||||
|
u_char ch;
|
||||||
|
struct utf8_data *ud;
|
||||||
|
|
||||||
if (c->tty.sx == 0 || c->tty.sy == 0)
|
if (c->tty.sx == 0 || c->tty.sy == 0)
|
||||||
return (0);
|
return (0);
|
||||||
@ -801,17 +803,25 @@ status_prompt_redraw(struct client *c)
|
|||||||
|
|
||||||
width = 0;
|
width = 0;
|
||||||
for (i = 0; c->prompt_buffer[i].size != 0; i++) {
|
for (i = 0; c->prompt_buffer[i].size != 0; i++) {
|
||||||
|
ud = &c->prompt_buffer[i];
|
||||||
if (width < offset) {
|
if (width < offset) {
|
||||||
width += c->prompt_buffer[i].width;
|
width += ud->width;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (width >= offset + pwidth)
|
if (width >= offset + pwidth)
|
||||||
break;
|
break;
|
||||||
width += c->prompt_buffer[i].width;
|
width += ud->width;
|
||||||
if (width > offset + pwidth)
|
if (width > offset + pwidth)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
utf8_copy(&gc.data, &c->prompt_buffer[i]);
|
ch = *ud->data;
|
||||||
|
if (ud->size == 1 && (ch <= 0x1f || ch == 0x7f)) {
|
||||||
|
gc.data.data[0] = '^';
|
||||||
|
gc.data.data[1] = (ch == 0x7f) ? '?' : ch|0x40;
|
||||||
|
gc.data.size = gc.data.have = 2;
|
||||||
|
gc.data.width = 2;
|
||||||
|
} else
|
||||||
|
utf8_copy(&gc.data, ud);
|
||||||
screen_write_cell(&ctx, &gc);
|
screen_write_cell(&ctx, &gc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -864,6 +874,7 @@ status_prompt_translate_key(struct client *c, key_code key, key_code *new_key)
|
|||||||
case 'p'|KEYC_CTRL:
|
case 'p'|KEYC_CTRL:
|
||||||
case 't'|KEYC_CTRL:
|
case 't'|KEYC_CTRL:
|
||||||
case 'u'|KEYC_CTRL:
|
case 'u'|KEYC_CTRL:
|
||||||
|
case 'v'|KEYC_CTRL:
|
||||||
case 'w'|KEYC_CTRL:
|
case 'w'|KEYC_CTRL:
|
||||||
case 'y'|KEYC_CTRL:
|
case 'y'|KEYC_CTRL:
|
||||||
case '\n':
|
case '\n':
|
||||||
@ -1262,6 +1273,19 @@ status_prompt_key(struct client *c, key_code key)
|
|||||||
}
|
}
|
||||||
key &= ~KEYC_MASK_FLAGS;
|
key &= ~KEYC_MASK_FLAGS;
|
||||||
|
|
||||||
|
if (c->prompt_flags & (PROMPT_SINGLE|PROMPT_QUOTENEXT)) {
|
||||||
|
c->prompt_flags &= ~PROMPT_QUOTENEXT;
|
||||||
|
if ((key & KEYC_MASK_KEY) == KEYC_BSPACE)
|
||||||
|
key = 0x7f;
|
||||||
|
else if ((key & KEYC_MASK_KEY) > 0x7f) {
|
||||||
|
if (!KEYC_IS_UNICODE(key))
|
||||||
|
return (0);
|
||||||
|
key &= KEYC_MASK_KEY;
|
||||||
|
} else
|
||||||
|
key &= (key & KEYC_CTRL) ? 0x1f : KEYC_MASK_KEY;
|
||||||
|
goto append_key;
|
||||||
|
}
|
||||||
|
|
||||||
keys = options_get_number(c->session->options, "status-keys");
|
keys = options_get_number(c->session->options, "status-keys");
|
||||||
if (keys == MODEKEY_VI) {
|
if (keys == MODEKEY_VI) {
|
||||||
switch (status_prompt_translate_key(c, key, &key)) {
|
switch (status_prompt_translate_key(c, key, &key)) {
|
||||||
@ -1484,6 +1508,9 @@ process_key:
|
|||||||
} else
|
} else
|
||||||
prefix = '+';
|
prefix = '+';
|
||||||
goto changed;
|
goto changed;
|
||||||
|
case 'v'|KEYC_CTRL:
|
||||||
|
c->prompt_flags |= PROMPT_QUOTENEXT;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
goto append_key;
|
goto append_key;
|
||||||
}
|
}
|
||||||
@ -1492,9 +1519,11 @@ process_key:
|
|||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
append_key:
|
append_key:
|
||||||
if (key <= 0x7f)
|
if (key <= 0x7f) {
|
||||||
utf8_set(&tmp, key);
|
utf8_set(&tmp, key);
|
||||||
else if (KEYC_IS_UNICODE(key))
|
if (key <= 0x1f || key == 0x7f)
|
||||||
|
tmp.width = 2;
|
||||||
|
} else if (KEYC_IS_UNICODE(key))
|
||||||
utf8_to_data(key, &tmp);
|
utf8_to_data(key, &tmp);
|
||||||
else
|
else
|
||||||
return (0);
|
return (0);
|
||||||
|
3
tmux.h
3
tmux.h
@ -718,6 +718,7 @@ struct colour_palette {
|
|||||||
#define GRID_FLAG_SELECTED 0x10
|
#define GRID_FLAG_SELECTED 0x10
|
||||||
#define GRID_FLAG_NOPALETTE 0x20
|
#define GRID_FLAG_NOPALETTE 0x20
|
||||||
#define GRID_FLAG_CLEARED 0x40
|
#define GRID_FLAG_CLEARED 0x40
|
||||||
|
#define GRID_FLAG_TAB 0x80
|
||||||
|
|
||||||
/* Grid line flags. */
|
/* Grid line flags. */
|
||||||
#define GRID_LINE_WRAPPED 0x1
|
#define GRID_LINE_WRAPPED 0x1
|
||||||
@ -1971,6 +1972,7 @@ struct client {
|
|||||||
#define PROMPT_NOFORMAT 0x8
|
#define PROMPT_NOFORMAT 0x8
|
||||||
#define PROMPT_KEY 0x10
|
#define PROMPT_KEY 0x10
|
||||||
#define PROMPT_ACCEPT 0x20
|
#define PROMPT_ACCEPT 0x20
|
||||||
|
#define PROMPT_QUOTENEXT 0x40
|
||||||
int prompt_flags;
|
int prompt_flags;
|
||||||
enum prompt_type prompt_type;
|
enum prompt_type prompt_type;
|
||||||
int prompt_cursor;
|
int prompt_cursor;
|
||||||
@ -2905,6 +2907,7 @@ int attributes_fromstring(const char *);
|
|||||||
/* grid.c */
|
/* grid.c */
|
||||||
extern const struct grid_cell grid_default_cell;
|
extern const struct grid_cell grid_default_cell;
|
||||||
void grid_empty_line(struct grid *, u_int, u_int);
|
void grid_empty_line(struct grid *, u_int, u_int);
|
||||||
|
void grid_set_tab(struct grid_cell *, u_int);
|
||||||
int grid_cells_equal(const struct grid_cell *, const struct grid_cell *);
|
int grid_cells_equal(const struct grid_cell *, const struct grid_cell *);
|
||||||
int grid_cells_look_equal(const struct grid_cell *,
|
int grid_cells_look_equal(const struct grid_cell *,
|
||||||
const struct grid_cell *);
|
const struct grid_cell *);
|
||||||
|
@ -3301,6 +3301,11 @@ window_copy_cellstring(const struct grid_line *gl, u_int px, size_t *size,
|
|||||||
*allocated = 0;
|
*allocated = 0;
|
||||||
return (&gce->data.data);
|
return (&gce->data.data);
|
||||||
}
|
}
|
||||||
|
if (gce->flags & GRID_FLAG_TAB) {
|
||||||
|
*size = 1;
|
||||||
|
*allocated = 0;
|
||||||
|
return ("\t");
|
||||||
|
}
|
||||||
|
|
||||||
utf8_to_data(gl->extddata[gce->offset].data, &ud);
|
utf8_to_data(gl->extddata[gce->offset].data, &ud);
|
||||||
if (ud.size == 0) {
|
if (ud.size == 0) {
|
||||||
@ -3696,7 +3701,7 @@ window_copy_search(struct window_mode_entry *wme, int direction, int regex)
|
|||||||
struct screen_write_ctx ctx;
|
struct screen_write_ctx ctx;
|
||||||
struct grid *gd = s->grid;
|
struct grid *gd = s->grid;
|
||||||
const char *str = data->searchstr;
|
const char *str = data->searchstr;
|
||||||
u_int at, endline, fx, fy, start;
|
u_int at, endline, fx, fy, start, ssx;
|
||||||
int cis, found, keys, visible_only;
|
int cis, found, keys, visible_only;
|
||||||
int wrapflag;
|
int wrapflag;
|
||||||
|
|
||||||
@ -3723,7 +3728,9 @@ window_copy_search(struct window_mode_entry *wme, int direction, int regex)
|
|||||||
fx = data->cx;
|
fx = data->cx;
|
||||||
fy = screen_hsize(data->backing) - data->oy + data->cy;
|
fy = screen_hsize(data->backing) - data->oy + data->cy;
|
||||||
|
|
||||||
screen_init(&ss, screen_write_strlen("%s", str), 1, 0);
|
if ((ssx = screen_write_strlen("%s", str)) == 0)
|
||||||
|
return (0);
|
||||||
|
screen_init(&ss, ssx, 1, 0);
|
||||||
screen_write_start(&ctx, &ss);
|
screen_write_start(&ctx, &ss);
|
||||||
screen_write_nputs(&ctx, -1, &grid_default_cell, "%s", str);
|
screen_write_nputs(&ctx, -1, &grid_default_cell, "%s", str);
|
||||||
screen_write_stop(&ctx);
|
screen_write_stop(&ctx);
|
||||||
@ -4083,9 +4090,15 @@ window_copy_match_at_cursor(struct window_copy_mode_data *data)
|
|||||||
px = at - (py * sx);
|
px = at - (py * sx);
|
||||||
|
|
||||||
grid_get_cell(gd, px, gd->hsize + py - data->oy, &gc);
|
grid_get_cell(gd, px, gd->hsize + py - data->oy, &gc);
|
||||||
buf = xrealloc(buf, len + gc.data.size + 1);
|
if (gc.flags & GRID_FLAG_TAB) {
|
||||||
memcpy(buf + len, gc.data.data, gc.data.size);
|
buf = xrealloc(buf, len + 2);
|
||||||
len += gc.data.size;
|
buf[len] = '\t';
|
||||||
|
len++;
|
||||||
|
} else {
|
||||||
|
buf = xrealloc(buf, len + gc.data.size + 1);
|
||||||
|
memcpy(buf + len, gc.data.data, gc.data.size);
|
||||||
|
len += gc.data.size;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (len != 0)
|
if (len != 0)
|
||||||
buf[len] = '\0';
|
buf[len] = '\0';
|
||||||
@ -4812,7 +4825,10 @@ window_copy_copy_line(struct window_mode_entry *wme, char **buf, size_t *off,
|
|||||||
grid_get_cell(gd, i, sy, &gc);
|
grid_get_cell(gd, i, sy, &gc);
|
||||||
if (gc.flags & GRID_FLAG_PADDING)
|
if (gc.flags & GRID_FLAG_PADDING)
|
||||||
continue;
|
continue;
|
||||||
utf8_copy(&ud, &gc.data);
|
if (gc.flags & GRID_FLAG_TAB)
|
||||||
|
utf8_set(&ud, '\t');
|
||||||
|
else
|
||||||
|
utf8_copy(&ud, &gc.data);
|
||||||
if (ud.size == 1 && (gc.attr & GRID_ATTR_CHARSET)) {
|
if (ud.size == 1 && (gc.attr & GRID_ATTR_CHARSET)) {
|
||||||
s = tty_acs_get(NULL, ud.data[0]);
|
s = tty_acs_get(NULL, ud.data[0]);
|
||||||
if (s != NULL && strlen(s) <= sizeof ud.data) {
|
if (s != NULL && strlen(s) <= sizeof ud.data) {
|
||||||
|
Loading…
Reference in New Issue
Block a user