Merge branch 'obsd-master'

Sync from OpenBSD.
This commit is contained in:
Thomas Adam 2012-11-27 18:12:04 +00:00
commit 39631edb98
11 changed files with 142 additions and 55 deletions

11
cfg.c
View File

@ -34,9 +34,10 @@
void printflike2 cfg_print(struct cmd_ctx *, const char *, ...);
void printflike2 cfg_error(struct cmd_ctx *, const char *, ...);
char *cfg_cause;
int cfg_finished;
struct causelist cfg_causes = ARRAY_INITIALIZER;
char *cfg_cause;
int cfg_finished;
int cfg_references;
struct causelist cfg_causes;
/* ARGSUSED */
void printflike2
@ -89,6 +90,8 @@ load_cfg(const char *path, struct cmd_ctx *ctxin, struct causelist *causes)
}
n = 0;
cfg_references++;
line = NULL;
retval = CMD_RETURN_NORMAL;
while ((buf = fgetln(f, &len))) {
@ -171,6 +174,8 @@ load_cfg(const char *path, struct cmd_ctx *ctxin, struct causelist *causes)
}
fclose(f);
cfg_references--;
return (retval);
}

View File

@ -30,13 +30,15 @@
*/
enum cmd_retval cmd_run_shell_exec(struct cmd *, struct cmd_ctx *);
void cmd_run_shell_callback(struct job *);
void cmd_run_shell_free(void *);
void cmd_run_shell_callback(struct job *);
void cmd_run_shell_free(void *);
void cmd_run_shell_print(struct job *, const char *);
const struct cmd_entry cmd_run_shell_entry = {
"run-shell", "run",
"", 1, 1,
"command",
"t:", 1, 1,
CMD_TARGET_PANE_USAGE " command",
0,
NULL,
NULL,
@ -46,17 +48,42 @@ const struct cmd_entry cmd_run_shell_entry = {
struct cmd_run_shell_data {
char *cmd;
struct cmd_ctx ctx;
u_int wp_id;
};
void
cmd_run_shell_print(struct job *job, const char *msg)
{
struct cmd_run_shell_data *cdata = job->data;
struct cmd_ctx *ctx = &cdata->ctx;
struct window_pane *wp;
wp = window_pane_find_by_id(cdata->wp_id);
if (wp == NULL) {
ctx->print(ctx, "%s", msg);
return;
}
if (window_pane_set_mode(wp, &window_copy_mode) == 0)
window_copy_init_for_output(wp);
if (wp->mode == &window_copy_mode)
window_copy_add(wp, "%s", msg);
}
enum cmd_retval
cmd_run_shell_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct args *args = self->args;
struct cmd_run_shell_data *cdata;
const char *shellcmd = args->argv[0];
struct window_pane *wp;
if (cmd_find_pane(ctx, args_get(args, 't'), NULL, &wp) == NULL)
return (CMD_RETURN_ERROR);
cdata = xmalloc(sizeof *cdata);
cdata->cmd = xstrdup(args->argv[0]);
cdata->wp_id = wp->id;
memcpy(&cdata->ctx, ctx, sizeof cdata->ctx);
if (ctx->cmdclient != NULL)
@ -87,7 +114,7 @@ cmd_run_shell_callback(struct job *job)
lines = 0;
do {
if ((line = evbuffer_readline(job->event->input)) != NULL) {
ctx->print(ctx, "%s", line);
cmd_run_shell_print (job, line);
lines++;
}
} while (line != NULL);
@ -98,7 +125,7 @@ cmd_run_shell_callback(struct job *job)
memcpy(line, EVBUFFER_DATA(job->event->input), size);
line[size] = '\0';
ctx->print(ctx, "%s", line);
cmd_run_shell_print(job, line);
lines++;
free(line);
@ -115,10 +142,10 @@ cmd_run_shell_callback(struct job *job)
xasprintf(&msg, "'%s' terminated by signal %d", cmd, retcode);
}
if (msg != NULL) {
if (lines != 0)
ctx->print(ctx, "%s", msg);
else
if (lines == 0)
ctx->info(ctx, "%s", msg);
else
cmd_run_shell_print(job, msg);
free(msg);
}
}

View File

