Merge branch 'obsd-master'

This commit is contained in:
Thomas Adam 2013-11-14 07:51:26 +00:00
commit 3e498cdb49
9 changed files with 150 additions and 58 deletions

15
cfg.c
View File

@ -31,6 +31,7 @@ struct cmd_q *cfg_cmd_q;
int cfg_finished; int cfg_finished;
int cfg_references; int cfg_references;
struct causelist cfg_causes; struct causelist cfg_causes;
struct client *cfg_client;
int int
load_cfg(const char *path, struct cmd_q *cmdq, char **cause) load_cfg(const char *path, struct cmd_q *cmdq, char **cause)
@ -127,6 +128,20 @@ cfg_default_done(unused struct cmd_q *cmdq)
cmdq_free(cfg_cmd_q); cmdq_free(cfg_cmd_q);
cfg_cmd_q = NULL; cfg_cmd_q = NULL;
if (cfg_client != NULL) {
/*
* The client command queue starts with client_exit set to 1 so
* only continue if not empty (that is, we have been delayed
* during configuration parsing for long enough that the
* MSG_COMMAND has arrived), else the client will exit before
* the MSG_COMMAND which might tell it not to.
*/
if (!TAILQ_EMPTY(&cfg_client->cmdq->queue))
cmdq_continue(cfg_client->cmdq);
cfg_client->references--;
cfg_client = NULL;
}
} }
void void

View File

@ -468,7 +468,7 @@ client_callback(unused int fd, short events, void *data)
} }
if (events & EV_WRITE) { if (events & EV_WRITE) {
if (msgbuf_write(&client_ibuf.w) < 0) if (msgbuf_write(&client_ibuf.w) < 0 && errno != EAGAIN)
goto lost_server; goto lost_server;
} }

View File

