mirror of
https://github.com/tmux/tmux.git
synced 2025-01-07 16:28:48 +00:00
Add non-regex search variants to avoid the performance cost for people
with large histories or long lines.
This commit is contained in:
parent
2ca95840d1
commit
2624edde46
24
tmux.1
24
tmux.1
@ -1503,9 +1503,11 @@ The following commands are supported in copy mode:
|
|||||||
.It Li "scroll-up" Ta "C-y" Ta "C-Up"
|
.It Li "scroll-up" Ta "C-y" Ta "C-Up"
|
||||||
.It Li "search-again" Ta "n" Ta "n"
|
.It Li "search-again" Ta "n" Ta "n"
|
||||||
.It Li "search-backward <for>" Ta "?" Ta ""
|
.It Li "search-backward <for>" Ta "?" Ta ""
|
||||||
.It Li "search-forward <for>" Ta "/" Ta ""
|
|
||||||
.It Li "search-backward-incremental <for>" Ta "" Ta "C-r"
|
.It Li "search-backward-incremental <for>" Ta "" Ta "C-r"
|
||||||
|
.It Li "search-backward-text <for>" Ta "" Ta ""
|
||||||
|
.It Li "search-forward <for>" Ta "/" Ta ""
|
||||||
.It Li "search-forward-incremental <for>" Ta "" Ta "C-s"
|
.It Li "search-forward-incremental <for>" Ta "" Ta "C-s"
|
||||||
|
.It Li "search-forward-text <for>" Ta "" Ta ""
|
||||||
.It Li "search-reverse" Ta "N" Ta "N"
|
.It Li "search-reverse" Ta "N" Ta "N"
|
||||||
.It Li "select-line" Ta "V" Ta ""
|
.It Li "select-line" Ta "V" Ta ""
|
||||||
.It Li "select-word" Ta "" Ta ""
|
.It Li "select-word" Ta "" Ta ""
|
||||||
@ -1514,6 +1516,26 @@ The following commands are supported in copy mode:
|
|||||||
.It Li "top-line" Ta "H" Ta "M-R"
|
.It Li "top-line" Ta "H" Ta "M-R"
|
||||||
.El
|
.El
|
||||||
.Pp
|
.Pp
|
||||||
|
The search commands come in several varieties:
|
||||||
|
.Ql search-forward
|
||||||
|
and
|
||||||
|
.Ql search-backward
|
||||||
|
search for a regular expression;
|
||||||
|
the
|
||||||
|
.Ql -text
|
||||||
|
variants search for a plain text string rather than a regular expression;
|
||||||
|
.Ql -incremental
|
||||||
|
perform an incremental search and expect to be used with the
|
||||||
|
.Fl i
|
||||||
|
flag to the
|
||||||
|
.Ic command-prompt
|
||||||
|
command.
|
||||||
|
.Ql search-again
|
||||||
|
repeats the last search and
|
||||||
|
.Ql search-reverse
|
||||||
|
does the same but reverses the direction (forward becomes backward and backward
|
||||||
|
becomes forward).
|
||||||
|
.Pp
|
||||||
Copy commands may take an optional buffer prefix argument which is used
|
Copy commands may take an optional buffer prefix argument which is used
|
||||||
to generate the buffer name (the default is
|
to generate the buffer name (the default is
|
||||||
.Ql buffer
|
.Ql buffer
|
||||||
|
2
tmux.h
2
tmux.h
@ -927,7 +927,9 @@ struct window_pane {
|
|||||||
TAILQ_HEAD (, window_mode_entry) modes;
|
TAILQ_HEAD (, window_mode_entry) modes;
|
||||||
struct event modetimer;
|
struct event modetimer;
|
||||||
time_t modelast;
|
time_t modelast;
|
||||||
|
|
||||||
char *searchstr;
|
char *searchstr;
|
||||||
|
int searchregex;
|
||||||
|
|
||||||
TAILQ_ENTRY(window_pane) entry;
|
TAILQ_ENTRY(window_pane) entry;
|
||||||
RB_ENTRY(window_pane) tree_entry;
|
RB_ENTRY(window_pane) tree_entry;
|
||||||
|
135
window-copy.c
135
window-copy.c
@ -256,6 +256,7 @@ struct window_copy_mode_data {
|
|||||||
u_int lastsx; /* size of last line w/ content */
|
u_int lastsx; /* size of last line w/ content */
|
||||||
|
|
||||||
int searchtype;
|
int searchtype;
|
||||||
|
int searchregex;
|
||||||
char *searchstr;
|
char *searchstr;
|
||||||
bitstr_t *searchmark;
|
bitstr_t *searchmark;
|
||||||
u_int searchcount;
|
u_int searchcount;
|
||||||
@ -310,9 +311,11 @@ window_copy_common_init(struct window_mode_entry *wme)
|
|||||||
|
|
||||||
if (wp->searchstr != NULL) {
|
if (wp->searchstr != NULL) {
|
||||||
data->searchtype = WINDOW_COPY_SEARCHUP;
|
data->searchtype = WINDOW_COPY_SEARCHUP;
|
||||||
|
data->searchregex = wp->searchregex;
|
||||||
data->searchstr = xstrdup(wp->searchstr);
|
data->searchstr = xstrdup(wp->searchstr);
|
||||||
} else {
|
} else {
|
||||||
data->searchtype = WINDOW_COPY_OFF;
|
data->searchtype = WINDOW_COPY_OFF;
|
||||||
|
data->searchregex = 0;
|
||||||
data->searchstr = NULL;
|
data->searchstr = NULL;
|
||||||
}
|
}
|
||||||
data->searchmark = NULL;
|
data->searchmark = NULL;
|
||||||
@ -700,6 +703,35 @@ window_copy_key_table(struct window_mode_entry *wme)
|
|||||||
return ("copy-mode");
|
return ("copy-mode");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
window_copy_expand_search_string(struct window_copy_cmd_state *cs)
|
||||||
|
{
|
||||||
|
struct window_mode_entry *wme = cs->wme;
|
||||||
|
struct window_copy_mode_data *data = wme->data;
|
||||||
|
const char *argument;
|
||||||
|
char *expanded;
|
||||||
|
|
||||||
|
if (cs->args->argc == 2) {
|
||||||
|
argument = cs->args->argv[1];
|
||||||
|
if (*argument != '\0') {
|
||||||
|
if (args_has(cs->args, 'F')) {
|
||||||
|
expanded = format_single(NULL, argument, NULL,
|
||||||
|
NULL, NULL, wme->wp);
|
||||||
|
if (*expanded == '\0') {
|
||||||
|
free(expanded);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
free(data->searchstr);
|
||||||
|
data->searchstr = expanded;
|
||||||
|
} else {
|
||||||
|
free(data->searchstr);
|
||||||
|
data->searchstr = xstrdup(argument);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
static enum window_copy_cmd_action
|
static enum window_copy_cmd_action
|
||||||
window_copy_cmd_append_selection(struct window_copy_cmd_state *cs)
|
window_copy_cmd_append_selection(struct window_copy_cmd_state *cs)
|
||||||
{
|
{
|
||||||
@ -1525,10 +1557,10 @@ window_copy_cmd_search_again(struct window_copy_cmd_state *cs)
|
|||||||
|
|
||||||
if (data->searchtype == WINDOW_COPY_SEARCHUP) {
|
if (data->searchtype == WINDOW_COPY_SEARCHUP) {
|
||||||
for (; np != 0; np--)
|
for (; np != 0; np--)
|
||||||
window_copy_search_up(wme, 1);
|
window_copy_search_up(wme, data->searchregex);
|
||||||
} else if (data->searchtype == WINDOW_COPY_SEARCHDOWN) {
|
} else if (data->searchtype == WINDOW_COPY_SEARCHDOWN) {
|
||||||
for (; np != 0; np--)
|
for (; np != 0; np--)
|
||||||
window_copy_search_down(wme, 1);
|
window_copy_search_down(wme, data->searchregex);
|
||||||
}
|
}
|
||||||
return (WINDOW_COPY_CMD_NOTHING);
|
return (WINDOW_COPY_CMD_NOTHING);
|
||||||
}
|
}
|
||||||
@ -1542,10 +1574,10 @@ window_copy_cmd_search_reverse(struct window_copy_cmd_state *cs)
|
|||||||
|
|
||||||
if (data->searchtype == WINDOW_COPY_SEARCHUP) {
|
if (data->searchtype == WINDOW_COPY_SEARCHUP) {
|
||||||
for (; np != 0; np--)
|
for (; np != 0; np--)
|
||||||
window_copy_search_down(wme, 1);
|
window_copy_search_down(wme, data->searchregex);
|
||||||
} else if (data->searchtype == WINDOW_COPY_SEARCHDOWN) {
|
} else if (data->searchtype == WINDOW_COPY_SEARCHDOWN) {
|
||||||
for (; np != 0; np--)
|
for (; np != 0; np--)
|
||||||
window_copy_search_up(wme, 1);
|
window_copy_search_up(wme, data->searchregex);
|
||||||
}
|
}
|
||||||
return (WINDOW_COPY_CMD_NOTHING);
|
return (WINDOW_COPY_CMD_NOTHING);
|
||||||
}
|
}
|
||||||
@ -1765,70 +1797,76 @@ window_copy_cmd_search_backward(struct window_copy_cmd_state *cs)
|
|||||||
struct window_mode_entry *wme = cs->wme;
|
struct window_mode_entry *wme = cs->wme;
|
||||||
struct window_copy_mode_data *data = wme->data;
|
struct window_copy_mode_data *data = wme->data;
|
||||||
u_int np = wme->prefix;
|
u_int np = wme->prefix;
|
||||||
const char *argument;
|
|
||||||
char *expanded;
|
|
||||||
|
|
||||||
if (cs->args->argc == 2) {
|
if (!window_copy_expand_search_string(cs))
|
||||||
argument = cs->args->argv[1];
|
return (WINDOW_COPY_CMD_NOTHING);
|
||||||
if (*argument != '\0') {
|
|
||||||
if (args_has(cs->args, 'F')) {
|
|
||||||
expanded = format_single(NULL, argument, NULL,
|
|
||||||
NULL, NULL, wme->wp);
|
|
||||||
if (*expanded == '\0') {
|
|
||||||
free(expanded);
|
|
||||||
return (WINDOW_COPY_CMD_NOTHING);
|
|
||||||
}
|
|
||||||
free(data->searchstr);
|
|
||||||
data->searchstr = expanded;
|
|
||||||
} else {
|
|
||||||
free(data->searchstr);
|
|
||||||
data->searchstr = xstrdup(argument);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (data->searchstr != NULL) {
|
if (data->searchstr != NULL) {
|
||||||
data->searchtype = WINDOW_COPY_SEARCHUP;
|
data->searchtype = WINDOW_COPY_SEARCHUP;
|
||||||
|
data->searchregex = 1;
|
||||||
for (; np != 0; np--)
|
for (; np != 0; np--)
|
||||||
window_copy_search_up(wme, 1);
|
window_copy_search_up(wme, 1);
|
||||||
}
|
}
|
||||||
return (WINDOW_COPY_CMD_NOTHING);
|
return (WINDOW_COPY_CMD_NOTHING);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static enum window_copy_cmd_action
|
||||||
|
window_copy_cmd_search_backward_text(struct window_copy_cmd_state *cs)
|
||||||
|
{
|
||||||
|
struct window_mode_entry *wme = cs->wme;
|
||||||
|
struct window_copy_mode_data *data = wme->data;
|
||||||
|
u_int np = wme->prefix;
|
||||||
|
|
||||||
|
if (!window_copy_expand_search_string(cs))
|
||||||
|
return (WINDOW_COPY_CMD_NOTHING);
|
||||||
|
|
||||||
|
if (data->searchstr != NULL) {
|
||||||
|
data->searchtype = WINDOW_COPY_SEARCHUP;
|
||||||
|
data->searchregex = 0;
|
||||||
|
for (; np != 0; np--)
|
||||||
|
window_copy_search_up(wme, 0);
|
||||||
|
}
|
||||||
|
return (WINDOW_COPY_CMD_NOTHING);
|
||||||
|
}
|
||||||
|
|
||||||
static enum window_copy_cmd_action
|
static enum window_copy_cmd_action
|
||||||
window_copy_cmd_search_forward(struct window_copy_cmd_state *cs)
|
window_copy_cmd_search_forward(struct window_copy_cmd_state *cs)
|
||||||
{
|
{
|
||||||
struct window_mode_entry *wme = cs->wme;
|
struct window_mode_entry *wme = cs->wme;
|
||||||
struct window_copy_mode_data *data = wme->data;
|
struct window_copy_mode_data *data = wme->data;
|
||||||
u_int np = wme->prefix;
|
u_int np = wme->prefix;
|
||||||
const char *argument;
|
|
||||||
char *expanded;
|
|
||||||
|
|
||||||
if (cs->args->argc == 2) {
|
if (!window_copy_expand_search_string(cs))
|
||||||
argument = cs->args->argv[1];
|
return (WINDOW_COPY_CMD_NOTHING);
|
||||||
if (*argument != '\0') {
|
|
||||||
if (args_has(cs->args, 'F')) {
|
|
||||||
expanded = format_single(NULL, argument, NULL,
|
|
||||||
NULL, NULL, wme->wp);
|
|
||||||
if (*expanded == '\0') {
|
|
||||||
free(expanded);
|
|
||||||
return (WINDOW_COPY_CMD_NOTHING);
|
|
||||||
}
|
|
||||||
free(data->searchstr);
|
|
||||||
data->searchstr = expanded;
|
|
||||||
} else {
|
|
||||||
free(data->searchstr);
|
|
||||||
data->searchstr = xstrdup(argument);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (data->searchstr != NULL) {
|
if (data->searchstr != NULL) {
|
||||||
data->searchtype = WINDOW_COPY_SEARCHDOWN;
|
data->searchtype = WINDOW_COPY_SEARCHDOWN;
|
||||||
|
data->searchregex = 1;
|
||||||
for (; np != 0; np--)
|
for (; np != 0; np--)
|
||||||
window_copy_search_down(wme, 1);
|
window_copy_search_down(wme, 1);
|
||||||
}
|
}
|
||||||
return (WINDOW_COPY_CMD_NOTHING);
|
return (WINDOW_COPY_CMD_NOTHING);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static enum window_copy_cmd_action
|
||||||
|
window_copy_cmd_search_forward_text(struct window_copy_cmd_state *cs)
|
||||||
|
{
|
||||||
|
struct window_mode_entry *wme = cs->wme;
|
||||||
|
struct window_copy_mode_data *data = wme->data;
|
||||||
|
u_int np = wme->prefix;
|
||||||
|
|
||||||
|
if (!window_copy_expand_search_string(cs))
|
||||||
|
return (WINDOW_COPY_CMD_NOTHING);
|
||||||
|
|
||||||
|
if (data->searchstr != NULL) {
|
||||||
|
data->searchtype = WINDOW_COPY_SEARCHDOWN;
|
||||||
|
data->searchregex = 0;
|
||||||
|
for (; np != 0; np--)
|
||||||
|
window_copy_search_down(wme, 0);
|
||||||
|
}
|
||||||
|
return (WINDOW_COPY_CMD_NOTHING);
|
||||||
|
}
|
||||||
|
|
||||||
static enum window_copy_cmd_action
|
static enum window_copy_cmd_action
|
||||||
window_copy_cmd_search_backward_incremental(struct window_copy_cmd_state *cs)
|
window_copy_cmd_search_backward_incremental(struct window_copy_cmd_state *cs)
|
||||||
{
|
{
|
||||||
@ -1858,6 +1896,7 @@ window_copy_cmd_search_backward_incremental(struct window_copy_cmd_state *cs)
|
|||||||
case '=':
|
case '=':
|
||||||
case '-':
|
case '-':
|
||||||
data->searchtype = WINDOW_COPY_SEARCHUP;
|
data->searchtype = WINDOW_COPY_SEARCHUP;
|
||||||
|
data->searchregex = 0;
|
||||||
free(data->searchstr);
|
free(data->searchstr);
|
||||||
data->searchstr = xstrdup(argument);
|
data->searchstr = xstrdup(argument);
|
||||||
if (!window_copy_search_up(wme, 0)) {
|
if (!window_copy_search_up(wme, 0)) {
|
||||||
@ -1867,6 +1906,7 @@ window_copy_cmd_search_backward_incremental(struct window_copy_cmd_state *cs)
|
|||||||
break;
|
break;
|
||||||
case '+':
|
case '+':
|
||||||
data->searchtype = WINDOW_COPY_SEARCHDOWN;
|
data->searchtype = WINDOW_COPY_SEARCHDOWN;
|
||||||
|
data->searchregex = 0;
|
||||||
free(data->searchstr);
|
free(data->searchstr);
|
||||||
data->searchstr = xstrdup(argument);
|
data->searchstr = xstrdup(argument);
|
||||||
if (!window_copy_search_down(wme, 0)) {
|
if (!window_copy_search_down(wme, 0)) {
|
||||||
@ -1907,6 +1947,7 @@ window_copy_cmd_search_forward_incremental(struct window_copy_cmd_state *cs)
|
|||||||
case '=':
|
case '=':
|
||||||
case '+':
|
case '+':
|
||||||
data->searchtype = WINDOW_COPY_SEARCHDOWN;
|
data->searchtype = WINDOW_COPY_SEARCHDOWN;
|
||||||
|
data->searchregex = 0;
|
||||||
free(data->searchstr);
|
free(data->searchstr);
|
||||||
data->searchstr = xstrdup(argument);
|
data->searchstr = xstrdup(argument);
|
||||||
if (!window_copy_search_down(wme, 0)) {
|
if (!window_copy_search_down(wme, 0)) {
|
||||||
@ -1916,6 +1957,7 @@ window_copy_cmd_search_forward_incremental(struct window_copy_cmd_state *cs)
|
|||||||
break;
|
break;
|
||||||
case '-':
|
case '-':
|
||||||
data->searchtype = WINDOW_COPY_SEARCHUP;
|
data->searchtype = WINDOW_COPY_SEARCHUP;
|
||||||
|
data->searchregex = 0;
|
||||||
free(data->searchstr);
|
free(data->searchstr);
|
||||||
data->searchstr = xstrdup(argument);
|
data->searchstr = xstrdup(argument);
|
||||||
if (!window_copy_search_up(wme, 0)) {
|
if (!window_copy_search_up(wme, 0)) {
|
||||||
@ -2041,10 +2083,14 @@ static const struct {
|
|||||||
window_copy_cmd_search_again },
|
window_copy_cmd_search_again },
|
||||||
{ "search-backward", 0, 1, 0,
|
{ "search-backward", 0, 1, 0,
|
||||||
window_copy_cmd_search_backward },
|
window_copy_cmd_search_backward },
|
||||||
|
{ "search-backward-text", 0, 1, 0,
|
||||||
|
window_copy_cmd_search_backward_text },
|
||||||
{ "search-backward-incremental", 1, 1, 0,
|
{ "search-backward-incremental", 1, 1, 0,
|
||||||
window_copy_cmd_search_backward_incremental },
|
window_copy_cmd_search_backward_incremental },
|
||||||
{ "search-forward", 0, 1, 0,
|
{ "search-forward", 0, 1, 0,
|
||||||
window_copy_cmd_search_forward },
|
window_copy_cmd_search_forward },
|
||||||
|
{ "search-forward-text", 0, 1, 0,
|
||||||
|
window_copy_cmd_search_forward_text },
|
||||||
{ "search-forward-incremental", 1, 1, 0,
|
{ "search-forward-incremental", 1, 1, 0,
|
||||||
window_copy_cmd_search_forward_incremental },
|
window_copy_cmd_search_forward_incremental },
|
||||||
{ "search-reverse", 0, 0, 0,
|
{ "search-reverse", 0, 0, 0,
|
||||||
@ -2653,6 +2699,7 @@ window_copy_search(struct window_mode_entry *wme, int direction, int regex)
|
|||||||
|
|
||||||
free(wp->searchstr);
|
free(wp->searchstr);
|
||||||
wp->searchstr = xstrdup(data->searchstr);
|
wp->searchstr = xstrdup(data->searchstr);
|
||||||
|
wp->searchregex = regex;
|
||||||
|
|
||||||
fx = data->cx;
|
fx = data->cx;
|
||||||
fy = screen_hsize(data->backing) - data->oy + data->cy;
|
fy = screen_hsize(data->backing) - data->oy + data->cy;
|
||||||
|
Loading…
Reference in New Issue
Block a user