1
0
mirror of https://github.com/tmux/tmux.git synced 2025-04-05 07:38:49 +00:00

Merge branch 'obsd-master'

This commit is contained in:
Thomas Adam 2025-03-24 22:01:11 +00:00
commit 9e1f110db0
8 changed files with 125 additions and 34 deletions

4
cmd.c
View File

@ -636,7 +636,7 @@ cmd_list_free(struct cmd_list *cmdlist)
/* Copy a command list, expanding %s in arguments. */
struct cmd_list *
cmd_list_copy(struct cmd_list *cmdlist, int argc, char **argv)
cmd_list_copy(const struct cmd_list *cmdlist, int argc, char **argv)
{
struct cmd *cmd;
struct cmd_list *new_cmdlist;
@ -667,7 +667,7 @@ cmd_list_copy(struct cmd_list *cmdlist, int argc, char **argv)
/* Get a command list as a string. */
char *
cmd_list_print(struct cmd_list *cmdlist, int escaped)
cmd_list_print(const struct cmd_list *cmdlist, int escaped)
{
struct cmd *cmd, *next;
char *buf, *this;

View File

@ -5432,9 +5432,14 @@ format_grid_hyperlink(struct grid *gd, u_int x, u_int y, struct screen* s)
const char *uri;
struct grid_cell gc;
grid_get_cell(gd, x, y, &gc);
if (gc.flags & GRID_FLAG_PADDING)
return (NULL);
for (;;) {
grid_get_cell(gd, x, y, &gc);
if (~gc.flags & GRID_FLAG_PADDING)
break;
if (x == 0)
return (NULL);
x--;
}
if (s->hyperlinks == NULL || gc.link == 0)
return (NULL);
if (!hyperlinks_get(s->hyperlinks, gc.link, &uri, NULL, NULL))

View File

@ -285,6 +285,13 @@ const struct options_table_entry options_table[] = {
.text = "Style of the cursor."
},
{ .name = "default-client-command",
.type = OPTIONS_TABLE_COMMAND,
.scope = OPTIONS_TABLE_SERVER,
.default_str = "new-session",
.text = "Default command to run when tmux is run without a command."
},
{ .name = "default-terminal",
.type = OPTIONS_TABLE_STRING,
.scope = OPTIONS_TABLE_SERVER,

View File

@ -260,6 +260,7 @@ options_default(struct options *oo, const struct options_table_entry *oe)
struct options_entry *o;
union options_value *ov;
u_int i;
struct cmd_parse_result *pr;
o = options_empty(oo, oe);
ov = &o->value;
@ -278,6 +279,17 @@ options_default(struct options *oo, const struct options_table_entry *oe)
case OPTIONS_TABLE_STRING:
ov->string = xstrdup(oe->default_str);
break;
case OPTIONS_TABLE_COMMAND:
pr = cmd_parse_from_string(oe->default_str, NULL);
switch (pr->status) {
case CMD_PARSE_ERROR:
free(pr->error);
break;
case CMD_PARSE_SUCCESS:
ov->cmdlist = pr->cmdlist;
break;
}
break;
default:
ov->number = oe->default_num;
break;
@ -737,6 +749,19 @@ options_get_number(struct options *oo, const char *name)
return (o->value.number);
}
const struct cmd_list *
options_get_command(struct options *oo, const char *name)
{
struct options_entry *o;
o = options_get(oo, name);
if (o == NULL)
fatalx("missing option %s", name);
if (!OPTIONS_IS_COMMAND(o))
fatalx("option %s is not a command", name);
return (o->value.cmdlist);
}
struct options_entry *
options_set_string(struct options *oo, const char *name, int append,
const char *fmt, ...)
@ -798,6 +823,30 @@ options_set_number(struct options *oo, const char *name, long long value)
return (o);
}
struct options_entry *
options_set_command(struct options *oo, const char *name,
struct cmd_list *value)
{
struct options_entry *o;
if (*name == '@')
fatalx("user option %s must be a string", name);
o = options_get_only(oo, name);
if (o == NULL) {
o = options_default(oo, options_parent_table_entry(oo, name));
if (o == NULL)
return (NULL);
}
if (!OPTIONS_IS_COMMAND(o))
fatalx("option %s is not a command", name);
if (o->value.cmdlist != NULL)
cmd_list_free(o->value.cmdlist);
o->value.cmdlist = value;
return (o);
}
int
options_scope_from_name(struct args *args, int window,
const char *name, struct cmd_find_state *fs, struct options **oo,
@ -1054,6 +1103,7 @@ options_from_string(struct options *oo, const struct options_table_entry *oe,
const char *errstr, *new;
char *old;
key_code key;
struct cmd_parse_result *pr;
if (oe != NULL) {
if (value == NULL &&
@ -1112,6 +1162,15 @@ options_from_string(struct options *oo, const struct options_table_entry *oe,
case OPTIONS_TABLE_CHOICE:
return (options_from_string_choice(oe, oo, name, value, cause));
case OPTIONS_TABLE_COMMAND:
pr = cmd_parse_from_string(value, NULL);
switch (pr->status) {
case CMD_PARSE_ERROR:
*cause = pr->error;
return (-1);
case CMD_PARSE_SUCCESS:
options_set_command(oo, name, pr->cmdlist);
return (0);
}
break;
}
return (-1);

View File

@ -3448,6 +3448,7 @@ server_client_dispatch_command(struct client *c, struct imsg *imsg)
struct cmd_parse_result *pr;
struct args_value *values;
struct cmdq_item *new_item;
struct cmd_list *cmdlist;
if (c->flags & CLIENT_EXIT)
return;
@ -3468,33 +3469,33 @@ server_client_dispatch_command(struct client *c, struct imsg *imsg)
}
if (argc == 0) {
argc = 1;
argv = xcalloc(1, sizeof *argv);
*argv = xstrdup("new-session");
cmdlist = cmd_list_copy(options_get_command(global_options,
"default-client-command"), 0, NULL);
} else {
values = args_from_vector(argc, argv);
pr = cmd_parse_from_arguments(values, argc, NULL);
switch (pr->status) {
case CMD_PARSE_ERROR:
cause = pr->error;
goto error;
case CMD_PARSE_SUCCESS:
break;
}
args_free_values(values, argc);
free(values);
cmd_free_argv(argc, argv);
cmdlist = pr->cmdlist;
}
values = args_from_vector(argc, argv);
pr = cmd_parse_from_arguments(values, argc, NULL);
switch (pr->status) {
case CMD_PARSE_ERROR:
cause = pr->error;
goto error;
case CMD_PARSE_SUCCESS:
break;
}
args_free_values(values, argc);
free(values);
cmd_free_argv(argc, argv);
if ((c->flags & CLIENT_READONLY) &&
!cmd_list_all_have(pr->cmdlist, CMD_READONLY))
!cmd_list_all_have(cmdlist, CMD_READONLY))
new_item = cmdq_get_callback(server_client_read_only, NULL);
else
new_item = cmdq_get_command(pr->cmdlist, NULL);
new_item = cmdq_get_command(cmdlist, NULL);
cmdq_append(c, new_item);
cmdq_append(c, cmdq_get_callback(server_client_command_done, NULL));
cmd_list_free(pr->cmdlist);
cmd_list_free(cmdlist);
return;
error:

11
tmux.1
View File

@ -254,9 +254,10 @@ was given) and off.
This specifies one of a set of commands used to control
.Nm ,
as described in the following sections.
If no commands are specified, the
.Ic new-session
command is assumed.
If no commands are specified, the command in
.Ic default-client-command
is assumed, which defaults to
.Ic new-session .
.El
.Sh DEFAULT KEY BINDINGS
.Nm
@ -4085,6 +4086,10 @@ where the number is a hexadecimal number.
Give the command to pipe to if the
.Ic copy-pipe
copy mode command is used without arguments.
.It Ic default-client-command Ar command
Set the default command to run when tmux is called without a command.
The default is
.Ic new-session .
.It Ic default-terminal Ar terminal
Set the default terminal for new windows created in this session - the
default value of the

7
tmux.h
View File

@ -2393,10 +2393,13 @@ struct options_entry *options_match_get(struct options *, const char *, int *,
int, int *);
const char *options_get_string(struct options *, const char *);
long long options_get_number(struct options *, const char *);
const struct cmd_list *options_get_command(struct options *, const char *);
struct options_entry * printflike(4, 5) options_set_string(struct options *,
const char *, int, const char *, ...);
struct options_entry *options_set_number(struct options *, const char *,
long long);
struct options_entry *options_set_command(struct options *, const char *,
struct cmd_list *);
int options_scope_from_name(struct args *, int,
const char *, struct cmd_find_state *, struct options **,
char **);
@ -2680,12 +2683,12 @@ struct cmd *cmd_copy(struct cmd *, int, char **);
void cmd_free(struct cmd *);
char *cmd_print(struct cmd *);
struct cmd_list *cmd_list_new(void);
struct cmd_list *cmd_list_copy(struct cmd_list *, int, char **);
struct cmd_list *cmd_list_copy(const struct cmd_list *, int, char **);
void cmd_list_append(struct cmd_list *, struct cmd *);
void cmd_list_append_all(struct cmd_list *, struct cmd_list *);
void cmd_list_move(struct cmd_list *, struct cmd_list *);
void cmd_list_free(struct cmd_list *);
char *cmd_list_print(struct cmd_list *, int);
char *cmd_list_print(const struct cmd_list *, int);
struct cmd *cmd_list_first(struct cmd_list *);
struct cmd *cmd_list_next(struct cmd *);
int cmd_list_all_have(struct cmd_list *, int);

View File

@ -302,6 +302,7 @@ window_tree_build_pane(struct session *s, struct winlink *wl,
struct window_tree_itemdata *item;
char *name, *text;
u_int idx;
struct format_tree *ft;
window_pane_index(wp, &idx);
@ -311,8 +312,11 @@ window_tree_build_pane(struct session *s, struct winlink *wl,
item->winlink = wl->idx;
item->pane = wp->id;
text = format_single(NULL, data->format, NULL, s, wl, wp);
ft = format_create(NULL, NULL, FORMAT_PANE|wp->id, 0);
format_defaults(ft, NULL, s, wl, wp);
text = format_expand(ft, data->format);
xasprintf(&name, "%u", idx);
format_free(ft);
mode_tree_add(data->data, parent, item, (uint64_t)wp, name, text, -1);
free(text);
@ -348,6 +352,7 @@ window_tree_build_window(struct session *s, struct winlink *wl,
struct window_pane *wp, **l;
u_int n, i;
int expanded;
struct format_tree *ft;
item = window_tree_add_item(data);
item->type = WINDOW_TREE_WINDOW;
@ -355,8 +360,11 @@ window_tree_build_window(struct session *s, struct winlink *wl,
item->winlink = wl->idx;
item->pane = -1;
text = format_single(NULL, data->format, NULL, s, wl, NULL);
ft = format_create(NULL, NULL, FORMAT_PANE|wl->window->active->id, 0);
format_defaults(ft, NULL, s, wl, NULL);
text = format_expand(ft, data->format);
xasprintf(&name, "%u", wl->idx);
format_free(ft);
if (data->type == WINDOW_TREE_SESSION ||
data->type == WINDOW_TREE_WINDOW)
@ -373,7 +381,6 @@ window_tree_build_window(struct session *s, struct winlink *wl,
if (TAILQ_NEXT(wp, entry) == NULL) {
if (!window_tree_filter_pane(s, wl, wp, filter))
goto empty;
return (1);
}
l = NULL;
@ -411,9 +418,10 @@ window_tree_build_session(struct session *s, void *modedata,
struct window_tree_itemdata *item;
struct mode_tree_item *mti;
char *text;
struct winlink *wl, **l;
struct winlink *wl = s->curw, **l;
u_int n, i, empty;
int expanded;
struct format_tree *ft;
item = window_tree_add_item(data);
item->type = WINDOW_TREE_SESSION;
@ -421,7 +429,10 @@ window_tree_build_session(struct session *s, void *modedata,
item->winlink = -1;
item->pane = -1;
text = format_single(NULL, data->format, NULL, s, NULL, NULL);
ft = format_create(NULL, NULL, FORMAT_PANE|wl->window->active->id, 0);
format_defaults(ft, NULL, s, NULL, NULL);
text = format_expand(ft, data->format);
format_free(ft);
if (data->type == WINDOW_TREE_SESSION)
expanded = 0;