@ -292,6 +292,7 @@ const struct mode_key_entry mode_key_vi_copy[] = {
{ 'k', 0, MODEKEYCOPY_UP }, { 'k', 0, MODEKEYCOPY_UP },
{ 'l', 0, MODEKEYCOPY_RIGHT }, { 'l', 0, MODEKEYCOPY_RIGHT },
{ 'n', 0, MODEKEYCOPY_SEARCHAGAIN }, { 'n', 0, MODEKEYCOPY_SEARCHAGAIN },
{ 'o', 0, MODEKEYCOPY_OTHEREND },
{ 't', 0, MODEKEYCOPY_JUMPTO }, { 't', 0, MODEKEYCOPY_JUMPTO },
{ 'q', 0, MODEKEYCOPY_CANCEL }, { 'q', 0, MODEKEYCOPY_CANCEL },
{ 'v', 0, MODEKEYCOPY_RECTANGLETOGGLE }, { 'v', 0, MODEKEYCOPY_RECTANGLETOGGLE },

View File

@ -155,8 +155,8 @@ server_client_lost(struct client *c)
free(c->ttyname); free(c->ttyname);
free(c->term); free(c->term);
evbuffer_free (c->stdin_data); evbuffer_free(c->stdin_data);
evbuffer_free (c->stdout_data); evbuffer_free(c->stdout_data);
if (c->stderr_data != c->stdout_data) if (c->stderr_data != c->stdout_data)
evbuffer_free (c->stderr_data); evbuffer_free (c->stderr_data);
@ -222,7 +222,8 @@ server_client_callback(int fd, short events, void *data)
return; return;
if (fd == c->ibuf.fd) { if (fd == c->ibuf.fd) {
if (events & EV_WRITE && msgbuf_write(&c->ibuf.w) < 0) if (events & EV_WRITE && msgbuf_write(&c->ibuf.w) < 0 &&
errno != EAGAIN)
goto client_lost; goto client_lost;
if (c->flags & CLIENT_BAD) { if (c->flags & CLIENT_BAD) {
@ -932,7 +933,10 @@ server_client_msg_command(struct client *c, struct imsg *imsg)
} }
cmd_free_argv(argc, argv); cmd_free_argv(argc, argv);
cmdq_run(c->cmdq, cmdlist); if (c != cfg_client || cfg_finished)
cmdq_run(c->cmdq, cmdlist);
else
cmdq_append(c->cmdq, cmdlist);
cmd_list_free(cmdlist); cmd_list_free(cmdlist);
return; return;

View File

@ -169,6 +169,9 @@ server_start(int lockfd, char *lockfile)
cfg_finished = 0; cfg_finished = 0;
cfg_references = 1; cfg_references = 1;
ARRAY_INIT(&cfg_causes); ARRAY_INIT(&cfg_causes);
cfg_client = ARRAY_FIRST(&clients);
if (cfg_client != NULL)
cfg_client->references++;
if (access(TMUX_CONF, R_OK) == 0) { if (access(TMUX_CONF, R_OK) == 0) {
if (load_cfg(TMUX_CONF, cfg_cmd_q, &cause) == -1) { if (load_cfg(TMUX_CONF, cfg_cmd_q, &cause) == -1) {

1
tmux.1
View File

@ -874,6 +874,7 @@ The following keys are supported as appropriate for the mode:
.It Li "Next space, end of word" Ta "E" Ta "" .It Li "Next space, end of word" Ta "E" Ta ""
.It Li "Next word" Ta "w" Ta "" .It Li "Next word" Ta "w" Ta ""
.It Li "Next word end" Ta "e" Ta "M-f" .It Li "Next word end" Ta "e" Ta "M-f"
.It Li "Other end of selection" Ta "o" Ta ""
.It Li "Paste buffer" Ta "p" Ta "C-y" .It Li "Paste buffer" Ta "p" Ta "C-y"
.It Li "Previous page" Ta "C-b" Ta "Page up" .It Li "Previous page" Ta "C-b" Ta "Page up"
.It Li "Previous word" Ta "b" Ta "M-b" .It Li "Previous word" Ta "b" Ta "M-b"

2
tmux.h
View File

@ -557,6 +557,7 @@ enum mode_key_cmd {
MODEKEYCOPY_NEXTSPACEEND, MODEKEYCOPY_NEXTSPACEEND,
MODEKEYCOPY_NEXTWORD, MODEKEYCOPY_NEXTWORD,
MODEKEYCOPY_NEXTWORDEND, MODEKEYCOPY_NEXTWORDEND,
MODEKEYCOPY_OTHEREND,
MODEKEYCOPY_PREVIOUSPAGE, MODEKEYCOPY_PREVIOUSPAGE,
MODEKEYCOPY_PREVIOUSSPACE, MODEKEYCOPY_PREVIOUSSPACE,
MODEKEYCOPY_PREVIOUSWORD, MODEKEYCOPY_PREVIOUSWORD,
@ -1503,6 +1504,7 @@ extern struct cmd_q *cfg_cmd_q;
extern int cfg_finished; extern int cfg_finished;
extern int cfg_references; extern int cfg_references;
extern struct causelist cfg_causes; extern struct causelist cfg_causes;
extern struct client *cfg_client;
int load_cfg(const char *, struct cmd_q *, char **); int load_cfg(const char *, struct cmd_q *, char **);
void cfg_default_done(struct cmd_q *); void cfg_default_done(struct cmd_q *);
void cfg_show_causes(struct session *); void cfg_show_causes(struct session *);

3
tty.c
View File

@ -224,7 +224,7 @@ tty_start_tty(struct tty *tty)
tty->flags |= TTY_FOCUS; tty->flags |= TTY_FOCUS;
tty_puts(tty, "\033[?1004h"); tty_puts(tty, "\033[?1004h");
} }
tty_puts(tty, "\033[c\033[>4;1m\033[m"); tty_puts(tty, "\033[c");
} }
tty->cx = UINT_MAX; tty->cx = UINT_MAX;
@ -292,7 +292,6 @@ tty_stop_tty(struct tty *tty)
tty->flags &= ~TTY_FOCUS; tty->flags &= ~TTY_FOCUS;
tty_puts(tty, "\033[?1004l"); tty_puts(tty, "\033[?1004l");
} }
tty_raw(tty, "\033[>4m\033[m");
} }
tty_raw(tty, tty_term_string(tty->term, TTYC_RMCUP)); tty_raw(tty, tty_term_string(tty->term, TTYC_RMCUP));

View File

