mirror of
https://github.com/tmux/tmux.git
synced 2026-05-30 14:16:18 +00:00
Merge branch 'obsd-master'
This commit is contained in:
@@ -63,6 +63,7 @@ cmd_copy_mode_exec(struct cmd *self, struct cmdq_item *item)
|
||||
struct client *c = cmdq_get_client(item);
|
||||
struct session *s;
|
||||
struct window_pane *wp = target->wp, *swp;
|
||||
int line_numbers;
|
||||
|
||||
if (args_has(args, 'q')) {
|
||||
window_pane_reset_mode_all(wp);
|
||||
@@ -85,10 +86,15 @@ cmd_copy_mode_exec(struct cmd *self, struct cmdq_item *item)
|
||||
swp = source->wp;
|
||||
else
|
||||
swp = wp;
|
||||
line_numbers = 1;
|
||||
if (event != NULL && KEYC_IS_MOUSE(event->key))
|
||||
line_numbers = 0;
|
||||
if (!window_pane_set_mode(wp, swp, &window_copy_mode, NULL, args)) {
|
||||
window_copy_set_line_numbers(wp, line_numbers);
|
||||
if (args_has(args, 'M'))
|
||||
window_copy_start_drag(c, &event->m);
|
||||
}
|
||||
} else
|
||||
window_copy_set_line_numbers(wp, line_numbers);
|
||||
if (args_has(args, 'u'))
|
||||
window_copy_pageup(wp, 0);
|
||||
if (args_has(args, 'd'))
|
||||
|
||||
24
format.c
24
format.c
@@ -4243,6 +4243,20 @@ format_choose(struct format_expand_state *es, const char *s, char **left,
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Check format has not taken too lon. */
|
||||
static int
|
||||
format_check_time(struct format_expand_state *es)
|
||||
{
|
||||
uint64_t t = get_timer();
|
||||
|
||||
if (t - es->start_time < FORMAT_TIME_LIMIT)
|
||||
return (1);
|
||||
t -= es->start_time;
|
||||
|
||||
format_log(es, "reached time limit (%llu)", (unsigned long long)t);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Is this true? */
|
||||
int
|
||||
format_true(const char *s)
|
||||
@@ -5265,6 +5279,8 @@ format_replace(struct format_expand_state *es, const char *key, size_t keylen,
|
||||
else {
|
||||
value = xstrdup("");
|
||||
for (i = 0; i < nrep; i++) {
|
||||
if (!format_check_time(es))
|
||||
goto fail;
|
||||
xasprintf(&new, "%s%s", value, left);
|
||||
free(value);
|
||||
value = new;
|
||||
@@ -5538,16 +5554,10 @@ format_expand1(struct format_expand_state *es, const char *fmt)
|
||||
size_t off, len, n, outlen;
|
||||
int ch, brackets;
|
||||
char expanded[8192];
|
||||
uint64_t t = get_timer();
|
||||
|
||||
if (fmt == NULL || *fmt == '\0')
|
||||
if (fmt == NULL || *fmt == '\0' || !format_check_time(es))
|
||||
return (xstrdup(""));
|
||||
|
||||
if (t - es->start_time >= FORMAT_TIME_LIMIT) {
|
||||
format_log(es, "reached time limit (%llu)",
|
||||
(unsigned long long)(t - es->start_time));
|
||||
return (xstrdup(""));
|
||||
}
|
||||
if (es->loop == FORMAT_LOOP_LIMIT) {
|
||||
format_log(es, "reached loop limit (%u)", FORMAT_LOOP_LIMIT);
|
||||
return (xstrdup(""));
|
||||
|
||||
@@ -108,6 +108,9 @@ static const char *options_table_extended_keys_format_list[] = {
|
||||
static const char *options_table_allow_passthrough_list[] = {
|
||||
"off", "on", "all", NULL
|
||||
};
|
||||
static const char *options_table_copy_mode_line_numbers_list[] = {
|
||||
"off", "default", "absolute", "relative", "hybrid", NULL
|
||||
};
|
||||
|
||||
/* Status line format. */
|
||||
#define OPTIONS_TABLE_STATUS_FORMAT1 \
|
||||
@@ -1176,7 +1179,7 @@ const struct options_table_entry options_table[] = {
|
||||
.scope = OPTIONS_TABLE_WINDOW|OPTIONS_TABLE_PANE,
|
||||
.default_str = "#[align=right]"
|
||||
"#{t/p:top_line_time}#{?#{e|>:#{top_line_time},0}, ,}"
|
||||
"[#{scroll_position}/#{history_size}]"
|
||||
"[#{copy_position}/#{copy_position_limit}]"
|
||||
"#{?search_timed_out, (timed out),"
|
||||
"#{?search_count, (#{search_count}"
|
||||
"#{?search_count_partial,+,} results),}}",
|
||||
@@ -1201,6 +1204,32 @@ const struct options_table_entry options_table[] = {
|
||||
.text = "Style of selection in copy mode."
|
||||
},
|
||||
|
||||
{ .name = "copy-mode-current-line-number-style",
|
||||
.type = OPTIONS_TABLE_STRING,
|
||||
.scope = OPTIONS_TABLE_WINDOW,
|
||||
.default_str = "fg=yellow",
|
||||
.flags = OPTIONS_TABLE_IS_STYLE,
|
||||
.separator = ",",
|
||||
.text = "Style of current line number in copy mode."
|
||||
},
|
||||
|
||||
{ .name = "copy-mode-line-number-style",
|
||||
.type = OPTIONS_TABLE_STRING,
|
||||
.scope = OPTIONS_TABLE_WINDOW,
|
||||
.default_str = "fg=white,dim",
|
||||
.flags = OPTIONS_TABLE_IS_STYLE,
|
||||
.separator = ",",
|
||||
.text = "Style of line numbers in copy mode."
|
||||
},
|
||||
|
||||
{ .name = "copy-mode-line-numbers",
|
||||
.type = OPTIONS_TABLE_CHOICE,
|
||||
.scope = OPTIONS_TABLE_WINDOW,
|
||||
.choices = options_table_copy_mode_line_numbers_list,
|
||||
.default_num = 0,
|
||||
.text = "Line number mode in copy mode."
|
||||
},
|
||||
|
||||
{ .name = "fill-character",
|
||||
.type = OPTIONS_TABLE_STRING,
|
||||
.scope = OPTIONS_TABLE_WINDOW,
|
||||
|
||||
8
screen.c
8
screen.c
@@ -36,6 +36,8 @@ struct screen_sel {
|
||||
u_int ex;
|
||||
u_int ey;
|
||||
|
||||
u_int clipx;
|
||||
|
||||
struct grid_cell cell;
|
||||
};
|
||||
|
||||
@@ -465,7 +467,8 @@ screen_resize_y(struct screen *s, u_int sy, int eat_empty, u_int *cy)
|
||||
/* Set selection. */
|
||||
void
|
||||
screen_set_selection(struct screen *s, u_int sx, u_int sy,
|
||||
u_int ex, u_int ey, u_int rectangle, int modekeys, struct grid_cell *gc)
|
||||
u_int ex, u_int ey, u_int rectangle, u_int clipx, int modekeys,
|
||||
struct grid_cell *gc)
|
||||
{
|
||||
if (s->sel == NULL)
|
||||
s->sel = xcalloc(1, sizeof *s->sel);
|
||||
@@ -479,6 +482,7 @@ screen_set_selection(struct screen *s, u_int sx, u_int sy,
|
||||
s->sel->sy = sy;
|
||||
s->sel->ex = ex;
|
||||
s->sel->ey = ey;
|
||||
s->sel->clipx = clipx;
|
||||
}
|
||||
|
||||
/* Clear selection. */
|
||||
@@ -506,6 +510,8 @@ screen_check_selection(struct screen *s, u_int px, u_int py)
|
||||
|
||||
if (sel == NULL || sel->hidden)
|
||||
return (0);
|
||||
if (px < sel->clipx)
|
||||
return (0);
|
||||
|
||||
if (sel->rectangle) {
|
||||
if (sel->sy < sel->ey) {
|
||||
|
||||
48
tmux.1
48
tmux.1
@@ -5175,6 +5175,52 @@ see the
|
||||
.Sx STYLES
|
||||
section.
|
||||
.Pp
|
||||
.It Ic copy\-mode\-current\-line\-number\-style Ar style
|
||||
Set style of current line number in copy mode.
|
||||
For how to specify
|
||||
.Ar style ,
|
||||
see the
|
||||
.Sx STYLES
|
||||
section.
|
||||
.Pp
|
||||
.It Ic copy\-mode\-line\-number\-style Ar style
|
||||
Set style of line numbers in copy mode.
|
||||
For how to specify
|
||||
.Ar style ,
|
||||
see the
|
||||
.Sx STYLES
|
||||
section.
|
||||
.Pp
|
||||
.It Xo Ic copy\-mode\-line\-numbers
|
||||
.Op Ic off | default | absolute | relative | hybrid
|
||||
.Xc
|
||||
Show line numbers in copy mode.
|
||||
.Ic off
|
||||
hides line numbers,
|
||||
.Ic default
|
||||
shows line numbers matching the copy mode position indicator and
|
||||
.Ic goto\-line ,
|
||||
.Ic absolute
|
||||
shows absolute line numbers,
|
||||
.Ic relative
|
||||
shows line numbers relative to the cursor, and
|
||||
.Ic hybrid
|
||||
shows the current line number as absolute and other line numbers as
|
||||
relative.
|
||||
With
|
||||
.Ic off
|
||||
or
|
||||
.Ic default ,
|
||||
the position indicator and
|
||||
.Ic goto\-line
|
||||
use the same numbering;
|
||||
with
|
||||
.Ic absolute ,
|
||||
.Ic relative
|
||||
and
|
||||
.Ic hybrid ,
|
||||
they use absolute line numbers.
|
||||
.Pp
|
||||
.It Ic mode\-style Ar style
|
||||
Set window modes style.
|
||||
For how to specify
|
||||
@@ -6310,6 +6356,8 @@ The following variables are available, where appropriate:
|
||||
.It Li "copy_cursor_word" Ta "" Ta "Word under cursor in copy mode"
|
||||
.It Li "copy_cursor_x" Ta "" Ta "Cursor X position in copy mode"
|
||||
.It Li "copy_cursor_y" Ta "" Ta "Cursor Y position in copy mode"
|
||||
.It Li "copy_position" Ta "" Ta "Position shown in the copy mode indicator"
|
||||
.It Li "copy_position_limit" Ta "" Ta "Limit shown in the copy mode indicator"
|
||||
.It Li "current_file" Ta "" Ta "Current configuration file"
|
||||
.It Li "cursor_character" Ta "" Ta "Character at cursor in pane"
|
||||
.It Li "cursor_colour" Ta "" Ta "Cursor colour in pane"
|
||||
|
||||
3
tmux.h
3
tmux.h
@@ -3343,7 +3343,7 @@ void screen_set_progress_bar(struct screen *, enum progress_bar_state, int);
|
||||
void screen_resize(struct screen *, u_int, u_int, int);
|
||||
void screen_resize_cursor(struct screen *, u_int, u_int, int, int, int);
|
||||
void screen_set_selection(struct screen *, u_int, u_int, u_int, u_int,
|
||||
u_int, int, struct grid_cell *);
|
||||
u_int, u_int, int, struct grid_cell *);
|
||||
void screen_clear_selection(struct screen *);
|
||||
void screen_hide_selection(struct screen *);
|
||||
int screen_check_selection(struct screen *, u_int, u_int);
|
||||
@@ -3581,6 +3581,7 @@ char *window_copy_get_line(struct window_pane *, u_int);
|
||||
int window_copy_get_current_offset(struct window_pane *, u_int *,
|
||||
u_int *);
|
||||
char *window_copy_get_hyperlink(struct window_pane *, u_int, u_int);
|
||||
void window_copy_set_line_numbers(struct window_pane *, int);
|
||||
|
||||
/* window-option.c */
|
||||
extern const struct window_mode window_customize_mode;
|
||||
|
||||
343
window-copy.c
343
window-copy.c
@@ -52,6 +52,12 @@ static void window_copy_redraw_lines(struct window_mode_entry *, u_int,
|
||||
u_int);
|
||||
static void window_copy_redraw_screen(struct window_mode_entry *);
|
||||
static void window_copy_style_changed(struct window_mode_entry *);
|
||||
static int window_copy_line_number_mode(struct window_mode_entry *);
|
||||
static int window_copy_line_number_is_absolute(struct window_mode_entry *);
|
||||
static int window_copy_line_numbers_active(struct window_mode_entry *);
|
||||
static u_int window_copy_line_number_width(struct window_mode_entry *);
|
||||
static u_int window_copy_cursor_offset(struct window_mode_entry *, u_int, u_int);
|
||||
static u_int window_copy_cursor_unoffset(struct window_mode_entry *, u_int, u_int);
|
||||
static void window_copy_write_line(struct window_mode_entry *,
|
||||
struct screen_write_ctx *, u_int);
|
||||
static void window_copy_write_lines(struct window_mode_entry *,
|
||||
@@ -207,6 +213,14 @@ enum window_copy_cmd_clear {
|
||||
WINDOW_COPY_CMD_CLEAR_EMACS_ONLY,
|
||||
};
|
||||
|
||||
enum window_copy_line_numbers {
|
||||
WINDOW_COPY_LINE_NUMBERS_OFF,
|
||||
WINDOW_COPY_LINE_NUMBERS_DEFAULT,
|
||||
WINDOW_COPY_LINE_NUMBERS_ABSOLUTE,
|
||||
WINDOW_COPY_LINE_NUMBERS_RELATIVE,
|
||||
WINDOW_COPY_LINE_NUMBERS_HYBRID,
|
||||
};
|
||||
|
||||
struct window_copy_cmd_state {
|
||||
struct window_mode_entry *wme;
|
||||
struct args *args;
|
||||
@@ -264,6 +278,7 @@ struct window_copy_mode_data {
|
||||
int rectflag; /* in rectangle copy mode? */
|
||||
int scroll_exit; /* exit on scroll to end? */
|
||||
int hide_position; /* hide position marker */
|
||||
int line_numbers;
|
||||
|
||||
enum {
|
||||
SEL_CHAR, /* select one char at a time */
|
||||
@@ -427,6 +442,7 @@ window_copy_common_init(struct window_mode_entry *wme)
|
||||
|
||||
data->jumptype = WINDOW_COPY_OFF;
|
||||
data->jumpchar = NULL;
|
||||
data->line_numbers = 1;
|
||||
|
||||
screen_init(&data->screen, screen_size_x(base), screen_size_y(base), 0);
|
||||
screen_set_default_cursor(&data->screen, global_w_options);
|
||||
@@ -467,7 +483,8 @@ window_copy_init(struct window_mode_entry *wme,
|
||||
hyperlinks_free(data->screen.hyperlinks);
|
||||
data->screen.hyperlinks = hyperlinks_copy(base->hyperlinks);
|
||||
}
|
||||
data->screen.cx = data->cx;
|
||||
data->screen.cx = window_copy_cursor_offset(wme, data->cx,
|
||||
screen_size_x(&data->screen));
|
||||
data->screen.cy = data->cy;
|
||||
data->mx = data->cx;
|
||||
data->my = screen_hsize(data->backing) + data->cy - data->oy;
|
||||
@@ -476,7 +493,8 @@ window_copy_init(struct window_mode_entry *wme,
|
||||
screen_write_start(&ctx, &data->screen);
|
||||
for (i = 0; i < screen_size_y(&data->screen); i++)
|
||||
window_copy_write_line(wme, &ctx, i);
|
||||
screen_write_cursormove(&ctx, data->cx, data->cy, 0);
|
||||
screen_write_cursormove(&ctx, window_copy_cursor_offset(wme, data->cx,
|
||||
screen_size_x(&data->screen)), data->cy, 0);
|
||||
screen_write_stop(&ctx);
|
||||
|
||||
return (&data->screen);
|
||||
@@ -493,6 +511,7 @@ window_copy_view_init(struct window_mode_entry *wme,
|
||||
|
||||
data = window_copy_common_init(wme);
|
||||
data->viewmode = 1;
|
||||
data->line_numbers = 0;
|
||||
|
||||
data->backing = xmalloc(sizeof *data->backing);
|
||||
screen_init(data->backing, sx, screen_size_y(base), UINT_MAX);
|
||||
@@ -931,12 +950,22 @@ window_copy_formats(struct window_mode_entry *wme, struct format_tree *ft)
|
||||
{
|
||||
struct window_copy_mode_data *data = wme->data;
|
||||
u_int hsize = screen_hsize(data->backing);
|
||||
u_int position, limit;
|
||||
struct grid_line *gl;
|
||||
|
||||
gl = grid_get_line(data->backing->grid, hsize - data->oy);
|
||||
format_add(ft, "top_line_time", "%llu", (unsigned long long)gl->time);
|
||||
|
||||
format_add(ft, "scroll_position", "%d", data->oy);
|
||||
if (window_copy_line_number_is_absolute(wme)) {
|
||||
position = hsize - data->oy + 1;
|
||||
limit = hsize + screen_size_y(data->backing);
|
||||
} else {
|
||||
position = data->oy;
|
||||
limit = hsize;
|
||||
}
|
||||
format_add(ft, "copy_position", "%u", position);
|
||||
format_add(ft, "copy_position_limit", "%u", limit);
|
||||
format_add(ft, "rectangle_toggle", "%d", data->rectflag);
|
||||
|
||||
format_add(ft, "copy_cursor_x", "%d", data->cx);
|
||||
@@ -4462,15 +4491,28 @@ window_copy_goto_line(struct window_mode_entry *wme, const char *linestr)
|
||||
{
|
||||
struct window_copy_mode_data *data = wme->data;
|
||||
const char *errstr;
|
||||
u_int hsize = screen_hsize(data->backing);
|
||||
u_int line;
|
||||
int lineno;
|
||||
|
||||
lineno = strtonum(linestr, -1, INT_MAX, &errstr);
|
||||
if (errstr != NULL)
|
||||
return;
|
||||
if (lineno < 0 || (u_int)lineno > screen_hsize(data->backing))
|
||||
lineno = screen_hsize(data->backing);
|
||||
|
||||
if (window_copy_line_number_is_absolute(wme)) {
|
||||
if (lineno <= 0)
|
||||
line = 1;
|
||||
else if ((u_int)lineno > hsize + 1)
|
||||
line = hsize + 1;
|
||||
else
|
||||
line = lineno;
|
||||
data->oy = hsize - (line - 1);
|
||||
} else {
|
||||
if (lineno < 0 || (u_int)lineno > hsize)
|
||||
lineno = hsize;
|
||||
data->oy = lineno;
|
||||
}
|
||||
|
||||
window_copy_update_selection(wme, 1, 0);
|
||||
window_copy_redraw_screen(wme);
|
||||
}
|
||||
@@ -4619,7 +4661,7 @@ window_copy_update_style(struct window_mode_entry *wme, u_int fx, u_int fy,
|
||||
|
||||
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,
|
||||
struct screen_write_ctx *ctx, u_int px, u_int py, u_int fy, u_int nx,
|
||||
const struct grid_cell *mgc, const struct grid_cell *cgc,
|
||||
const struct grid_cell *mkgc)
|
||||
{
|
||||
@@ -4628,7 +4670,7 @@ window_copy_write_one(struct window_mode_entry *wme,
|
||||
struct grid_cell gc;
|
||||
u_int fx;
|
||||
|
||||
screen_write_cursormove(ctx, 0, py, 0);
|
||||
screen_write_cursormove(ctx, px, py, 0);
|
||||
for (fx = 0; fx < nx; fx++) {
|
||||
grid_get_cell(gd, fx, fy, &gc);
|
||||
if (fx + gc.data.width <= nx) {
|
||||
@@ -4639,6 +4681,116 @@ window_copy_write_one(struct window_mode_entry *wme,
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
window_copy_line_number_mode(struct window_mode_entry *wme)
|
||||
{
|
||||
struct window_pane *wp = wme->wp;
|
||||
struct window_copy_mode_data *data = wme->data;
|
||||
struct options *oo = wp->window->options;
|
||||
|
||||
if (!data->line_numbers)
|
||||
return (WINDOW_COPY_LINE_NUMBERS_OFF);
|
||||
return (options_get_number(oo, "copy-mode-line-numbers"));
|
||||
}
|
||||
|
||||
static int
|
||||
window_copy_line_number_is_absolute(struct window_mode_entry *wme)
|
||||
{
|
||||
switch (window_copy_line_number_mode(wme)) {
|
||||
case WINDOW_COPY_LINE_NUMBERS_ABSOLUTE:
|
||||
case WINDOW_COPY_LINE_NUMBERS_RELATIVE:
|
||||
case WINDOW_COPY_LINE_NUMBERS_HYBRID:
|
||||
return (1);
|
||||
case WINDOW_COPY_LINE_NUMBERS_OFF:
|
||||
case WINDOW_COPY_LINE_NUMBERS_DEFAULT:
|
||||
return (0);
|
||||
}
|
||||
fatalx("bad line number mode");
|
||||
}
|
||||
|
||||
static int
|
||||
window_copy_line_numbers_active(struct window_mode_entry *wme)
|
||||
{
|
||||
return (window_copy_line_number_mode(wme) !=
|
||||
WINDOW_COPY_LINE_NUMBERS_OFF);
|
||||
}
|
||||
|
||||
static u_int
|
||||
window_copy_line_number_width(struct window_mode_entry *wme)
|
||||
{
|
||||
struct window_copy_mode_data *data = wme->data;
|
||||
u_int lines, digits;
|
||||
|
||||
if (!window_copy_line_numbers_active(wme))
|
||||
return (0);
|
||||
|
||||
lines = screen_hsize(data->backing) + screen_size_y(data->backing) + 1;
|
||||
digits = 1;
|
||||
while (lines >= 10) {
|
||||
lines /= 10;
|
||||
digits++;
|
||||
}
|
||||
if (digits < 3)
|
||||
digits = 3;
|
||||
return (digits + 1);
|
||||
}
|
||||
|
||||
static u_int
|
||||
window_copy_cursor_offset(struct window_mode_entry *wme, u_int cx, u_int sx)
|
||||
{
|
||||
u_int width = window_copy_line_number_width(wme);
|
||||
u_int content;
|
||||
|
||||
if (width == 0)
|
||||
return (cx);
|
||||
if (width >= sx)
|
||||
content = 1;
|
||||
else
|
||||
content = sx - width;
|
||||
if (cx >= content)
|
||||
return (sx - 1);
|
||||
return (width + cx);
|
||||
}
|
||||
|
||||
static u_int
|
||||
window_copy_cursor_unoffset(struct window_mode_entry *wme, u_int vx, u_int sx)
|
||||
{
|
||||
u_int width = window_copy_line_number_width(wme);
|
||||
u_int content;
|
||||
|
||||
if (width == 0)
|
||||
return (vx);
|
||||
if (width >= sx)
|
||||
content = 1;
|
||||
else
|
||||
content = sx - width;
|
||||
if (vx < width)
|
||||
return (0);
|
||||
vx -= width;
|
||||
if (vx >= content)
|
||||
return (content - 1);
|
||||
return (vx);
|
||||
}
|
||||
|
||||
void
|
||||
window_copy_set_line_numbers(struct window_pane *wp, int enabled)
|
||||
{
|
||||
struct window_mode_entry *wme = TAILQ_FIRST(&wp->modes);
|
||||
struct window_copy_mode_data *data;
|
||||
|
||||
if (wme == NULL)
|
||||
return;
|
||||
if (wme->mode != &window_copy_mode)
|
||||
return;
|
||||
data = wme->data;
|
||||
if (data == NULL)
|
||||
return;
|
||||
if (data->line_numbers == enabled)
|
||||
return;
|
||||
data->line_numbers = enabled;
|
||||
window_copy_redraw_screen(wme);
|
||||
}
|
||||
|
||||
int
|
||||
window_copy_get_current_offset(struct window_pane *wp, u_int *offset,
|
||||
u_int *size)
|
||||
@@ -4664,12 +4816,23 @@ window_copy_write_line(struct window_mode_entry *wme,
|
||||
struct window_copy_mode_data *data = wme->data;
|
||||
struct screen *s = &data->screen;
|
||||
struct options *oo = wp->window->options;
|
||||
struct grid_cell gc, mgc, cgc, mkgc;
|
||||
struct grid_cell gc, mgc, cgc, mkgc, ln_gc, cur_ln_gc;
|
||||
u_int sx = screen_size_x(s);
|
||||
u_int hsize = screen_hsize(data->backing);
|
||||
u_int width;
|
||||
u_int absolute, line_number, content_sx;
|
||||
const char *value;
|
||||
char *expanded;
|
||||
struct format_tree *ft;
|
||||
int current, mode;
|
||||
|
||||
width = window_copy_line_number_width(wme);
|
||||
if (width >= sx)
|
||||
content_sx = 1;
|
||||
else if (width != 0)
|
||||
content_sx = sx - width;
|
||||
else
|
||||
content_sx = sx;
|
||||
|
||||
ft = format_create_defaults(NULL, NULL, NULL, NULL, wp);
|
||||
|
||||
@@ -4681,24 +4844,52 @@ window_copy_write_line(struct window_mode_entry *wme,
|
||||
cgc.flags |= GRID_FLAG_NOPALETTE;
|
||||
style_apply(&mkgc, oo, "copy-mode-mark-style", ft);
|
||||
mkgc.flags |= GRID_FLAG_NOPALETTE;
|
||||
if (width != 0) {
|
||||
style_apply(&ln_gc, oo, "copy-mode-line-number-style", ft);
|
||||
ln_gc.flags |= GRID_FLAG_NOPALETTE;
|
||||
style_apply(&cur_ln_gc, oo,
|
||||
"copy-mode-current-line-number-style", ft);
|
||||
cur_ln_gc.flags |= GRID_FLAG_NOPALETTE;
|
||||
current = (py == data->cy);
|
||||
absolute = hsize - data->oy + py + 1;
|
||||
mode = window_copy_line_number_mode(wme);
|
||||
if (mode == WINDOW_COPY_LINE_NUMBERS_DEFAULT) {
|
||||
if (py < data->oy)
|
||||
line_number = data->oy - py;
|
||||
else
|
||||
line_number = py - data->oy;
|
||||
} else if (mode == WINDOW_COPY_LINE_NUMBERS_ABSOLUTE)
|
||||
line_number = absolute;
|
||||
else if (mode == WINDOW_COPY_LINE_NUMBERS_HYBRID && current)
|
||||
line_number = absolute;
|
||||
else if (py > data->cy)
|
||||
line_number = py - data->cy;
|
||||
else
|
||||
line_number = data->cy - py;
|
||||
screen_write_cursormove(ctx, 0, py, 0);
|
||||
screen_write_nputs(ctx, width, current ? &cur_ln_gc : &ln_gc,
|
||||
"%*u ", (int)width - 1, line_number);
|
||||
}
|
||||
|
||||
window_copy_write_one(wme, ctx, py, hsize - data->oy + py,
|
||||
screen_size_x(s), &mgc, &cgc, &mkgc);
|
||||
window_copy_write_one(wme, ctx, width, py, hsize - data->oy + py,
|
||||
content_sx, &mgc, &cgc, &mkgc);
|
||||
|
||||
if (py == 0 && s->rupper < s->rlower && !data->hide_position) {
|
||||
value = options_get_string(oo, "copy-mode-position-format");
|
||||
if (*value != '\0') {
|
||||
expanded = format_expand(ft, value);
|
||||
if (*expanded != '\0') {
|
||||
screen_write_cursormove(ctx, 0, 0, 0);
|
||||
format_draw(ctx, &gc, sx, expanded, NULL, 0);
|
||||
screen_write_cursormove(ctx, width, 0, 0);
|
||||
format_draw(ctx, &gc, content_sx, expanded,
|
||||
NULL, 0);
|
||||
}
|
||||
free(expanded);
|
||||
}
|
||||
}
|
||||
|
||||
if (py == data->cy && data->cx == screen_size_x(s)) {
|
||||
screen_write_cursormove(ctx, screen_size_x(s) - 1, py, 0);
|
||||
if (py == data->cy && data->cx >= content_sx) {
|
||||
screen_write_cursormove(ctx, window_copy_cursor_offset(wme,
|
||||
data->cx, screen_size_x(s)), py, 0);
|
||||
screen_write_putc(ctx, &grid_default_cell, '$');
|
||||
}
|
||||
|
||||
@@ -4748,13 +4939,28 @@ window_copy_redraw_lines(struct window_mode_entry *wme, u_int py, u_int ny)
|
||||
{
|
||||
struct window_pane *wp = wme->wp;
|
||||
struct window_copy_mode_data *data = wme->data;
|
||||
struct screen *s = &data->screen;
|
||||
struct screen_write_ctx ctx;
|
||||
u_int i;
|
||||
|
||||
if (window_copy_line_number_width(wme) != 0) {
|
||||
screen_write_start(&ctx, &data->screen);
|
||||
for (i = py; i < py + ny; i++)
|
||||
window_copy_write_line(wme, &ctx, i);
|
||||
screen_write_cursormove(&ctx,
|
||||
window_copy_cursor_offset(wme, data->cx, screen_size_x(s)),
|
||||
data->cy, 0);
|
||||
screen_write_stop(&ctx);
|
||||
wp->flags |= (PANE_REDRAW|PANE_REDRAWSCROLLBAR);
|
||||
return;
|
||||
}
|
||||
|
||||
screen_write_start_pane(&ctx, wp, NULL);
|
||||
for (i = py; i < py + ny; i++)
|
||||
window_copy_write_line(wme, &ctx, i);
|
||||
screen_write_cursormove(&ctx, data->cx, data->cy, 0);
|
||||
screen_write_cursormove(&ctx,
|
||||
window_copy_cursor_offset(wme, data->cx, screen_size_x(s)), data->cy,
|
||||
0);
|
||||
screen_write_stop(&ctx);
|
||||
|
||||
wp->flags |= PANE_REDRAWSCROLLBAR;
|
||||
@@ -4873,17 +5079,42 @@ window_copy_update_cursor(struct window_mode_entry *wme, u_int cx, u_int cy)
|
||||
struct window_copy_mode_data *data = wme->data;
|
||||
struct screen *s = &data->screen;
|
||||
struct screen_write_ctx ctx;
|
||||
u_int old_cx, old_cy;
|
||||
u_int old_cx, old_cy, width, content_sx;
|
||||
|
||||
old_cx = data->cx; old_cy = data->cy;
|
||||
data->cx = cx; data->cy = cy;
|
||||
if (window_copy_line_numbers_active(wme)) {
|
||||
width = window_copy_line_number_width(wme);
|
||||
|
||||
if (s->sel != NULL || data->lineflag != LINE_SEL_NONE ||
|
||||
old_cy != data->cy) {
|
||||
window_copy_redraw_screen(wme);
|
||||
return;
|
||||
}
|
||||
if (width >= screen_size_x(s))
|
||||
content_sx = 1;
|
||||
else
|
||||
content_sx = screen_size_x(s) - width;
|
||||
if (old_cx >= content_sx || data->cx >= content_sx) {
|
||||
window_copy_redraw_screen(wme);
|
||||
return;
|
||||
}
|
||||
screen_write_start_pane(&ctx, wp, NULL);
|
||||
screen_write_cursormove(&ctx,
|
||||
window_copy_cursor_offset(wme, data->cx, screen_size_x(s)),
|
||||
data->cy, 0);
|
||||
screen_write_stop(&ctx);
|
||||
return;
|
||||
}
|
||||
if (old_cx == screen_size_x(s))
|
||||
window_copy_redraw_lines(wme, old_cy, 1);
|
||||
if (data->cx == screen_size_x(s))
|
||||
window_copy_redraw_lines(wme, data->cy, 1);
|
||||
else {
|
||||
screen_write_start_pane(&ctx, wp, NULL);
|
||||
screen_write_cursormove(&ctx, data->cx, data->cy, 0);
|
||||
screen_write_cursormove(&ctx,
|
||||
window_copy_cursor_offset(wme, data->cx, screen_size_x(s)),
|
||||
data->cy, 0);
|
||||
screen_write_stop(&ctx);
|
||||
}
|
||||
}
|
||||
@@ -4958,7 +5189,7 @@ window_copy_set_selection(struct window_mode_entry *wme, int may_redraw,
|
||||
struct screen *s = &data->screen;
|
||||
struct options *oo = wp->window->options;
|
||||
struct grid_cell gc;
|
||||
u_int sx, sy, cy, endsx, endsy;
|
||||
u_int sx, sy, cy, endsx, endsy, clipx;
|
||||
int startrelpos, endrelpos;
|
||||
struct format_tree *ft;
|
||||
|
||||
@@ -4986,8 +5217,15 @@ window_copy_set_selection(struct window_mode_entry *wme, int may_redraw,
|
||||
style_apply(&gc, oo, "copy-mode-selection-style", ft);
|
||||
gc.flags |= GRID_FLAG_NOPALETTE;
|
||||
format_free(ft);
|
||||
clipx = window_copy_line_number_width(wme);
|
||||
if (clipx >= screen_size_x(s))
|
||||
clipx = screen_size_x(s) - 1;
|
||||
if (window_copy_line_numbers_active(wme)) {
|
||||
sx = window_copy_cursor_offset(wme, sx, screen_size_x(s));
|
||||
endsx = window_copy_cursor_offset(wme, endsx, screen_size_x(s));
|
||||
}
|
||||
screen_set_selection(s, sx, sy, endsx, endsy, data->rectflag,
|
||||
data->modekeys, &gc);
|
||||
clipx, data->modekeys, &gc);
|
||||
|
||||
if (data->rectflag && may_redraw) {
|
||||
/*
|
||||
@@ -5143,12 +5381,20 @@ window_copy_copy_buffer(struct window_mode_entry *wme, const char *prefix,
|
||||
{
|
||||
struct window_pane *wp = wme->wp;
|
||||
struct screen_write_ctx ctx;
|
||||
int redraw = 0;
|
||||
|
||||
if (set_clip &&
|
||||
options_get_number(global_options, "set-clipboard") != 0) {
|
||||
if (window_copy_line_numbers_active(wme) &&
|
||||
(wp->flags & PANE_REDRAW)) {
|
||||
/* Clear PANE_REDRAW so clipboard write not skipped. */
|
||||
redraw = PANE_REDRAW;
|
||||
wp->flags &= ~PANE_REDRAW;
|
||||
}
|
||||
screen_write_start_pane(&ctx, wp, NULL);
|
||||
screen_write_setselection(&ctx, "", buf, len);
|
||||
screen_write_stop(&ctx);
|
||||
wp->flags |= redraw;
|
||||
notify_pane("pane-set-clipboard", wp);
|
||||
}
|
||||
|
||||
@@ -5922,6 +6168,32 @@ window_copy_scroll_up(struct window_mode_entry *wme, u_int ny)
|
||||
if (data->searchmark != NULL && !data->timeout)
|
||||
window_copy_search_marks(wme, NULL, data->searchregex, 1);
|
||||
window_copy_update_selection(wme, 0, 0);
|
||||
if (window_copy_line_numbers_active(wme)) {
|
||||
if (window_copy_line_number_mode(wme) !=
|
||||
WINDOW_COPY_LINE_NUMBERS_ABSOLUTE) {
|
||||
window_copy_redraw_screen(wme);
|
||||
return;
|
||||
}
|
||||
screen_write_start(&ctx, &data->screen);
|
||||
screen_write_cursormove(&ctx, 0, 0, 0);
|
||||
screen_write_deleteline(&ctx, ny, 8);
|
||||
window_copy_write_lines(wme, &ctx, screen_size_y(s) - ny, ny);
|
||||
window_copy_write_line(wme, &ctx, 0);
|
||||
if (screen_size_y(s) > 1)
|
||||
window_copy_write_line(wme, &ctx, 1);
|
||||
if (screen_size_y(s) > 3)
|
||||
window_copy_write_line(wme, &ctx, screen_size_y(s) - 2);
|
||||
if (s->sel != NULL && screen_size_y(s) > ny) {
|
||||
window_copy_write_line(wme, &ctx,
|
||||
screen_size_y(s) - ny - 1);
|
||||
}
|
||||
screen_write_cursormove(&ctx,
|
||||
window_copy_cursor_offset(wme, data->cx, screen_size_x(s)),
|
||||
data->cy, 0);
|
||||
screen_write_stop(&ctx);
|
||||
wp->flags |= (PANE_REDRAW|PANE_REDRAWSCROLLBAR);
|
||||
return;
|
||||
}
|
||||
|
||||
screen_write_start_pane(&ctx, wp, NULL);
|
||||
screen_write_cursormove(&ctx, 0, 0, 0);
|
||||
@@ -5934,7 +6206,9 @@ window_copy_scroll_up(struct window_mode_entry *wme, u_int ny)
|
||||
window_copy_write_line(wme, &ctx, screen_size_y(s) - 2);
|
||||
if (s->sel != NULL && screen_size_y(s) > ny)
|
||||
window_copy_write_line(wme, &ctx, screen_size_y(s) - ny - 1);
|
||||
screen_write_cursormove(&ctx, data->cx, data->cy, 0);
|
||||
screen_write_cursormove(&ctx,
|
||||
window_copy_cursor_offset(wme, data->cx, screen_size_x(s)), data->cy,
|
||||
0);
|
||||
screen_write_stop(&ctx);
|
||||
wp->flags |= PANE_REDRAWSCROLLBAR;
|
||||
}
|
||||
@@ -5959,6 +6233,27 @@ window_copy_scroll_down(struct window_mode_entry *wme, u_int ny)
|
||||
if (data->searchmark != NULL && !data->timeout)
|
||||
window_copy_search_marks(wme, NULL, data->searchregex, 1);
|
||||
window_copy_update_selection(wme, 0, 0);
|
||||
if (window_copy_line_numbers_active(wme)) {
|
||||
if (window_copy_line_number_mode(wme) !=
|
||||
WINDOW_COPY_LINE_NUMBERS_ABSOLUTE) {
|
||||
window_copy_redraw_screen(wme);
|
||||
return;
|
||||
}
|
||||
screen_write_start(&ctx, &data->screen);
|
||||
screen_write_cursormove(&ctx, 0, 0, 0);
|
||||
screen_write_insertline(&ctx, ny, 8);
|
||||
window_copy_write_lines(wme, &ctx, 0, ny);
|
||||
if (s->sel != NULL && screen_size_y(s) > ny)
|
||||
window_copy_write_line(wme, &ctx, ny);
|
||||
else if (ny == 1)
|
||||
window_copy_write_line(wme, &ctx, 1);
|
||||
screen_write_cursormove(&ctx,
|
||||
window_copy_cursor_offset(wme, data->cx, screen_size_x(s)),
|
||||
data->cy, 0);
|
||||
screen_write_stop(&ctx);
|
||||
wp->flags |= (PANE_REDRAW|PANE_REDRAWSCROLLBAR);
|
||||
return;
|
||||
}
|
||||
|
||||
screen_write_start_pane(&ctx, wp, NULL);
|
||||
screen_write_cursormove(&ctx, 0, 0, 0);
|
||||
@@ -5968,7 +6263,8 @@ window_copy_scroll_down(struct window_mode_entry *wme, u_int ny)
|
||||
window_copy_write_line(wme, &ctx, ny);
|
||||
else if (ny == 1) /* nuke position */
|
||||
window_copy_write_line(wme, &ctx, 1);
|
||||
screen_write_cursormove(&ctx, data->cx, data->cy, 0);
|
||||
screen_write_cursormove(&ctx, window_copy_cursor_offset(wme, data->cx,
|
||||
screen_size_x(s)), data->cy, 0);
|
||||
screen_write_stop(&ctx);
|
||||
wp->flags |= PANE_REDRAWSCROLLBAR;
|
||||
}
|
||||
@@ -5996,6 +6292,7 @@ window_copy_move_mouse(struct mouse_event *m)
|
||||
struct window_pane *wp;
|
||||
struct window_mode_entry *wme;
|
||||
u_int x, y;
|
||||
struct window_copy_mode_data *data;
|
||||
|
||||
wp = cmd_mouse_pane(m, NULL, NULL);
|
||||
if (wp == NULL)
|
||||
@@ -6009,6 +6306,8 @@ window_copy_move_mouse(struct mouse_event *m)
|
||||
if (cmd_mouse_at(wp, m, &x, &y, 0) != 0)
|
||||
return;
|
||||
|
||||
data = wme->data;
|
||||
x = window_copy_cursor_unoffset(wme, x, screen_size_x(&data->screen));
|
||||
window_copy_update_cursor(wme, x, y);
|
||||
}
|
||||
|
||||
@@ -6039,6 +6338,7 @@ window_copy_start_drag(struct client *c, struct mouse_event *m)
|
||||
c->tty.mouse_drag_release = window_copy_drag_release;
|
||||
|
||||
data = wme->data;
|
||||
x = window_copy_cursor_unoffset(wme, x, screen_size_x(&data->screen));
|
||||
yg = screen_hsize(data->backing) + y - data->oy;
|
||||
if (x < data->selrx || x > data->endselrx || yg != data->selry)
|
||||
data->selflag = SEL_CHAR;
|
||||
@@ -6093,6 +6393,7 @@ window_copy_drag_update(struct client *c, struct mouse_event *m)
|
||||
|
||||
if (cmd_mouse_at(wp, m, &x, &y, 0) != 0)
|
||||
return;
|
||||
x = window_copy_cursor_unoffset(wme, x, screen_size_x(&data->screen));
|
||||
old_cx = data->cx;
|
||||
old_cy = data->cy;
|
||||
|
||||
@@ -6130,6 +6431,8 @@ window_copy_drag_release(struct client *c, struct mouse_event *m)
|
||||
return;
|
||||
|
||||
data = wme->data;
|
||||
if (window_copy_line_numbers_active(wme))
|
||||
window_copy_drag_update(c, m);
|
||||
evtimer_del(&data->dragtimer);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user