@ -42,35 +42,32 @@ enum cmd_retval
cmd_source_file_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct args *args = self->args;
struct causelist causes;
char *cause;
struct window_pane *wp;
int retval;
u_int i;
char *cause;
ARRAY_INIT(&causes);
retval = load_cfg(args->argv[0], ctx, &cfg_causes);
retval = load_cfg(args->argv[0], ctx, &causes);
if (ARRAY_EMPTY(&causes))
/*
* If the context for the cmdclient came from tmux's configuration
* file, then return the status of this command now, regardless of the
* error condition. Any errors from parsing a configuration file at
* startup will be handled for us by the server.
*/
if (cfg_references > 0 ||
(ctx->curclient == NULL && ctx->cmdclient == NULL))
return (retval);
if (retval == 1 && !RB_EMPTY(&sessions) && ctx->cmdclient != NULL) {
wp = RB_MIN(sessions, &sessions)->curw->window->active;
window_pane_set_mode(wp, &window_copy_mode);
window_copy_init_for_output(wp);
for (i = 0; i < ARRAY_LENGTH(&causes); i++) {
cause = ARRAY_ITEM(&causes, i);
window_copy_add(wp, "%s", cause);
free(cause);
}
} else {
for (i = 0; i < ARRAY_LENGTH(&causes); i++) {
cause = ARRAY_ITEM(&causes, i);
ctx->print(ctx, "%s", cause);
free(cause);
}
/*
* We were called from the command-line in which case print the errors
* gathered here directly.
*/
for (i = 0; i < ARRAY_LENGTH(&cfg_causes); i++) {
cause = ARRAY_ITEM(&cfg_causes, i);
ctx->print(ctx, "%s", cause);
free(cause);
}
ARRAY_FREE(&causes);
ARRAY_FREE(&cfg_causes);
return (retval);
}

36
cmd.c
View File

@ -115,6 +115,7 @@ const struct cmd_entry *cmd_table[] = {
NULL
};
int cmd_session_better(struct session *, struct session *, int);
struct session *cmd_choose_session_list(struct sessionslist *);
struct session *cmd_choose_session(int);
struct client *cmd_choose_client(struct clients *);
@ -370,6 +371,24 @@ cmd_current_session(struct cmd_ctx *ctx, int prefer_unattached)
return (cmd_choose_session(prefer_unattached));
}
/* Is this session better? */
int
cmd_session_better(struct session *s, struct session *best,
int prefer_unattached)
{
if (best == NULL)
return 1;
if (prefer_unattached) {
if (!(best->flags & SESSION_UNATTACHED) &&
(s->flags & SESSION_UNATTACHED))
return 1;
else if ((best->flags & SESSION_UNATTACHED) &&
!(s->flags & SESSION_UNATTACHED))
return 0;
}
return (timercmp(&s->activity_time, &best->activity_time, >));
}
/*
* Find the most recently used session, preferring unattached if the flag is
* set.
@ -377,21 +396,14 @@ cmd_current_session(struct cmd_ctx *ctx, int prefer_unattached)
struct session *
cmd_choose_session(int prefer_unattached)
{
struct session *s, *sbest;
struct timeval *tv = NULL;
struct session *s, *best;
sbest = NULL;
best = NULL;
RB_FOREACH(s, sessions, &sessions) {
if (tv == NULL || timercmp(&s->activity_time, tv, >) ||
(prefer_unattached &&
!(sbest->flags & SESSION_UNATTACHED) &&
(s->flags & SESSION_UNATTACHED))) {
sbest = s;
tv = &s->activity_time;
}
if (cmd_session_better(s, best, prefer_unattached))
best = s;
}
return (sbest);
return (best);
}
/* Find the most recently used session from a list. */

View File

@ -76,7 +76,7 @@ window_name_callback(unused int fd, unused short events, void *data)
name != NULL && name[0] == '-' && name[1] != '\0')
wname = parse_window_name(name + 1);
else
wname = parse_window_name(name);
wname = parse_window_name(name);
free(name);
}

View File

