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); window_pane_stack_remove(&dst_w->last_panes, dst_wp);
colour_palette_from_option(&src_wp->palette, src_wp->options); colour_palette_from_option(&src_wp->palette, src_wp->options);
colour_palette_from_option(&dst_wp->palette, dst_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); server_redraw_window(dst_w);
notify_window("window-layout-changed", src_w); notify_window("window-layout-changed", src_w);
if (src_w != dst_w) if (src_w != dst_w)
notify_window("window-layout-changed", 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 format_tree *ft = es->ft;
struct window_pane *wp = ft->wp; 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; const char *time_format = NULL;
char *copy0, *condition, *found, *new; char *copy0, *condition, *found, *new;
char *value, *left, *right; char *value, *left, *right;
@ -4781,53 +4782,81 @@ format_replace(struct format_expand_state *es, const char *key, size_t keylen,
free(right); free(right);
free(left); free(left);
} else if (*copy == '?') { } else if (*copy == '?') {
/* Conditional: check first and choose second or third. */ /*
cp = format_skip(copy + 1, ","); * Conditional: For each pair of (condition, value), check the
if (cp == NULL) { * condition and return the value if true. If no condition
format_log(es, "condition syntax error: %s", copy + 1); * matches, return the last unpaired arg if there is one, or the
goto fail; * empty string if not.
} */
condition = xstrndup(copy + 1, cp - (copy + 1)); cp = copy + 1;
format_log(es, "condition is: %s", condition); while (1) {
cp2 = format_skip(cp, ",");
found = format_find(ft, condition, modifiers, time_format); if (cp2 == NULL) {
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, 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); condition);
} }
} else {
format_log(es, "condition '%s' found: %s", condition,
found);
}
if (format_choose(es, cp + 1, &left, &right, 0) != 0) { free(condition);
format_log(es, "condition '%s' syntax error: %s",
condition, cp + 1);
free(found); 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); if (cp2 == NULL) {
free(found); format_log(es,
"no condition matched in '%s'; using empty "
"string", copy + 1);
value = xstrdup("");
break;
}
cp = cp2 + 1;
}
} else if (mexp != NULL) { } else if (mexp != NULL) {
value = format_replace_expression(mexp, es, copy); value = format_replace_expression(mexp, es, copy);
if (value == NULL) 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); bd = key_bindings_get(table, key & ~KEYC_MASK_FLAGS);
if (cmdlist == NULL) { if (cmdlist == NULL) {
if (bd != NULL) { if (bd != NULL) {
free((void *)bd->note); if (note != NULL) {
if (note != NULL) free((void *)bd->note);
bd->note = xstrdup(note); bd->note = xstrdup(note);
else }
bd->note = NULL; if (repeat)
bd->flags |= KEY_BINDING_REPEAT;
} }
return; return;
} }
@ -433,8 +434,9 @@ key_bindings_init(void)
"bind -N 'Resize the pane right' -r C-Right { resize-pane -R }", "bind -N 'Resize the pane right' -r C-Right { resize-pane -R }",
/* Menu keys */ /* Menu keys */
"bind < { display-menu -xW -yW -T '#[align=centre]#{window_index}:#{window_name}' " DEFAULT_WINDOW_MENU " }", "bind -N 'Display window menu' < { 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 pane menu' > { display-menu -xP -yP -T '#[align=centre]#{pane_index} (#{pane_id})' " DEFAULT_PANE_MENU " }",
/* Mouse button 1 down on pane. */ /* Mouse button 1 down on pane. */
"bind -n MouseDown1Pane { select-pane -t=; send -M }", "bind -n MouseDown1Pane { select-pane -t=; send -M }",

28
tmux.1
View File

