version 1.217, 2019/04/25 06:34:57 |
version 1.218, 2019/04/29 06:55:21 |
|
|
|
|
int searchtype; |
int searchtype; |
char *searchstr; |
char *searchstr; |
bitstr_t *searchmark; |
bitstr_t *searchmark; |
u_int searchcount; |
u_int searchcount; |
int searchthis; |
int searchthis; |
int searchx; |
int searchx; |
|
|
} |
} |
|
|
static enum window_copy_cmd_action |
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) |
window_copy_cmd_next_paragraph(struct window_copy_cmd_state *cs) |
{ |
{ |
struct window_mode_entry *wme = cs->wme; |
struct window_mode_entry *wme = cs->wme; |
|
|
window_copy_cmd_jump_to_forward }, |
window_copy_cmd_jump_to_forward }, |
{ "middle-line", 0, 0, |
{ "middle-line", 0, 0, |
window_copy_cmd_middle_line }, |
window_copy_cmd_middle_line }, |
|
{ "next-matching-bracket", 0, 0, |
|
window_copy_cmd_next_matching_bracket }, |
{ "next-paragraph", 0, 0, |
{ "next-paragraph", 0, 0, |
window_copy_cmd_next_paragraph }, |
window_copy_cmd_next_paragraph }, |
{ "next-space", 0, 0, |
{ "next-space", 0, 0, |
|
|
window_copy_cmd_page_down_and_cancel }, |
window_copy_cmd_page_down_and_cancel }, |
{ "page-up", 0, 0, |
{ "page-up", 0, 0, |
window_copy_cmd_page_up }, |
window_copy_cmd_page_up }, |
|
{ "previous-matching-bracket", 0, 0, |
|
window_copy_cmd_previous_matching_bracket }, |
{ "previous-paragraph", 0, 0, |
{ "previous-paragraph", 0, 0, |
window_copy_cmd_previous_paragraph }, |
window_copy_cmd_previous_paragraph }, |
{ "previous-space", 0, 0, |
{ "previous-space", 0, 0, |
|
|
|
|
py = screen_hsize(data->backing) + data->cy - data->oy; |
py = screen_hsize(data->backing) + data->cy - data->oy; |
px = window_copy_find_length(wme, py); |
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; |
} |
} |
} |
} |
|
|