@ -685,6 +685,21 @@ const struct options_table_entry window_options_table[] = {
.default_str = "#I:#W#F"
},
{ .name = "window-status-last-attr",
.type = OPTIONS_TABLE_ATTRIBUTES,
.default_num = 0
},
{ .name = "window-status-last-bg",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 8
},
{ .name = "window-status-last-fg",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 8
},
{ .name = "window-status-fg",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 8

View File

@ -705,6 +705,17 @@ status_print(
gc->attr = attr;
fmt = options_get_string(oo, "window-status-current-format");
}
if (wl == TAILQ_FIRST(&s->lastw)) {
fg = options_get_number(oo, "window-status-last-fg");
if (fg != 8)
colour_set_fg(gc, fg);
bg = options_get_number(oo, "window-status-last-bg");
if (bg != 8)
colour_set_bg(gc, bg);
attr = options_get_number(oo, "window-status-last-attr");
if (attr != 0)
gc->attr = attr;
}
if (wl->flags & WINLINK_BELL) {
fg = options_get_number(oo, "window-status-bell-fg");

19
tmux.1
View File

@ -2827,6 +2827,15 @@ Like
.Ar window-status-format ,
but is the format used when the window is the current window.
.Pp
.It Ic window-status-last-attr Ar attributes
Set status line attributes for the last active window.
.Pp
.It Ic window-status-last-bg Ar colour
Set status line background colour for the last active window.
.Pp
.It Ic window-status-last-fg Ar colour
Set status line foreground colour for the last active window.
.Pp
.It Ic window-status-fg Ar colour
Set status line foreground colour for a single window.
.Pp
@ -3389,12 +3398,18 @@ otherwise.
Lock each client individually by running the command specified by the
.Ic lock-command
option.
.It Ic run-shell Ar shell-command
.It Xo Ic run-shell
.Op Fl t Ar target-pane
.Ar shell-command
.Xc
.D1 (alias: Ic run )
Execute
.Ar shell-command
in the background without creating a window.
After it finishes, any output to stdout is displayed in copy mode.
After it finishes, any output to stdout is displayed in copy mode (in the pane
specified by
.Fl t
or the current pane if omitted).
If the command doesn't return success, the exit status is also displayed.
.It Ic server-info
.D1 (alias: Ic info )

12
tmux.c
View File

@ -162,7 +162,7 @@ parseenvironment(void)
char *
makesocketpath(const char *label)
{
char base[MAXPATHLEN], *path, *s;
char base[MAXPATHLEN], realbase[MAXPATHLEN], *path, *s;
struct stat sb;
u_int uid;
@ -186,7 +186,10 @@ makesocketpath(const char *label)
return (NULL);
}
xasprintf(&path, "%s/%s", base, label);
if (realpath(base, realbase) == NULL)
strlcpy(realbase, base, sizeof realbase);
xasprintf(&path, "%s/%s", realbase, label);
return (path);
}
@ -333,6 +336,8 @@ main(int argc, char **argv)
options_init(&global_w_options, NULL);
options_table_populate_tree(window_options_table, &global_w_options);
ARRAY_INIT(&cfg_causes);
/* Enable UTF-8 if the first client is on UTF-8 terminal. */
if (flags & IDENTIFY_UTF8) {
options_set_number(&global_s_options, "status-utf8", 1);
@ -390,8 +395,7 @@ main(int argc, char **argv)
}
}
free(label);
if (realpath(path, socket_path) == NULL)
strlcpy(socket_path, path, sizeof socket_path);
strlcpy(socket_path, path, sizeof socket_path);
free(path);
#ifdef HAVE_SETPROCTITLE

1
tmux.h
View File

@ -1513,6 +1513,7 @@ __dead void shell_exec(const char *, const char *);
/* cfg.c */
extern int cfg_finished;
extern int cfg_references;
extern struct causelist cfg_causes;
void printflike2 cfg_add_cause(struct causelist *, const char *, ...);
int load_cfg(const char *, struct cmd_ctx *, struct causelist *);

View File

@ -832,10 +832,10 @@ window_copy_mouse(
if (m->event == MOUSE_EVENT_WHEEL) {
if (m->wheel == MOUSE_WHEEL_UP) {
for (i = 0; i < 5; i++)
window_copy_cursor_up(wp, 0);
window_copy_cursor_up(wp, 1);
} else if (m->wheel == MOUSE_WHEEL_DOWN) {
for (i = 0; i < 5; i++)
window_copy_cursor_down(wp, 0);
window_copy_cursor_down(wp, 1);
if (data->oy == 0)
goto reset_mode;
}