mirror of
https://github.com/tmate-io/tmate.git
synced 2024-11-08 01:04:06 +01:00
Merge branch 'obsd-master'
Sync from OpenBSD.
This commit is contained in:
commit
39631edb98
11
cfg.c
11
cfg.c
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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
36
cmd.c
@ -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. */
|
||||
|
2
names.c
2
names.c
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
11
status.c
11
status.c
@ -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
19
tmux.1
@ -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
12
tmux.c
@ -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
1
tmux.h
@ -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 *);
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user