Merge branch 'obsd-master'

This commit is contained in:
Thomas Adam
2025-04-22 16:01:12 +01:00
7 changed files with 120 additions and 84 deletions

View File

@ -132,9 +132,12 @@ cmd_swap_pane_exec(struct cmd *self, struct cmdq_item *item)
window_pane_stack_remove(&dst_w->last_panes, dst_wp);
colour_palette_from_option(&src_wp->palette, src_wp->options);
colour_palette_from_option(&dst_wp->palette, dst_wp->options);
layout_fix_panes(src_w, NULL);
server_redraw_window(src_w);
}
server_redraw_window(src_w);
layout_fix_panes(dst_w, NULL);
server_redraw_window(dst_w);
notify_window("window-layout-changed", src_w);
if (src_w != dst_w)
notify_window("window-layout-changed", dst_w);

113
format.c
View File

@ -4518,7 +4518,8 @@ format_replace(struct format_expand_state *es, const char *key, size_t keylen,
{
struct format_tree *ft = es->ft;
struct window_pane *wp = ft->wp;
const char *errstr, *copy, *cp, *marker = NULL;
const char *errstr, *copy, *cp, *cp2;
const char *marker = NULL;
const char *time_format = NULL;
char *copy0, *condition, *found, *new;
char *value, *left, *right;
@ -4781,53 +4782,81 @@ format_replace(struct format_expand_state *es, const char *key, size_t keylen,
free(right);
free(left);
} else if (*copy == '?') {
/* Conditional: check first and choose second or third. */
cp = format_skip(copy + 1, ",");
if (cp == NULL) {
format_log(es, "condition syntax error: %s", copy + 1);
goto fail;
}
condition = xstrndup(copy + 1, cp - (copy + 1));
format_log(es, "condition is: %s", condition);
found = format_find(ft, condition, modifiers, time_format);
if (found == NULL) {
/*
* If the condition not found, try to expand it. If
* the expansion doesn't have any effect, then assume
* false.
*/
found = format_expand1(es, condition);
if (strcmp(found, condition) == 0) {
free(found);
found = xstrdup("");
/*
* Conditional: For each pair of (condition, value), check the
* condition and return the value if true. If no condition
* matches, return the last unpaired arg if there is one, or the
* empty string if not.
*/
cp = copy + 1;
while (1) {
cp2 = format_skip(cp, ",");
if (cp2 == NULL) {
format_log(es,
"condition '%s' not found; assuming false",
"no condition matched in '%s'; using last "
"arg", copy + 1);
value = format_expand1(es, cp);
break;
}
condition = xstrndup(cp, cp2 - cp);
format_log(es, "condition is: %s", condition);
found = format_find(ft, condition, modifiers,
time_format);
if (found == NULL) {
/*
* If the condition not found, try to expand it.
* If the expansion doesn't have any effect,
* then assume false.
*/
found = format_expand1(es, condition);
if (strcmp(found, condition) == 0) {
free(found);
found = xstrdup("");
format_log(es,
"condition '%s' not found; "
"assuming false",
condition);
}
} else {
format_log(es, "condition '%s' found: %s",
condition, found);
}
cp = cp2 + 1;
cp2 = format_skip(cp, ",");
if (format_true(found)) {
format_log(es, "condition '%s' is true",
condition);
if (cp2 == NULL)
value = format_expand1(es, cp);
else {
right = xstrndup(cp, cp2 - cp);
value = format_expand1(es, right);
free(right);
}
free(condition);
free(found);
break;
} else {
format_log(es, "condition '%s' is false",
condition);
}
} else {
format_log(es, "condition '%s' found: %s", condition,
found);
}
if (format_choose(es, cp + 1, &left, &right, 0) != 0) {
format_log(es, "condition '%s' syntax error: %s",
condition, cp + 1);
free(condition);
free(found);
goto fail;
}
if (format_true(found)) {
format_log(es, "condition '%s' is true", condition);
value = format_expand1(es, left);
} else {
format_log(es, "condition '%s' is false", condition);
value = format_expand1(es, right);
}
free(right);
free(left);
free(condition);
free(found);
if (cp2 == NULL) {
format_log(es,
"no condition matched in '%s'; using empty "
"string", copy + 1);
value = xstrdup("");
break;
}
cp = cp2 + 1;
}
} else if (mexp != NULL) {
value = format_replace_expression(mexp, es, copy);
if (value == NULL)

View File

@ -197,11 +197,12 @@ key_bindings_add(const char *name, key_code key, const char *note, int repeat,
bd = key_bindings_get(table, key & ~KEYC_MASK_FLAGS);
if (cmdlist == NULL) {
if (bd != NULL) {
free((void *)bd->note);
if (note != NULL)
if (note != NULL) {
free((void *)bd->note);
bd->note = xstrdup(note);
else
bd->note = NULL;
}
if (repeat)
bd->flags |= KEY_BINDING_REPEAT;
}
return;
}
@ -433,8 +434,9 @@ key_bindings_init(void)
"bind -N 'Resize the pane right' -r C-Right { resize-pane -R }",
/* Menu keys */
"bind < { display-menu -xW -yW -T '#[align=centre]#{window_index}:#{window_name}' " DEFAULT_WINDOW_MENU " }",
"bind > { display-menu -xP -yP -T '#[align=centre]#{pane_index} (#{pane_id})' " DEFAULT_PANE_MENU " }",
"bind -N 'Display window menu' < { display-menu -xW -yW -T '#[align=centre]#{window_index}:#{window_name}' " DEFAULT_WINDOW_MENU " }",
"bind -N 'Display pane menu' > { display-menu -xP -yP -T '#[align=centre]#{pane_index} (#{pane_id})' " DEFAULT_PANE_MENU " }",
/* Mouse button 1 down on pane. */
"bind -n MouseDown1Pane { select-pane -t=; send -M }",

28
tmux.1
View File

@ -3730,7 +3730,15 @@ options.
.Fl N
attaches a note to the key (shown with
.Ic list-keys
.Fl N ) .
.Fl N ) ,
which can be cleared by passing an empty string.
The
.Fl r
and
.Fl N
flags can be used without
.Ar command
to alter an existing binding.
.Pp
To view the default bindings and possible commands, see the
.Ic list-keys
@ -5633,10 +5641,12 @@ by a
.Ql } .
.Pp
Conditionals are available by prefixing with
.Ql \&?
and separating two alternatives with a comma;
if the specified variable exists and is not zero, the first alternative
is chosen, otherwise the second is used.
.Ql \&? .
For each pair of two arguments, if the variable in the first of the pair exists
and is not zero, the second of the pair is chosen, otherwise it continues.
If no condition from paired arguments matches, the default value is chosen.
If there's an unpaired final argument, that is the default.
If not, the default is the empty string.
For example
.Ql #{?session_attached,attached,not attached}
will include the string
@ -5652,6 +5662,12 @@ if
is enabled, or
.Ql no
if not.
.Ql #{?#{n:window_name},#{window_name} - }
will include the window name with a dash separator if there is a window name, or
the empty string if the window name is empty.
.Ql #{?session_format,format1,window_format,format2,format3}
will include format1 for a session format, format2 for a window format, or
format3 for neither a session nor a window format.
Conditionals can be nested arbitrarily.
Inside a conditional,
.Ql \&,
@ -6054,7 +6070,7 @@ The following variables are available, where appropriate:
.It Li "pane_format" Ta "" Ta "1 if format is for a pane"
.It Li "pane_height" Ta "" Ta "Height of pane"
.It Li "pane_id" Ta "#D" Ta "Unique pane ID"
.It Li "pane_in_mode" Ta "" Ta "1 if pane is in a mode"
.It Li "pane_in_mode" Ta "" Ta "Number of modes pane is in"
.It Li "pane_index" Ta "#P" Ta "Index of pane"
.It Li "pane_input_off" Ta "" Ta "1 if input to pane is disabled"
.It Li "pane_key_mode" Ta "" Ta "Extended key reporting mode in this pane"

View File

@ -44,12 +44,8 @@ static void window_buffer_key(struct window_mode_entry *,
#define WINDOW_BUFFER_DEFAULT_KEY_FORMAT \
"#{?#{e|<:#{line},10}," \
"#{line}" \
"," \
"#{?#{e|<:#{line},36}," \
"M-#{a:#{e|+:97,#{e|-:#{line},10}}}" \
"," \
"" \
"}" \
",#{e|<:#{line},36}," \
"M-#{a:#{e|+:97,#{e|-:#{line},10}}}" \
"}"
static const struct menu_item window_buffer_menu_items[] = {

View File

@ -43,12 +43,8 @@ static void window_client_key(struct window_mode_entry *,
#define WINDOW_CLIENT_DEFAULT_KEY_FORMAT \
"#{?#{e|<:#{line},10}," \
"#{line}" \
"," \
"#{?#{e|<:#{line},36}," \
"M-#{a:#{e|+:97,#{e|-:#{line},10}}}" \
"," \
"" \
"}" \
",#{e|<:#{line},36}," \
"M-#{a:#{e|+:97,#{e|-:#{line},10}}}" \
"}"
static const struct menu_item window_client_menu_items[] = {

View File

@ -41,30 +41,24 @@ static void window_tree_key(struct window_mode_entry *,
"#{?pane_marked,#[reverse],}" \
"#{pane_current_command}#{?pane_active,*,}#{?pane_marked,M,}" \
"#{?#{&&:#{pane_title},#{!=:#{pane_title},#{host_short}}},: \"#{pane_title}\",}" \
",window_format," \
"#{?window_marked_flag,#[reverse],}" \
"#{window_name}#{window_flags}" \
"#{?#{&&:#{==:#{window_panes},1},#{&&:#{pane_title},#{!=:#{pane_title},#{host_short}}}},: \"#{pane_title}\",}" \
"," \
"#{?window_format," \
"#{?window_marked_flag,#[reverse],}" \
"#{window_name}#{window_flags}" \
"#{?#{&&:#{==:#{window_panes},1},#{&&:#{pane_title},#{!=:#{pane_title},#{host_short}}}},: \"#{pane_title}\",}" \
"," \
"#{session_windows} windows" \
"#{?session_grouped, " \
"(group #{session_group}: " \
"#{session_group_list})," \
"}" \
"#{?session_attached, (attached),}" \
"#{session_windows} windows" \
"#{?session_grouped, " \
"(group #{session_group}: " \
"#{session_group_list})," \
"}" \
"#{?session_attached, (attached),}" \
"}"
#define WINDOW_TREE_DEFAULT_KEY_FORMAT \
"#{?#{e|<:#{line},10}," \
"#{line}" \
"," \
"#{?#{e|<:#{line},36}," \
"M-#{a:#{e|+:97,#{e|-:#{line},10}}}" \
"," \
"" \
"}" \
",#{e|<:#{line},36}," \
"M-#{a:#{e|+:97,#{e|-:#{line},10}}}" \
"}"
static const struct menu_item window_tree_menu_items[] = {