@ -3730,7 +3730,15 @@ options.
.Fl N .Fl N
attaches a note to the key (shown with attaches a note to the key (shown with
.Ic list-keys .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 .Pp
To view the default bindings and possible commands, see the To view the default bindings and possible commands, see the
.Ic list-keys .Ic list-keys
@ -5633,10 +5641,12 @@ by a
.Ql } . .Ql } .
.Pp .Pp
Conditionals are available by prefixing with Conditionals are available by prefixing with
.Ql \&? .Ql \&? .
and separating two alternatives with a comma; For each pair of two arguments, if the variable in the first of the pair exists
if the specified variable exists and is not zero, the first alternative and is not zero, the second of the pair is chosen, otherwise it continues.
is chosen, otherwise the second is used. 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 For example
.Ql #{?session_attached,attached,not attached} .Ql #{?session_attached,attached,not attached}
will include the string will include the string
@ -5652,6 +5662,12 @@ if
is enabled, or is enabled, or
.Ql no .Ql no
if not. 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. Conditionals can be nested arbitrarily.
Inside a conditional, Inside a conditional,
.Ql \&, .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_format" Ta "" Ta "1 if format is for a pane"
.It Li "pane_height" Ta "" Ta "Height of pane" .It Li "pane_height" Ta "" Ta "Height of pane"
.It Li "pane_id" Ta "#D" Ta "Unique pane ID" .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_index" Ta "#P" Ta "Index of pane"
.It Li "pane_input_off" Ta "" Ta "1 if input to pane is disabled" .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" .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 \ #define WINDOW_BUFFER_DEFAULT_KEY_FORMAT \
"#{?#{e|<:#{line},10}," \ "#{?#{e|<:#{line},10}," \
"#{line}" \ "#{line}" \
"," \ ",#{e|<:#{line},36}," \
"#{?#{e|<:#{line},36}," \ "M-#{a:#{e|+:97,#{e|-:#{line},10}}}" \
"M-#{a:#{e|+:97,#{e|-:#{line},10}}}" \
"," \
"" \
"}" \
"}" "}"
static const struct menu_item window_buffer_menu_items[] = { 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 \ #define WINDOW_CLIENT_DEFAULT_KEY_FORMAT \
"#{?#{e|<:#{line},10}," \ "#{?#{e|<:#{line},10}," \
"#{line}" \ "#{line}" \
"," \ ",#{e|<:#{line},36}," \
"#{?#{e|<:#{line},36}," \ "M-#{a:#{e|+:97,#{e|-:#{line},10}}}" \
"M-#{a:#{e|+:97,#{e|-:#{line},10}}}" \
"," \
"" \
"}" \
"}" "}"
static const struct menu_item window_client_menu_items[] = { 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_marked,#[reverse],}" \
"#{pane_current_command}#{?pane_active,*,}#{?pane_marked,M,}" \ "#{pane_current_command}#{?pane_active,*,}#{?pane_marked,M,}" \
"#{?#{&&:#{pane_title},#{!=:#{pane_title},#{host_short}}},: \"#{pane_title}\",}" \ "#{?#{&&:#{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," \ "#{session_windows} windows" \
"#{?window_marked_flag,#[reverse],}" \ "#{?session_grouped, " \
"#{window_name}#{window_flags}" \ "(group #{session_group}: " \
"#{?#{&&:#{==:#{window_panes},1},#{&&:#{pane_title},#{!=:#{pane_title},#{host_short}}}},: \"#{pane_title}\",}" \ "#{session_group_list})," \
"," \
"#{session_windows} windows" \
"#{?session_grouped, " \
"(group #{session_group}: " \
"#{session_group_list})," \
"}" \
"#{?session_attached, (attached),}" \
"}" \ "}" \
"#{?session_attached, (attached),}" \
"}" "}"
#define WINDOW_TREE_DEFAULT_KEY_FORMAT \ #define WINDOW_TREE_DEFAULT_KEY_FORMAT \
"#{?#{e|<:#{line},10}," \ "#{?#{e|<:#{line},10}," \
"#{line}" \ "#{line}" \
"," \ ",#{e|<:#{line},36}," \
"#{?#{e|<:#{line},36}," \ "M-#{a:#{e|+:97,#{e|-:#{line},10}}}" \
"M-#{a:#{e|+:97,#{e|-:#{line},10}}}" \
"," \
"" \
"}" \
"}" "}"
static const struct menu_item window_tree_menu_items[] = { static const struct menu_item window_tree_menu_items[] = {