--- config.def.h | 1 + st.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++ st.h | 1 + 3 files changed, 80 insertions(+) diff --git a/config.def.h b/config.def.h index 82b1b09..cbe923e 100644 --- a/config.def.h +++ b/config.def.h _AT_@ -178,6 +178,7 @@ static Shortcut shortcuts[] = { { TERMMOD, XK_Y, selpaste, {.i = 0} }, { TERMMOD, XK_Num_Lock, numlock, {.i = 0} }, { TERMMOD, XK_I, iso14755, {.i = 0} }, + { MODKEY, XK_l, copyurl, {.i = 0} }, }; /* diff --git a/st.c b/st.c index 0628707..f1ac7b6 100644 --- a/st.c +++ b/st.c _AT_@ -204,6 +204,7 @@ static void tdefutf8(char); static int32_t tdefcolor(int *, int *, int); static void tdeftran(char); static void tstrsequence(uchar); +static void tsetcolor(int, int, int, uint32_t, uint32_t); static void drawregion(int, int, int, int); _AT_@ -1600,6 +1601,17 @@ tsetmode(int priv, int set, int *args, int narg) } } +void +tsetcolor( int row, int start, int end, uint32_t fg, uint32_t bg ) +{ + int i = start; + for( ; i < end; ++i ) + { + term.line[row][i].fg = fg; + term.line[row][i].bg = bg; + } +} + void csihandle(void) { _AT_@ -2617,3 +2629,69 @@ redraw(void) tfulldirt(); draw(); } + +/* select and copy the previous url on screen (do nothing if there's no url). + * known bug: doesn't handle urls that span multiple lines (wontfix) + * known bug: only finds first url on line (mightfix) + */ +void +copyurl(const Arg *arg) { + /* () and [] can appear in urls, but excluding them here will reduce false + * positives when figuring out where a given url ends. + */ + static char URLCHARS[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789-._~:/?#_AT_!$&'*+,;=%"; + + tsetcolor( sel.nb.y, sel.ob.x, sel.oe.x - sel.ob.x + 1, defaultfg, defaultbg ); + + int i, row, startrow; + char *linestr = calloc(sizeof(char), term.col+1); /* assume ascii */ + char *c, *match = NULL; + + row = (sel.ob.x >= 0 && sel.nb.y > 0) ? sel.nb.y-1 : term.bot; + LIMIT(row, term.top, term.bot); + startrow = row; + + /* find the start of the last url before selection */ + do { + for (i = 0; i < term.col; ++i) { + if (term.line[row][i].u > 127) /* assume ascii */ + continue; + linestr[i] = term.line[row][i].u; + } + linestr[term.col] = '\0'; + if ((match = strstr(linestr, "http://")) + || (match = strstr(linestr, "https://"))) + break; + if (--row < term.top) + row = term.bot; + } while (row != startrow); + + if (match) { + /* must happen before trim */ + selclear(); + sel.ob.x = strlen(linestr) - strlen(match); + + /* trim the rest of the line from the url match */ + for (c = match; *c != '\0'; ++c) + if (!strchr(URLCHARS, *c)) { + *c = '\0'; + break; + } + + tsetcolor( row, sel.ob.x, strlen( match ), defaultbg, defaultfg ); + + /* select and copy */ + sel.mode = 1; + sel.type = SEL_REGULAR; + sel.oe.x = sel.ob.x + strlen(match)-1; + sel.ob.y = sel.oe.y = row; + selnormalize(); + tsetdirt(sel.nb.y, sel.ne.y); + xsetsel(getsel()); + xclipcopy(); + } + + free(linestr); +} diff --git a/st.h b/st.h index dac64d8..5a58f8f 100644 --- a/st.h +++ b/st.h _AT_@ -85,6 +85,7 @@ void printscreen(const Arg *); void printsel(const Arg *); void sendbreak(const Arg *); void toggleprinter(const Arg *); +void copyurl(const Arg *); int tattrset(int); void tnew(int, int); -- 2.17.0Received on Fri Apr 27 2018 - 01:57:15 CEST
This archive was generated by hypermail 2.3.0 : Fri Apr 27 2018 - 02:00:42 CEST