@ -18,6 +18,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <ctype.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -41,17 +42,17 @@ void window_copy_write_lines(
void window_copy_scroll_to(struct window_pane *, u_int, u_int); void window_copy_scroll_to(struct window_pane *, u_int, u_int);
int window_copy_search_compare( int window_copy_search_compare(
struct grid *, u_int, u_int, struct grid *, u_int); struct grid *, u_int, u_int, struct grid *, u_int, int);
int window_copy_search_lr( int window_copy_search_lr(
struct grid *, struct grid *, u_int *, u_int, u_int, u_int); struct grid *, struct grid *, u_int *, u_int, u_int, u_int, int);
int window_copy_search_rl( int window_copy_search_rl(
struct grid *, struct grid *, u_int *, u_int, u_int, u_int); struct grid *, struct grid *, u_int *, u_int, u_int, u_int, int);
void window_copy_search_up(struct window_pane *, const char *); void window_copy_search_up(struct window_pane *, const char *);
void window_copy_search_down(struct window_pane *, const char *); void window_copy_search_down(struct window_pane *, const char *);
void window_copy_goto_line(struct window_pane *, const char *); void window_copy_goto_line(struct window_pane *, const char *);
void window_copy_update_cursor(struct window_pane *, u_int, u_int); void window_copy_update_cursor(struct window_pane *, u_int, u_int);
void window_copy_start_selection(struct window_pane *); void window_copy_start_selection(struct window_pane *);
int window_copy_update_selection(struct window_pane *); int window_copy_update_selection(struct window_pane *, int);
void *window_copy_get_selection(struct window_pane *, size_t *); void *window_copy_get_selection(struct window_pane *, size_t *);
void window_copy_copy_buffer(struct window_pane *, int, void *, size_t); void window_copy_copy_buffer(struct window_pane *, int, void *, size_t);
void window_copy_copy_pipe( void window_copy_copy_pipe(
@ -65,6 +66,7 @@ u_int window_copy_find_length(struct window_pane *, u_int);
void window_copy_cursor_start_of_line(struct window_pane *); void window_copy_cursor_start_of_line(struct window_pane *);
void window_copy_cursor_back_to_indentation(struct window_pane *); void window_copy_cursor_back_to_indentation(struct window_pane *);
void window_copy_cursor_end_of_line(struct window_pane *); void window_copy_cursor_end_of_line(struct window_pane *);
void window_copy_other_end(struct window_pane *);
void window_copy_cursor_left(struct window_pane *); void window_copy_cursor_left(struct window_pane *);
void window_copy_cursor_right(struct window_pane *); void window_copy_cursor_right(struct window_pane *);
void window_copy_cursor_up(struct window_pane *, int); void window_copy_cursor_up(struct window_pane *, int);
@ -328,7 +330,7 @@ window_copy_pageup(struct window_pane *wp)
data->oy = screen_hsize(data->backing); data->oy = screen_hsize(data->backing);
else else
data->oy += n; data->oy += n;
window_copy_update_selection(wp); window_copy_update_selection(wp, 1);
window_copy_redraw_screen(wp); window_copy_redraw_screen(wp);
} }
@ -415,6 +417,10 @@ window_copy_key(struct window_pane *wp, struct session *sess, int key)
case MODEKEYCOPY_CANCEL: case MODEKEYCOPY_CANCEL:
window_pane_reset_mode(wp); window_pane_reset_mode(wp);
return; return;
case MODEKEYCOPY_OTHEREND:
for (; np != 0; np--)
window_copy_other_end(wp);
break;
case MODEKEYCOPY_LEFT: case MODEKEYCOPY_LEFT:
for (; np != 0; np--) for (; np != 0; np--)
window_copy_cursor_left(wp); window_copy_cursor_left(wp);
@ -453,7 +459,7 @@ window_copy_key(struct window_pane *wp, struct session *sess, int key)
else else
data->oy -= n; data->oy -= n;
} }
window_copy_update_selection(wp); window_copy_update_selection(wp, 1);
window_copy_redraw_screen(wp); window_copy_redraw_screen(wp);
break; break;
case MODEKEYCOPY_HALFPAGEUP: case MODEKEYCOPY_HALFPAGEUP:
@ -464,7 +470,7 @@ window_copy_key(struct window_pane *wp, struct session *sess, int key)
else else
data->oy += n; data->oy += n;
} }
window_copy_update_selection(wp); window_copy_update_selection(wp, 1);
window_copy_redraw_screen(wp); window_copy_redraw_screen(wp);
break; break;
case MODEKEYCOPY_HALFPAGEDOWN: case MODEKEYCOPY_HALFPAGEDOWN:
@ -475,39 +481,39 @@ window_copy_key(struct window_pane *wp, struct session *sess, int key)
else else
data->oy -= n; data->oy -= n;
} }
window_copy_update_selection(wp); window_copy_update_selection(wp, 1);
window_copy_redraw_screen(wp); window_copy_redraw_screen(wp);
break; break;
case MODEKEYCOPY_TOPLINE: case MODEKEYCOPY_TOPLINE:
data->cx = 0; data->cx = 0;
data->cy = 0; data->cy = 0;
window_copy_update_selection(wp); window_copy_update_selection(wp, 1);
window_copy_redraw_screen(wp); window_copy_redraw_screen(wp);
break; break;
case MODEKEYCOPY_MIDDLELINE: case MODEKEYCOPY_MIDDLELINE:
data->cx = 0; data->cx = 0;
data->cy = (screen_size_y(s) - 1) / 2; data->cy = (screen_size_y(s) - 1) / 2;
window_copy_update_selection(wp); window_copy_update_selection(wp, 1);
window_copy_redraw_screen(wp); window_copy_redraw_screen(wp);
break; break;
case MODEKEYCOPY_BOTTOMLINE: case MODEKEYCOPY_BOTTOMLINE:
data->cx = 0; data->cx = 0;
data->cy = screen_size_y(s) - 1; data->cy = screen_size_y(s) - 1;
window_copy_update_selection(wp); window_copy_update_selection(wp, 1);
window_copy_redraw_screen(wp); window_copy_redraw_screen(wp);
break; break;
case MODEKEYCOPY_HISTORYTOP: case MODEKEYCOPY_HISTORYTOP:
data->cx = 0; data->cx = 0;
data->cy = 0; data->cy = 0;
data->oy = screen_hsize(data->backing); data->oy = screen_hsize(data->backing);
window_copy_update_selection(wp); window_copy_update_selection(wp, 1);
window_copy_redraw_screen(wp); window_copy_redraw_screen(wp);
break; break;
case MODEKEYCOPY_HISTORYBOTTOM: case MODEKEYCOPY_HISTORYBOTTOM:
data->cx = 0; data->cx = 0;
data->cy = screen_size_y(s) - 1; data->cy = screen_size_y(s) - 1;
data->oy = 0; data->oy = 0;
window_copy_update_selection(wp); window_copy_update_selection(wp, 1);
window_copy_redraw_screen(wp); window_copy_redraw_screen(wp);
break; break;
case MODEKEYCOPY_STARTSELECTION: case MODEKEYCOPY_STARTSELECTION:
@ -860,7 +866,7 @@ window_copy_mouse(
if (s->mode & MODE_MOUSE_BUTTON) { if (s->mode & MODE_MOUSE_BUTTON) {
if (~m->event & MOUSE_EVENT_UP) { if (~m->event & MOUSE_EVENT_UP) {
window_copy_update_cursor(wp, m->x, m->y); window_copy_update_cursor(wp, m->x, m->y);
if (window_copy_update_selection(wp)) if (window_copy_update_selection(wp, 1))
window_copy_redraw_screen(wp); window_copy_redraw_screen(wp);
return; return;
} }
@ -910,13 +916,13 @@ window_copy_scroll_to(struct window_pane *wp, u_int px, u_int py)
} }
data->oy = gd->hsize - offset; data->oy = gd->hsize - offset;
window_copy_update_selection(wp); window_copy_update_selection(wp, 1);
window_copy_redraw_screen(wp); window_copy_redraw_screen(wp);
} }
int int
window_copy_search_compare( window_copy_search_compare(
struct grid *gd, u_int px, u_int py, struct grid *sgd, u_int spx) struct grid *gd, u_int px, u_int py, struct grid *sgd, u_int spx, int cis)
{ {
const struct grid_cell *gc, *sgc; const struct grid_cell *gc, *sgc;
struct utf8_data ud, sud; struct utf8_data ud, sud;
@ -928,21 +934,28 @@ window_copy_search_compare(
if (ud.size != sud.size || ud.width != sud.width) if (ud.size != sud.size || ud.width != sud.width)
return (0); return (0);
if (cis && ud.size == 1)
return (tolower(ud.data[0]) == sud.data[0]);
return (memcmp(ud.data, sud.data, ud.size) == 0); return (memcmp(ud.data, sud.data, ud.size) == 0);
} }
int int
window_copy_search_lr(struct grid *gd, window_copy_search_lr(struct grid *gd,
struct grid *sgd, u_int *ppx, u_int py, u_int first, u_int last) struct grid *sgd, u_int *ppx, u_int py, u_int first, u_int last, int cis)
{ {
u_int ax, bx, px; u_int ax, bx, px;
int matched;
for (ax = first; ax < last; ax++) { for (ax = first; ax < last; ax++) {
if (ax + sgd->sx >= gd->sx) if (ax + sgd->sx >= gd->sx)
break; break;
for (bx = 0; bx < sgd->sx; bx++) { for (bx = 0; bx < sgd->sx; bx++) {
px = ax + bx; px = ax + bx;
if (!window_copy_search_compare(gd, px, py, sgd, bx)) matched = window_copy_search_compare(gd, px, py, sgd,
bx, cis);
if (!matched)
break; break;
} }
if (bx == sgd->sx) { if (bx == sgd->sx) {
@ -955,16 +968,19 @@ window_copy_search_lr(struct grid *gd,
int int
window_copy_search_rl(struct grid *gd, window_copy_search_rl(struct grid *gd,
struct grid *sgd, u_int *ppx, u_int py, u_int first, u_int last) struct grid *sgd, u_int *ppx, u_int py, u_int first, u_int last, int cis)
{ {
u_int ax, bx, px; u_int ax, bx, px;
int matched;
for (ax = last + 1; ax > first; ax--) { for (ax = last + 1; ax > first; ax--) {
if (gd->sx - (ax - 1) < sgd->sx) if (gd->sx - (ax - 1) < sgd->sx)
continue; continue;
for (bx = 0; bx < sgd->sx; bx++) { for (bx = 0; bx < sgd->sx; bx++) {
px = ax - 1 + bx; px = ax - 1 + bx;
if (!window_copy_search_compare(gd, px, py, sgd, bx)) matched = window_copy_search_compare(gd, px, py, sgd,
bx, cis);
if (!matched)
break; break;
} }
if (bx == sgd->sx) { if (bx == sgd->sx) {
@ -985,7 +1001,8 @@ window_copy_search_up(struct window_pane *wp, const char *searchstr)
struct grid_cell gc; struct grid_cell gc;
size_t searchlen; size_t searchlen;
u_int i, last, fx, fy, px; u_int i, last, fx, fy, px;
int utf8flag, n, wrapped, wrapflag; int utf8flag, n, wrapped, wrapflag, cis;
const char *ptr;
if (*searchstr == '\0') if (*searchstr == '\0')
return; return;
@ -1011,13 +1028,21 @@ window_copy_search_up(struct window_pane *wp, const char *searchstr)
fx--; fx--;
n = wrapped = 0; n = wrapped = 0;
cis = 1;
for (ptr = searchstr; *ptr != '\0'; ptr++) {
if (*ptr != tolower(*ptr)) {
cis = 0;
break;
}
}
retry: retry:
sgd = ss.grid; sgd = ss.grid;
for (i = fy + 1; i > 0; i--) { for (i = fy + 1; i > 0; i--) {
last = screen_size_x(s); last = screen_size_x(s);
if (i == fy + 1) if (i == fy + 1)
last = fx; last = fx;
n = window_copy_search_rl(gd, sgd, &px, i - 1, 0, last); n = window_copy_search_rl(gd, sgd, &px, i - 1, 0, last, cis);
if (n) { if (n) {
window_copy_scroll_to(wp, px, i - 1); window_copy_scroll_to(wp, px, i - 1);
break; break;
@ -1043,7 +1068,8 @@ window_copy_search_down(struct window_pane *wp, const char *searchstr)
struct grid_cell gc; struct grid_cell gc;
size_t searchlen; size_t searchlen;
u_int i, first, fx, fy, px; u_int i, first, fx, fy, px;
int utf8flag, n, wrapped, wrapflag; int utf8flag, n, wrapped, wrapflag, cis;
const char *ptr;
if (*searchstr == '\0') if (*searchstr == '\0')
return; return;
@ -1069,13 +1095,22 @@ window_copy_search_down(struct window_pane *wp, const char *searchstr)
fx++; fx++;
n = wrapped = 0; n = wrapped = 0;
cis = 1;
for (ptr = searchstr; *ptr != '\0'; ptr++) {
if (*ptr != tolower(*ptr)) {
cis = 0;
break;
}
}
retry: retry:
sgd = ss.grid; sgd = ss.grid;
for (i = fy + 1; i < gd->hsize + gd->sy + 1; i++) { for (i = fy + 1; i < gd->hsize + gd->sy + 1; i++) {
first = 0; first = 0;
if (i == fy + 1) if (i == fy + 1)
first = fx; first = fx;
n = window_copy_search_lr(gd, sgd, &px, i - 1, first, gd->sx); n = window_copy_search_lr(gd, sgd, &px, i - 1, first, gd->sx,
cis);
if (n) { if (n) {
window_copy_scroll_to(wp, px, i - 1); window_copy_scroll_to(wp, px, i - 1);
break; break;
@ -1103,7 +1138,7 @@ window_copy_goto_line(struct window_pane *wp, const char *linestr)
return; return;
data->oy = lineno; data->oy = lineno;
window_copy_update_selection(wp); window_copy_update_selection(wp, 1);
window_copy_redraw_screen(wp); window_copy_redraw_screen(wp);
} }
@ -1216,11 +1251,11 @@ window_copy_start_selection(struct window_pane *wp)
data->sely = screen_hsize(data->backing) + data->cy - data->oy; data->sely = screen_hsize(data->backing) + data->cy - data->oy;
s->sel.flag = 1; s->sel.flag = 1;
window_copy_update_selection(wp); window_copy_update_selection(wp, 1);
} }
int int
window_copy_update_selection(struct window_pane *wp) window_copy_update_selection(struct window_pane *wp, int may_redraw)
{ {
struct window_copy_mode_data *data = wp->modedata; struct window_copy_mode_data *data = wp->modedata;
struct screen *s = &data->screen; struct screen *s = &data->screen;
@ -1255,7 +1290,7 @@ window_copy_update_selection(struct window_pane *wp)
screen_set_selection(s, screen_set_selection(s,
sx, sy, data->cx, screen_hsize(s) + data->cy, data->rectflag, &gc); sx, sy, data->cx, screen_hsize(s) + data->cy, data->rectflag, &gc);
if (data->rectflag) { if (data->rectflag && may_redraw) {
/* /*
* Can't rely on the caller to redraw the right lines for * Can't rely on the caller to redraw the right lines for
* rectangle selection - find the highest line and the number * rectangle selection - find the highest line and the number
@ -1559,7 +1594,7 @@ window_copy_cursor_start_of_line(struct window_pane *wp)
} }
} }
window_copy_update_cursor(wp, 0, data->cy); window_copy_update_cursor(wp, 0, data->cy);
if (window_copy_update_selection(wp)) if (window_copy_update_selection(wp, 1))
window_copy_redraw_lines(wp, data->cy, 1); window_copy_redraw_lines(wp, data->cy, 1);
} }
@ -1584,7 +1619,7 @@ window_copy_cursor_back_to_indentation(struct window_pane *wp)
} }
window_copy_update_cursor(wp, px, data->cy); window_copy_update_cursor(wp, px, data->cy);
if (window_copy_update_selection(wp)) if (window_copy_update_selection(wp, 1))
window_copy_redraw_lines(wp, data->cy, 1); window_copy_redraw_lines(wp, data->cy, 1);
} }
@ -1614,10 +1649,43 @@ window_copy_cursor_end_of_line(struct window_pane *wp)
} }
window_copy_update_cursor(wp, px, data->cy); window_copy_update_cursor(wp, px, data->cy);
if (window_copy_update_selection(wp)) if (window_copy_update_selection(wp, 1))
window_copy_redraw_lines(wp, data->cy, 1); window_copy_redraw_lines(wp, data->cy, 1);
} }
void
window_copy_other_end(struct window_pane *wp)
{
struct window_copy_mode_data *data = wp->modedata;
struct screen *s = &data->screen;
u_int selx, sely, cx, cy, yy;
if (!s->sel.flag)
return;
selx = data->selx;
sely = data->sely;
cx = data->cx;
cy = data->cy;
yy = screen_hsize(data->backing) + data->cy - data->oy;
data->selx = cx;
data->sely = yy;
data->cx = selx;
if (sely < screen_hsize(data->backing) - data->oy) {
data->oy = screen_hsize(data->backing) - sely;
data->cy = 0;
} else if (sely > screen_hsize(data->backing) - data->oy + screen_size_y(s)) {
data->oy = screen_hsize(data->backing) - sely + screen_size_y(s) - 1;
data->cy = screen_size_y(s) - 1;
} else
data->cy = cy + sely - yy;
window_copy_redraw_screen(wp);
}
void void
window_copy_cursor_left(struct window_pane *wp) window_copy_cursor_left(struct window_pane *wp)
{ {
@ -1628,7 +1696,7 @@ window_copy_cursor_left(struct window_pane *wp)
window_copy_cursor_end_of_line(wp); window_copy_cursor_end_of_line(wp);
} else { } else {
window_copy_update_cursor(wp, data->cx - 1, data->cy); window_copy_update_cursor(wp, data->cx - 1, data->cy);
if (window_copy_update_selection(wp)) if (window_copy_update_selection(wp, 1))
window_copy_redraw_lines(wp, data->cy, 1); window_copy_redraw_lines(wp, data->cy, 1);
} }
} }
@ -1651,7 +1719,7 @@ window_copy_cursor_right(struct window_pane *wp)
window_copy_cursor_down(wp, 0); window_copy_cursor_down(wp, 0);
} else { } else {
window_copy_update_cursor(wp, data->cx + 1, data->cy); window_copy_update_cursor(wp, data->cx + 1, data->cy);
if (window_copy_update_selection(wp)) if (window_copy_update_selection(wp, 1))
window_copy_redraw_lines(wp, data->cy, 1); window_copy_redraw_lines(wp, data->cy, 1);
} }
} }
@ -1681,7 +1749,7 @@ window_copy_cursor_up(struct window_pane *wp, int scroll_only)
} }
} else { } else {
window_copy_update_cursor(wp, data->cx, data->cy - 1); window_copy_update_cursor(wp, data->cx, data->cy - 1);
if (window_copy_update_selection(wp)) { if (window_copy_update_selection(wp, 1)) {
if (data->cy == screen_size_y(s) - 1) if (data->cy == screen_size_y(s) - 1)
window_copy_redraw_lines(wp, data->cy, 1); window_copy_redraw_lines(wp, data->cy, 1);
else else
@ -1719,7 +1787,7 @@ window_copy_cursor_down(struct window_pane *wp, int scroll_only)
window_copy_redraw_lines(wp, data->cy - 1, 2); window_copy_redraw_lines(wp, data->cy - 1, 2);
} else { } else {
window_copy_update_cursor(wp, data->cx, data->cy + 1); window_copy_update_cursor(wp, data->cx, data->cy + 1);
if (window_copy_update_selection(wp)) if (window_copy_update_selection(wp, 1))
window_copy_redraw_lines(wp, data->cy - 1, 2); window_copy_redraw_lines(wp, data->cy - 1, 2);
} }
@ -1751,7 +1819,7 @@ window_copy_cursor_jump(struct window_pane *wp)
if (!(gc->flags & GRID_FLAG_PADDING) && if (!(gc->flags & GRID_FLAG_PADDING) &&
ud.size == 1 && *ud.data == data->jumpchar) { ud.size == 1 && *ud.data == data->jumpchar) {
window_copy_update_cursor(wp, px, data->cy); window_copy_update_cursor(wp, px, data->cy);
if (window_copy_update_selection(wp)) if (window_copy_update_selection(wp, 1))
window_copy_redraw_lines(wp, data->cy, 1); window_copy_redraw_lines(wp, data->cy, 1);
return; return;
} }
@ -1780,7 +1848,7 @@ window_copy_cursor_jump_back(struct window_pane *wp)
if (!(gc->flags & GRID_FLAG_PADDING) && if (!(gc->flags & GRID_FLAG_PADDING) &&
ud.size == 1 && *ud.data == data->jumpchar) { ud.size == 1 && *ud.data == data->jumpchar) {
window_copy_update_cursor(wp, px, data->cy); window_copy_update_cursor(wp, px, data->cy);
if (window_copy_update_selection(wp)) if (window_copy_update_selection(wp, 1))
window_copy_redraw_lines(wp, data->cy, 1); window_copy_redraw_lines(wp, data->cy, 1);
return; return;
} }
@ -1809,7 +1877,7 @@ window_copy_cursor_jump_to(struct window_pane *wp)
if (!(gc->flags & GRID_FLAG_PADDING) && if (!(gc->flags & GRID_FLAG_PADDING) &&
ud.size == 1 && *ud.data == data->jumpchar) { ud.size == 1 && *ud.data == data->jumpchar) {
window_copy_update_cursor(wp, px - 1, data->cy); window_copy_update_cursor(wp, px - 1, data->cy);
if (window_copy_update_selection(wp)) if (window_copy_update_selection(wp, 1))
window_copy_redraw_lines(wp, data->cy, 1); window_copy_redraw_lines(wp, data->cy, 1);
return; return;
} }
@ -1838,7 +1906,7 @@ window_copy_cursor_jump_to_back(struct window_pane *wp)
if (!(gc->flags & GRID_FLAG_PADDING) && if (!(gc->flags & GRID_FLAG_PADDING) &&
ud.size == 1 && *ud.data == data->jumpchar) { ud.size == 1 && *ud.data == data->jumpchar) {
window_copy_update_cursor(wp, px + 1, data->cy); window_copy_update_cursor(wp, px + 1, data->cy);
if (window_copy_update_selection(wp)) if (window_copy_update_selection(wp, 1))
window_copy_redraw_lines(wp, data->cy, 1); window_copy_redraw_lines(wp, data->cy, 1);
return; return;
} }
@ -1886,7 +1954,7 @@ window_copy_cursor_next_word(struct window_pane *wp, const char *separators)
} while (expected == 1); } while (expected == 1);
window_copy_update_cursor(wp, px, data->cy); window_copy_update_cursor(wp, px, data->cy);
if (window_copy_update_selection(wp)) if (window_copy_update_selection(wp, 1))
window_copy_redraw_lines(wp, data->cy, 1); window_copy_redraw_lines(wp, data->cy, 1);
} }
@ -1936,7 +2004,7 @@ window_copy_cursor_next_word_end(struct window_pane *wp, const char *separators)
px--; px--;
window_copy_update_cursor(wp, px, data->cy); window_copy_update_cursor(wp, px, data->cy);
if (window_copy_update_selection(wp)) if (window_copy_update_selection(wp, 1))
window_copy_redraw_lines(wp, data->cy, 1); window_copy_redraw_lines(wp, data->cy, 1);
} }
@ -1974,7 +2042,7 @@ window_copy_cursor_previous_word(struct window_pane *wp, const char *separators)
out: out:
window_copy_update_cursor(wp, px, data->cy); window_copy_update_cursor(wp, px, data->cy);
if (window_copy_update_selection(wp)) if (window_copy_update_selection(wp, 1))
window_copy_redraw_lines(wp, data->cy, 1); window_copy_redraw_lines(wp, data->cy, 1);
} }
@ -1991,6 +2059,8 @@ window_copy_scroll_up(struct window_pane *wp, u_int ny)
return; return;
data->oy -= ny; data->oy -= ny;
window_copy_update_selection(wp, 0);
screen_write_start(&ctx, wp, NULL); screen_write_start(&ctx, wp, NULL);
screen_write_cursormove(&ctx, 0, 0); screen_write_cursormove(&ctx, 0, 0);
screen_write_deleteline(&ctx, ny); screen_write_deleteline(&ctx, ny);
@ -2000,12 +2070,9 @@ window_copy_scroll_up(struct window_pane *wp, u_int ny)
window_copy_write_line(wp, &ctx, 1); window_copy_write_line(wp, &ctx, 1);
if (screen_size_y(s) > 3) if (screen_size_y(s) > 3)
window_copy_write_line(wp, &ctx, screen_size_y(s) - 2); window_copy_write_line(wp, &ctx, screen_size_y(s) - 2);
if (s->sel.flag && screen_size_y(s) > ny) { if (s->sel.flag && screen_size_y(s) > ny)
window_copy_update_selection(wp);
window_copy_write_line(wp, &ctx, screen_size_y(s) - ny - 1); window_copy_write_line(wp, &ctx, screen_size_y(s) - ny - 1);
}
screen_write_cursormove(&ctx, data->cx, data->cy); screen_write_cursormove(&ctx, data->cx, data->cy);
window_copy_update_selection(wp);
screen_write_stop(&ctx); screen_write_stop(&ctx);
} }
@ -2025,17 +2092,17 @@ window_copy_scroll_down(struct window_pane *wp, u_int ny)
return; return;
data->oy += ny; data->oy += ny;
window_copy_update_selection(wp, 0);
screen_write_start(&ctx, wp, NULL); screen_write_start(&ctx, wp, NULL);
screen_write_cursormove(&ctx, 0, 0); screen_write_cursormove(&ctx, 0, 0);
screen_write_insertline(&ctx, ny); screen_write_insertline(&ctx, ny);
window_copy_write_lines(wp, &ctx, 0, ny); window_copy_write_lines(wp, &ctx, 0, ny);
if (s->sel.flag && screen_size_y(s) > ny) { if (s->sel.flag && screen_size_y(s) > ny)
window_copy_update_selection(wp);
window_copy_write_line(wp, &ctx, ny); window_copy_write_line(wp, &ctx, ny);
} else if (ny == 1) /* nuke position */ else if (ny == 1) /* nuke position */
window_copy_write_line(wp, &ctx, 1); window_copy_write_line(wp, &ctx, 1);
screen_write_cursormove(&ctx, data->cx, data->cy); screen_write_cursormove(&ctx, data->cx, data->cy);
window_copy_update_selection(wp);
screen_write_stop(&ctx); screen_write_stop(&ctx);
} }
@ -2052,6 +2119,6 @@ window_copy_rectangle_toggle(struct window_pane *wp)
if (data->cx > px) if (data->cx > px)
window_copy_update_cursor(wp, px, data->cy); window_copy_update_cursor(wp, px, data->cy);
window_copy_update_selection(wp); window_copy_update_selection(wp, 1);
window_copy_redraw_screen(wp); window_copy_redraw_screen(wp);
} }