st-copyurl-20230406-211964d.diff - sites - public wiki contents of suckless.org
 (HTM) git clone git://git.suckless.org/sites
 (DIR) Log
 (DIR) Files
 (DIR) 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