Add keyboard shortcuts for snarf, cut, paste, and exchange. - sam - An updated version of the sam text editor.
 (HTM) git clone git://vernunftzentrum.de/sam.git
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) LICENSE
       ---
 (DIR) commit 5ec62bf406a1c2aaffb1d54315c91b5ef871447d
 (DIR) parent 69987ee5a8f00c4bdaf7bec8daab8fa5b2152d6d
 (HTM) Author: Rob King <jking@deadpixi.com>
       Date:   Fri, 12 Aug 2016 15:11:44 -0500
       
       Add keyboard shortcuts for snarf, cut, paste, and exchange.
       
       Diffstat:
         commands.h.def                      |      25 +++++++++++++++++--------
         include/commands.h                  |       1 +
         libXg/gwin.c                        |      30 ++++--------------------------
         samterm/io.c                        |       6 ++++++
         samterm/main.c                      |      86 ++++++++++++++++++++++++++++---
         samterm/samterm.h                   |       1 +
       
       6 files changed, 107 insertions(+), 42 deletions(-)
       ---
 (DIR) diff --git a/commands.h.def b/commands.h.def
       @@ -3,7 +3,9 @@
         *
         *    {mask, keysym, kind, action}
         *
       - * mask   - one of the X modifier masks, or the user-configured COMMANDMASK
       + * mask   - one of the X modifier masks
       + *          or the user-defined COMMANDMASK (see config.h)
       + *          or 0, for no modifier
         * keysym - one of the X symbolic keysym names
         * kind   - Kcommand for commands
         *          Kraw for literal characters
       @@ -23,6 +25,10 @@
         * Cdel         - delete previous character
         * Cjump        - jump to and from the command window
         * Cescape      - highlight recently typed text
       + * Csnarf       - copy text to the snarf buffer
       + * Cpaste       - paste text from the snarf buffer
       + * Ccut         - cut text to the snarf buffer
       + * Cexchange    - exchange operating system and sam snarf buffers
         *
         * The default configuration shipped with sam has the keyboard commands mapped
         * to the "classic" Unix sam of the 1980s, plus the WordStar Diamond for cursor
       @@ -40,6 +46,9 @@
        {COMMANDMASK, XK_w,             Kcommand,  Cdelword},
        {COMMANDMASK, XK_k,             Kcommand,  Cjump},
        {COMMANDMASK, XK_BackSpace,     Kcommand,  Cdelword},
       +{COMMANDMASK, XK_c,             Kcommand,  Csnarf},
       +{COMMANDMASK, XK_v,             Kcommand,  Cpaste},
       +{COMMANDMASK, XK_q,             Kcommand,  Cexchange},
        
        /* Use COMMAND-Tab to insert a literal tab when tab expansion is enabled. */
        {COMMANDMASK, XK_Tab,           Kcomposed, '\t'},
       @@ -52,7 +61,13 @@
        {COMMANDMASK, XK_space,         Kcommand, Cescape},
        {0,           XK_Escape,        Kcommand, Cjump}, */
        
       -/* Less commonly changed commands. See below for a common change. */
       +/* Some users might like to make the arrow keys move the selection more logically.
       +{0,           XK_Up,            Kcommand, Cscrollup},
       +{0,           XK_Down,          Kcommand, Cscrolldown},
       +{0,           XK_Left,          Kcommand, Ccharleft},
       +{0,           XK_Right,         Kcommand, Ccharright}, */
       +
       +/* Less commonly changed commands (though see above about the arrow keys). */
        {0,           XK_Up,            Kcommand, Cscrollup},
        {0,           XK_Prior,         Kcommand, Cscrollup},
        {0,           XK_Left,          Kcommand, Cscrollup},
       @@ -61,12 +76,6 @@
        {0,           XK_Right,         Kcommand, Cscrolldown},
        {0,           XK_Escape,        Kcommand, Cescape},
        
       -/* Some users might like to make the arrow keys move the selection more logically.
       -{0,           XK_Up,            Kcommand, Cscrollup},
       -{0,           XK_Down,          Kcommand, Cscrolldown},
       -{0,           XK_Left,          Kcommand, Ccharleft},
       -{0,           XK_Right,         Kcommand, Ccharright}, */
       -
        /* You probably shouldn't change these. */
        {0,           XK_BackSpace,     Kcommand, Cdel},
        {0,           XK_Delete,        Kcommand, Cdel},
 (DIR) diff --git a/include/commands.h b/include/commands.h
       @@ -25,6 +25,7 @@ enum{
            Csnarf,
            Ccut,
            Cpaste,
       +    Cexchange,
            Cmax
        }; /* virtual command keystrokes */
        
 (DIR) diff --git a/libXg/gwin.c b/libXg/gwin.c
       @@ -392,23 +392,7 @@ SendSel(Widget w, Atom *sel, Atom *target, Atom *rtype, XtPointer *ans,
                        *ansfmt = 8;
                        return TRUE;
                }
       -#ifndef R3
       -        if(targets == 0){
       -                src.addr = "TARGETS";
       -                src.size = strlen(src.addr)+1;
       -                dst.size = sizeof(Atom);
       -                dst.addr = (XtPointer) &targets;
       -                XtConvertAndStore(w, XtRString, &src, XtRAtom, &dst);
       -        }
       -        if(*target == targets){
       -                *rtype = XA_ATOM;
       -                *ans = (XtPointer) XtNew(Atom);
       -                *(Atom*) *ans = XA_STRING;
       -                *anslen = 1;
       -                *ansfmt = 32;
       -                return TRUE;
       -        }
       -#endif
       +
                return FALSE;
        }
        
       @@ -423,24 +407,18 @@ SelectSwap(Widget w, String s)
                        XtFree(gw->gwin.selection);
                        gw->gwin.selection = 0;
                }
       -#ifdef R3
       -        XtGetSelectionValue(w, XA_PRIMARY, XA_STRING, SelCallback, 0,
       -                        CurrentTime);
       -#else
                XtGetSelectionValue(w, XA_PRIMARY, XA_STRING, SelCallback, 0,
                                XtLastTimestampProcessed(XtDisplay(w)));
       -#endif
       +
                while(gw->gwin.selection == 0)
                        XtAppProcessEvent(XtWidgetToApplicationContext(w) , XtIMAll);
                ans = gw->gwin.selection;
                gw->gwin.selection = XtMalloc(strlen(s)+1);
                strcpy(gw->gwin.selection, s);
       -#ifdef R3
       -        XtOwnSelection(w, XA_PRIMARY, CurrentTime, SendSel, NULL, NULL);
       -#else
       +
                XtOwnSelection(w, XA_PRIMARY, XtLastTimestampProcessed(XtDisplay(w)),
                                SendSel, NULL, NULL);
       -#endif
       +
                return ans;
        }
        
 (DIR) diff --git a/samterm/io.c b/samterm/io.c
       @@ -146,6 +146,12 @@ externchar(void)
        }
        
        Keystroke
       +qpeekc(void)
       +{
       +    return keystroke;
       +}
       +
       +Keystroke
        kbdchar(void)
        {
            Keystroke k = {0};
 (DIR) diff --git a/samterm/main.c b/samterm/main.c
       @@ -676,6 +676,66 @@ cmddel(Flayer *l, long a, Text *t)
            return a;
        }
        
       +static inline int
       +getlayer(const Flayer *l, const Text *t)
       +{
       +    int i;
       +    for (i = 0; i < NL; i++)
       +        if (&t->l[i] == l)
       +            return i;
       +
       +    return -1;
       +}
       +
       +static long
       +cmdexchange(Flayer *l, long a, Text *t)
       +{
       +    int w = getlayer(l, t);
       +    if (w >= 0){
       +        snarf(t, w);
       +        outT0(Tstartsnarf);
       +        setlock();
       +    }
       +
       +    return a;
       +}
       +
       +static long
       +cmdsnarf(Flayer *l, long a, Text *t)
       +{
       +    flushtyping(0);
       +
       +    int w = getlayer(l, t);
       +    if (w >= 0)
       +        snarf(t, w);
       +
       +    return a;
       +}
       +
       +static long
       +cmdcut(Flayer *l, long a, Text *t)
       +{
       +    flushtyping(0);
       +
       +    int w = getlayer(l, t);
       +    if (w >= 0)
       +        cut(t, w, 1, 1);
       +
       +    return a;
       +}
       +
       +static long
       +cmdpaste(Flayer *l, long a, Text *t)
       +{
       +    flushtyping(0);
       +
       +    int w = getlayer(l, t);
       +    if (w >= 0)
       +        paste(t, w);
       +
       +    return a;
       +}
       +
        typedef long (*Commandfunc)(Flayer *, long, Text *);
        typedef struct CommandEntry CommandEntry;
        struct CommandEntry{
       @@ -692,13 +752,17 @@ CommandEntry commands[Cmax] ={
            [Clinedown]   = {cmdlinedown,   0},
            [Cjump]       = {cmdjump,       0},
            [Cescape]     = {cmdescape,     0},
       +    [Csnarf]      = {cmdsnarf,      0},
       +    [Ccut]        = {cmdcut,        0},
       +    [Cpaste]      = {cmdpaste,      0},
       +    [Cexchange]   = {cmdexchange,   0},
            [Cdelword]    = {cmddelword,    1},
            [Cdelbol]     = {cmddelbol,     1},
            [Cdel]        = {cmddel,        1}
        };
        
        void
       -type(Flayer *l, int res)        /* what a bloody mess this is */
       +type(Flayer *l, int res)        /* what a bloody mess this is -- but it's getting better! */
        {
                Text *t = (Text *)l->user1;
                Rune buf[100];
       @@ -712,6 +776,7 @@ type(Flayer *l, int res)        /* what a bloody mess this is */
                        return;
                }
        
       +    k = qpeekc();
                a = l->p0;
            if (a != l->p1 && k.k != Kcommand){
                        flushtyping(1);
       @@ -740,6 +805,16 @@ type(Flayer *l, int res)        /* what a bloody mess this is */
                                break;
                }
        
       +    if (k.k == Kcommand){
       +        if (k.c < 0 || k.c >= Cmax)
       +            panic("command table miss");
       +
       +        CommandEntry *e = &commands[k.c];
       +        if (!e->unlocked || !lock)
       +            a = e->f(l, a, t);
       +        return;
       +    }
       +
            if (p > buf){
                if (typestart < 0)
                    typestart = a;
       @@ -759,12 +834,6 @@ type(Flayer *l, int res)        /* what a bloody mess this is */
                onethird(l, a);
            }
        
       -    if (k.k == Kcommand){
       -        CommandEntry *e = &commands[k.c];
       -        if (!e->unlocked || !lock)
       -            a = e->f(l, a, t);
       -    }
       -
            if (typeesc >= l->p0)
                typeesc = l->p0;
        
       @@ -781,7 +850,8 @@ type(Flayer *l, int res)        /* what a bloody mess this is */
        }
        
        void
       -outcmd(void){
       +outcmd(void)
       +{
                if(work)
                        outTsll(Tworkfile, ((Text *)work->user1)->tag, work->p0, work->p1);
        }
 (DIR) diff --git a/samterm/samterm.h b/samterm/samterm.h
       @@ -90,6 +90,7 @@ int        load(char*, int);
        int        waitforio(void);
        int        rcvchar(void);
        int        getch(void);
       +Keystroke qpeekc(void);
        Keystroke        kbdchar(void);
        void        mouseexit(void);
        void        cut(Text*, int, int, int);