示例#1
0
文件: g_rtext.c 项目: geeetarguy/pd
void rtext_key(t_rtext *x, int keynum, t_symbol *keysym)
{
    int w = 0, h = 0, indx, i, newsize, ndel;
    char *s1, *s2;
    //fprintf(stderr,"rtext_key keysym=%s\n", keysym->s_name);
    if (keynum)
    {
        int n = keynum;
        if (n == '\r') n = '\n';
        if (n == '\b')  /* backspace */
        {
                    /* LATER delete the box if all text is selected...
                    this causes reentrancy problems now. */
            /* if ((!x->x_selstart) && (x->x_selend == x->x_bufsize))
            {
                ....
            } */
            if (x->x_selstart && (x->x_selstart == x->x_selend))
            {
                u8_dec(x->x_buf, &x->x_selstart);
                if (glist_isvisible(glist_getcanvas(x->x_glist)))
                    sys_vgui("pdtk_canvas_getscroll .x%lx.c\n",
                        (t_int)glist_getcanvas(x->x_glist));
            }
            
        }
        else if (n == 127)      /* delete */
        {
            if (x->x_selend < x->x_bufsize && (x->x_selstart == x->x_selend))
                u8_inc(x->x_buf, &x->x_selend);
            if (glist_isvisible(glist_getcanvas(x->x_glist)))
                sys_vgui("pdtk_canvas_getscroll .x%lx.c\n",
                    (t_int)glist_getcanvas(x->x_glist));
        }
        
        ndel = x->x_selend - x->x_selstart;
        for (i = x->x_selend; i < x->x_bufsize; i++)
            x->x_buf[i- ndel] = x->x_buf[i];
        newsize = x->x_bufsize - ndel;
        x->x_buf = resizebytes(x->x_buf, x->x_bufsize, newsize);
        x->x_bufsize = newsize;

/* at Guenter's suggestion, use 'n>31' to test wither a character might
be printable in whatever 8-bit character set we find ourselves. */

/*-- moo:
  ... but test with "<" rather than "!=" in order to accomodate unicode
  codepoints for n (which we get since Tk is sending the "%A" substitution
  for bind <Key>), effectively reducing the coverage of this clause to 7
  bits.  Case n>127 is covered by the next clause.
*/
        if (n == '\n' || (n > 31 && n < 127))
        {
            //fprintf(stderr,"return or 31-127\n");
            newsize = x->x_bufsize+1;
            x->x_buf = resizebytes(x->x_buf, x->x_bufsize, newsize);
            for (i = x->x_bufsize; i > x->x_selstart; i--)
                x->x_buf[i] = x->x_buf[i-1];
            x->x_buf[x->x_selstart] = n;
            x->x_bufsize = newsize;
            x->x_selstart = x->x_selstart + 1;
            if (glist_isvisible(glist_getcanvas(x->x_glist)))
                sys_vgui("pdtk_canvas_getscroll .x%lx.c\n",
                    (t_int)glist_getcanvas(x->x_glist));
        }
        /*--moo: check for unicode codepoints beyond 7-bit ASCII --*/
        else if (n > 127)
        {
            //fprintf(stderr,">127\n");
            int ch_nbytes = u8_wc_nbytes(n);
            newsize = x->x_bufsize + ch_nbytes;
            x->x_buf = resizebytes(x->x_buf, x->x_bufsize, newsize);
            for (i = x->x_bufsize; i > x->x_selstart; i--)
                x->x_buf[i] = x->x_buf[i-1];
            x->x_bufsize = newsize;
            /*-- moo: assume canvas_key() has encoded keysym as UTF-8 */
            strncpy(x->x_buf+x->x_selstart, keysym->s_name, ch_nbytes);
            x->x_selstart = x->x_selstart + ch_nbytes;
        }
        x->x_selend = x->x_selstart;
        x->x_glist->gl_editor->e_textdirty = 1;
    }
    else if (!strcmp(keysym->s_name, "Right"))
    {
        if (x->x_selend == x->x_selstart && x->x_selstart < x->x_bufsize)
        {
            u8_inc(x->x_buf, &x->x_selstart);
            x->x_selend = x->x_selstart;
        }
        else
            x->x_selstart = x->x_selend;
        last_sel = 0;        
    }
    else if (!strcmp(keysym->s_name, "Left"))
    {
        if (x->x_selend == x->x_selstart && x->x_selstart > 0)
        {
            u8_dec(x->x_buf, &x->x_selstart);
            x->x_selend = x->x_selstart;
        }
        else
            x->x_selend = x->x_selstart;
        last_sel = 0;
    }
    else if (!strcmp(keysym->s_name, "ShiftRight"))
    {
        if (!last_sel) last_sel = 2;
        if (last_sel == 1 && x->x_selstart < x->x_selend)
        {
            if (x->x_selstart < x->x_bufsize)
                u8_inc(x->x_buf, &x->x_selstart);        
        }
        else
        {
            last_sel = 2;
            if (x->x_selend < x->x_bufsize)
                u8_inc(x->x_buf, &x->x_selend);
        }
    }
    else if (!strcmp(keysym->s_name, "ShiftLeft"))
    {
        if (!last_sel) last_sel = 1;
        if (last_sel == 2 && x->x_selend > x->x_selstart)
        {
            x->x_selend = x->x_selend - 1;
        }
        else
        {
            last_sel = 1;
            if (x->x_selstart > 0)
                u8_dec(x->x_buf, &x->x_selstart);
        }
    }
    else if (!strcmp(keysym->s_name, "Up"))
    {
        if (x->x_selstart)
            u8_dec(x->x_buf, &x->x_selstart);
        while (x->x_selstart > 0 &&
            (x->x_buf[x->x_selstart] != '\n' &&
                x->x_buf[x->x_selstart] != '\v'))
            u8_dec(x->x_buf, &x->x_selstart);
        x->x_selend = x->x_selstart;
        last_sel = 0;
    }
    else if (!strcmp(keysym->s_name, "Down"))
    {
        while (x->x_selend < x->x_bufsize &&
            (x->x_buf[x->x_selend] != '\n' && x->x_buf[x->x_selend] != '\v'))
            u8_inc(x->x_buf, &x->x_selend);
        if (x->x_selend < x->x_bufsize)
            u8_inc(x->x_buf, &x->x_selend);
        x->x_selstart = x->x_selend;
        last_sel = 0;
    }
    else if (!strcmp(keysym->s_name, "Home"))
    {
        if (x->x_selstart)
            u8_dec(x->x_buf, &x->x_selstart);
        while (x->x_selstart > 0 && x->x_buf[x->x_selstart] != '\n')
            u8_dec(x->x_buf, &x->x_selstart);
        x->x_selend = x->x_selstart;
        last_sel = 0;
    }
    else if (!strcmp(keysym->s_name, "End"))
    {
        while (x->x_selend < x->x_bufsize &&
            x->x_buf[x->x_selend] != '\n')
            u8_inc(x->x_buf, &x->x_selend);
        if (x->x_selend < x->x_bufsize)
            u8_inc(x->x_buf, &x->x_selend);
        x->x_selstart = x->x_selend;
        last_sel = 0;
    }
    else if (!strcmp(keysym->s_name, "CtrlLeft"))
    {
        //fprintf(stderr,"ctrleft\n");
        /* first find first non-space char going back */
        while (x->x_selstart > 0 &&
            rtext_compare_special_chars(x->x_buf[x->x_selstart-1]))
        {
            //fprintf(stderr,"while 1 <%c>\n", x->x_buf[x->x_selstart-1]);
            u8_dec(x->x_buf, &x->x_selstart);
        }
        /* now go back until you find another space or
           the beginning of the buffer */
        while (x->x_selstart > 0 &&
          !rtext_compare_special_chars(x->x_buf[x->x_selstart-1]))
        {
            //fprintf(stderr,"while 2 <%c>\n", x->x_buf[x->x_selstart-1]);
            u8_dec(x->x_buf, &x->x_selstart);
        }
        if (x->x_buf[x->x_selstart+1] == ' ' &&
            x->x_buf[x->x_selstart] == ' ')
        {
            //fprintf(stderr,"go forward\n");
            u8_inc(x->x_buf, &x->x_selstart);
        }
        x->x_selend = x->x_selstart;
    }
    else if (!strcmp(keysym->s_name, "CtrlRight"))
    {
        /* now go forward until you find another space
           or the end of the buffer */
        if (x->x_selend < x->x_bufsize - 1)
            u8_inc(x->x_buf, &x->x_selend);
        while (x->x_selend < x->x_bufsize &&
          !rtext_compare_special_chars(x->x_buf[x->x_selend]))
            u8_inc(x->x_buf, &x->x_selend);
        /* now skip all the spaces and land before next word */
        /*while (x->x_selend < x->x_bufsize &&
          x->x_buf[x->x_selend] == ' ')
            u8_inc(x->x_buf, &x->x_selend);
        if (x->x_selend > 0 && x->x_buf[x->x_selend-1] == ' ')
            u8_dec(x->x_buf, &x->x_selend);*/
        x->x_selstart = x->x_selend;
    }
    else if (!strcmp(keysym->s_name, "CtrlShiftLeft"))
    {
        //fprintf(stderr,"ctrlshiftleft %d %d %d\n",
        //    last_sel, x->x_selstart, x->x_selend);
        int swap = 0;
        int *target;
        if (!last_sel) last_sel = 1;
        if (last_sel == 2 && x->x_selend > x->x_selstart)
            target = &x->x_selend;
        else
        {
            last_sel = 1;
            target = &x->x_selstart;
        }
        /* first find first non-space char going back */
        while (*target > 0 &&
            rtext_compare_special_chars(x->x_buf[*target-1]))
        {
            u8_dec(x->x_buf, target);
            //(*target)--;
        }
        //fprintf(stderr,"%d %d\n", x->x_selstart, x->x_selend);
        /* now go back until you find another space or
           the beginning of the buffer */
        while (*target > 0 &&
            !rtext_compare_special_chars(x->x_buf[*target-1]))
        {
            u8_dec(x->x_buf, target);
            //(*target)--;
        }
        //fprintf(stderr,"%d %d\n", x->x_selstart, x->x_selend);
        if (x->x_buf[*target+1] == ' ' &&
            x->x_buf[x->x_selstart] == ' ')
        {
            u8_inc(x->x_buf, target);
            //(*target)++;
        }
        //fprintf(stderr,"%d %d\n", x->x_selstart, x->x_selend);
        if (x->x_selstart > x->x_selend)
        {
            swap = x->x_selend;
            x->x_selend = x->x_selstart;
            x->x_selstart = swap;
            last_sel = 1;
        }
    }
    else if (!strcmp(keysym->s_name, "CtrlShiftRight"))
    {
        //fprintf(stderr,"ctrlshiftright %d %d %d\n",
        //    last_sel, x->x_selstart, x->x_selend);
        int swap = 0;
        int *target;
        if (!last_sel) last_sel = 2;
        if (last_sel == 1 && x->x_selstart < x->x_selend)
            target = &x->x_selstart;
        else
        {
            last_sel = 2;
            target = &x->x_selend;
        }
        //fprintf(stderr,"%d %d\n", x->x_selstart, x->x_selend);
        /* now go forward until you find another space or
           the end of the buffer */
        if (*target < x->x_bufsize - 1)
        {
            //fprintf(stderr,"while 1 <%c>\n", x->x_buf[*target]);
            u8_inc(x->x_buf, target);
            //(*target)++;
        }
        //fprintf(stderr,"%d %d\n", x->x_selstart, x->x_selend);
        while (*target < x->x_bufsize &&
            !rtext_compare_special_chars(x->x_buf[*target]))
        {
            //fprintf(stderr,"while 2 <%c>\n", x->x_buf[*target]);
            u8_inc(x->x_buf, target);
            //(*target)++;
        }
        /* now skip all the spaces and land before next word */

        /*while (*target < x->x_bufsize &&
            x->x_buf[*target] == ' ')
        {
            u8_inc(x->x_buf, target);
            //(*target)++;
        }
        if (*target > 0 && x->x_buf[*target-1] == ' ')
        {
            u8_dec(x->x_buf, target);
            //(*target)--;
        }*/

        //fprintf(stderr,"%d %d\n", x->x_selstart, x->x_selend);
        if (x->x_selstart > x->x_selend)
        {
            swap = x->x_selend;
            x->x_selend = x->x_selstart;
            x->x_selstart = swap;
            last_sel = 2;
        }
        //fprintf(stderr,"%d %d\n", x->x_selstart, x->x_selend);
    }

    rtext_senditup(x, SEND_UPDATE, &w, &h, &indx);
}
示例#2
0
文件: g_rtext.c 项目: cviejo/mPD
void rtext_key(t_rtext *x, int keynum, t_symbol *keysym)
{
    //fprintf(stderr,"rtext_key %d %s\n", keynum, keysym->s_name);
    int w = 0, h = 0, indx, i, newsize, ndel;
    if (keynum)
    {
        int n = keynum;
        if (n == '\r' || n == '\v') n = '\n';
        if (n == '\b') /* backspace */
        {
            if (x->x_selstart && (x->x_selstart == x->x_selend))
            {
                u8_dec(x->x_buf, &x->x_selstart);
                if (glist_isvisible(glist_getcanvas(x->x_glist)))
                    canvas_getscroll(glist_getcanvas(x->x_glist));
            }
            
        }
        else if (n == 127) /* delete */
        {
            if (x->x_selend < x->x_bufsize && (x->x_selstart == x->x_selend))
                u8_inc(x->x_buf, &x->x_selend);
            if (glist_isvisible(glist_getcanvas(x->x_glist)))
                canvas_getscroll(glist_getcanvas(x->x_glist));
        }
        
        ndel = x->x_selend - x->x_selstart;
        if (ndel)
        {
            for (i = x->x_selend; i < x->x_bufsize; i++)
                x->x_buf[i- ndel] = x->x_buf[i];
            newsize = x->x_bufsize - ndel;
            x->x_buf = resizebytes(x->x_buf, x->x_bufsize, newsize);
            x->x_bufsize = newsize;
        }

/* at Guenter's suggestion, use 'n>31' to test wither a character might
be printable in whatever 8-bit character set we find ourselves. */

/*-- moo:
  ... but test with "<" rather than "!=" in order to accomodate unicode
  codepoints for n (which we get since Tk is sending the "%A" substitution
  for bind <Key>), effectively reducing the coverage of this clause to 7
  bits.  Case n>127 is covered by the next clause.
*/
        if (n == '\n' || (n > 31 && n < 127))
        {
            newsize = x->x_bufsize+1;
            x->x_buf = resizebytes(x->x_buf, x->x_bufsize, newsize);
            for (i = x->x_bufsize; i > x->x_selstart; i--)
                x->x_buf[i] = x->x_buf[i-1];
            x->x_buf[x->x_selstart] = n;
            x->x_bufsize = newsize;
            x->x_selstart = x->x_selstart + 1;
            if (glist_isvisible(glist_getcanvas(x->x_glist)))
                canvas_getscroll(glist_getcanvas(x->x_glist));
        }
        /*--moo: check for unicode codepoints beyond 7-bit ASCII --*/
        else if (n > 127)
        {
            int ch_nbytes = u8_wc_nbytes(n);
            newsize = x->x_bufsize + ch_nbytes;
            x->x_buf = resizebytes(x->x_buf, x->x_bufsize, newsize);
            //fprintf(stderr,"x->x_bufsize=%d newsize=%d\n", x->x_bufsize, newsize);
            //for (i = newsize-1; i >= x->x_selstart; i--)
            //{
                //fprintf(stderr,"%d-%d <%d>\n", i, i-ch_nbytes, x->x_buf[i-ch_nbytes]);
                //x->x_buf[i] = '\0';
            //}
            x->x_bufsize = newsize;
            /*-- moo: assume canvas_key() has encoded keysym as UTF-8 */
            strncpy(x->x_buf+x->x_selstart, keysym->s_name, ch_nbytes);
            x->x_selstart = x->x_selstart + ch_nbytes;
        }
        x->x_selend = x->x_selstart;
        x->x_glist->gl_editor->e_textdirty = 1;
    }
    else if (!strcmp(keysym->s_name, "Right"))
    {
        if (x->x_selend == x->x_selstart && x->x_selstart < x->x_bufsize)
        {
            u8_inc(x->x_buf, &x->x_selstart);
            x->x_selend = x->x_selstart;
        }
        else
            x->x_selstart = x->x_selend;
        last_sel = 0;        
    }
    else if (!strcmp(keysym->s_name, "Left"))
    {
        if (x->x_selend == x->x_selstart && x->x_selstart > 0)
        {
            u8_dec(x->x_buf, &x->x_selstart);
            x->x_selend = x->x_selstart;
        }
        else
            x->x_selend = x->x_selstart;
        last_sel = 0;
    }
    else if (!strcmp(keysym->s_name, "ShiftRight"))
    {
        if (!last_sel) last_sel = 2;
        if (last_sel == 1 && x->x_selstart < x->x_selend)
        {
            if (x->x_selstart < x->x_bufsize)
                u8_inc(x->x_buf, &x->x_selstart);        
        }
        else
        {
            last_sel = 2;
            if (x->x_selend < x->x_bufsize)
                u8_inc(x->x_buf, &x->x_selend);
        }
    }
    else if (!strcmp(keysym->s_name, "ShiftLeft"))
    {
        if (!last_sel) last_sel = 1;
        if (last_sel == 2 && x->x_selend > x->x_selstart)
        {
            x->x_selend = x->x_selend - 1;
        }
        else
        {
            last_sel = 1;
            if (x->x_selstart > 0)
                u8_dec(x->x_buf, &x->x_selstart);
        }
    }
    else if (!strcmp(keysym->s_name, "Up"))
    {
        if (x->x_selstart != x->x_selend)
        {
            x->x_selend = x->x_selstart;
            last_sel = 0;
        }
        else
        {
            // we do this twice and then move to the right
            // as many spots as we had before, this will
            // allow us to go visually above where we used
            // to be in multiline situations (e.g. comments)
            int right = 0;
            //printf("start: selstart=%d x->x_bufsize=%d\n", x->x_selstart, x->x_bufsize);
            if (x->x_selstart > 0 &&
                   (x->x_selstart == x->x_bufsize ||
                    x->x_buf[x->x_selstart] == '\n' ||
                    x->x_buf[x->x_selstart] == '\v'))
            {
                //printf("found break\n");
                u8_dec(x->x_buf, &x->x_selstart);
                right++;
            }
            while (x->x_selstart > 0 &&
                    (x->x_buf[x->x_selstart-1] != '\n' &&
                        x->x_buf[x->x_selstart-1] != '\v'))
            {
                u8_dec(x->x_buf, &x->x_selstart);
                right++;
            }
            if (x->x_selstart == 0)
                right = 0;
            //printf("first linebreak: right=%d selstart=%d\n", right, x->x_selstart);
            if (x->x_selstart > 0)
                u8_dec(x->x_buf, &x->x_selstart);
            //printf("decrease by 1: selstart=%d\n", x->x_selstart);
            while (x->x_selstart > 0 &&
                (x->x_buf[x->x_selstart-1] != '\n' &&
                    x->x_buf[x->x_selstart-1] != '\v'))
                u8_dec(x->x_buf, &x->x_selstart);
            //printf("second linebreak: selstart=%d\n", x->x_selstart);
            if (x->x_selstart < x->x_bufsize && right > 0)
            {
                u8_inc(x->x_buf, &x->x_selstart);
                right--;
            }
            //printf("increase by 1: selstart=%d\n", x->x_selstart);
            while (right > 0 && 
                (x->x_buf[x->x_selstart] != '\n' &&
                    x->x_buf[x->x_selstart] != '\v'))
            {
                u8_inc(x->x_buf, &x->x_selstart);
                right--;
            }
            //printf("final: selstart=%d\n", x->x_selstart);
            x->x_selend = x->x_selstart;
            last_sel = 0;
        }
    }
    else if (!strcmp(keysym->s_name, "Down"))
    {
        if (x->x_selstart != x->x_selend)
        {
            x->x_selstart = x->x_selend;
            last_sel = 0;
        }
        else
        {
            // we do this twice and then move to the right
            // as many spots as we had before, this will
            // allow us to go visually below where we used
            // to be in multiline situations (e.g. comments)
            int right = 0;
            if (x->x_selstart > 0 &&
                    (x->x_buf[x->x_selstart] != '\n' ||
                        x->x_buf[x->x_selstart] != '\v'))
            {
                while (x->x_selstart > 0 &&
                        (x->x_buf[x->x_selstart-1] != '\n' &&
                            x->x_buf[x->x_selstart-1] != '\v'))
                {
                    x->x_selstart--;
                    right++;
                }
            }
            //printf("start: right=%d selstart=%d selend=%d\n", right, x->x_selstart, x->x_selend);
            if (x->x_selend < x->x_bufsize &&
                    (x->x_buf[x->x_selend] == '\n' ||
                        x->x_buf[x->x_selend] == '\v'))
            {
                //printf("found break\n");
                u8_inc(x->x_buf, &x->x_selend);
                right--;
            }
            else while (x->x_selend < x->x_bufsize &&
                (x->x_buf[x->x_selend] != '\n' && x->x_buf[x->x_selend] != '\v'))
            {
                u8_inc(x->x_buf, &x->x_selend);
            }
            //printf("first linebreak: selend=%d\n", x->x_selend);
            if (x->x_selend+1 < x->x_bufsize)
            {
                u8_inc(x->x_buf, &x->x_selend);
            }
            //printf("increase by 1: selend=%d\n", x->x_selend);
            while (right > 0 && x->x_selend < x->x_bufsize &&
                (x->x_buf[x->x_selend] != '\n' &&
                    x->x_buf[x->x_selend] != '\v'))
            {
                u8_inc(x->x_buf, &x->x_selend);
                right--;
            }
            //printf("final: selend=%d\n", x->x_selend);
            x->x_selstart = x->x_selend;
            last_sel = 0;
        }
    }
    else if (!strcmp(keysym->s_name, "Home"))
    {
        if (x->x_selstart)
            u8_dec(x->x_buf, &x->x_selstart);
        while (x->x_selstart > 0 && x->x_buf[x->x_selstart] != '\n')
            u8_dec(x->x_buf, &x->x_selstart);
        x->x_selend = x->x_selstart;
        last_sel = 0;
    }
    else if (!strcmp(keysym->s_name, "ShiftHome"))
    {
        if (x->x_selstart)
        {
            if (last_sel == 2)
                x->x_selend = x->x_selstart;
            u8_dec(x->x_buf, &x->x_selstart);
            last_sel = 1;
        }
        while (x->x_selstart > 0 && x->x_buf[x->x_selstart] != '\n')
            u8_dec(x->x_buf, &x->x_selstart);
        //x->x_selend = x->x_selstart;
        //last_sel = 1;
    }
    else if (!strcmp(keysym->s_name, "End"))
    {
        while (x->x_selend < x->x_bufsize &&
            x->x_buf[x->x_selend] != '\n')
            u8_inc(x->x_buf, &x->x_selend);
        if (x->x_selend < x->x_bufsize)
            u8_inc(x->x_buf, &x->x_selend);
        x->x_selstart = x->x_selend;
        last_sel = 0;
    }
    else if (!strcmp(keysym->s_name, "ShiftEnd"))
    {
        if (last_sel == 1)
            x->x_selstart = x->x_selend;
        while (x->x_selend < x->x_bufsize &&
            x->x_buf[x->x_selend] != '\n')
            u8_inc(x->x_buf, &x->x_selend);
        if (x->x_selend < x->x_bufsize)
        {
            u8_inc(x->x_buf, &x->x_selend);
        }
        //x->x_selstart = x->x_selend;
        last_sel = 2;
    }
    else if (!strcmp(keysym->s_name, "CtrlLeft"))
    {
        /* first find first non-space char going back */
        while (x->x_selstart > 0 &&
            rtext_compare_special_chars(x->x_buf[x->x_selstart-1]))
        {
            u8_dec(x->x_buf, &x->x_selstart);
        }
        /* now go back until you find another space or
           the beginning of the buffer */
        while (x->x_selstart > 0 &&
          !rtext_compare_special_chars(x->x_buf[x->x_selstart-1]))
        {
            u8_dec(x->x_buf, &x->x_selstart);
        }
        if (x->x_buf[x->x_selstart+1] == ' ' &&
            x->x_buf[x->x_selstart] == ' ')
        {
            u8_inc(x->x_buf, &x->x_selstart);
        }
        x->x_selend = x->x_selstart;
    }
    else if (!strcmp(keysym->s_name, "CtrlRight"))
    {
        /* now go forward until you find another space
           or the end of the buffer */
        if (x->x_selend < x->x_bufsize - 1)
            u8_inc(x->x_buf, &x->x_selend);
        while (x->x_selend < x->x_bufsize &&
          !rtext_compare_special_chars(x->x_buf[x->x_selend]))
            u8_inc(x->x_buf, &x->x_selend);
        x->x_selstart = x->x_selend;
    }
    else if (!strcmp(keysym->s_name, "CtrlShiftLeft"))
    {
        int swap = 0;
        int *target;
        if (!last_sel) last_sel = 1;
        if (last_sel == 2 && x->x_selend > x->x_selstart)
            target = &x->x_selend;
        else
        {
            last_sel = 1;
            target = &x->x_selstart;
        }
        /* first find first non-space char going back */
        while (*target > 0 &&
            rtext_compare_special_chars(x->x_buf[*target-1]))
        {
            u8_dec(x->x_buf, target);
        }
        /* now go back until you find another space or
           the beginning of the buffer */
        while (*target > 0 &&
            !rtext_compare_special_chars(x->x_buf[*target-1]))
        {
            u8_dec(x->x_buf, target);
        }
        if (x->x_buf[*target+1] == ' ' &&
            x->x_buf[x->x_selstart] == ' ')
        {
            u8_inc(x->x_buf, target);
        }
        if (x->x_selstart > x->x_selend)
        {
            swap = x->x_selend;
            x->x_selend = x->x_selstart;
            x->x_selstart = swap;
            last_sel = 1;
        }
    }
    else if (!strcmp(keysym->s_name, "CtrlShiftRight"))
    {
        int swap = 0;
        int *target;
        if (!last_sel) last_sel = 2;
        if (last_sel == 1 && x->x_selstart < x->x_selend)
            target = &x->x_selstart;
        else
        {
            last_sel = 2;
            target = &x->x_selend;
        }
        /* now go forward until you find another space or
           the end of the buffer */
        if (*target < x->x_bufsize - 1)
        {
            u8_inc(x->x_buf, target);
        }
        while (*target < x->x_bufsize &&
            !rtext_compare_special_chars(x->x_buf[*target]))
        {
            u8_inc(x->x_buf, target);
        }
        if (x->x_selstart > x->x_selend)
        {
            swap = x->x_selend;
            x->x_selend = x->x_selstart;
            x->x_selstart = swap;
            last_sel = 2;
        }
    }
    rtext_senditup(x, SEND_UPDATE, &w, &h, &indx);
}