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