aboutsummaryrefslogtreecommitdiff
path: root/window-copy.c
diff options
context:
space:
mode:
authornicm <nicm>2020-05-16 16:10:28 +0000
committernicm <nicm>2020-05-16 16:10:28 +0000
commitff8dd150e0c59b37d9a4942e499a2a025820db8d (patch)
tree6bb50aa2be5983d21c8609ee58dacff1bca166fc /window-copy.c
parentdceb6a15d04a2b2e050ab41816d0df3fe224b416 (diff)
downloadrtmux-ff8dd150e0c59b37d9a4942e499a2a025820db8d.tar.gz
rtmux-ff8dd150e0c59b37d9a4942e499a2a025820db8d.tar.bz2
rtmux-ff8dd150e0c59b37d9a4942e499a2a025820db8d.zip
Add a mark in copy mode. Set with set-mark command (bound to 'X') by
default and the mark and cursor position are swapped with 'jump-to-mark' (bound to M-x). The line containing the mark is shown in copy-mode-mark-style with the horizontal position in reverse. From Anindya Mukherjee in GitHub issue 2209.
Diffstat (limited to 'window-copy.c')
-rw-r--r--window-copy.c107
1 files changed, 98 insertions, 9 deletions
diff --git a/window-copy.c b/window-copy.c
index 95b4cc6e..e572eaa8 100644
--- a/window-copy.c
+++ b/window-copy.c
@@ -131,6 +131,7 @@ static void window_copy_rectangle_toggle(struct window_mode_entry *);
static void window_copy_move_mouse(struct mouse_event *);
static void window_copy_drag_update(struct client *, struct mouse_event *);
static void window_copy_drag_release(struct client *, struct mouse_event *);
+static void window_copy_jump_to_mark(struct window_mode_entry *);
const struct window_mode window_copy_mode = {
.name = "copy-mode",
@@ -254,6 +255,10 @@ struct window_copy_mode_data {
u_int lastcx; /* position in last line w/ content */
u_int lastsx; /* size of last line w/ content */
+ u_int mx; /* mark position */
+ u_int my;
+ int showmark;
+
int searchtype;
int searchregex;
char *searchstr;
@@ -424,6 +429,9 @@ window_copy_init(struct window_mode_entry *wme,
data->screen.cx = data->cx;
data->screen.cy = data->cy;
+ data->mx = data->cx;
+ data->my = screen_hsize(data->backing) + data->cy - data->oy;
+ data->showmark = 0;
screen_write_start(&ctx, &data->screen);
for (i = 0; i < screen_size_y(&data->screen); i++)
@@ -448,6 +456,9 @@ window_copy_view_init(struct window_mode_entry *wme,
data->backing = s = xmalloc(sizeof *data->backing);
screen_init(s, screen_size_x(base), screen_size_y(base), UINT_MAX);
+ data->mx = data->cx;
+ data->my = screen_hsize(data->backing) + data->cy - data->oy;
+ data->showmark = 0;
return (&data->screen);
}
@@ -1734,6 +1745,17 @@ window_copy_cmd_select_word(struct window_copy_cmd_state *cs)
}
static enum window_copy_cmd_action
+window_copy_cmd_set_mark(struct window_copy_cmd_state *cs)
+{
+ struct window_copy_mode_data *data = cs->wme->data;
+
+ data->mx = data->cx;
+ data->my = screen_hsize(data->backing) + data->cy - data->oy;
+ data->showmark = 1;
+ return (WINDOW_COPY_CMD_REDRAW);
+}
+
+static enum window_copy_cmd_action
window_copy_cmd_start_of_line(struct window_copy_cmd_state *cs)
{
struct window_mode_entry *wme = cs->wme;
@@ -1878,6 +1900,15 @@ window_copy_cmd_jump_to_forward(struct window_copy_cmd_state *cs)
}
static enum window_copy_cmd_action
+window_copy_cmd_jump_to_mark(struct window_copy_cmd_state *cs)
+{
+ struct window_mode_entry *wme = cs->wme;
+
+ window_copy_jump_to_mark(wme);
+ return (WINDOW_COPY_CMD_NOTHING);
+}
+
+static enum window_copy_cmd_action
window_copy_cmd_search_backward(struct window_copy_cmd_state *cs)
{
struct window_mode_entry *wme = cs->wme;
@@ -2154,6 +2185,8 @@ static const struct {
window_copy_cmd_jump_to_backward },
{ "jump-to-forward", 1, 1, 1,
window_copy_cmd_jump_to_forward },
+ { "jump-to-mark", 0, 0, 0,
+ window_copy_cmd_jump_to_mark },
{ "middle-line", 0, 0, 1,
window_copy_cmd_middle_line },
{ "next-matching-bracket", 0, 0, 0,
@@ -2214,6 +2247,8 @@ static const struct {
window_copy_cmd_select_line },
{ "select-word", 0, 0, 0,
window_copy_cmd_select_word },
+ { "set-mark", 0, 0, 0,
+ window_copy_cmd_set_mark },
{ "start-of-line", 0, 0, 1,
window_copy_cmd_start_of_line },
{ "stop-selection", 0, 0, 0,
@@ -3129,11 +3164,26 @@ window_copy_match_at_cursor(struct window_copy_mode_data *data)
static void
window_copy_update_style(struct window_mode_entry *wme, u_int fx, u_int fy,
struct grid_cell *gc, const struct grid_cell *mgc,
- const struct grid_cell *cgc)
+ const struct grid_cell *cgc, const struct grid_cell *mkgc)
{
struct window_copy_mode_data *data = wme->data;
u_int mark, start, end, cy, cursor, current;
u_int sx = screen_size_x(data->backing);
+ int inv = 0;
+
+ if (data->showmark && fy == data->my) {
+ gc->attr = mkgc->attr;
+ if (fx == data->mx)
+ inv = 1;
+ if (inv) {
+ gc->fg = mkgc->bg;
+ gc->bg = mkgc->fg;
+ }
+ else {
+ gc->fg = mkgc->fg;
+ gc->bg = mkgc->bg;
+ }
+ }
if (data->searchmark == NULL)
return;
@@ -3150,21 +3200,34 @@ window_copy_update_style(struct window_mode_entry *wme, u_int fx, u_int fy,
window_copy_match_start_end(data, cursor, &start, &end);
if (current >= start && current <= end) {
gc->attr = cgc->attr;
- gc->fg = cgc->fg;
- gc->bg = cgc->bg;
+ if (inv) {
+ gc->fg = cgc->bg;
+ gc->bg = cgc->fg;
+ }
+ else {
+ gc->fg = cgc->fg;
+ gc->bg = cgc->bg;
+ }
return;
}
}
gc->attr = mgc->attr;
- gc->fg = mgc->fg;
- gc->bg = mgc->bg;
+ if (inv) {
+ gc->fg = mgc->bg;
+ gc->bg = mgc->fg;
+ }
+ else {
+ gc->fg = mgc->fg;
+ gc->bg = mgc->bg;
+ }
}
static void
window_copy_write_one(struct window_mode_entry *wme,
struct screen_write_ctx *ctx, u_int py, u_int fy, u_int nx,
- const struct grid_cell *mgc, const struct grid_cell *cgc)
+ const struct grid_cell *mgc, const struct grid_cell *cgc,
+ const struct grid_cell *mkgc)
{
struct window_copy_mode_data *data = wme->data;
struct grid *gd = data->backing->grid;
@@ -3175,7 +3238,8 @@ window_copy_write_one(struct window_mode_entry *wme,
for (fx = 0; fx < nx; fx++) {
grid_get_cell(gd, fx, fy, &gc);
if (fx + gc.data.width <= nx) {
- window_copy_update_style(wme, fx, fy, &gc, mgc, cgc);
+ window_copy_update_style(wme, fx, fy, &gc, mgc, cgc,
+ mkgc);
screen_write_cell(ctx, &gc);
}
}
@@ -3189,7 +3253,7 @@ window_copy_write_line(struct window_mode_entry *wme,
struct window_copy_mode_data *data = wme->data;
struct screen *s = &data->screen;
struct options *oo = wp->window->options;
- struct grid_cell gc, mgc, cgc;
+ struct grid_cell gc, mgc, cgc, mkgc;
char hdr[512];
size_t size = 0;
u_int hsize = screen_hsize(data->backing);
@@ -3200,6 +3264,8 @@ window_copy_write_line(struct window_mode_entry *wme,
mgc.flags |= GRID_FLAG_NOPALETTE;
style_apply(&cgc, oo, "copy-mode-current-match-style", NULL);
cgc.flags |= GRID_FLAG_NOPALETTE;
+ style_apply(&mkgc, oo, "copy-mode-mark-style", NULL);
+ mkgc.flags |= GRID_FLAG_NOPALETTE;
if (py == 0 && s->rupper < s->rlower && !data->hide_position) {
if (data->searchmark == NULL) {
@@ -3233,7 +3299,7 @@ window_copy_write_line(struct window_mode_entry *wme,
if (size < screen_size_x(s)) {
window_copy_write_one(wme, ctx, py, hsize - data->oy + py,
- screen_size_x(s) - size, &mgc, &cgc);
+ screen_size_x(s) - size, &mgc, &cgc, &mkgc);
}
if (py == data->cy && data->cx == screen_size_x(s)) {
@@ -4687,3 +4753,26 @@ window_copy_drag_release(struct client *c, struct mouse_event *m)
data = wme->data;
evtimer_del(&data->dragtimer);
}
+
+static void
+window_copy_jump_to_mark(struct window_mode_entry *wme)
+{
+ struct window_copy_mode_data *data = wme->data;
+ u_int tmx, tmy;
+
+ tmx = data->cx;
+ tmy = screen_hsize(data->backing) + data->cy - data->oy;
+ data->cx = data->mx;
+ if (data->my < screen_hsize(data->backing)) {
+ data->cy = 0;
+ data->oy = screen_hsize(data->backing) - data->my;
+ } else {
+ data->cy = data->my - screen_hsize(data->backing);
+ data->oy = 0;
+ }
+ data->mx = tmx;
+ data->my = tmy;
+ data->showmark = 1;
+ window_copy_update_selection(wme, 0, 0);
+ window_copy_redraw_screen(wme);
+}