summaryrefslogtreecommitdiff
path: root/usr.bin/tmux/format.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin/tmux/format.c')
-rw-r--r--usr.bin/tmux/format.c146
1 files changed, 144 insertions, 2 deletions
diff --git a/usr.bin/tmux/format.c b/usr.bin/tmux/format.c
index 562b1ae016c..68d0d64205a 100644
--- a/usr.bin/tmux/format.c
+++ b/usr.bin/tmux/format.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: format.c,v 1.196 2019/05/26 12:02:42 nicm Exp $ */
+/* $OpenBSD: format.c,v 1.197 2019/05/26 17:34:45 nicm Exp $ */
/*
* Copyright (c) 2011 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -84,6 +84,12 @@ static void format_defaults_winlink(struct format_tree *, struct winlink *);
"New After,w,new-window -a|" \
"New At End,W,new-window"
#define DEFAULT_PANE_MENU \
+ "#{?mouse_word,Search For #[underscore]#{=/9/...:mouse_word},},,copy-mode -t=; send -Xt= search-backward \"#{q:mouse_word}\"|" \
+ "#{?mouse_word,Type #[underscore]#{=/9/...:mouse_word},},,send-keys -l \"#{q:mouse_word}\"|" \
+ "|" \
+ "#{?mouse_word,Copy #[underscore]#{=/9/...:mouse_word},},c,set-buffer \"#{q:mouse_word}\"|" \
+ "#{?mouse_line,Copy Line,},l,set-buffer \"#{q:mouse_line}\"|" \
+ "|" \
"Horizontal Split,h,split-window -h|" \
"Vertical Split,v,split-window -v|" \
"|" \
@@ -170,6 +176,8 @@ struct format_tree {
time_t time;
u_int loop;
+ struct mouse_event m;
+
RB_HEAD(format_entry_tree, format_entry) tree;
};
static int format_entry_cmp(struct format_entry *, struct format_entry *);
@@ -743,6 +751,121 @@ format_cb_cursor_character(struct format_tree *ft, struct format_entry *fe)
xasprintf(&fe->value, "%.*s", (int)gc.data.size, gc.data.data);
}
+/* Callback for mouse_word. */
+static void
+format_cb_mouse_word(struct format_tree *ft, struct format_entry *fe)
+{
+ struct window_pane *wp;
+ u_int x, y, end;
+ struct grid *gd;
+ struct grid_line *gl;
+ struct grid_cell gc;
+ const char *ws;
+ struct utf8_data *ud = NULL;
+ size_t size = 0;
+ int found = 0;
+
+ if (!ft->m.valid)
+ return;
+ wp = cmd_mouse_pane(&ft->m, NULL, NULL);
+ if (wp == NULL)
+ return;
+ if (cmd_mouse_at(wp, &ft->m, &x, &y, 0) != 0)
+ return;
+ gd = wp->base.grid;
+ ws = options_get_string(global_s_options, "word-separators");
+
+ y = gd->hsize + y;
+ for (;;) {
+ grid_get_cell(gd, x, y, &gc);
+ if (gc.flags & GRID_FLAG_PADDING)
+ break;
+ if (utf8_cstrhas(ws, &gc.data)) {
+ found = 1;
+ break;
+ }
+
+ if (x == 0) {
+ if (y == 0)
+ break;
+ gl = &gd->linedata[y - 1];
+ if (~gl->flags & GRID_LINE_WRAPPED)
+ break;
+ y--;
+ x = grid_line_length(gd, y);
+ if (x == 0)
+ break;
+ }
+ x--;
+ }
+ for (;;) {
+ if (found) {
+ end = grid_line_length(gd, y);
+ if (end == 0 || x == end - 1) {
+ if (y == gd->hsize + gd->sy - 1)
+ break;
+ gl = &gd->linedata[y];
+ if (~gl->flags & GRID_LINE_WRAPPED)
+ break;
+ y++;
+ x = 0;
+ } else
+ x++;
+ }
+ found = 1;
+
+ grid_get_cell(gd, x, y, &gc);
+ if (gc.flags & GRID_FLAG_PADDING)
+ break;
+ if (utf8_cstrhas(ws, &gc.data))
+ break;
+
+ ud = xreallocarray(ud, size + 2, sizeof *ud);
+ memcpy(&ud[size++], &gc.data, sizeof *ud);
+ }
+ if (size != 0) {
+ ud[size].size = 0;
+ fe->value = utf8_tocstr(ud);
+ free(ud);
+ }
+}
+
+/* Callback for mouse_line. */
+static void
+format_cb_mouse_line(struct format_tree *ft, struct format_entry *fe)
+{
+ struct window_pane *wp;
+ u_int x, y;
+ struct grid *gd;
+ struct grid_cell gc;
+ struct utf8_data *ud = NULL;
+ size_t size = 0;
+
+ if (!ft->m.valid)
+ return;
+ wp = cmd_mouse_pane(&ft->m, NULL, NULL);
+ if (wp == NULL)
+ return;
+ if (cmd_mouse_at(wp, &ft->m, &x, &y, 0) != 0)
+ return;
+ gd = wp->base.grid;
+
+ y = gd->hsize + y;
+ for (x = 0; x < grid_line_length(gd, y); x++) {
+ grid_get_cell(gd, x, y, &gc);
+ if (gc.flags & GRID_FLAG_PADDING)
+ break;
+
+ ud = xreallocarray(ud, size + 2, sizeof *ud);
+ memcpy(&ud[size++], &gc.data, sizeof *ud);
+ }
+ if (size != 0) {
+ ud[size].size = 0;
+ fe->value = utf8_tocstr(ud);
+ free(ud);
+ }
+}
+
/* Merge a format tree. */
static void
format_merge(struct format_tree *ft, struct format_tree *from)
@@ -759,10 +882,29 @@ format_merge(struct format_tree *ft, struct format_tree *from)
static void
format_create_add_item(struct format_tree *ft, struct cmdq_item *item)
{
+ struct mouse_event *m;
+ struct window_pane *wp;
+ u_int x, y;
+
if (item->cmd != NULL)
format_add(ft, "command", "%s", item->cmd->entry->name);
- if (item->shared != NULL && item->shared->formats != NULL)
+
+ if (item->shared == NULL)
+ return;
+ if (item->shared->formats != NULL)
format_merge(ft, item->shared->formats);
+
+ m = &item->shared->mouse;
+ if (m->valid && ((wp = cmd_mouse_pane(m, NULL, NULL)) != NULL)) {
+ format_add(ft, "mouse_pane", "%%%u", wp->id);
+ if (cmd_mouse_at(wp, m, &x, &y, 0) == 0) {
+ format_add(ft, "mouse_x", "%u", x);
+ format_add(ft, "mouse_y", "%u", y);
+ format_add_cb(ft, "mouse_word", format_cb_mouse_word);
+ format_add_cb(ft, "mouse_line", format_cb_mouse_line);
+ }
+ }
+ memcpy(&ft->m, m, sizeof ft->m);
}
/* Create a new tree. */