Add formats for word and line under the mouse and use them to add some

items to the pane menu.
This commit is contained in:
nicm
2019-05-26 17:34:45 +00:00
parent 6431005169
commit e90d4a6021
10 changed files with 224 additions and 60 deletions

144
format.c
View File

@ -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. */