Merge branch 'obsd-master'

This commit is contained in:
Thomas Adam
2020-03-19 14:01:31 +00:00
9 changed files with 129 additions and 91 deletions

View File

@@ -60,6 +60,8 @@ cmd_display_menu_get_position(struct client *c, struct cmdq_item *item,
*px = 0; *px = 0;
else if (strcmp(xp, "R") == 0) else if (strcmp(xp, "R") == 0)
*px = c->tty.sx - 1; *px = c->tty.sx - 1;
else if (strcmp(xp, "C") == 0)
*px = (c->tty.sx - 1) / 2 - w / 2;
else if (strcmp(xp, "P") == 0) { else if (strcmp(xp, "P") == 0) {
tty_window_offset(&c->tty, &ox, &oy, &sx, &sy); tty_window_offset(&c->tty, &ox, &oy, &sx, &sy);
if (wp->xoff >= ox) if (wp->xoff >= ox)
@@ -94,6 +96,8 @@ cmd_display_menu_get_position(struct client *c, struct cmdq_item *item,
yp = args_get(args, 'y'); yp = args_get(args, 'y');
if (yp == NULL) if (yp == NULL)
*py = 0; *py = 0;
else if (strcmp(yp, "C") == 0)
*py = (c->tty.sy - 1) / 2 + h / 2;
else if (strcmp(yp, "P") == 0) { else if (strcmp(yp, "P") == 0) {
tty_window_offset(&c->tty, &ox, &oy, &sx, &sy); tty_window_offset(&c->tty, &ox, &oy, &sx, &sy);
if (wp->yoff + wp->sy >= oy) if (wp->yoff + wp->sy >= oy)
@@ -132,7 +136,7 @@ cmd_display_menu_exec(struct cmd *self, struct cmdq_item *item)
struct menu_item menu_item; struct menu_item menu_item;
const char *key; const char *key;
char *title, *name; char *title, *name;
int flags, i; int flags = 0, i;
u_int px, py; u_int px, py;
if ((c = cmd_find_client(item, args_get(args, 'c'), 0)) == NULL) if ((c = cmd_find_client(item, args_get(args, 'c'), 0)) == NULL)
@@ -180,7 +184,6 @@ cmd_display_menu_exec(struct cmd *self, struct cmdq_item *item)
cmd_display_menu_get_position(c, item, args, &px, &py, menu->width + 4, cmd_display_menu_get_position(c, item, args, &px, &py, menu->width + 4,
menu->count + 2); menu->count + 2);
flags = 0;
if (!item->shared->mouse.valid) if (!item->shared->mouse.valid)
flags |= MENU_NOMOUSE; flags |= MENU_NOMOUSE;
if (menu_display(menu, flags, item, px, py, c, fs, NULL, NULL) != 0) if (menu_display(menu, flags, item, px, py, c, fs, NULL, NULL) != 0)

View File

@@ -144,7 +144,8 @@ cmd_if_shell_exec(struct cmd *self, struct cmdq_item *item)
cmd_find_copy_state(&cdata->input.fs, fs); cmd_find_copy_state(&cdata->input.fs, fs);
if (job_run(shellcmd, s, server_client_get_cwd(item->client, s), NULL, if (job_run(shellcmd, s, server_client_get_cwd(item->client, s), NULL,
cmd_if_shell_callback, cmd_if_shell_free, cdata, 0) == NULL) { cmd_if_shell_callback, cmd_if_shell_free, cdata, 0, -1,
-1) == NULL) {
cmdq_error(item, "failed to run command: %s", shellcmd); cmdq_error(item, "failed to run command: %s", shellcmd);
free(shellcmd); free(shellcmd);
free(cdata); free(cdata);

View File

@@ -145,8 +145,8 @@ cmd_run_shell_timer(__unused int fd, __unused short events, void* arg)
if (cdata->cmd != NULL) { if (cdata->cmd != NULL) {
if (job_run(cdata->cmd, cdata->s, cdata->cwd, NULL, if (job_run(cdata->cmd, cdata->s, cdata->cwd, NULL,
cmd_run_shell_callback, cmd_run_shell_free, cdata, cmd_run_shell_callback, cmd_run_shell_free, cdata, 0, -1,
0) == NULL) -1) == NULL)
cmd_run_shell_free(cdata); cmd_run_shell_free(cdata);
} else { } else {
if (cdata->item != NULL) if (cdata->item != NULL)

View File

@@ -354,7 +354,7 @@ format_job_get(struct format_tree *ft, const char *cmd)
if (force || (fj->job == NULL && fj->last != t)) { if (force || (fj->job == NULL && fj->last != t)) {
fj->job = job_run(expanded, NULL, fj->job = job_run(expanded, NULL,
server_client_get_cwd(ft->client, NULL), format_job_update, server_client_get_cwd(ft->client, NULL), format_job_update,
format_job_complete, NULL, fj, JOB_NOWAIT); format_job_complete, NULL, fj, JOB_NOWAIT, -1, -1);
if (fj->job == NULL) { if (fj->job == NULL) {
free(fj->out); free(fj->out);
xasprintf(&fj->out, "<'%s' didn't start>", fj->cmd); xasprintf(&fj->out, "<'%s' didn't start>", fj->cmd);

3
grid.c
View File

@@ -258,7 +258,10 @@ grid_create(u_int sx, u_int sy, u_int hlimit)
gd->sx = sx; gd->sx = sx;
gd->sy = sy; gd->sy = sy;
if (hlimit != 0)
gd->flags = GRID_HISTORY; gd->flags = GRID_HISTORY;
else
gd->flags = 0;
gd->hscrolled = 0; gd->hscrolled = 0;
gd->hsize = 0; gd->hsize = 0;

46
job.c
View File

@@ -24,6 +24,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include <util.h>
#include "tmux.h" #include "tmux.h"
@@ -68,18 +69,15 @@ static LIST_HEAD(joblist, job) all_jobs = LIST_HEAD_INITIALIZER(all_jobs);
struct job * struct job *
job_run(const char *cmd, struct session *s, const char *cwd, job_run(const char *cmd, struct session *s, const char *cwd,
job_update_cb updatecb, job_complete_cb completecb, job_free_cb freecb, job_update_cb updatecb, job_complete_cb completecb, job_free_cb freecb,
void *data, int flags) void *data, int flags, int sx, int sy)
{ {
struct job *job; struct job *job;
struct environ *env; struct environ *env;
pid_t pid; pid_t pid;
int nullfd, out[2]; int nullfd, out[2], master;
const char *home; const char *home;
sigset_t set, oldset; sigset_t set, oldset;
struct winsize ws;
if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, out) != 0)
return (NULL);
log_debug("%s: cmd=%s, cwd=%s", __func__, cmd, cwd == NULL ? "" : cwd);
/* /*
* Do not set TERM during .tmux.conf, it is nice to be able to use * Do not set TERM during .tmux.conf, it is nice to be able to use
@@ -89,13 +87,26 @@ job_run(const char *cmd, struct session *s, const char *cwd,
sigfillset(&set); sigfillset(&set);
sigprocmask(SIG_BLOCK, &set, &oldset); sigprocmask(SIG_BLOCK, &set, &oldset);
switch (pid = fork()) {
if (flags & JOB_PTY) {
memset(&ws, 0, sizeof ws);
ws.ws_col = sx;
ws.ws_row = sy;
pid = fdforkpty(ptm_fd, &master, NULL, NULL, &ws);
} else {
if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, out) != 0)
goto fail;
pid = fork();
}
log_debug("%s: cmd=%s, cwd=%s", __func__, cmd, cwd == NULL ? "" : cwd);
switch (pid) {
case -1: case -1:
sigprocmask(SIG_SETMASK, &oldset, NULL); if (~flags & JOB_PTY) {
environ_free(env);
close(out[0]); close(out[0]);
close(out[1]); close(out[1]);
return (NULL); }
goto fail;
case 0: case 0:
proc_clear_signals(server_proc, 1); proc_clear_signals(server_proc, 1);
sigprocmask(SIG_SETMASK, &oldset, NULL); sigprocmask(SIG_SETMASK, &oldset, NULL);
@@ -108,6 +119,7 @@ job_run(const char *cmd, struct session *s, const char *cwd,
environ_push(env); environ_push(env);
environ_free(env); environ_free(env);
if (~flags & JOB_PTY) {
if (dup2(out[1], STDIN_FILENO) == -1) if (dup2(out[1], STDIN_FILENO) == -1)
fatal("dup2 failed"); fatal("dup2 failed");
if (dup2(out[1], STDOUT_FILENO) == -1) if (dup2(out[1], STDOUT_FILENO) == -1)
@@ -123,7 +135,7 @@ job_run(const char *cmd, struct session *s, const char *cwd,
fatal("dup2 failed"); fatal("dup2 failed");
if (nullfd != STDERR_FILENO) if (nullfd != STDERR_FILENO)
close(nullfd); close(nullfd);
}
closefrom(STDERR_FILENO + 1); closefrom(STDERR_FILENO + 1);
execl(_PATH_BSHELL, "sh", "-c", cmd, (char *) NULL); execl(_PATH_BSHELL, "sh", "-c", cmd, (char *) NULL);
@@ -132,7 +144,6 @@ job_run(const char *cmd, struct session *s, const char *cwd,
sigprocmask(SIG_SETMASK, &oldset, NULL); sigprocmask(SIG_SETMASK, &oldset, NULL);
environ_free(env); environ_free(env);
close(out[1]);
job = xmalloc(sizeof *job); job = xmalloc(sizeof *job);
job->state = JOB_RUNNING; job->state = JOB_RUNNING;
@@ -149,7 +160,11 @@ job_run(const char *cmd, struct session *s, const char *cwd,
job->freecb = freecb; job->freecb = freecb;
job->data = data; job->data = data;
if (~flags & JOB_PTY) {
close(out[1]);
job->fd = out[0]; job->fd = out[0];
} else
job->fd = master;
setblocking(job->fd, 0); setblocking(job->fd, 0);
job->event = bufferevent_new(job->fd, job_read_callback, job->event = bufferevent_new(job->fd, job_read_callback,
@@ -160,6 +175,11 @@ job_run(const char *cmd, struct session *s, const char *cwd,
log_debug("run job %p: %s, pid %ld", job, job->cmd, (long) job->pid); log_debug("run job %p: %s, pid %ld", job, job->cmd, (long) job->pid);
return (job); return (job);
fail:
sigprocmask(SIG_SETMASK, &oldset, NULL);
environ_free(env);
return (NULL);
} }
/* Kill and free an individual job. */ /* Kill and free an individual job. */
@@ -208,7 +228,7 @@ job_write_callback(__unused struct bufferevent *bufev, void *data)
log_debug("job write %p: %s, pid %ld, output left %zu", job, job->cmd, log_debug("job write %p: %s, pid %ld, output left %zu", job, job->cmd,
(long) job->pid, len); (long) job->pid, len);
if (len == 0) { if (len == 0 && (~job->flags & JOB_KEEPWRITE)) {
shutdown(job->fd, SHUT_WR); shutdown(job->fd, SHUT_WR);
bufferevent_disable(job->event, EV_WRITE); bufferevent_disable(job->event, EV_WRITE);
} }

1
tmux.1
View File

@@ -4919,6 +4919,7 @@ give the position of the menu.
Both may be a row or column number, or one of the following special values: Both may be a row or column number, or one of the following special values:
.Bl -column "XXXXX" "XXXX" -offset indent .Bl -column "XXXXX" "XXXX" -offset indent
.It Sy "Value" Ta Sy "Flag" Ta Sy "Meaning" .It Sy "Value" Ta Sy "Flag" Ta Sy "Meaning"
.It Li "C" Ta "Both" Ta "The centre of the terminal"
.It Li "R" Ta Fl x Ta "The right side of the terminal" .It Li "R" Ta Fl x Ta "The right side of the terminal"
.It Li "P" Ta "Both" Ta "The bottom left of the pane" .It Li "P" Ta "Both" Ta "The bottom left of the pane"
.It Li "M" Ta "Both" Ta "The mouse position" .It Li "M" Ta "Both" Ta "The mouse position"

5
tmux.h
View File

@@ -1931,8 +1931,11 @@ typedef void (*job_update_cb) (struct job *);
typedef void (*job_complete_cb) (struct job *); typedef void (*job_complete_cb) (struct job *);
typedef void (*job_free_cb) (void *); typedef void (*job_free_cb) (void *);
#define JOB_NOWAIT 0x1 #define JOB_NOWAIT 0x1
#define JOB_KEEPWRITE 0x2
#define JOB_PTY 0x4
struct job *job_run(const char *, struct session *, const char *, struct job *job_run(const char *, struct session *, const char *,
job_update_cb, job_complete_cb, job_free_cb, void *, int); job_update_cb, job_complete_cb, job_free_cb, void *, int,
int, int);
void job_free(struct job *); void job_free(struct job *);
void job_check_died(pid_t, int); void job_check_died(pid_t, int);
int job_get_status(struct job *); int job_get_status(struct job *);

View File

@@ -87,9 +87,10 @@ static void window_copy_update_cursor(struct window_mode_entry *, u_int,
static void window_copy_start_selection(struct window_mode_entry *); static void window_copy_start_selection(struct window_mode_entry *);
static int window_copy_adjust_selection(struct window_mode_entry *, static int window_copy_adjust_selection(struct window_mode_entry *,
u_int *, u_int *); u_int *, u_int *);
static int window_copy_set_selection(struct window_mode_entry *, int); static int window_copy_set_selection(struct window_mode_entry *, int, int);
static int window_copy_update_selection(struct window_mode_entry *, int); static int window_copy_update_selection(struct window_mode_entry *, int,
static void window_copy_synchronize_cursor(struct window_mode_entry *); int);
static void window_copy_synchronize_cursor(struct window_mode_entry *, int);
static void *window_copy_get_selection(struct window_mode_entry *, size_t *); static void *window_copy_get_selection(struct window_mode_entry *, size_t *);
static void window_copy_copy_buffer(struct window_mode_entry *, static void window_copy_copy_buffer(struct window_mode_entry *,
const char *, void *, size_t); const char *, void *, size_t);
@@ -505,7 +506,7 @@ window_copy_pageup1(struct window_mode_entry *wme, int half_page)
window_copy_cursor_end_of_line(wme); window_copy_cursor_end_of_line(wme);
} }
window_copy_update_selection(wme, 1); window_copy_update_selection(wme, 1, 0);
window_copy_redraw_screen(wme); window_copy_redraw_screen(wme);
} }
@@ -553,7 +554,7 @@ window_copy_pagedown(struct window_mode_entry *wme, int half_page,
if (scroll_exit && data->oy == 0) if (scroll_exit && data->oy == 0)
return (1); return (1);
window_copy_update_selection(wme, 1); window_copy_update_selection(wme, 1, 0);
window_copy_redraw_screen(wme); window_copy_redraw_screen(wme);
return (0); return (0);
} }
@@ -718,9 +719,6 @@ window_copy_cmd_begin_selection(struct window_copy_cmd_state *cs)
struct client *c = cs->c; struct client *c = cs->c;
struct mouse_event *m = cs->m; struct mouse_event *m = cs->m;
struct window_copy_mode_data *data = wme->data; struct window_copy_mode_data *data = wme->data;
struct options *oo = cs->s->options;
data->ws = options_get_string(oo, "word-separators");
if (m != NULL) { if (m != NULL) {
window_copy_start_drag(c, m); window_copy_start_drag(c, m);
@@ -728,6 +726,7 @@ window_copy_cmd_begin_selection(struct window_copy_cmd_state *cs)
} }
data->lineflag = LINE_SEL_NONE; data->lineflag = LINE_SEL_NONE;
data->selflag = SEL_CHAR;
window_copy_start_selection(wme); window_copy_start_selection(wme);
return (WINDOW_COPY_CMD_REDRAW); return (WINDOW_COPY_CMD_REDRAW);
} }
@@ -753,7 +752,7 @@ window_copy_cmd_bottom_line(struct window_copy_cmd_state *cs)
data->cx = 0; data->cx = 0;
data->cy = screen_size_y(&data->screen) - 1; data->cy = screen_size_y(&data->screen) - 1;
window_copy_update_selection(wme, 1); window_copy_update_selection(wme, 1, 0);
return (WINDOW_COPY_CMD_REDRAW); return (WINDOW_COPY_CMD_REDRAW);
} }
@@ -810,12 +809,14 @@ window_copy_cmd_copy_line(struct window_copy_cmd_state *cs)
struct session *s = cs->s; struct session *s = cs->s;
struct winlink *wl = cs->wl; struct winlink *wl = cs->wl;
struct window_pane *wp = wme->wp; struct window_pane *wp = wme->wp;
struct window_copy_mode_data *data = wme->data;
u_int np = wme->prefix; u_int np = wme->prefix;
char *prefix = NULL; char *prefix = NULL;
if (cs->args->argc == 2) if (cs->args->argc == 2)
prefix = format_single(NULL, cs->args->argv[1], c, s, wl, wp); prefix = format_single(NULL, cs->args->argv[1], c, s, wl, wp);
data->selflag = SEL_CHAR;
window_copy_cursor_start_of_line(wme); window_copy_cursor_start_of_line(wme);
window_copy_start_selection(wme); window_copy_start_selection(wme);
for (; np > 1; np--) for (; np > 1; np--)
@@ -995,7 +996,7 @@ window_copy_cmd_history_bottom(struct window_copy_cmd_state *cs)
data->cx = window_copy_find_length(wme, data->cy); data->cx = window_copy_find_length(wme, data->cy);
data->oy = 0; data->oy = 0;
window_copy_update_selection(wme, 1); window_copy_update_selection(wme, 1, 0);
return (WINDOW_COPY_CMD_REDRAW); return (WINDOW_COPY_CMD_REDRAW);
} }
@@ -1014,7 +1015,7 @@ window_copy_cmd_history_top(struct window_copy_cmd_state *cs)
data->cx = 0; data->cx = 0;
data->oy = screen_hsize(data->backing); data->oy = screen_hsize(data->backing);
window_copy_update_selection(wme, 1); window_copy_update_selection(wme, 1, 0);
return (WINDOW_COPY_CMD_REDRAW); return (WINDOW_COPY_CMD_REDRAW);
} }
@@ -1083,7 +1084,7 @@ window_copy_cmd_middle_line(struct window_copy_cmd_state *cs)
data->cx = 0; data->cx = 0;
data->cy = (screen_size_y(&data->screen) - 1) / 2; data->cy = (screen_size_y(&data->screen) - 1) / 2;
window_copy_update_selection(wme, 1); window_copy_update_selection(wme, 1, 0);
return (WINDOW_COPY_CMD_REDRAW); return (WINDOW_COPY_CMD_REDRAW);
} }
@@ -1557,7 +1558,6 @@ window_copy_cmd_select_word(struct window_copy_cmd_state *cs)
struct window_mode_entry *wme = cs->wme; struct window_mode_entry *wme = cs->wme;
struct session *s = cs->s; struct session *s = cs->s;
struct window_copy_mode_data *data = wme->data; struct window_copy_mode_data *data = wme->data;
const char *ws;
u_int px, py; u_int px, py;
data->lineflag = LINE_SEL_LEFT_RIGHT; data->lineflag = LINE_SEL_LEFT_RIGHT;
@@ -1569,18 +1569,18 @@ window_copy_cmd_select_word(struct window_copy_cmd_state *cs)
px = data->cx; px = data->cx;
py = screen_hsize(data->backing) + data->cy - data->oy; py = screen_hsize(data->backing) + data->cy - data->oy;
ws = options_get_string(s->options, "word-separators"); data->ws = options_get_string(s->options, "word-separators");
window_copy_cursor_previous_word(wme, ws, 0); window_copy_cursor_previous_word(wme, data->ws, 0);
data->selrx = data->cx; data->selrx = data->cx;
data->selry = screen_hsize(data->backing) + data->cy - data->oy; data->selry = screen_hsize(data->backing) + data->cy - data->oy;
window_copy_start_selection(wme); window_copy_start_selection(wme);
if (px >= window_copy_find_length(wme, py) || if (px >= window_copy_find_length(wme, py) ||
!window_copy_in_set(wme, px + 1, py, ws)) !window_copy_in_set(wme, px + 1, py, data->ws))
window_copy_cursor_next_word_end(wme, ws); window_copy_cursor_next_word_end(wme, data->ws);
else { else {
window_copy_update_cursor(wme, px, data->cy); window_copy_update_cursor(wme, px, data->cy);
if (window_copy_update_selection(wme, 1)) if (window_copy_update_selection(wme, 1, 0))
window_copy_redraw_lines(wme, data->cy, 1); window_copy_redraw_lines(wme, data->cy, 1);
} }
data->endselrx = data->cx; data->endselrx = data->cx;
@@ -1607,7 +1607,7 @@ window_copy_cmd_top_line(struct window_copy_cmd_state *cs)
data->cx = 0; data->cx = 0;
data->cy = 0; data->cy = 0;
window_copy_update_selection(wme, 1); window_copy_update_selection(wme, 1, 0);
return (WINDOW_COPY_CMD_REDRAW); return (WINDOW_COPY_CMD_REDRAW);
} }
@@ -2121,7 +2121,7 @@ window_copy_scroll_to(struct window_mode_entry *wme, u_int px, u_int py)
data->oy = gd->hsize - offset; data->oy = gd->hsize - offset;
} }
window_copy_update_selection(wme, 1); window_copy_update_selection(wme, 1, 0);
window_copy_redraw_screen(wme); window_copy_redraw_screen(wme);
} }
@@ -2759,7 +2759,7 @@ window_copy_goto_line(struct window_mode_entry *wme, const char *linestr)
lineno = screen_hsize(data->backing); lineno = screen_hsize(data->backing);
data->oy = lineno; data->oy = lineno;
window_copy_update_selection(wme, 1); window_copy_update_selection(wme, 1, 0);
window_copy_redraw_screen(wme); window_copy_redraw_screen(wme);
} }
@@ -2877,7 +2877,8 @@ window_copy_redraw_screen(struct window_mode_entry *wme)
} }
static void static void
window_copy_synchronize_cursor_end(struct window_mode_entry *wme, int begin) window_copy_synchronize_cursor_end(struct window_mode_entry *wme, int begin,
int no_reset)
{ {
struct window_copy_mode_data *data = wme->data; struct window_copy_mode_data *data = wme->data;
u_int xx, yy; u_int xx, yy;
@@ -2885,10 +2886,10 @@ window_copy_synchronize_cursor_end(struct window_mode_entry *wme, int begin)
yy = screen_hsize(data->backing) + data->cy - data->oy; yy = screen_hsize(data->backing) + data->cy - data->oy;
switch (data->selflag) { switch (data->selflag) {
case SEL_WORD: case SEL_WORD:
begin = 0;
xx = data->cx; xx = data->cx;
if (data->ws == NULL) if (no_reset)
break; break;
begin = 0;
if (data->dy > yy || (data->dy == yy && data->dx > xx)) { if (data->dy > yy || (data->dy == yy && data->dx > xx)) {
/* Right to left selection. */ /* Right to left selection. */
window_copy_cursor_previous_word_pos(wme, data->ws, 0, window_copy_cursor_previous_word_pos(wme, data->ws, 0,
@@ -2911,6 +2912,10 @@ window_copy_synchronize_cursor_end(struct window_mode_entry *wme, int begin)
} }
break; break;
case SEL_LINE: case SEL_LINE:
if (no_reset) {
xx = data->cx;
break;
}
begin = 0; begin = 0;
if (data->dy > yy) { if (data->dy > yy) {
/* Right to left selection. */ /* Right to left selection. */
@@ -2943,16 +2948,16 @@ window_copy_synchronize_cursor_end(struct window_mode_entry *wme, int begin)
} }
static void static void
window_copy_synchronize_cursor(struct window_mode_entry *wme) window_copy_synchronize_cursor(struct window_mode_entry *wme, int no_reset)
{ {
struct window_copy_mode_data *data = wme->data; struct window_copy_mode_data *data = wme->data;
switch (data->cursordrag) { switch (data->cursordrag) {
case CURSORDRAG_ENDSEL: case CURSORDRAG_ENDSEL:
window_copy_synchronize_cursor_end(wme, 0); window_copy_synchronize_cursor_end(wme, 0, no_reset);
break; break;
case CURSORDRAG_SEL: case CURSORDRAG_SEL:
window_copy_synchronize_cursor_end(wme, 1); window_copy_synchronize_cursor_end(wme, 1, no_reset);
break; break;
case CURSORDRAG_NONE: case CURSORDRAG_NONE:
break; break;
@@ -2994,7 +2999,7 @@ window_copy_start_selection(struct window_mode_entry *wme)
data->cursordrag = CURSORDRAG_ENDSEL; data->cursordrag = CURSORDRAG_ENDSEL;
window_copy_set_selection(wme, 1); window_copy_set_selection(wme, 1, 0);
} }
static int static int
@@ -3031,18 +3036,20 @@ window_copy_adjust_selection(struct window_mode_entry *wme, u_int *selx,
} }
static int static int
window_copy_update_selection(struct window_mode_entry *wme, int may_redraw) window_copy_update_selection(struct window_mode_entry *wme, int may_redraw,
int no_reset)
{ {
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;
if (s->sel == NULL && data->lineflag == LINE_SEL_NONE) if (s->sel == NULL && data->lineflag == LINE_SEL_NONE)
return (0); return (0);
return (window_copy_set_selection(wme, may_redraw)); return (window_copy_set_selection(wme, may_redraw, no_reset));
} }
static int static int
window_copy_set_selection(struct window_mode_entry *wme, int may_redraw) window_copy_set_selection(struct window_mode_entry *wme, int may_redraw,
int no_reset)
{ {
struct window_pane *wp = wme->wp; struct window_pane *wp = wme->wp;
struct window_copy_mode_data *data = wme->data; struct window_copy_mode_data *data = wme->data;
@@ -3052,7 +3059,7 @@ window_copy_set_selection(struct window_mode_entry *wme, int may_redraw)
u_int sx, sy, cy, endsx, endsy; u_int sx, sy, cy, endsx, endsy;
int startrelpos, endrelpos; int startrelpos, endrelpos;
window_copy_synchronize_cursor(wme); window_copy_synchronize_cursor(wme, no_reset);
/* Adjust the selection. */ /* Adjust the selection. */
sx = data->selx; sx = data->selx;
@@ -3233,7 +3240,7 @@ window_copy_copy_buffer(struct window_mode_entry *wme, const char *prefix,
static void static void
window_copy_copy_pipe(struct window_mode_entry *wme, struct session *s, window_copy_copy_pipe(struct window_mode_entry *wme, struct session *s,
const char *prefix, const char *command) const char *prefix, const char *cmd)
{ {
void *buf; void *buf;
size_t len; size_t len;
@@ -3243,7 +3250,7 @@ window_copy_copy_pipe(struct window_mode_entry *wme, struct session *s,
if (buf == NULL) if (buf == NULL)
return; return;
job = job_run(command, s, NULL, NULL, NULL, NULL, NULL, JOB_NOWAIT); job = job_run(cmd, s, NULL, NULL, NULL, NULL, NULL, JOB_NOWAIT, -1, -1);
bufferevent_write(job_get_event(job), buf, len); bufferevent_write(job_get_event(job), buf, len);
window_copy_copy_buffer(wme, prefix, buf, len); window_copy_copy_buffer(wme, prefix, buf, len);
} }
@@ -3408,7 +3415,7 @@ window_copy_cursor_start_of_line(struct window_mode_entry *wme)
} }
} }
window_copy_update_cursor(wme, 0, data->cy); window_copy_update_cursor(wme, 0, data->cy);
if (window_copy_update_selection(wme, 1)) if (window_copy_update_selection(wme, 1, 0))
window_copy_redraw_lines(wme, data->cy, 1); window_copy_redraw_lines(wme, data->cy, 1);
} }
@@ -3431,7 +3438,7 @@ window_copy_cursor_back_to_indentation(struct window_mode_entry *wme)
} }
window_copy_update_cursor(wme, px, data->cy); window_copy_update_cursor(wme, px, data->cy);
if (window_copy_update_selection(wme, 1)) if (window_copy_update_selection(wme, 1, 0))
window_copy_redraw_lines(wme, data->cy, 1); window_copy_redraw_lines(wme, data->cy, 1);
} }
@@ -3464,7 +3471,7 @@ window_copy_cursor_end_of_line(struct window_mode_entry *wme)
} }
window_copy_update_cursor(wme, px, data->cy); window_copy_update_cursor(wme, px, data->cy);
if (window_copy_update_selection(wme, 1)) if (window_copy_update_selection(wme, 1, 0))
window_copy_redraw_lines(wme, data->cy, 1); window_copy_redraw_lines(wme, data->cy, 1);
} }
@@ -3515,7 +3522,7 @@ window_copy_other_end(struct window_mode_entry *wme)
} else } else
data->cy = cy + sely - yy; data->cy = cy + sely - yy;
window_copy_update_selection(wme, 1); window_copy_update_selection(wme, 1, 1);
window_copy_redraw_screen(wme); window_copy_redraw_screen(wme);
} }
@@ -3539,7 +3546,7 @@ window_copy_cursor_left(struct window_mode_entry *wme)
window_copy_cursor_end_of_line(wme); window_copy_cursor_end_of_line(wme);
} else if (cx > 0) { } else if (cx > 0) {
window_copy_update_cursor(wme, cx - 1, data->cy); window_copy_update_cursor(wme, cx - 1, data->cy);
if (window_copy_update_selection(wme, 1)) if (window_copy_update_selection(wme, 1, 0))
window_copy_redraw_lines(wme, data->cy, 1); window_copy_redraw_lines(wme, data->cy, 1);
} }
} }
@@ -3571,7 +3578,7 @@ window_copy_cursor_right(struct window_mode_entry *wme)
cx++; cx++;
} }
window_copy_update_cursor(wme, cx, data->cy); window_copy_update_cursor(wme, cx, data->cy);
if (window_copy_update_selection(wme, 1)) if (window_copy_update_selection(wme, 1, 0))
window_copy_redraw_lines(wme, data->cy, 1); window_copy_redraw_lines(wme, data->cy, 1);
} }
} }
@@ -3604,7 +3611,7 @@ window_copy_cursor_up(struct window_mode_entry *wme, int scroll_only)
} }
} else { } else {
window_copy_update_cursor(wme, data->lastcx, data->cy - 1); window_copy_update_cursor(wme, data->lastcx, data->cy - 1);
if (window_copy_update_selection(wme, 1)) { if (window_copy_update_selection(wme, 1, 0)) {
if (data->cy == screen_size_y(s) - 1) if (data->cy == screen_size_y(s) - 1)
window_copy_redraw_lines(wme, data->cy, 1); window_copy_redraw_lines(wme, data->cy, 1);
else else
@@ -3650,7 +3657,7 @@ window_copy_cursor_down(struct window_mode_entry *wme, int scroll_only)
window_copy_redraw_lines(wme, data->cy - 1, 2); window_copy_redraw_lines(wme, data->cy - 1, 2);
} else { } else {
window_copy_update_cursor(wme, data->lastcx, data->cy + 1); window_copy_update_cursor(wme, data->lastcx, data->cy + 1);
if (window_copy_update_selection(wme, 1)) if (window_copy_update_selection(wme, 1, 0))
window_copy_redraw_lines(wme, data->cy - 1, 2); window_copy_redraw_lines(wme, data->cy - 1, 2);
} }
@@ -3685,7 +3692,7 @@ window_copy_cursor_jump(struct window_mode_entry *wme)
if (!(gc.flags & GRID_FLAG_PADDING) && if (!(gc.flags & GRID_FLAG_PADDING) &&
gc.data.size == 1 && *gc.data.data == data->jumpchar) { gc.data.size == 1 && *gc.data.data == data->jumpchar) {
window_copy_update_cursor(wme, px, data->cy); window_copy_update_cursor(wme, px, data->cy);
if (window_copy_update_selection(wme, 1)) if (window_copy_update_selection(wme, 1, 0))
window_copy_redraw_lines(wme, data->cy, 1); window_copy_redraw_lines(wme, data->cy, 1);
return; return;
} }
@@ -3712,7 +3719,7 @@ window_copy_cursor_jump_back(struct window_mode_entry *wme)
if (!(gc.flags & GRID_FLAG_PADDING) && if (!(gc.flags & GRID_FLAG_PADDING) &&
gc.data.size == 1 && *gc.data.data == data->jumpchar) { gc.data.size == 1 && *gc.data.data == data->jumpchar) {
window_copy_update_cursor(wme, px, data->cy); window_copy_update_cursor(wme, px, data->cy);
if (window_copy_update_selection(wme, 1)) if (window_copy_update_selection(wme, 1, 0))
window_copy_redraw_lines(wme, data->cy, 1); window_copy_redraw_lines(wme, data->cy, 1);
return; return;
} }
@@ -3739,7 +3746,7 @@ window_copy_cursor_jump_to(struct window_mode_entry *wme)
if (!(gc.flags & GRID_FLAG_PADDING) && if (!(gc.flags & GRID_FLAG_PADDING) &&
gc.data.size == 1 && *gc.data.data == data->jumpchar) { gc.data.size == 1 && *gc.data.data == data->jumpchar) {
window_copy_update_cursor(wme, px - 1, data->cy); window_copy_update_cursor(wme, px - 1, data->cy);
if (window_copy_update_selection(wme, 1)) if (window_copy_update_selection(wme, 1, 0))
window_copy_redraw_lines(wme, data->cy, 1); window_copy_redraw_lines(wme, data->cy, 1);
return; return;
} }
@@ -3769,7 +3776,7 @@ window_copy_cursor_jump_to_back(struct window_mode_entry *wme)
if (!(gc.flags & GRID_FLAG_PADDING) && if (!(gc.flags & GRID_FLAG_PADDING) &&
gc.data.size == 1 && *gc.data.data == data->jumpchar) { gc.data.size == 1 && *gc.data.data == data->jumpchar) {
window_copy_update_cursor(wme, px + 1, data->cy); window_copy_update_cursor(wme, px + 1, data->cy);
if (window_copy_update_selection(wme, 1)) if (window_copy_update_selection(wme, 1, 0))
window_copy_redraw_lines(wme, data->cy, 1); window_copy_redraw_lines(wme, data->cy, 1);
return; return;
} }
@@ -3818,7 +3825,7 @@ window_copy_cursor_next_word(struct window_mode_entry *wme,
} while (expected == 1); } while (expected == 1);
window_copy_update_cursor(wme, px, data->cy); window_copy_update_cursor(wme, px, data->cy);
if (window_copy_update_selection(wme, 1)) if (window_copy_update_selection(wme, 1, 0))
window_copy_redraw_lines(wme, data->cy, 1); window_copy_redraw_lines(wme, data->cy, 1);
} }
@@ -3919,7 +3926,7 @@ window_copy_cursor_next_word_end(struct window_mode_entry *wme,
px--; px--;
window_copy_update_cursor(wme, px, data->cy); window_copy_update_cursor(wme, px, data->cy);
if (window_copy_update_selection(wme, 1)) if (window_copy_update_selection(wme, 1, 0))
window_copy_redraw_lines(wme, data->cy, 1); window_copy_redraw_lines(wme, data->cy, 1);
} }
@@ -4016,7 +4023,7 @@ window_copy_cursor_previous_word(struct window_mode_entry *wme,
out: out:
window_copy_update_cursor(wme, px, data->cy); window_copy_update_cursor(wme, px, data->cy);
if (window_copy_update_selection(wme, 1)) if (window_copy_update_selection(wme, 1, 0))
window_copy_redraw_lines(wme, data->cy, 1); window_copy_redraw_lines(wme, data->cy, 1);
} }
@@ -4034,7 +4041,7 @@ window_copy_scroll_up(struct window_mode_entry *wme, u_int ny)
return; return;
data->oy -= ny; data->oy -= ny;
window_copy_update_selection(wme, 0); window_copy_update_selection(wme, 0, 0);
screen_write_start(&ctx, wp, NULL); screen_write_start(&ctx, wp, NULL);
screen_write_cursormove(&ctx, 0, 0, 0); screen_write_cursormove(&ctx, 0, 0, 0);
@@ -4068,7 +4075,7 @@ window_copy_scroll_down(struct window_mode_entry *wme, u_int ny)
return; return;
data->oy += ny; data->oy += ny;
window_copy_update_selection(wme, 0); window_copy_update_selection(wme, 0, 0);
screen_write_start(&ctx, wp, NULL); screen_write_start(&ctx, wp, NULL);
screen_write_cursormove(&ctx, 0, 0, 0); screen_write_cursormove(&ctx, 0, 0, 0);
@@ -4095,7 +4102,7 @@ window_copy_rectangle_toggle(struct window_mode_entry *wme)
if (data->cx > px) if (data->cx > px)
window_copy_update_cursor(wme, px, data->cy); window_copy_update_cursor(wme, px, data->cy);
window_copy_update_selection(wme, 1); window_copy_update_selection(wme, 1, 0);
window_copy_redraw_screen(wme); window_copy_redraw_screen(wme);
} }
@@ -4206,7 +4213,7 @@ window_copy_drag_update(struct client *c, struct mouse_event *m)
old_cy = data->cy; old_cy = data->cy;
window_copy_update_cursor(wme, x, y); window_copy_update_cursor(wme, x, y);
if (window_copy_update_selection(wme, 1)) if (window_copy_update_selection(wme, 1, 0))
window_copy_redraw_selection(wme, old_cy); window_copy_redraw_selection(wme, old_cy);
if (old_cy != data->cy || old_cx == data->cx) { if (old_cy != data->cy || old_cx == data->cx) {
if (y == 0) { if (y == 0) {