mirror of
https://github.com/tmux/tmux.git
synced 2025-01-05 23:38:48 +00:00
Merge branch 'obsd-master' into master
This commit is contained in:
commit
70a0eb3a22
303
grid-reader.c
Normal file
303
grid-reader.c
Normal file
@ -0,0 +1,303 @@
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2020 Anindya Mukherjee <anindya49@hotmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "tmux.h"
|
||||
|
||||
/* Initialise virtual cursor. */
|
||||
void
|
||||
grid_reader_start(struct grid_reader *gr, struct grid *gd, u_int cx, u_int cy)
|
||||
{
|
||||
gr->gd = gd;
|
||||
gr->cx = cx;
|
||||
gr->cy = cy;
|
||||
}
|
||||
|
||||
/* Get cursor position from reader. */
|
||||
void
|
||||
grid_reader_get_cursor(struct grid_reader *gr, u_int *cx, u_int *cy)
|
||||
{
|
||||
*cx = gr->cx;
|
||||
*cy = gr->cy;
|
||||
}
|
||||
|
||||
/* Get length of line containing the cursor. */
|
||||
u_int
|
||||
grid_reader_line_length(struct grid_reader *gr)
|
||||
{
|
||||
return (grid_line_length(gr->gd, gr->cy));
|
||||
}
|
||||
|
||||
/* Move cursor forward one position. */
|
||||
void
|
||||
grid_reader_cursor_right(struct grid_reader *gr, int wrap, int all)
|
||||
{
|
||||
u_int px;
|
||||
struct grid_cell gc;
|
||||
|
||||
if (all)
|
||||
px = gr->gd->sx;
|
||||
else
|
||||
px = grid_reader_line_length(gr);
|
||||
|
||||
if (wrap && gr->cx >= px && gr->cy < gr->gd->hsize + gr->gd->sy - 1) {
|
||||
grid_reader_cursor_start_of_line(gr, 0);
|
||||
grid_reader_cursor_down(gr);
|
||||
} else if (gr->cx < px) {
|
||||
gr->cx++;
|
||||
while (gr->cx < px) {
|
||||
grid_get_cell(gr->gd, gr->cx, gr->cy, &gc);
|
||||
if (~gc.flags & GRID_FLAG_PADDING)
|
||||
break;
|
||||
gr->cx++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Move cursor back one position. */
|
||||
void
|
||||
grid_reader_cursor_left(struct grid_reader *gr)
|
||||
{
|
||||
struct grid_cell gc;
|
||||
|
||||
while (gr->cx > 0) {
|
||||
grid_get_cell(gr->gd, gr->cx, gr->cy, &gc);
|
||||
if (~gc.flags & GRID_FLAG_PADDING)
|
||||
break;
|
||||
gr->cx--;
|
||||
}
|
||||
if (gr->cx == 0 && gr->cy > 0) {
|
||||
grid_reader_cursor_up(gr);
|
||||
grid_reader_cursor_end_of_line(gr, 0, 0);
|
||||
} else if (gr->cx > 0)
|
||||
gr->cx--;
|
||||
}
|
||||
|
||||
/* Move cursor down one line. */
|
||||
void
|
||||
grid_reader_cursor_down(struct grid_reader *gr)
|
||||
{
|
||||
struct grid_cell gc;
|
||||
|
||||
if (gr->cy < gr->gd->hsize + gr->gd->sy - 1)
|
||||
gr->cy++;
|
||||
while (gr->cx > 0) {
|
||||
grid_get_cell(gr->gd, gr->cx, gr->cy, &gc);
|
||||
if (~gc.flags & GRID_FLAG_PADDING)
|
||||
break;
|
||||
gr->cx--;
|
||||
}
|
||||
}
|
||||
|
||||
/* Move cursor up one line. */
|
||||
void
|
||||
grid_reader_cursor_up(struct grid_reader *gr)
|
||||
{
|
||||
struct grid_cell gc;
|
||||
|
||||
if (gr->cy > 0)
|
||||
gr->cy--;
|
||||
while (gr->cx > 0) {
|
||||
grid_get_cell(gr->gd, gr->cx, gr->cy, &gc);
|
||||
if (~gc.flags & GRID_FLAG_PADDING)
|
||||
break;
|
||||
gr->cx--;
|
||||
}
|
||||
}
|
||||
|
||||
/* Move cursor to the start of the line. */
|
||||
void
|
||||
grid_reader_cursor_start_of_line(struct grid_reader *gr, int wrap)
|
||||
{
|
||||
if (wrap) {
|
||||
while (gr->cy > 0 &&
|
||||
grid_get_line(gr->gd, gr->cy - 1)->flags &
|
||||
GRID_LINE_WRAPPED)
|
||||
gr->cy--;
|
||||
}
|
||||
gr->cx = 0;
|
||||
}
|
||||
|
||||
/* Move cursor to the end of the line. */
|
||||
void
|
||||
grid_reader_cursor_end_of_line(struct grid_reader *gr, int wrap, int all)
|
||||
{
|
||||
u_int yy;
|
||||
|
||||
if (wrap) {
|
||||
yy = gr->gd->hsize + gr->gd->sy - 1;
|
||||
while (gr->cy < yy && grid_get_line(gr->gd, gr->cy)->flags &
|
||||
GRID_LINE_WRAPPED)
|
||||
gr->cy++;
|
||||
}
|
||||
if (all)
|
||||
gr->cx = gr->gd->sx;
|
||||
else
|
||||
gr->cx = grid_reader_line_length(gr);
|
||||
}
|
||||
|
||||
/* Check if character under cursor is in set. */
|
||||
int
|
||||
grid_reader_in_set(struct grid_reader *gr, const char *set)
|
||||
{
|
||||
struct grid_cell gc;
|
||||
|
||||
grid_get_cell(gr->gd, gr->cx, gr->cy, &gc);
|
||||
if (gc.flags & GRID_FLAG_PADDING)
|
||||
return (0);
|
||||
return (utf8_cstrhas(set, &gc.data));
|
||||
}
|
||||
|
||||
/* Move cursor to the start of the next word. */
|
||||
void
|
||||
grid_reader_cursor_next_word(struct grid_reader *gr, const char *separators)
|
||||
{
|
||||
u_int xx, yy;
|
||||
int expected = 0;
|
||||
|
||||
/* Do not break up wrapped words. */
|
||||
if (grid_get_line(gr->gd, gr->cy)->flags & GRID_LINE_WRAPPED)
|
||||
xx = grid_reader_line_length(gr) - 1;
|
||||
else
|
||||
xx = grid_reader_line_length(gr);
|
||||
yy = gr->gd->hsize + gr->gd->sy - 1;
|
||||
|
||||
/*
|
||||
* If we started inside a word, skip over word characters. Then skip
|
||||
* over separators till the next word.
|
||||
*
|
||||
* expected is initially set to 0 for the former and then 1 for the
|
||||
* latter. It is finally set to 0 when the beginning of the next word is
|
||||
* found.
|
||||
*/
|
||||
do {
|
||||
while (gr->cx > xx ||
|
||||
grid_reader_in_set(gr, separators) == expected) {
|
||||
/* Move down if we are past the end of the line. */
|
||||
if (gr->cx > xx) {
|
||||
if (gr->cy == yy)
|
||||
return;
|
||||
grid_reader_cursor_start_of_line(gr, 0);
|
||||
grid_reader_cursor_down(gr);
|
||||
|
||||
if (grid_get_line(gr->gd, gr->cy)->flags &
|
||||
GRID_LINE_WRAPPED)
|
||||
xx = grid_reader_line_length(gr) - 1;
|
||||
else
|
||||
xx = grid_reader_line_length(gr);
|
||||
} else
|
||||
gr->cx++;
|
||||
}
|
||||
expected = !expected;
|
||||
} while (expected == 1);
|
||||
}
|
||||
|
||||
/* Move cursor to the end of the next word. */
|
||||
void
|
||||
grid_reader_cursor_next_word_end(struct grid_reader *gr, const char *separators)
|
||||
{
|
||||
u_int xx, yy;
|
||||
int expected = 1;
|
||||
|
||||
/* Do not break up wrapped words. */
|
||||
if (grid_get_line(gr->gd, gr->cy)->flags & GRID_LINE_WRAPPED)
|
||||
xx = grid_reader_line_length(gr) - 1;
|
||||
else
|
||||
xx = grid_reader_line_length(gr);
|
||||
yy = gr->gd->hsize + gr->gd->sy - 1;
|
||||
|
||||
/*
|
||||
* If we started on a separator, skip over separators. Then skip over
|
||||
* word characters till the next separator.
|
||||
*
|
||||
* expected is initially set to 1 for the former and then 1 for the
|
||||
* latter. It is finally set to 1 when the end of the next word is
|
||||
* found.
|
||||
*/
|
||||
do {
|
||||
while (gr->cx > xx ||
|
||||
grid_reader_in_set(gr, separators) == expected) {
|
||||
/* Move down if we are past the end of the line. */
|
||||
if (gr->cx > xx) {
|
||||
if (gr->cy == yy)
|
||||
return;
|
||||
grid_reader_cursor_start_of_line(gr, 0);
|
||||
grid_reader_cursor_down(gr);
|
||||
|
||||
if (grid_get_line(gr->gd, gr->cy)->flags &
|
||||
GRID_LINE_WRAPPED)
|
||||
xx = grid_reader_line_length(gr) - 1;
|
||||
else
|
||||
xx = grid_reader_line_length(gr);
|
||||
} else
|
||||
gr->cx++;
|
||||
}
|
||||
expected = !expected;
|
||||
} while (expected == 0);
|
||||
}
|
||||
|
||||
/* Move to the previous place where a word begins. */
|
||||
void
|
||||
grid_reader_cursor_previous_word(struct grid_reader *gr, const char *separators,
|
||||
int already)
|
||||
{
|
||||
int oldx, oldy, r;
|
||||
|
||||
/* Move back to the previous word character. */
|
||||
if (already || grid_reader_in_set(gr, separators)) {
|
||||
for (;;) {
|
||||
if (gr->cx > 0) {
|
||||
gr->cx--;
|
||||
if (!grid_reader_in_set(gr, separators))
|
||||
break;
|
||||
} else {
|
||||
if (gr->cy == 0)
|
||||
return;
|
||||
grid_reader_cursor_up(gr);
|
||||
grid_reader_cursor_end_of_line(gr, 0, 0);
|
||||
|
||||
/* Stop if separator at EOL. */
|
||||
if (gr->cx > 0) {
|
||||
oldx = gr->cx;
|
||||
gr->cx--;
|
||||
r = grid_reader_in_set(gr, separators);
|
||||
gr->cx = oldx;
|
||||
if (r)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Move back to the beginning of this word. */
|
||||
do {
|
||||
oldx = gr->cx;
|
||||
oldy = gr->cy;
|
||||
if (gr->cx == 0) {
|
||||
if (gr->cy == 0 ||
|
||||
~grid_get_line(gr->gd, gr->cy - 1)->flags &
|
||||
GRID_LINE_WRAPPED)
|
||||
break;
|
||||
grid_reader_cursor_up(gr);
|
||||
grid_reader_cursor_end_of_line(gr, 0, 0);
|
||||
}
|
||||
if (gr->cx > 0)
|
||||
gr->cx--;
|
||||
} while (!grid_reader_in_set(gr, separators));
|
||||
gr->cx = oldx;
|
||||
gr->cy = oldy;
|
||||
}
|
23
tmux.h
23
tmux.h
@ -728,6 +728,13 @@ struct grid {
|
||||
struct grid_line *linedata;
|
||||
};
|
||||
|
||||
/* Virtual cursor in a grid. */
|
||||
struct grid_reader {
|
||||
struct grid *gd;
|
||||
u_int cx;
|
||||
u_int cy;
|
||||
};
|
||||
|
||||
/* Style alignment. */
|
||||
enum style_align {
|
||||
STYLE_ALIGN_DEFAULT,
|
||||
@ -2550,6 +2557,22 @@ void grid_wrap_position(struct grid *, u_int, u_int, u_int *, u_int *);
|
||||
void grid_unwrap_position(struct grid *, u_int *, u_int *, u_int, u_int);
|
||||
u_int grid_line_length(struct grid *, u_int);
|
||||
|
||||
/* grid-reader.c */
|
||||
void grid_reader_start(struct grid_reader *, struct grid *, u_int, u_int);
|
||||
void grid_reader_get_cursor(struct grid_reader *, u_int *, u_int *);
|
||||
u_int grid_reader_line_length(struct grid_reader *);
|
||||
int grid_reader_in_set(struct grid_reader *, const char *);
|
||||
void grid_reader_cursor_right(struct grid_reader *, int, int);
|
||||
void grid_reader_cursor_left(struct grid_reader *);
|
||||
void grid_reader_cursor_down(struct grid_reader *);
|
||||
void grid_reader_cursor_up(struct grid_reader *);
|
||||
void grid_reader_cursor_start_of_line(struct grid_reader *, int);
|
||||
void grid_reader_cursor_end_of_line(struct grid_reader *, int, int);
|
||||
void grid_reader_cursor_next_word(struct grid_reader *, const char *);
|
||||
void grid_reader_cursor_next_word_end(struct grid_reader *, const char *);
|
||||
void grid_reader_cursor_previous_word(struct grid_reader *, const char *,
|
||||
int);
|
||||
|
||||
/* grid-view.c */
|
||||
void grid_view_get_cell(struct grid *, u_int, u_int, struct grid_cell *);
|
||||
void grid_view_set_cell(struct grid *, u_int, u_int,
|
||||
|
329
window-copy.c
329
window-copy.c
@ -3993,18 +3993,31 @@ window_copy_cursor_start_of_line(struct window_mode_entry *wme)
|
||||
{
|
||||
struct window_copy_mode_data *data = wme->data;
|
||||
struct screen *back_s = data->backing;
|
||||
struct grid *gd = back_s->grid;
|
||||
u_int py;
|
||||
struct grid_reader gr;
|
||||
u_int px, py, cy, yy, ny, hsize;
|
||||
|
||||
if (data->cx == 0 && data->lineflag == LINE_SEL_NONE) {
|
||||
py = screen_hsize(back_s) + data->cy - data->oy;
|
||||
while (py > 0 &&
|
||||
grid_get_line(gd, py - 1)->flags & GRID_LINE_WRAPPED) {
|
||||
window_copy_cursor_up(wme, 0);
|
||||
py = screen_hsize(back_s) + data->cy - data->oy;
|
||||
}
|
||||
px = data->cx;
|
||||
hsize = screen_hsize(back_s);
|
||||
py = hsize + data->cy - data->oy;
|
||||
|
||||
grid_reader_start(&gr, back_s->grid, px, py);
|
||||
grid_reader_cursor_start_of_line(&gr, 1);
|
||||
grid_reader_get_cursor(&gr, &px, &py);
|
||||
|
||||
/* Scroll up if we went off the visible screen. */
|
||||
yy = hsize - data->oy;
|
||||
if (py < yy) {
|
||||
ny = yy - py;
|
||||
cy = 0;
|
||||
} else {
|
||||
ny = 0;
|
||||
cy = py - yy;
|
||||
}
|
||||
window_copy_update_cursor(wme, 0, data->cy);
|
||||
while (ny > 0) {
|
||||
window_copy_cursor_up(wme, 1);
|
||||
ny--;
|
||||
}
|
||||
window_copy_update_cursor(wme, px, cy);
|
||||
if (window_copy_update_selection(wme, 1, 0))
|
||||
window_copy_redraw_lines(wme, data->cy, 1);
|
||||
}
|
||||
@ -4037,30 +4050,35 @@ window_copy_cursor_end_of_line(struct window_mode_entry *wme)
|
||||
{
|
||||
struct window_copy_mode_data *data = wme->data;
|
||||
struct screen *back_s = data->backing;
|
||||
struct grid *gd = back_s->grid;
|
||||
struct grid_line *gl;
|
||||
u_int px, py;
|
||||
struct grid_reader gr;
|
||||
u_int px, py, cy, yy, ny, hsize;
|
||||
|
||||
py = screen_hsize(back_s) + data->cy - data->oy;
|
||||
px = window_copy_find_length(wme, py);
|
||||
px = data->cx;
|
||||
hsize = screen_hsize(back_s);
|
||||
py = hsize + data->cy - data->oy;
|
||||
|
||||
if (data->cx == px && data->lineflag == LINE_SEL_NONE) {
|
||||
if (data->screen.sel != NULL && data->rectflag)
|
||||
px = screen_size_x(back_s);
|
||||
gl = grid_get_line(gd, py);
|
||||
if (gl->flags & GRID_LINE_WRAPPED) {
|
||||
while (py < gd->sy + gd->hsize) {
|
||||
gl = grid_get_line(gd, py);
|
||||
if (~gl->flags & GRID_LINE_WRAPPED)
|
||||
break;
|
||||
window_copy_cursor_down(wme, 0);
|
||||
py = screen_hsize(back_s) + data->cy - data->oy;
|
||||
}
|
||||
px = window_copy_find_length(wme, py);
|
||||
}
|
||||
grid_reader_start(&gr, back_s->grid, px, py);
|
||||
if (data->screen.sel != NULL && data->rectflag)
|
||||
grid_reader_cursor_end_of_line(&gr, 1, 1);
|
||||
else
|
||||
grid_reader_cursor_end_of_line(&gr, 1, 0);
|
||||
grid_reader_get_cursor(&gr, &px, &py);
|
||||
|
||||
/* Scroll down if we went off the visible screen. */
|
||||
cy = py - hsize + data->oy;
|
||||
yy = screen_size_y(back_s) - 1;
|
||||
if (cy > yy)
|
||||
ny = cy - yy;
|
||||
else
|
||||
ny = 0;
|
||||
while (ny > 0) {
|
||||
window_copy_cursor_down(wme, 1);
|
||||
ny--;
|
||||
}
|
||||
window_copy_update_cursor(wme, px, data->cy);
|
||||
|
||||
if (cy > yy)
|
||||
window_copy_update_cursor(wme, px, yy);
|
||||
else
|
||||
window_copy_update_cursor(wme, px, cy);
|
||||
if (window_copy_update_selection(wme, 1, 0))
|
||||
window_copy_redraw_lines(wme, data->cy, 1);
|
||||
}
|
||||
@ -4120,57 +4138,69 @@ static void
|
||||
window_copy_cursor_left(struct window_mode_entry *wme)
|
||||
{
|
||||
struct window_copy_mode_data *data = wme->data;
|
||||
u_int py, cx;
|
||||
struct grid_cell gc;
|
||||
struct screen *back_s = data->backing;
|
||||
struct grid_reader gr;
|
||||
u_int px, py, cy, yy, ny, hsize;
|
||||
|
||||
py = screen_hsize(data->backing) + data->cy - data->oy;
|
||||
cx = data->cx;
|
||||
while (cx > 0) {
|
||||
grid_get_cell(data->backing->grid, cx, py, &gc);
|
||||
if (~gc.flags & GRID_FLAG_PADDING)
|
||||
break;
|
||||
cx--;
|
||||
px = data->cx;
|
||||
hsize = screen_hsize(back_s);
|
||||
py = hsize + data->cy - data->oy;
|
||||
|
||||
grid_reader_start(&gr, back_s->grid, px, py);
|
||||
grid_reader_cursor_left(&gr);
|
||||
grid_reader_get_cursor(&gr, &px, &py);
|
||||
|
||||
/* Scroll up if we went off the visible screen. */
|
||||
yy = hsize - data->oy;
|
||||
if (py < yy) {
|
||||
ny = yy - py;
|
||||
cy = 0;
|
||||
} else {
|
||||
ny = 0;
|
||||
cy = py - yy;
|
||||
}
|
||||
if (cx == 0 && py > 0) {
|
||||
window_copy_cursor_up(wme, 0);
|
||||
window_copy_cursor_end_of_line(wme);
|
||||
} else if (cx > 0) {
|
||||
window_copy_update_cursor(wme, cx - 1, data->cy);
|
||||
if (window_copy_update_selection(wme, 1, 0))
|
||||
window_copy_redraw_lines(wme, data->cy, 1);
|
||||
while (ny > 0) {
|
||||
window_copy_cursor_up(wme, 1);
|
||||
ny--;
|
||||
}
|
||||
window_copy_update_cursor(wme, px, cy);
|
||||
if (window_copy_update_selection(wme, 1, 0))
|
||||
window_copy_redraw_lines(wme, data->cy, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
window_copy_cursor_right(struct window_mode_entry *wme, int all)
|
||||
{
|
||||
struct window_copy_mode_data *data = wme->data;
|
||||
u_int px, py, yy, cx, cy;
|
||||
struct grid_cell gc;
|
||||
struct screen *back_s = data->backing;
|
||||
struct grid_reader gr;
|
||||
u_int px, py, cy, yy, ny, hsize;
|
||||
|
||||
py = screen_hsize(data->backing) + data->cy - data->oy;
|
||||
yy = screen_hsize(data->backing) + screen_size_y(data->backing) - 1;
|
||||
if (all || (data->screen.sel != NULL && data->rectflag))
|
||||
px = screen_size_x(&data->screen);
|
||||
px = data->cx;
|
||||
hsize = screen_hsize(back_s);
|
||||
py = hsize + data->cy - data->oy;
|
||||
|
||||
grid_reader_start(&gr, back_s->grid, px, py);
|
||||
grid_reader_cursor_right(&gr, 1, all);
|
||||
grid_reader_get_cursor(&gr, &px, &py);
|
||||
|
||||
/* Scroll down if we went off the visible screen. */
|
||||
cy = py - hsize + data->oy;
|
||||
yy = screen_size_y(back_s) - 1;
|
||||
if (cy > yy)
|
||||
ny = cy - yy;
|
||||
else
|
||||
px = window_copy_find_length(wme, py);
|
||||
|
||||
if (data->cx >= px && py < yy) {
|
||||
window_copy_cursor_start_of_line(wme);
|
||||
window_copy_cursor_down(wme, 0);
|
||||
} else if (data->cx < px) {
|
||||
cx = data->cx + 1;
|
||||
cy = screen_hsize(data->backing) + data->cy - data->oy;
|
||||
while (cx < px) {
|
||||
grid_get_cell(data->backing->grid, cx, cy, &gc);
|
||||
if (~gc.flags & GRID_FLAG_PADDING)
|
||||
break;
|
||||
cx++;
|
||||
}
|
||||
window_copy_update_cursor(wme, cx, data->cy);
|
||||
if (window_copy_update_selection(wme, 1, 0))
|
||||
window_copy_redraw_lines(wme, data->cy, 1);
|
||||
ny = 0;
|
||||
while (ny > 0) {
|
||||
window_copy_cursor_down(wme, 1);
|
||||
ny--;
|
||||
}
|
||||
if (cy > yy)
|
||||
window_copy_update_cursor(wme, px, yy);
|
||||
else
|
||||
window_copy_update_cursor(wme, px, cy);
|
||||
if (window_copy_update_selection(wme, 1, 0))
|
||||
window_copy_redraw_lines(wme, data->cy, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -4214,13 +4244,30 @@ window_copy_cursor_up(struct window_mode_entry *wme, int scroll_only)
|
||||
px = window_copy_find_length(wme, py);
|
||||
if ((data->cx >= data->lastsx && data->cx != px) ||
|
||||
data->cx > px)
|
||||
window_copy_cursor_end_of_line(wme);
|
||||
{
|
||||
window_copy_update_cursor(wme, px, data->cy);
|
||||
if (window_copy_update_selection(wme, 1, 0))
|
||||
window_copy_redraw_lines(wme, data->cy, 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (data->lineflag == LINE_SEL_LEFT_RIGHT)
|
||||
window_copy_cursor_end_of_line(wme);
|
||||
{
|
||||
py = screen_hsize(data->backing) + data->cy - data->oy;
|
||||
if (data->rectflag)
|
||||
px = screen_size_x(data->backing);
|
||||
else
|
||||
px = window_copy_find_length(wme, py);
|
||||
window_copy_update_cursor(wme, px, data->cy);
|
||||
if (window_copy_update_selection(wme, 1, 0))
|
||||
window_copy_redraw_lines(wme, data->cy, 1);
|
||||
}
|
||||
else if (data->lineflag == LINE_SEL_RIGHT_LEFT)
|
||||
window_copy_cursor_start_of_line(wme);
|
||||
{
|
||||
window_copy_update_cursor(wme, 0, data->cy);
|
||||
if (window_copy_update_selection(wme, 1, 0))
|
||||
window_copy_redraw_lines(wme, data->cy, 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -4256,13 +4303,30 @@ window_copy_cursor_down(struct window_mode_entry *wme, int scroll_only)
|
||||
px = window_copy_find_length(wme, py);
|
||||
if ((data->cx >= data->lastsx && data->cx != px) ||
|
||||
data->cx > px)
|
||||
window_copy_cursor_end_of_line(wme);
|
||||
{
|
||||
window_copy_update_cursor(wme, px, data->cy);
|
||||
if (window_copy_update_selection(wme, 1, 0))
|
||||
window_copy_redraw_lines(wme, data->cy, 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (data->lineflag == LINE_SEL_LEFT_RIGHT)
|
||||
window_copy_cursor_end_of_line(wme);
|
||||
{
|
||||
py = screen_hsize(data->backing) + data->cy - data->oy;
|
||||
if (data->rectflag)
|
||||
px = screen_size_x(data->backing);
|
||||
else
|
||||
px = window_copy_find_length(wme, py);
|
||||
window_copy_update_cursor(wme, px, data->cy);
|
||||
if (window_copy_update_selection(wme, 1, 0))
|
||||
window_copy_redraw_lines(wme, data->cy, 1);
|
||||
}
|
||||
else if (data->lineflag == LINE_SEL_RIGHT_LEFT)
|
||||
window_copy_cursor_start_of_line(wme);
|
||||
{
|
||||
window_copy_update_cursor(wme, 0, data->cy);
|
||||
if (window_copy_update_selection(wme, 1, 0))
|
||||
window_copy_redraw_lines(wme, data->cy, 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -4476,46 +4540,38 @@ window_copy_cursor_next_word_end(struct window_mode_entry *wme,
|
||||
struct window_copy_mode_data *data = wme->data;
|
||||
struct options *oo = wp->window->options;
|
||||
struct screen *back_s = data->backing;
|
||||
u_int px, py, xx, yy;
|
||||
int keys, expected = 1;
|
||||
struct grid_reader gr;
|
||||
u_int px, py, cy, yy, ny, hsize;
|
||||
int keys;
|
||||
|
||||
px = data->cx;
|
||||
py = screen_hsize(back_s) + data->cy - data->oy;
|
||||
xx = window_copy_find_length(wme, py);
|
||||
yy = screen_hsize(back_s) + screen_size_y(back_s) - 1;
|
||||
hsize = screen_hsize(back_s);
|
||||
py = hsize + data->cy - data->oy;
|
||||
|
||||
grid_reader_start(&gr, back_s->grid, px, py);
|
||||
keys = options_get_number(oo, "mode-keys");
|
||||
if (keys == MODEKEY_VI && !window_copy_in_set(wme, px, py, separators))
|
||||
px++;
|
||||
if (keys == MODEKEY_VI && !grid_reader_in_set(&gr, separators))
|
||||
grid_reader_cursor_right(&gr, 0, 0);
|
||||
grid_reader_cursor_next_word_end(&gr, separators);
|
||||
if (keys == MODEKEY_VI)
|
||||
grid_reader_cursor_left(&gr);
|
||||
grid_reader_get_cursor(&gr, &px, &py);
|
||||
|
||||
/*
|
||||
* First skip past any word characters, then any nonword characters.
|
||||
*
|
||||
* expected is initially set to 1 for the former and then 0 for the
|
||||
* latter.
|
||||
*/
|
||||
do {
|
||||
while (px > xx ||
|
||||
window_copy_in_set(wme, px, py, separators) == expected) {
|
||||
/* Move down if we're past the end of the line. */
|
||||
if (px > xx) {
|
||||
if (py == yy)
|
||||
return;
|
||||
window_copy_cursor_down(wme, 0);
|
||||
px = 0;
|
||||
|
||||
py = screen_hsize(back_s) + data->cy - data->oy;
|
||||
xx = window_copy_find_length(wme, py);
|
||||
} else
|
||||
px++;
|
||||
}
|
||||
expected = !expected;
|
||||
} while (expected == 0);
|
||||
|
||||
if (keys == MODEKEY_VI && px != 0)
|
||||
px--;
|
||||
|
||||
window_copy_update_cursor(wme, px, data->cy);
|
||||
/* Scroll down if we went off the visible screen. */
|
||||
cy = py - hsize + data->oy;
|
||||
yy = screen_size_y(back_s) - 1;
|
||||
if (cy > yy)
|
||||
ny = cy - yy;
|
||||
else
|
||||
ny = 0;
|
||||
while (ny > 0) {
|
||||
window_copy_cursor_down(wme, 1);
|
||||
ny--;
|
||||
}
|
||||
if (cy > yy)
|
||||
window_copy_update_cursor(wme, px, yy);
|
||||
else
|
||||
window_copy_update_cursor(wme, px, cy);
|
||||
if (window_copy_update_selection(wme, 1, no_reset))
|
||||
window_copy_redraw_lines(wme, data->cy, 1);
|
||||
}
|
||||
@ -4572,43 +4628,32 @@ window_copy_cursor_previous_word(struct window_mode_entry *wme,
|
||||
const char *separators, int already)
|
||||
{
|
||||
struct window_copy_mode_data *data = wme->data;
|
||||
u_int px, py, hsize;
|
||||
struct screen *back_s = data->backing;
|
||||
struct grid_reader gr;
|
||||
u_int px, py, cy, yy, ny, hsize;
|
||||
|
||||
hsize = screen_hsize(data->backing);
|
||||
px = data->cx;
|
||||
hsize = screen_hsize(back_s);
|
||||
py = hsize + data->cy - data->oy;
|
||||
|
||||
/* Move back to the previous word character. */
|
||||
if (already || window_copy_in_set(wme, px, py, separators)) {
|
||||
for (;;) {
|
||||
if (px > 0) {
|
||||
px--;
|
||||
if (!window_copy_in_set(wme, px, py,
|
||||
separators))
|
||||
break;
|
||||
} else {
|
||||
if (data->cy == 0 &&
|
||||
(hsize == 0 || data->oy > hsize - 1))
|
||||
goto out;
|
||||
window_copy_cursor_up(wme, 0);
|
||||
grid_reader_start(&gr, back_s->grid, px, py);
|
||||
grid_reader_cursor_previous_word(&gr, separators, already);
|
||||
grid_reader_get_cursor(&gr, &px, &py);
|
||||
|
||||
py = hsize + 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;
|
||||
}
|
||||
}
|
||||
/* Scroll up if we went off the visible screen. */
|
||||
yy = hsize - data->oy;
|
||||
if (py < yy) {
|
||||
ny = yy - py;
|
||||
cy = 0;
|
||||
} else {
|
||||
ny = 0;
|
||||
cy = py - yy;
|
||||
}
|
||||
|
||||
/* Move back to the beginning of this word. */
|
||||
while (px > 0 && !window_copy_in_set(wme, px - 1, py, separators))
|
||||
px--;
|
||||
|
||||
out:
|
||||
window_copy_update_cursor(wme, px, data->cy);
|
||||
while (ny > 0) {
|
||||
window_copy_cursor_up(wme, 1);
|
||||
ny--;
|
||||
}
|
||||
window_copy_update_cursor(wme, px, cy);
|
||||
if (window_copy_update_selection(wme, 1, 0))
|
||||
window_copy_redraw_lines(wme, data->cy, 1);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user