sites

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

st-copyurl-20230406-211964d.diff (4255B)


      1 From 8b07fb9ab581eb31714f0dd25a419926a7f34cc6 Mon Sep 17 00:00:00 2001
      2 From: Gildasio Junior <gildasiojunior@riseup.net>
      3 Date: Thu, 6 Apr 2023 14:54:23 -0300
      4 Subject: [PATCH] Loop through urls on screen in both directions
      5 
      6 Using previous patches one can loop through urls in the screen in one
      7 direction: botton-up. This patch add a way that can go in the opposite
      8 direction: top-down.
      9 
     10 This is usefull in a screen with lots of urls.
     11 ---
     12  config.def.h |  2 ++
     13  st.c         | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++
     14  st.h         |  1 +
     15  3 files changed, 93 insertions(+)
     16 
     17 diff --git a/config.def.h b/config.def.h
     18 index 91ab8ca..4df78eb 100644
     19 --- a/config.def.h
     20 +++ b/config.def.h
     21 @@ -201,6 +201,8 @@ static Shortcut shortcuts[] = {
     22  	{ TERMMOD,              XK_Y,           selpaste,       {.i =  0} },
     23  	{ ShiftMask,            XK_Insert,      selpaste,       {.i =  0} },
     24  	{ TERMMOD,              XK_Num_Lock,    numlock,        {.i =  0} },
     25 +	{ MODKEY,               XK_l,           copyurl,        {.i =  0} },
     26 +	{ MODKEY|ShiftMask,     XK_L,           copyurl,        {.i =  1} },
     27  };
     28  
     29  /*
     30 diff --git a/st.c b/st.c
     31 index 134e724..1b321ab 100644
     32 --- a/st.c
     33 +++ b/st.c
     34 @@ -201,6 +201,7 @@ static void tdefutf8(char);
     35  static int32_t tdefcolor(const int *, int *, int);
     36  static void tdeftran(char);
     37  static void tstrsequence(uchar);
     38 +static const char *findlastany(const char *, const char**, size_t);
     39  
     40  static void drawregion(int, int, int, int);
     41  
     42 @@ -2666,3 +2667,92 @@ redraw(void)
     43  	tfulldirt();
     44  	draw();
     45  }
     46 +
     47 +const char *
     48 +findlastany(const char *str, const char**find, size_t len)
     49 +{
     50 +	const char *found = NULL;
     51 +	int i = 0;
     52 +
     53 +	for (found = str + strlen(str) - 1; found >= str; --found) {
     54 +		for(i = 0; i < len; i++) {
     55 +			if (strncmp(found, find[i], strlen(find[i])) == 0) {
     56 +				return found;
     57 +			}
     58 +		}
     59 +	}
     60 +
     61 +	return NULL;
     62 +}
     63 +
     64 +/*
     65 +** Select and copy the previous url on screen (do nothing if there's no url).
     66 +**
     67 +** FIXME: doesn't handle urls that span multiple lines; will need to add support
     68 +**        for multiline "getsel()" first
     69 +*/
     70 +void
     71 +copyurl(const Arg *arg) {
     72 +	/* () and [] can appear in urls, but excluding them here will reduce false
     73 +	 * positives when figuring out where a given url ends.
     74 +	 */
     75 +	static const char URLCHARS[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
     76 +		"abcdefghijklmnopqrstuvwxyz"
     77 +		"0123456789-._~:/?#@!$&'*+,;=%";
     78 +
     79 +	static const char* URLSTRINGS[] = {"http://", "https://"};
     80 +
     81 +	int row = 0, /* row of current URL */
     82 +		col = 0, /* column of current URL start */
     83 +		colend = 0, /* column of last occurrence */
     84 +		passes = 0; /* how many rows have been scanned */
     85 +
     86 +	char linestr[term.col + 1];
     87 +	const char *c = NULL,
     88 +		 *match = NULL;
     89 +
     90 +	row = (sel.ob.x >= 0 && sel.nb.y > 0) ? sel.nb.y : term.bot;
     91 +	LIMIT(row, term.top, term.bot);
     92 +
     93 +	colend = (sel.ob.x >= 0 && sel.nb.y > 0) ? sel.nb.x : term.col;
     94 +	LIMIT(colend, 0, term.col);
     95 +
     96 +	/*
     97 +	** Scan from (term.row - 1,term.col - 1) to (0,0) and find
     98 +	** next occurrance of a URL
     99 +	*/
    100 +	for (passes = 0; passes < term.row; passes++) {
    101 +		/* Read in each column of every row until
    102 +		** we hit previous occurrence of URL
    103 +		*/
    104 +		for (col = 0; col < colend; ++col)
    105 +			linestr[col] = term.line[row][col].u < 128 ? term.line[row][col].u : ' ';
    106 +		linestr[col] = '\0';
    107 +
    108 +		if ((match = findlastany(linestr, URLSTRINGS,
    109 +						sizeof(URLSTRINGS)/sizeof(URLSTRINGS[0]))))
    110 +			break;
    111 +
    112 +        /* .i = 0 --> botton-up
    113 +         * .i = 1 --> top-down
    114 +         * */
    115 +        if (!arg->i) {
    116 +            if (--row < 0)
    117 +                row = term.row - 1;
    118 +        } else {
    119 +            if (++row >= term.row)
    120 +                row = 0;
    121 +        }
    122 +
    123 +		colend = term.col;
    124 +	};
    125 +
    126 +	if (match) {
    127 +		size_t l = strspn(match, URLCHARS);
    128 +		selstart(match - linestr, row, 0);
    129 +		selextend(match - linestr + l - 1, row, SEL_REGULAR, 0);
    130 +		selextend(match - linestr + l - 1, row, SEL_REGULAR, 1);
    131 +		xsetsel(getsel());
    132 +		xclipcopy();
    133 +	}
    134 +}
    135 diff --git a/st.h b/st.h
    136 index fd3b0d8..baa8f29 100644
    137 --- a/st.h
    138 +++ b/st.h
    139 @@ -85,6 +85,7 @@ void printscreen(const Arg *);
    140  void printsel(const Arg *);
    141  void sendbreak(const Arg *);
    142  void toggleprinter(const Arg *);
    143 +void copyurl(const Arg *);
    144  
    145  int tattrset(int);
    146  void tnew(int, int);
    147 -- 
    148 2.40.0
    149