1
0
mirror of https://github.com/tmux/tmux.git synced 2025-03-24 06:48:48 +00:00

Add ||, && format operators and C: to search pane content.

This commit is contained in:
nicm 2017-05-29 18:06:34 +00:00
parent 1257501499
commit a2ace9da24
5 changed files with 84 additions and 19 deletions

View File

@ -122,7 +122,7 @@ cmd_find_window_match(struct cmd_find_window_list *find_list,
} }
if (match_flags & CMD_FIND_WINDOW_BY_CONTENT && if (match_flags & CMD_FIND_WINDOW_BY_CONTENT &&
(sres = window_pane_search(wp, str, &line)) != NULL) { (sres = window_pane_search_old(wp, str, &line)) != NULL) {
xasprintf(&find_data->list_ctx, xasprintf(&find_data->list_ctx,
"pane %u line %u: \"%s\"", i - 1, line + 1, sres); "pane %u line %u: \"%s\"", i - 1, line + 1, sres);
free(sres); free(sres);

View File

@ -848,19 +848,17 @@ format_true(const char *s)
return (0); return (0);
} }
/* /* Replace a key. */
* Replace a key/value pair in buffer. #{blah} is expanded directly,
* #{?blah,a,b} is replace with a if blah exists and is nonzero else b.
*/
static int static int
format_replace(struct format_tree *ft, const char *key, size_t keylen, format_replace(struct format_tree *ft, const char *key, size_t keylen,
char **buf, size_t *len, size_t *off) char **buf, size_t *len, size_t *off)
{ {
char *copy, *copy0, *endptr, *ptr, *found, *new, *value; struct window_pane *wp = ft->wp;
char *from = NULL, *to = NULL, *left, *right; char *copy, *copy0, *endptr, *ptr, *found, *new;
size_t valuelen, newlen, fromlen, tolen, used; char *value, *from = NULL, *to = NULL, *left, *right;
long limit = 0; size_t valuelen, newlen, fromlen, tolen, used;
int modifiers = 0, compare = 0; long limit = 0;
int modifiers = 0, compare = 0, search = 0;
/* Make a copy of the key. */ /* Make a copy of the key. */
copy0 = copy = xmalloc(keylen + 1); copy0 = copy = xmalloc(keylen + 1);
@ -875,6 +873,24 @@ format_replace(struct format_tree *ft, const char *key, size_t keylen,
compare = -2; compare = -2;
copy += 2; copy += 2;
break; break;
case 'C':
if (copy[1] != ':')
break;
search = 1;
copy += 2;
break;
case '|':
if (copy[1] != '|' || copy[2] != ':')
break;
compare = -3;
copy += 3;
break;
case '&':
if (copy[1] != '&' || copy[2] != ':')
break;
compare = -4;
copy += 3;
break;
case '!': case '!':
if (copy[1] == '=' && copy[2] == ':') { if (copy[1] == '=' && copy[2] == ':') {
compare = -1; compare = -1;
@ -940,13 +956,25 @@ format_replace(struct format_tree *ft, const char *key, size_t keylen,
} }
/* Is this a comparison or a conditional? */ /* Is this a comparison or a conditional? */
if (compare != 0) { if (search) {
/* Search in pane. */
if (wp == NULL)
value = xstrdup("0");
else
xasprintf(&value, "%u", window_pane_search(wp, copy));
} else if (compare != 0) {
/* Comparison: compare comma-separated left and right. */ /* Comparison: compare comma-separated left and right. */
if (format_choose(copy, &left, &right) != 0) if (format_choose(copy, &left, &right) != 0)
goto fail; goto fail;
left = format_expand(ft, left); left = format_expand(ft, left);
right = format_expand(ft, right); right = format_expand(ft, right);
if (compare == 1 && strcmp(left, right) == 0) if (compare == -3 &&
(format_true(left) || format_true(right)))
value = xstrdup("1");
else if (compare == -4 &&
(format_true(left) && format_true(right)))
value = xstrdup("1");
else if (compare == 1 && strcmp(left, right) == 0)
value = xstrdup("1"); value = xstrdup("1");
else if (compare == -1 && strcmp(left, right) != 0) else if (compare == -1 && strcmp(left, right) != 0)
value = xstrdup("1"); value = xstrdup("1");

22
tmux.1
View File

@ -3430,7 +3430,7 @@ is enabled, or
.Ql no .Ql no
if not. if not.
.Pp .Pp
Simple comparisons may be expressed by prefixing two comma-separated Comparisons may be expressed by prefixing two comma-separated
alternatives by alternatives by
.Ql == .Ql ==
or or
@ -3443,14 +3443,26 @@ will be replaced by
if running on if running on
.Ql myhost , .Ql myhost ,
otherwise by otherwise by
.Ql 0. .Ql 0 .
An An
.Ql m .Ql m
specifies a specifies an
.Xr fnmatch 3 .Xr fnmatch 3
comparison - the first argument is the pattern and the second the string to comparison where the first argument is the pattern and the second the string to
compare. For example, compare, for example
.Ql #{m:*foo*,#{host}} . .Ql #{m:*foo*,#{host}} .
.Ql ||
and
.Ql &&
evaluate to true if either or both of two comma-separated alternatives are
true, for example
.Ql #{||,#{pane_in_mode},#{alternate_on}} .
A
.Ql C
performs a search for an
.Xr fnmatch 3
pattern in the pane content and evaluates to zero if not found, or a line
number if found.
.Pp .Pp
A limit may be placed on the length of the resultant string by prefixing it A limit may be placed on the length of the resultant string by prefixing it
by an by an

3
tmux.h
View File

@ -2121,7 +2121,8 @@ void window_pane_key(struct window_pane *, struct client *,
struct session *, key_code, struct mouse_event *); struct session *, key_code, struct mouse_event *);
int window_pane_outside(struct window_pane *); int window_pane_outside(struct window_pane *);
int window_pane_visible(struct window_pane *); int window_pane_visible(struct window_pane *);
char *window_pane_search(struct window_pane *, const char *, u_int window_pane_search(struct window_pane *, const char *);
char *window_pane_search_old(struct window_pane *, const char *,
u_int *); u_int *);
const char *window_printable_flags(struct winlink *); const char *window_printable_flags(struct winlink *);
struct window_pane *window_pane_find_up(struct window_pane *); struct window_pane *window_pane_find_up(struct window_pane *);

View File

@ -1267,8 +1267,32 @@ window_pane_visible(struct window_pane *wp)
return (!window_pane_outside(wp)); return (!window_pane_outside(wp));
} }
u_int
window_pane_search(struct window_pane *wp, const char *searchstr)
{
struct screen *s = &wp->base;
char *newsearchstr, *line;
u_int i;
xasprintf(&newsearchstr, "*%s*", searchstr);
for (i = 0; i < screen_size_y(s); i++) {
line = grid_view_string_cells(s->grid, 0, i, screen_size_x(s));
if (fnmatch(newsearchstr, line, 0) == 0) {
free(line);
break;
}
free(line);
}
free(newsearchstr);
if (i == screen_size_y(s))
return (0);
return (i + 1);
}
char * char *
window_pane_search(struct window_pane *wp, const char *searchstr, window_pane_search_old(struct window_pane *wp, const char *searchstr,
u_int *lineno) u_int *lineno)
{ {
struct screen *s = &wp->base; struct screen *s = &wp->base;