aboutsummaryrefslogtreecommitdiff
path: root/format.c
diff options
context:
space:
mode:
Diffstat (limited to 'format.c')
-rw-r--r--format.c145
1 files changed, 103 insertions, 42 deletions
diff --git a/format.c b/format.c
index 7da6c802..ee507340 100644
--- a/format.c
+++ b/format.c
@@ -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));