mirror of
https://github.com/tmux/tmux.git
synced 2025-11-01 15:06:06 +00:00
Merge branch 'obsd-master'
This commit is contained in:
43
mode-tree.c
43
mode-tree.c
@@ -82,6 +82,7 @@ struct mode_tree_data {
|
||||
char *filter;
|
||||
int no_matches;
|
||||
enum mode_tree_search_dir search_dir;
|
||||
int search_icase;
|
||||
};
|
||||
|
||||
struct mode_tree_item {
|
||||
@@ -132,6 +133,17 @@ static const struct menu_item mode_tree_menu_items[] = {
|
||||
{ NULL, KEYC_NONE, NULL }
|
||||
};
|
||||
|
||||
static int
|
||||
mode_tree_is_lowercase(const char *ptr)
|
||||
{
|
||||
while (*ptr != '\0') {
|
||||
if (*ptr != tolower((u_char)*ptr))
|
||||
return (0);
|
||||
++ptr;
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
static struct mode_tree_item *
|
||||
mode_tree_find_item(struct mode_tree_list *mtl, uint64_t tag)
|
||||
{
|
||||
@@ -882,6 +894,7 @@ static struct mode_tree_item *
|
||||
mode_tree_search_backward(struct mode_tree_data *mtd)
|
||||
{
|
||||
struct mode_tree_item *mti, *last, *prev;
|
||||
int icase = mtd->search_icase;
|
||||
|
||||
if (mtd->search == NULL)
|
||||
return (NULL);
|
||||
@@ -890,8 +903,10 @@ mode_tree_search_backward(struct mode_tree_data *mtd)
|
||||
for (;;) {
|
||||
if ((prev = TAILQ_PREV(mti, mode_tree_list, entry)) != NULL) {
|
||||
/* Point to the last child in the previous subtree. */
|
||||
while (!TAILQ_EMPTY(&prev->children))
|
||||
prev = TAILQ_LAST(&prev->children, mode_tree_list);
|
||||
while (!TAILQ_EMPTY(&prev->children)) {
|
||||
prev = TAILQ_LAST(&prev->children,
|
||||
mode_tree_list);
|
||||
}
|
||||
mti = prev;
|
||||
} else {
|
||||
/* If prev is NULL, jump to the parent. */
|
||||
@@ -901,29 +916,34 @@ mode_tree_search_backward(struct mode_tree_data *mtd)
|
||||
if (mti == NULL) {
|
||||
/* Point to the last child in the last root subtree. */
|
||||
prev = TAILQ_LAST(&mtd->children, mode_tree_list);
|
||||
while (!TAILQ_EMPTY(&prev->children))
|
||||
prev = TAILQ_LAST(&prev->children, mode_tree_list);
|
||||
while (!TAILQ_EMPTY(&prev->children)) {
|
||||
prev = TAILQ_LAST(&prev->children,
|
||||
mode_tree_list);
|
||||
}
|
||||
mti = prev;
|
||||
}
|
||||
if (mti == last)
|
||||
break;
|
||||
|
||||
if (mtd->searchcb == NULL) {
|
||||
if (strstr(mti->name, mtd->search) != NULL)
|
||||
if (!icase && strstr(mti->name, mtd->search) != NULL)
|
||||
return (mti);
|
||||
if (icase && strcasestr(mti->name, mtd->search) != NULL)
|
||||
return (mti);
|
||||
continue;
|
||||
}
|
||||
if (mtd->searchcb(mtd->modedata, mti->itemdata, mtd->search))
|
||||
if (mtd->searchcb(mtd->modedata, mti->itemdata, mtd->search,
|
||||
icase))
|
||||
return (mti);
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
|
||||
static struct mode_tree_item *
|
||||
mode_tree_search_forward(struct mode_tree_data *mtd)
|
||||
{
|
||||
struct mode_tree_item *mti, *last, *next;
|
||||
int icase = mtd->search_icase;
|
||||
|
||||
if (mtd->search == NULL)
|
||||
return (NULL);
|
||||
@@ -951,11 +971,14 @@ mode_tree_search_forward(struct mode_tree_data *mtd)
|
||||
break;
|
||||
|
||||
if (mtd->searchcb == NULL) {
|
||||
if (strstr(mti->name, mtd->search) != NULL)
|
||||
if (!icase && strstr(mti->name, mtd->search) != NULL)
|
||||
return (mti);
|
||||
if (icase && strcasestr(mti->name, mtd->search) != NULL)
|
||||
return (mti);
|
||||
continue;
|
||||
}
|
||||
if (mtd->searchcb(mtd->modedata, mti->itemdata, mtd->search))
|
||||
if (mtd->searchcb(mtd->modedata, mti->itemdata, mtd->search,
|
||||
icase))
|
||||
return (mti);
|
||||
}
|
||||
return (NULL);
|
||||
@@ -1002,6 +1025,7 @@ mode_tree_search_callback(__unused struct client *c, void *data, const char *s,
|
||||
return (0);
|
||||
}
|
||||
mtd->search = xstrdup(s);
|
||||
mtd->search_icase = mode_tree_is_lowercase(s);
|
||||
mode_tree_search_set(mtd);
|
||||
|
||||
return (0);
|
||||
@@ -1309,6 +1333,7 @@ mode_tree_key(struct mode_tree_data *mtd, struct client *c, key_code *key,
|
||||
case '/':
|
||||
case 's'|KEYC_CTRL:
|
||||
mtd->references++;
|
||||
mtd->search_dir = MODE_TREE_SEARCH_FORWARD;
|
||||
status_prompt_set(c, NULL, "(search) ", "",
|
||||
mode_tree_search_callback, mode_tree_search_free, mtd,
|
||||
PROMPT_NOFORMAT, PROMPT_TYPE_SEARCH);
|
||||
|
||||
2
tmux.h
2
tmux.h
@@ -3338,7 +3338,7 @@ typedef void (*mode_tree_build_cb)(void *, struct mode_tree_sort_criteria *,
|
||||
uint64_t *, const char *);
|
||||
typedef void (*mode_tree_draw_cb)(void *, void *, struct screen_write_ctx *,
|
||||
u_int, u_int);
|
||||
typedef int (*mode_tree_search_cb)(void *, void *, const char *);
|
||||
typedef int (*mode_tree_search_cb)(void *, void *, const char *, int);
|
||||
typedef void (*mode_tree_menu_cb)(void *, struct client *, key_code);
|
||||
typedef u_int (*mode_tree_height_cb)(void *, u_int);
|
||||
typedef key_code (*mode_tree_key_cb)(void *, void *, u_int);
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
@@ -255,7 +256,30 @@ window_buffer_draw(__unused void *modedata, void *itemdata,
|
||||
}
|
||||
|
||||
static int
|
||||
window_buffer_search(__unused void *modedata, void *itemdata, const char *ss)
|
||||
window_buffer_find(const void *data, size_t datalen, const void *find,
|
||||
size_t findlen, int icase)
|
||||
{
|
||||
const u_char *udata = data, *ufind = find;
|
||||
size_t i, j;
|
||||
|
||||
if (findlen == 0 || datalen < findlen)
|
||||
return (0);
|
||||
for (i = 0; i + findlen <= datalen; i++) {
|
||||
for (j = 0; j < findlen; j++) {
|
||||
if (!icase && udata[i + j] != ufind[j])
|
||||
break;
|
||||
if (icase && tolower(udata[i + j]) != tolower(ufind[j]))
|
||||
break;
|
||||
}
|
||||
if (j == findlen)
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
window_buffer_search(__unused void *modedata, void *itemdata, const char *ss,
|
||||
int icase)
|
||||
{
|
||||
struct window_buffer_itemdata *item = itemdata;
|
||||
struct paste_buffer *pb;
|
||||
@@ -264,10 +288,19 @@ window_buffer_search(__unused void *modedata, void *itemdata, const char *ss)
|
||||
|
||||
if ((pb = paste_get_name(item->name)) == NULL)
|
||||
return (0);
|
||||
if (icase) {
|
||||
if (strcasestr(item->name, ss) != NULL)
|
||||
return (1);
|
||||
bufdata = paste_buffer_data(pb, &bufsize);
|
||||
return (window_buffer_find(bufdata, bufsize, ss, strlen(ss),
|
||||
icase));
|
||||
} else {
|
||||
if (strstr(item->name, ss) != NULL)
|
||||
return (1);
|
||||
bufdata = paste_buffer_data(pb, &bufsize);
|
||||
return (memmem(bufdata, bufsize, ss, strlen(ss)) != NULL);
|
||||
return (window_buffer_find(bufdata, bufsize, ss, strlen(ss),
|
||||
icase));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -836,7 +836,8 @@ window_tree_draw(void *modedata, void *itemdata, struct screen_write_ctx *ctx,
|
||||
}
|
||||
|
||||
static int
|
||||
window_tree_search(__unused void *modedata, void *itemdata, const char *ss)
|
||||
window_tree_search(__unused void *modedata, void *itemdata, const char *ss,
|
||||
int icase)
|
||||
{
|
||||
struct window_tree_itemdata *item = itemdata;
|
||||
struct session *s;
|
||||
@@ -853,10 +854,14 @@ window_tree_search(__unused void *modedata, void *itemdata, const char *ss)
|
||||
case WINDOW_TREE_SESSION:
|
||||
if (s == NULL)
|
||||
return (0);
|
||||
if (icase)
|
||||
return (strcasestr(s->name, ss) != NULL);
|
||||
return (strstr(s->name, ss) != NULL);
|
||||
case WINDOW_TREE_WINDOW:
|
||||
if (s == NULL || wl == NULL)
|
||||
return (0);
|
||||
if (icase)
|
||||
return (strcasestr(wl->window->name, ss) != NULL);
|
||||
return (strstr(wl->window->name, ss) != NULL);
|
||||
case WINDOW_TREE_PANE:
|
||||
if (s == NULL || wl == NULL || wp == NULL)
|
||||
@@ -866,6 +871,9 @@ window_tree_search(__unused void *modedata, void *itemdata, const char *ss)
|
||||
free(cmd);
|
||||
return (0);
|
||||
}
|
||||
if (icase)
|
||||
retval = (strcasestr(cmd, ss) != NULL);
|
||||
else
|
||||
retval = (strstr(cmd, ss) != NULL);
|
||||
free(cmd);
|
||||
return (retval);
|
||||
|
||||
Reference in New Issue
Block a user