mirror of
https://github.com/tmux/tmux.git
synced 2024-12-13 01:48:47 +00:00
Merge branch 'obsd-master'
This commit is contained in:
commit
2aa517c805
@ -335,7 +335,9 @@ key_bindings_init(void)
|
||||
"bind -Tcopy-mode M-> send -X history-bottom",
|
||||
"bind -Tcopy-mode M-R send -X top-line",
|
||||
"bind -Tcopy-mode M-b send -X previous-word",
|
||||
"bind -Tcopy-mode C-M-b send -X previous-matching-bracket",
|
||||
"bind -Tcopy-mode M-f send -X next-word-end",
|
||||
"bind -Tcopy-mode C-M-f send -X next-matching-bracket",
|
||||
"bind -Tcopy-mode M-m send -X back-to-indentation",
|
||||
"bind -Tcopy-mode M-r send -X middle-line",
|
||||
"bind -Tcopy-mode M-v send -X page-up",
|
||||
@ -408,6 +410,7 @@ key_bindings_init(void)
|
||||
"bind -Tcopy-mode-vi w send -X next-word",
|
||||
"bind -Tcopy-mode-vi { send -X previous-paragraph",
|
||||
"bind -Tcopy-mode-vi } send -X next-paragraph",
|
||||
"bind -Tcopy-mode-vi % send -X next-matching-bracket",
|
||||
"bind -Tcopy-mode-vi MouseDown1Pane select-pane",
|
||||
"bind -Tcopy-mode-vi MouseDrag1Pane select-pane\\; send -X begin-selection",
|
||||
"bind -Tcopy-mode-vi MouseDragEnd1Pane send -X copy-selection-and-cancel",
|
||||
|
223
window-copy.c
223
window-copy.c
@ -223,7 +223,7 @@ struct window_copy_mode_data {
|
||||
|
||||
int searchtype;
|
||||
char *searchstr;
|
||||
bitstr_t *searchmark;
|
||||
bitstr_t *searchmark;
|
||||
u_int searchcount;
|
||||
int searchthis;
|
||||
int searchx;
|
||||
@ -994,6 +994,218 @@ window_copy_cmd_middle_line(struct window_copy_cmd_state *cs)
|
||||
return (WINDOW_COPY_CMD_REDRAW);
|
||||
}
|
||||
|
||||
static enum window_copy_cmd_action
|
||||
window_copy_cmd_previous_matching_bracket(struct window_copy_cmd_state *cs)
|
||||
{
|
||||
struct window_mode_entry *wme = cs->wme;
|
||||
u_int np = wme->prefix;
|
||||
struct window_copy_mode_data *data = wme->data;
|
||||
struct screen *s = data->backing;
|
||||
char open[] = "{[(", close[] = "}])";
|
||||
char tried, found, start, *cp;
|
||||
u_int px, py, xx, yy, n;
|
||||
struct grid_cell gc;
|
||||
int failed;
|
||||
|
||||
for (; np != 0; np--) {
|
||||
/* Get cursor position and line length. */
|
||||
px = data->cx;
|
||||
py = screen_hsize(s) + data->cy - data->oy;
|
||||
xx = window_copy_find_length(wme, py);
|
||||
yy = screen_hsize(s) + screen_size_y(s) - 1;
|
||||
if (xx == 0)
|
||||
break;
|
||||
|
||||
/*
|
||||
* Get the current character. If not on a bracket, try the
|
||||
* previous. If still not, then behave like previous-word.
|
||||
*/
|
||||
tried = 0;
|
||||
retry:
|
||||
grid_get_cell(s->grid, px, py, &gc);
|
||||
if (gc.data.size != 1 || (gc.flags & GRID_FLAG_PADDING))
|
||||
cp = NULL;
|
||||
else {
|
||||
found = *gc.data.data;
|
||||
cp = strchr(close, found);
|
||||
}
|
||||
if (cp == NULL) {
|
||||
if (data->modekeys == MODEKEY_EMACS) {
|
||||
if (!tried && px > 0) {
|
||||
px--;
|
||||
tried = 1;
|
||||
goto retry;
|
||||
}
|
||||
window_copy_cursor_previous_word(wme, "}]) ");
|
||||
px = data->cx;
|
||||
continue;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
start = open[cp - close];
|
||||
|
||||
/* Walk backward until the matching bracket is reached. */
|
||||
n = 1;
|
||||
failed = 0;
|
||||
do {
|
||||
if (px == 0) {
|
||||
if (py == 0) {
|
||||
failed = 1;
|
||||
break;
|
||||
}
|
||||
do {
|
||||
py--;
|
||||
xx = window_copy_find_length(wme, py);
|
||||
} while (xx == 0 && py > 0);
|
||||
if (xx == 0 && py == 0) {
|
||||
failed = 1;
|
||||
break;
|
||||
}
|
||||
px = xx - 1;
|
||||
} else
|
||||
px--;
|
||||
|
||||
grid_get_cell(s->grid, px, py, &gc);
|
||||
if (gc.data.size == 1 &&
|
||||
(~gc.flags & GRID_FLAG_PADDING)) {
|
||||
if (*gc.data.data == found)
|
||||
n++;
|
||||
else if (*gc.data.data == start)
|
||||
n--;
|
||||
}
|
||||
} while (n != 0);
|
||||
|
||||
/* Move the cursor to the found location if any. */
|
||||
if (!failed)
|
||||
window_copy_scroll_to(wme, px, py);
|
||||
}
|
||||
|
||||
return (WINDOW_COPY_CMD_NOTHING);
|
||||
}
|
||||
|
||||
|
||||
static enum window_copy_cmd_action
|
||||
window_copy_cmd_next_matching_bracket(struct window_copy_cmd_state *cs)
|
||||
{
|
||||
struct window_mode_entry *wme = cs->wme;
|
||||
u_int np = wme->prefix;
|
||||
struct window_copy_mode_data *data = wme->data;
|
||||
struct screen *s = data->backing;
|
||||
char open[] = "{[(", close[] = "}])";
|
||||
char tried, found, end, *cp;
|
||||
u_int px, py, xx, yy, sx, sy, n;
|
||||
struct grid_cell gc;
|
||||
int failed;
|
||||
struct grid_line *gl;
|
||||
|
||||
for (; np != 0; np--) {
|
||||
/* Get cursor position and line length. */
|
||||
px = data->cx;
|
||||
py = screen_hsize(s) + data->cy - data->oy;
|
||||
xx = window_copy_find_length(wme, py);
|
||||
yy = screen_hsize(s) + screen_size_y(s) - 1;
|
||||
if (xx == 0)
|
||||
break;
|
||||
|
||||
/*
|
||||
* Get the current character. If not on a bracket, try the
|
||||
* next. If still not, then behave like next-word.
|
||||
*/
|
||||
tried = 0;
|
||||
retry:
|
||||
grid_get_cell(s->grid, px, py, &gc);
|
||||
if (gc.data.size != 1 || (gc.flags & GRID_FLAG_PADDING))
|
||||
cp = NULL;
|
||||
else {
|
||||
found = *gc.data.data;
|
||||
|
||||
/*
|
||||
* In vi mode, attempt to move to previous bracket if a
|
||||
* closing bracket is found first. If this fails,
|
||||
* return to the original cursor position.
|
||||
*/
|
||||
cp = strchr(close, found);
|
||||
if (cp != NULL && data->modekeys == MODEKEY_VI) {
|
||||
sx = data->cx;
|
||||
sy = screen_hsize(s) + data->cy - data->oy;
|
||||
|
||||
window_copy_scroll_to(wme, px, py);
|
||||
window_copy_cmd_previous_matching_bracket(cs);
|
||||
|
||||
px = data->cx;
|
||||
py = screen_hsize(s) + data->cy - data->oy;
|
||||
grid_get_cell(s->grid, px, py, &gc);
|
||||
if (gc.data.size != 1 ||
|
||||
(gc.flags & GRID_FLAG_PADDING) ||
|
||||
strchr(close, *gc.data.data) == NULL)
|
||||
window_copy_scroll_to(wme, sx, sy);
|
||||
break;
|
||||
}
|
||||
|
||||
cp = strchr(open, found);
|
||||
}
|
||||
if (cp == NULL) {
|
||||
if (data->modekeys == MODEKEY_EMACS) {
|
||||
if (!tried && px <= xx) {
|
||||
px++;
|
||||
tried = 1;
|
||||
goto retry;
|
||||
}
|
||||
window_copy_cursor_next_word_end(wme, "{[( ");
|
||||
px = data->cx;
|
||||
continue;
|
||||
}
|
||||
/* For vi, continue searching for bracket until EOL. */
|
||||
if (px > xx) {
|
||||
if (py == yy)
|
||||
continue;
|
||||
gl = grid_get_line(s->grid, py);
|
||||
if (~gl->flags & GRID_LINE_WRAPPED)
|
||||
continue;
|
||||
if (gl->cellsize > s->grid->sx)
|
||||
continue;
|
||||
px = 0;
|
||||
py++;
|
||||
xx = window_copy_find_length(wme, py);
|
||||
} else
|
||||
px++;
|
||||
goto retry;
|
||||
}
|
||||
end = close[cp - open];
|
||||
|
||||
/* Walk forward until the matching bracket is reached. */
|
||||
n = 1;
|
||||
failed = 0;
|
||||
do {
|
||||
if (px > xx) {
|
||||
if (py == yy) {
|
||||
failed = 1;
|
||||
break;
|
||||
}
|
||||
px = 0;
|
||||
py++;
|
||||
xx = window_copy_find_length(wme, py);
|
||||
} else
|
||||
px++;
|
||||
|
||||
grid_get_cell(s->grid, px, py, &gc);
|
||||
if (gc.data.size == 1 &&
|
||||
(~gc.flags & GRID_FLAG_PADDING)) {
|
||||
if (*gc.data.data == found)
|
||||
n++;
|
||||
else if (*gc.data.data == end)
|
||||
n--;
|
||||
}
|
||||
} while (n != 0);
|
||||
|
||||
/* Move the cursor to the found location if any. */
|
||||
if (!failed)
|
||||
window_copy_scroll_to(wme, px, py);
|
||||
}
|
||||
|
||||
return (WINDOW_COPY_CMD_NOTHING);
|
||||
}
|
||||
|
||||
static enum window_copy_cmd_action
|
||||
window_copy_cmd_next_paragraph(struct window_copy_cmd_state *cs)
|
||||
{
|
||||
@ -1613,6 +1825,8 @@ static const struct {
|
||||
window_copy_cmd_jump_to_forward },
|
||||
{ "middle-line", 0, 0,
|
||||
window_copy_cmd_middle_line },
|
||||
{ "next-matching-bracket", 0, 0,
|
||||
window_copy_cmd_next_matching_bracket },
|
||||
{ "next-paragraph", 0, 0,
|
||||
window_copy_cmd_next_paragraph },
|
||||
{ "next-space", 0, 0,
|
||||
@ -1631,6 +1845,8 @@ static const struct {
|
||||
window_copy_cmd_page_down_and_cancel },
|
||||
{ "page-up", 0, 0,
|
||||
window_copy_cmd_page_up },
|
||||
{ "previous-matching-bracket", 0, 0,
|
||||
window_copy_cmd_previous_matching_bracket },
|
||||
{ "previous-paragraph", 0, 0,
|
||||
window_copy_cmd_previous_paragraph },
|
||||
{ "previous-space", 0, 0,
|
||||
@ -3147,6 +3363,11 @@ window_copy_cursor_previous_word(struct window_mode_entry *wme,
|
||||
|
||||
py = screen_hsize(data->backing) + data->cy - data->oy;
|
||||
px = window_copy_find_length(wme, py);
|
||||
|
||||
/* Stop if separator at EOL. */
|
||||
if (px > 0 &&
|
||||
window_copy_in_set(wme, px - 1, py, separators))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user