diff --git a/format.c b/format.c index 330f95ce..9847b0f7 100644 --- a/format.c +++ b/format.c @@ -4514,7 +4514,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; @@ -4777,53 +4778,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) diff --git a/window-buffer.c b/window-buffer.c index 7ad33345..ef4c6a42 100644 --- a/window-buffer.c +++ b/window-buffer.c @@ -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[] = { diff --git a/window-client.c b/window-client.c index c1b962f1..a7735250 100644 --- a/window-client.c +++ b/window-client.c @@ -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[] = { diff --git a/window-tree.c b/window-tree.c index a6ec43a0..2f17a361 100644 --- a/window-tree.c +++ b/window-tree.c @@ -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[] = {