sites

public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log | Files | Refs

st-copyurl-20170802-e2ee5ee.diff (3036B)


      1 diff --git a/config.def.h b/config.def.h
      2 index fd80923..a2eb85e 100644
      3 --- a/config.def.h
      4 +++ b/config.def.h
      5 @@ -178,6 +178,7 @@ Shortcut shortcuts[] = {
      6  	{ MODKEY|ShiftMask,     XK_V,           clippaste,      {.i =  0} },
      7  	{ MODKEY,               XK_Num_Lock,    numlock,        {.i =  0} },
      8  	{ MODKEY,               XK_Control_L,   iso14755,       {.i =  0} },
      9 +	{ MODKEY,               XK_l,           copyurl,        {.i =  0} },
     10  };
     11  
     12  /*
     13 diff --git a/st.c b/st.c
     14 index 1e4196e..df9cc7d 100644
     15 --- a/st.c
     16 +++ b/st.c
     17 @@ -138,6 +138,7 @@ static void printscreen(const Arg *) ;
     18  static void iso14755(const Arg *);
     19  static void toggleprinter(const Arg *);
     20  static void sendbreak(const Arg *);
     21 +static void copyurl(const Arg *);
     22  
     23  /* config.h for applying patches and the configuration. */
     24  #include "config.h"
     25 @@ -2640,3 +2641,68 @@ usage(void)
     26  	    "          [-T title] [-t title] [-w windowid] -l line"
     27  	    " [stty_args ...]\n", argv0, argv0);
     28  }
     29 +
     30 +
     31 +/* predeclare selcopy, defined in x.c, for copyurl */
     32 +void selcopy(Time);
     33 +
     34 +/* select and copy the previous url on screen (do nothing if there's no url).
     35 + * known bug: doesn't handle urls that span multiple lines (wontfix)
     36 + * known bug: only finds first url on line (mightfix)
     37 + */
     38 +void
     39 +copyurl(const Arg *arg) {
     40 +	/* () and [] can appear in urls, but excluding them here will reduce false
     41 +	 * positives when figuring out where a given url ends.
     42 +	 */
     43 +	static char URLCHARS[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
     44 +		"abcdefghijklmnopqrstuvwxyz"
     45 +		"0123456789-._~:/?#@!$&'*+,;=%";
     46 +
     47 +	int i, row, startrow;
     48 +	char *linestr = calloc(sizeof(char), term.col+1); /* assume ascii */
     49 +	char *c, *match = NULL;
     50 +
     51 +	row = (sel.ob.x >= 0 && sel.nb.y > 0) ? sel.nb.y-1 : term.bot;
     52 +	LIMIT(row, term.top, term.bot);
     53 +	startrow = row;
     54 +
     55 +	/* find the start of the last url before selection */
     56 +	do {
     57 +		for (i = 0; i < term.col; ++i) {
     58 +			if (term.line[row][i].u > 127) /* assume ascii */
     59 +				continue;
     60 +			linestr[i] = term.line[row][i].u;
     61 +		}
     62 +		linestr[term.col] = '\0';
     63 +		if ((match = strstr(linestr, "http://"))
     64 +				|| (match = strstr(linestr, "https://")))
     65 +			break;
     66 +		if (--row < term.top)
     67 +			row = term.bot;
     68 +	} while (row != startrow);
     69 +
     70 +	if (match) {
     71 +		/* must happen before trim */
     72 +		selclear();
     73 +		sel.ob.x = strlen(linestr) - strlen(match);
     74 +
     75 +		/* trim the rest of the line from the url match */
     76 +		for (c = match; *c != '\0'; ++c)
     77 +			if (!strchr(URLCHARS, *c)) {
     78 +				*c = '\0';
     79 +				break;
     80 +			}
     81 +
     82 +		/* select and copy */
     83 +		sel.mode = 1;
     84 +		sel.type = SEL_REGULAR;
     85 +		sel.oe.x = sel.ob.x + strlen(match)-1;
     86 +		sel.ob.y = sel.oe.y = row;
     87 +		selnormalize();
     88 +		tsetdirt(sel.nb.y, sel.ne.y);
     89 +		selcopy(0);
     90 +	}
     91 +
     92 +	free(linestr);
     93 +}
     94 diff --git a/x.c b/x.c
     95 index 6474a01..c60cf94 100644
     96 --- a/x.c
     97 +++ b/x.c
     98 @@ -106,7 +106,7 @@ static void selnotify(XEvent *);
     99  static void selclear_(XEvent *);
    100  static void selrequest(XEvent *);
    101  
    102 -static void selcopy(Time);
    103 +void selcopy(Time);
    104  static void getbuttoninfo(XEvent *);
    105  static void mousereport(XEvent *);
    106