diff options
Diffstat (limited to 'format.c')
-rw-r--r-- | format.c | 145 |
1 files changed, 103 insertions, 42 deletions
@@ -574,7 +574,7 @@ format_cb_current_command(struct format_tree *ft, struct format_entry *fe) struct window_pane *wp = ft->wp; char *cmd; - if (wp == NULL) + if (wp == NULL || wp->shell == NULL) return; cmd = osdep_get_name(wp->fd, wp->tty); @@ -718,30 +718,19 @@ format_cb_cursor_character(struct format_tree *ft, struct format_entry *fe) xasprintf(&fe->value, "%.*s", (int)gc.data.size, gc.data.data); } -/* Callback for mouse_word. */ -static void -format_cb_mouse_word(struct format_tree *ft, struct format_entry *fe) +/* Return word at given coordinates. Caller frees. */ +char * +format_grid_word(struct grid *gd, u_int x, u_int y) { - struct window_pane *wp; - u_int x, y, end; - struct grid *gd; struct grid_line *gl; struct grid_cell gc; const char *ws; struct utf8_data *ud = NULL; + u_int end; size_t size = 0; int found = 0; + char *s = NULL; - if (!ft->m.valid) - return; - wp = cmd_mouse_pane(&ft->m, NULL, NULL); - if (wp == NULL) - return; - if (!TAILQ_EMPTY (&wp->modes)) - return; - if (cmd_mouse_at(wp, &ft->m, &x, &y, 0) != 0) - return; - gd = wp->base.grid; ws = options_get_string(global_s_options, "word-separators"); y = gd->hsize + y; @@ -794,21 +783,19 @@ format_cb_mouse_word(struct format_tree *ft, struct format_entry *fe) } if (size != 0) { ud[size].size = 0; - fe->value = utf8_tocstr(ud); + s = utf8_tocstr(ud); free(ud); } + return (s); } -/* Callback for mouse_line. */ +/* Callback for mouse_word. */ static void -format_cb_mouse_line(struct format_tree *ft, struct format_entry *fe) +format_cb_mouse_word(struct format_tree *ft, struct format_entry *fe) { struct window_pane *wp; u_int x, y; - struct grid *gd; - struct grid_cell gc; - struct utf8_data *ud = NULL; - size_t size = 0; + char *s; if (!ft->m.valid) return; @@ -819,7 +806,21 @@ format_cb_mouse_line(struct format_tree *ft, struct format_entry *fe) return; if (cmd_mouse_at(wp, &ft->m, &x, &y, 0) != 0) return; - gd = wp->base.grid; + + s = format_grid_word(wp->base.grid, x, y); + if (s != NULL) + fe->value = s; +} + +/* Return line at given coordinates. Caller frees. */ +char * +format_grid_line(struct grid *gd, u_int y) +{ + struct grid_cell gc; + struct utf8_data *ud = NULL; + u_int x; + size_t size = 0; + char *s = NULL; y = gd->hsize + y; for (x = 0; x < grid_line_length(gd, y); x++) { @@ -832,9 +833,33 @@ format_cb_mouse_line(struct format_tree *ft, struct format_entry *fe) } if (size != 0) { ud[size].size = 0; - fe->value = utf8_tocstr(ud); + s = utf8_tocstr(ud); free(ud); } + return (s); +} + +/* Callback for mouse_line. */ +static void +format_cb_mouse_line(struct format_tree *ft, struct format_entry *fe) +{ + struct window_pane *wp; + u_int x, y; + char *s; + + if (!ft->m.valid) + return; + wp = cmd_mouse_pane(&ft->m, NULL, NULL); + if (wp == NULL) + return; + if (!TAILQ_EMPTY (&wp->modes)) + return; + if (cmd_mouse_at(wp, &ft->m, &x, &y, 0) != 0) + return; + + s = format_grid_line(wp->base.grid, y); + if (s != NULL) + fe->value = s; } /* Merge a format tree. */ @@ -966,7 +991,6 @@ format_each(struct format_tree *ft, void (*cb)(const char *, const char *, } } - /* Add a key-value pair. */ void format_add(struct format_tree *ft, const char *key, const char *fmt, ...) @@ -1290,7 +1314,7 @@ format_build_modifiers(struct format_tree *ft, const char **s, u_int *count) } /* Now try single character with arguments. */ - if (strchr("mCs=", cp[0]) == NULL) + if (strchr("mCs=p", cp[0]) == NULL) break; c = cp[0]; @@ -1551,15 +1575,15 @@ static int format_replace(struct format_tree *ft, const char *key, size_t keylen, char **buf, size_t *len, size_t *off) { - struct window_pane *wp = ft->wp; - const char *errptr, *copy, *cp, *marker = NULL; - char *copy0, *condition, *found, *new; - char *value, *left, *right; - size_t valuelen; - int modifiers = 0, limit = 0, j; - struct format_modifier *list, *fm, *cmp = NULL, *search = NULL; - struct format_modifier *sub = NULL; - u_int i, count; + struct window_pane *wp = ft->wp; + const char *errptr, *copy, *cp, *marker = NULL; + char *copy0, *condition, *found, *new; + char *value, *left, *right; + size_t valuelen; + int modifiers = 0, limit = 0, width = 0, j; + struct format_modifier *list, *fm, *cmp = NULL, *search = NULL; + struct format_modifier **sub = NULL; + u_int i, count, nsub = 0; /* Make a copy of the key. */ copy = copy0 = xstrndup(key, keylen); @@ -1588,7 +1612,9 @@ format_replace(struct format_tree *ft, const char *key, size_t keylen, case 's': if (fm->argc < 2) break; - sub = fm; + sub = xreallocarray (sub, nsub + 1, + sizeof *sub); + sub[nsub++] = fm; break; case '=': if (fm->argc < 1) @@ -1600,6 +1626,14 @@ format_replace(struct format_tree *ft, const char *key, size_t keylen, if (fm->argc >= 2 && fm->argv[1] != NULL) marker = fm->argv[1]; break; + case 'p': + if (fm->argc < 1) + break; + width = strtonum(fm->argv[0], INT_MIN, INT_MAX, + &errptr); + if (errptr != NULL) + width = 0; + break; case 'l': modifiers |= FORMAT_LITERAL; break; @@ -1800,10 +1834,10 @@ done: } /* Perform substitution if any. */ - if (sub != NULL) { - left = format_expand(ft, sub->argv[0]); - right = format_expand(ft, sub->argv[1]); - new = format_sub(sub, value, left, right); + for (i = 0; i < nsub; i++) { + left = format_expand(ft, sub[i]->argv[0]); + right = format_expand(ft, sub[i]->argv[1]); + new = format_sub(sub[i], value, left, right); format_log(ft, "substitute '%s' to '%s': %s", left, right, new); free(value); value = new; @@ -1834,6 +1868,19 @@ done: format_log(ft, "applied length limit %d: %s", limit, value); } + /* Pad the value if needed. */ + if (width > 0) { + new = utf8_padcstr(value, width); + free(value); + value = new; + format_log(ft, "applied padding width %d: %s", width, value); + } else if (width < 0) { + new = utf8_rpadcstr(value, -width); + free(value); + value = new; + format_log(ft, "applied padding width %d: %s", width, value); + } + /* Expand the buffer and copy in the value. */ valuelen = strlen(value); while (*len - *off < valuelen + 1) { @@ -1846,12 +1893,15 @@ done: format_log(ft, "replaced '%s' with '%s'", copy0, value); free(value); + free(sub); format_free_modifiers(list, count); free(copy0); return (0); fail: format_log(ft, "failed %s", copy0); + + free(sub); format_free_modifiers(list, count); free(copy0); return (-1); @@ -2123,6 +2173,8 @@ format_defaults_client(struct format_tree *ft, struct client *c) format_add(ft, "client_pid", "%ld", (long) c->pid); format_add(ft, "client_height", "%u", tty->sy); format_add(ft, "client_width", "%u", tty->sx); + format_add(ft, "client_cell_width", "%u", tty->xpixel); + format_add(ft, "client_cell_height", "%u", tty->ypixel); format_add(ft, "client_tty", "%s", c->ttyname); format_add(ft, "client_control_mode", "%d", !!(c->flags & CLIENT_CONTROL)); @@ -2174,6 +2226,8 @@ format_defaults_window(struct format_tree *ft, struct window *w) format_add(ft, "window_name", "%s", w->name); format_add(ft, "window_width", "%u", w->sx); format_add(ft, "window_height", "%u", w->sy); + format_add(ft, "window_cell_width", "%u", w->xpixel); + format_add(ft, "window_cell_height", "%u", w->ypixel); format_add_cb(ft, "window_layout", format_cb_window_layout); format_add_cb(ft, "window_visible_layout", format_cb_window_visible_layout); @@ -2217,6 +2271,11 @@ format_defaults_winlink(struct format_tree *ft, struct winlink *wl) format_add(ft, "window_end_flag", "%d", !!(wl == RB_MAX(winlinks, &s->windows))); + if (server_check_marked() && marked_pane.wl == wl) + format_add(ft, "window_marked_flag", "1"); + else + format_add(ft, "window_marked_flag", "0"); + format_add(ft, "window_bell_flag", "%d", !!(wl->flags & WINLINK_BELL)); format_add(ft, "window_activity_flag", "%d", @@ -2253,6 +2312,8 @@ format_defaults_pane(struct format_tree *ft, struct window_pane *wp) format_add(ft, "pane_width", "%u", wp->sx); format_add(ft, "pane_height", "%u", wp->sy); format_add(ft, "pane_title", "%s", wp->base.title); + if (wp->base.path != NULL) + format_add(ft, "pane_path", "%s", wp->base.path); format_add(ft, "pane_id", "%%%u", wp->id); format_add(ft, "pane_active", "%d", wp == w->active); format_add(ft, "pane_input_off", "%d", !!(wp->flags & PANE_INPUTOFF)); |