sites

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

st-copyurl-20190202-3be4cf1.diff (4677B)


      1 From f0d27279e47dac9bc413830cc116662dde91837c Mon Sep 17 00:00:00 2001
      2 From: Michael Buch <michaelbuch12@gmail.com>
      3 Date: Sat, 2 Feb 2019 14:10:31 +0000
      4 Subject: [PATCH] Highlight selected urls
      5 
      6 ---
      7  config.def.h |   1 +
      8  st.c         | 124 +++++++++++++++++++++++++++++++++++++++++++++++++++
      9  st.h         |   1 +
     10  3 files changed, 126 insertions(+)
     11 
     12 diff --git a/config.def.h b/config.def.h
     13 index 0e01717..3fb13ec 100644
     14 --- a/config.def.h
     15 +++ b/config.def.h
     16 @@ -178,6 +178,7 @@ static Shortcut shortcuts[] = {
     17  	{ TERMMOD,              XK_Y,           selpaste,       {.i =  0} },
     18  	{ ShiftMask,            XK_Insert,      selpaste,       {.i =  0} },
     19  	{ TERMMOD,              XK_Num_Lock,    numlock,        {.i =  0} },
     20 +	{ MODKEY,               XK_l,           copyurl,        {.i =  0} },
     21  };
     22  
     23  /*
     24 diff --git a/st.c b/st.c
     25 index b8e6077..6970e51 100644
     26 --- a/st.c
     27 +++ b/st.c
     28 @@ -200,6 +200,8 @@ static void tdefutf8(char);
     29  static int32_t tdefcolor(int *, int *, int);
     30  static void tdeftran(char);
     31  static void tstrsequence(uchar);
     32 +static void tsetcolor(int, int, int, uint32_t, uint32_t);
     33 +static char * findlastany(char *, const char**, size_t);
     34  
     35  static void drawregion(int, int, int, int);
     36  
     37 @@ -2602,3 +2604,125 @@ redraw(void)
     38  	tfulldirt();
     39  	draw();
     40  }
     41 +
     42 +void
     43 +tsetcolor( int row, int start, int end, uint32_t fg, uint32_t bg )
     44 +{
     45 +	int i = start;
     46 +	for( ; i < end; ++i )
     47 +	{
     48 +		term.line[row][i].fg = fg;
     49 +		term.line[row][i].bg = bg;
     50 +	}
     51 +}
     52 +
     53 +char *
     54 +findlastany(char *str, const char** find, size_t len)
     55 +{
     56 +	char* found = NULL;
     57 +	int i = 0;
     58 +	for(found = str + strlen(str) - 1; found >= str; --found) {
     59 +		for(i = 0; i < len; i++) {
     60 +			if(strncmp(found, find[i], strlen(find[i])) == 0) {
     61 +				return found;
     62 +			}
     63 +		}
     64 +	}
     65 +
     66 +	return NULL;
     67 +}
     68 +
     69 +/*
     70 +** Select and copy the previous url on screen (do nothing if there's no url).
     71 +**
     72 +** FIXME: doesn't handle urls that span multiple lines; will need to add support
     73 +**        for multiline "getsel()" first
     74 +*/
     75 +void
     76 +copyurl(const Arg *arg) {
     77 +	/* () and [] can appear in urls, but excluding them here will reduce false
     78 +	 * positives when figuring out where a given url ends.
     79 +	 */
     80 +	static char URLCHARS[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
     81 +		"abcdefghijklmnopqrstuvwxyz"
     82 +		"0123456789-._~:/?#@!$&'*+,;=%";
     83 +
     84 +	static const char* URLSTRINGS[] = {"http://", "https://"};
     85 +
     86 +	/* remove highlighting from previous selection if any */
     87 +	if(sel.ob.x >= 0 && sel.oe.x >= 0)
     88 +		tsetcolor(sel.nb.y, sel.ob.x, sel.oe.x + 1, defaultfg, defaultbg);
     89 +
     90 +	int i = 0,
     91 +		row = 0, /* row of current URL */
     92 +		col = 0, /* column of current URL start */
     93 +		startrow = 0, /* row of last occurrence */
     94 +		colend = 0, /* column of last occurrence */
     95 +		passes = 0; /* how many rows have been scanned */
     96 +
     97 +	char *linestr = calloc(sizeof(char), term.col+1); /* assume ascii */
     98 +	char *c = NULL,
     99 +		 *match = NULL;
    100 +
    101 +	row = (sel.ob.x >= 0 && sel.nb.y > 0) ? sel.nb.y : term.bot;
    102 +	LIMIT(row, term.top, term.bot);
    103 +	startrow = row;
    104 +
    105 +	colend = (sel.ob.x >= 0 && sel.nb.y > 0) ? sel.nb.x : term.col;
    106 +	LIMIT(colend, 0, term.col);
    107 +
    108 +	/*
    109 + 	** Scan from (term.bot,term.col) to (0,0) and find
    110 +	** next occurrance of a URL
    111 +	*/
    112 +	while(passes !=term.bot + 2) {
    113 +		/* Read in each column of every row until
    114 + 		** we hit previous occurrence of URL
    115 +		*/
    116 +		for (col = 0, i = 0; col < colend; ++col,++i) {
    117 +			/* assume ascii */
    118 +			if (term.line[row][col].u > 127)
    119 +				continue;
    120 +			linestr[i] = term.line[row][col].u;
    121 +		}
    122 +		linestr[term.col] = '\0';
    123 +
    124 +		if ((match = findlastany(linestr, URLSTRINGS,
    125 +						sizeof(URLSTRINGS)/sizeof(URLSTRINGS[0]))))
    126 +			break;
    127 +
    128 +		if (--row < term.top)
    129 +			row = term.bot;
    130 +
    131 +		colend = term.col;
    132 +		passes++;
    133 +	};
    134 +
    135 +	if (match) {
    136 +		/* must happen before trim */
    137 +		selclear();
    138 +		sel.ob.x = strlen(linestr) - strlen(match);
    139 +
    140 +		/* trim the rest of the line from the url match */
    141 +		for (c = match; *c != '\0'; ++c)
    142 +			if (!strchr(URLCHARS, *c)) {
    143 +				*c = '\0';
    144 +				break;
    145 +			}
    146 +
    147 +		/* highlight selection by inverting terminal colors */
    148 +		tsetcolor(row, sel.ob.x, sel.ob.x + strlen( match ), defaultbg, defaultfg);
    149 +
    150 +		/* select and copy */
    151 +		sel.mode = 1;
    152 +		sel.type = SEL_REGULAR;
    153 +		sel.oe.x = sel.ob.x + strlen(match)-1;
    154 +		sel.ob.y = sel.oe.y = row;
    155 +		selnormalize();
    156 +		tsetdirt(sel.nb.y, sel.ne.y);
    157 +		xsetsel(getsel());
    158 +		xclipcopy();
    159 +	}
    160 +
    161 +	free(linestr);
    162 +}
    163 diff --git a/st.h b/st.h
    164 index 38c61c4..67e7419 100644
    165 --- a/st.h
    166 +++ b/st.h
    167 @@ -84,6 +84,7 @@ void printscreen(const Arg *);
    168  void printsel(const Arg *);
    169  void sendbreak(const Arg *);
    170  void toggleprinter(const Arg *);
    171 +void copyurl(const Arg *);
    172  
    173  int tattrset(int);
    174  void tnew(int, int);
    175 -- 
    176 2.20.1
    177