lynx-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

lynx-dev dev.15 patch 6 - extend KEYMAP, .lynx-keymaps for line-edit bin


From: Klaus Weide
Subject: lynx-dev dev.15 patch 6 - extend KEYMAP, .lynx-keymaps for line-edit bindings
Date: Sun, 28 Nov 1999 21:36:46 -0600 (CST)

Based on my previous dev.15 patch 1, patch 2, patch 3, patch 5.

Reference to Ilya's patch is
<http://www.flora.org/lynx-dev/html/month1199/msg00231.html>.  This patch
subsumes / replaces it.  Note that (afai read the code) Ilya's patch didn't
work with a normal slang compile (Unix, at least).  This one should, even
for the .lynx-keymap form, although that is untested.

Everybody (who is able to edit lynx.cfg or their own copy of it) should now
be able to map both functions of ^V away from ^V, for example (or map one of
them away to avoid confusion).

Documentation (updated lynx.cfg comments, UG updates) not yet done, but will
follow later.

   Klaus

* Allow KEYMAP directives in lynx.cfg of extended form
  KEYMAP:lynxkey:lynxaction:editaction[:sel], where lynxkey and
  lynxaction are as before, editaction is a line-editor action like
  FORW, BACK, ERASE etc. and sel selects the line-editor style to
  be affected (as a number, starting with 1 for the Default Binding;
  or 0 for all styles (the default); or a negative number -n meaning
  "all line-editor styles except n").  See Line Editor Help pages for
  keywords to use as editaction.  This includes PASS (which was already
  implemented), for "passing" on the key when line-editing form fields
  so that the normal lynxaction will be invoked.
  (KEYMAP:lynxkey:lynxaction:DIRED is also still possible for defining
  a Dired mode binding).
  This is based on a patch from IZ which introduced combined definitions
  in a .lynx-keymaps file in the form:
     setkey "\200s" LAC:LEFT_LINK/BACKW     # C-left
     setkey "\200t" LAC:RIGHT_LINK/FORWW    # C-right
  Combined definitions in .lynx-keymaps are also supported in this patch,
  but the syntax was changed to use another ':' instead of '/' as separator.
  Note that there is no need to support .lynx-keymaps (i.e. compile with
  USE_KEYMAPS defined) for using the extended KEYMAP lynx.cfg directive with
  this patch.
* Corrections to make LYEditmap.c compile for non-ASCII systems.
[ Reference for the latter is
  <http://www.flora.org/lynx-dev/html/month1199/msg00409.html>, by
  gil <address@hidden> ]


Index: 2.24/src/LYForms.c
--- 2.24/src/LYForms.c Thu, 25 Nov 1999 06:54:09 -0600
+++ 2.24(w)/src/LYForms.c Sun, 28 Nov 1999 18:12:44 -0600
@@ -468,7 +468,7 @@
        }
 #endif /* VMS */
 #  ifdef NCURSES_MOUSE_VERSION
-       if (ch != -1 && (ch & LKC_ISLAC)) /* already lynxactioncode? */
+       if (ch != -1 && (ch & LKC_ISLAC) && !(ch & LKC_ISLECLAC)) /* already 
lynxactioncode? */
            break;      /* @@@ maybe move these 2 lines outside ifdef -kw */
        if (ch == MOUSE_KEY) {          /* Need to process ourselves */
 #if defined(WIN_EX)
@@ -513,7 +513,8 @@
        } else
 #  endif       /* defined NCURSES_MOUSE_VERSION */
        {
-           ch |= MyEdit.current_modifiers;
+           if (!(ch & LKC_ISLECLAC))
+               ch |= MyEdit.current_modifiers;
            MyEdit.current_modifiers = 0;
            if (last_xlkc != -1) {
                if (ch == last_xlkc)
Index: 2.24/src/LYStrings.c
--- 2.24/src/LYStrings.c Thu, 25 Nov 1999 11:29:56 -0600
+++ 2.24(w)/src/LYStrings.c Sun, 28 Nov 1999 17:34:28 -0600
@@ -949,6 +949,22 @@
     *keysym = -1;
 
     if (strncasecomp(str, "LAC:", 4) == 0) {
+       char *other = strchr(str+4, ':');
+
+       if (other) {
+          int othersym = lecname_to_lec(other + 1);
+          char buf[BUFSIZ];
+
+          if (othersym >= 0 && other - str - 4 < BUFSIZ ) {
+               strncpy(buf, str + 4, other - str - 4);
+               buf[other - str - 4] = '\0';
+               *keysym = lacname_to_lac(buf);
+               if (*keysym >= 0) {
+                   *keysym = LACLEC_TO_LKC0(*keysym, othersym);
+                   return (*keysym);
+               }
+          }
+       }
        *keysym = lacname_to_lac(str + 4);
        if (*keysym >= 0) {
            *keysym = LAC_TO_LKC0(*keysym);
@@ -1415,7 +1431,7 @@
    if (keysym < 0)
        return 0;
 
-   if (keysym&LKC_ISLAC)
+   if (keysym & (LKC_ISLECLAC|LKC_ISLAC))
        return (keysym);
 
    current_sl_modifier = 0;
@@ -1725,7 +1741,11 @@
        }
     }
 #ifdef USE_KEYMAPS
-    if (c >= 0 && (c&LKC_ISLKC)) {
+    /* Extract a single code if two are merged: */
+    if (c >= 0 && (c&LKC_ISLECLAC)) {
+       if (!(code == FOR_INPUT || code == FOR_PROMPT))
+           c = LKC2_TO_LKC(c);
+    } else if (c >= 0 && (c&LKC_ISLKC)) {
        c &= ~LKC_ISLKC;
        done_esc = TRUE; /* already a lynxkeycode, skip keypad switches - kw */
     }
@@ -1733,7 +1753,7 @@
        current_modifier = LKC_MOD2;
        c &= LKC_MASK;
     }
-    if (c >= 0 && (c&LKC_ISLAC)) {
+    if (c >= 0 && (c&(LKC_ISLECLAC|LKC_ISLAC))) {
        done_esc = TRUE; /* already a lynxactioncode, skip keypad switches - iz 
*/
     }
 #endif
@@ -2238,7 +2258,7 @@
     }
 #endif /* USE_SLANG && __DJGPP__ && !DJGPP_KEYHANDLER && !USE_KEYMAPS */
 
-    if (c&LKC_ISLAC)
+    if (c&(LKC_ISLAC|LKC_ISLECLAC))
        return(c);
     if ((c+1) >= KEYMAP_SIZE) {
        /*
Index: 2.24/src/LYKeymap.c
--- 2.24/src/LYKeymap.c Thu, 25 Nov 1999 13:27:27 -0600
+++ 2.24(w)/src/LYKeymap.c Sun, 28 Nov 1999 17:27:05 -0600
@@ -778,6 +778,65 @@
   "mouse pseudo key",          /* normally not mapped to keymap[] action */
 };
 
+
+struct emap {
+       CONST char *name;
+       CONST int   code;
+       CONST char *descr;
+};
+
+PRIVATE struct emap ekmap[] = {
+  {"NOP",      LYE_NOP,        "Do Nothing"},
+  {"CHAR",     LYE_CHAR,       "Insert printable char"},
+  {"ENTER",    LYE_ENTER,      "Input complete, return char/lynxkeycode"},
+  {"TAB",      LYE_TAB,        "Input complete, return TAB"},
+  {"ABORT",    LYE_ABORT,      "Input cancelled"},
+
+  {"PASS",     LYE_FORM_PASS,  "In fields: input complete, or Do Nothing"},
+
+  {"DELN",     LYE_DELN,       "Delete next/curr char"},
+  {"DELP",     LYE_DELP,       "Delete prev      char"},
+  {"DELNW",    LYE_DELNW,      "Delete next word"},
+  {"DELPW",    LYE_DELPW,      "Delete prev word"},
+
+  {"ERASE",    LYE_ERASE,      "Erase the line"},
+
+  {"BOL",      LYE_BOL,        "Go to begin of line"},
+  {"EOL",      LYE_EOL,        "Go to end   of line"},
+  {"FORW",     LYE_FORW,       "Cursor forwards"},
+  {"BACK",     LYE_BACK,       "Cursor backwards"},
+  {"FORWW",    LYE_FORWW,      "Word forward"},
+  {"BACKW",    LYE_BACKW,      "Word back"},
+
+  {"LOWER",    LYE_LOWER,      "Lower case the line"},
+  {"UPPER",    LYE_UPPER,      "Upper case the line"},
+
+  {"LKCMD",    LYE_LKCMD,      "Invoke command prompt"},
+
+  {"AIX",      LYE_AIX,        "Hex 97"},
+
+  {"DELBL",    LYE_DELBL,      "Delete back to BOL"},
+  {"DELEL",    LYE_DELEL,      "Delete thru EOL"},
+
+  {"SWMAP",    LYE_SWMAP,      "Switch input keymap"},
+
+  {"TPOS",     LYE_TPOS,       "Transpose characters"},
+
+  {"SETM1",    LYE_SETM1,      "Set modifier 1 flag"},
+  {"SETM2",    LYE_SETM2,      "Set modifier 2 flag"},
+  {"UNMOD",    LYE_UNMOD,      "Fall back to no-modifier command"},
+
+  {"C1CHAR",   LYE_C1CHAR,     "Insert C1 char if printable"},
+
+  {"SETMARK",  LYE_SETMARK,    "emacs-like set-mark-command"},
+  {"XPMARK",   LYE_XPMARK,     "emacs-like exchange-point-and-mark"},
+  {"KILLREG",  LYE_KILLREG,    "emacs-like kill-region"},
+  {"YANK",     LYE_YANK,       "emacs-like yank"}
+#if defined(WIN_EX)
+, {"PASTE",    LYE_PASTE,      "ClipBoard to Lynx"}
+#endif
+};
+
 PRIVATE char *pretty ARGS1 (int, c)
 {
        static char buf[30];
@@ -935,6 +994,27 @@
 }
 
 /*
+ *  Return editactioncode whose name is the string func.
+ *  func must be present in the ekmap table.
+ *  returns -1 if not found. - kw
+ */
+PUBLIC int lecname_to_lec ARGS1(
+       CONST char *,   func)
+{
+       int i;
+       struct emap *mp;
+
+       if (func == NULL || *func == '\0')
+              return (-1);
+       for (i = 0, mp = ekmap; (*mp).name != NULL; mp++, i++) {
+               if (strcmp((*mp).name, func) == 0) {
+                       return (*mp).code;
+               }
+       }
+       return (-1);
+}
+
+/*
  *  Return lynxkeycode represented by string src.
  *  returns -1 if not valid.
  *  This is simpler than what map_string_to_keysym() does for
@@ -1077,7 +1157,7 @@
         * called for an invalid lynxkeycode, fail or silently ignore
         * modifiers. - kw
         */
-       if (c & LKC_ISLAC)
+       if (c & (LKC_ISLECLAC|LKC_ISLAC))
           return 0;
        if ((c & LKC_MASK) != c)
           c &= LKC_MASK;
Index: 2.24/src/LYEditmap.c
--- 2.24/src/LYEditmap.c Thu, 25 Nov 1999 13:27:27 -0600
+++ 2.24(w)/src/LYEditmap.c Sun, 28 Nov 1999 18:33:18 -0600
@@ -983,7 +983,9 @@
      *  If we have more than one modifier bits, the first currently
      *  wins. - kw
      */
-    if (xlkc & LKC_MOD1) {
+    if (xlkc & LKC_ISLECLAC) {
+       return LKC2_TO_LEC(xlkc);
+    } else if (xlkc & LKC_MOD1) {
        xleac = LKC_TO_LEC_M1(c);
     } else if (xlkc & LKC_MOD2) {
        xleac = LKC_TO_LEC_M2(c);
@@ -1008,17 +1010,25 @@
 /*
  *  Install lec as the lynxeditaction for lynxkeycode xlkc.
  *  func must be present in the revmap table.
+ *  For normal (non-modifier) lynxkeycodes, select_edi selects which
+ *  of the alternative line-editor binding tables is modified. If
+ *  select_edi is positive, only the table given by it is modified
+ *  (the DefaultEditBinding table is numbered 1).  If select_edi is 0,
+ *  all tables are modified.  If select_edi is negative, all tables
+ *  except the one given by abs(select_edi) are modified.
  *  returns TRUE if the mapping was made, FALSE if not.
  *  Note that this remapping cannot be undone (as might be desirable
  *  as a result of re-parsing lynx.cfg), we don't remember the
  *  original editaction from the Bindings tables anywhere. - kw
  */
-PUBLIC int LYRemapEditBinding ARGS2(
+PUBLIC BOOL LYRemapEditBinding ARGS3(
     int,       xlkc,
-    int,       lec)
+    int,       lec,
+    int,       select_edi)
 {
     int j;
     int c = xlkc & LKC_MASK;
+    BOOLEAN success = FALSE;
     if (xlkc < 0 || (xlkc&LKC_ISLAC) || c >= KEYMAP_SIZE + 1)
        return FALSE;
 #ifdef EXP_ALT_BINDINGS
@@ -1027,16 +1037,19 @@
            return FALSE;
        else
            Mod1Binding[c] = (short) lec;
+       return TRUE;
     } else if (xlkc & LKC_MOD2) {
        if (c > LAST_MOD2_LKC)
            return FALSE;
        else
            Mod2Binding[c] = (short) lec;
+       return TRUE;
     } else if (xlkc & LKC_MOD3) {
        if (c > LAST_MOD3_LKC)
            return FALSE;
        else
            Mod3Binding[c] = (short) lec;
+       return TRUE;
     } else
 #endif /* EXP_ALT_BINDINGS */
     {
@@ -1045,11 +1058,21 @@
 #endif
        if ((unsigned int)lec > UCHAR_MAX)
            return FALSE;       /* cannot do, doesn't fit in a char - kw */
-       for (j = 0; LYLineeditNames[j]; j++) {
-           LYLineEditors[j][c] = (char) lec;
+       if (select_edi > 0) {
+           if ((unsigned int)select_edi < TABLESIZE(LYLineEditors)) {
+               LYLineEditors[select_edi - 1][c] = (char) lec;
+               success = TRUE;
+           }
+       } else {
+           for (j = 0; LYLineeditNames[j]; j++) {
+               success = TRUE;
+               if (select_edi < 0 && j + 1 + select_edi == 0)
+                   continue;
+               LYLineEditors[j][c] = (char) lec;
+           }
        }
     }
-    return TRUE;
+    return success;
 }
 
 /*
@@ -1180,7 +1203,7 @@
        if (pmodkey) {
 #ifdef NOT_ASCII
            if (mod1found < 256) {
-               pmodkey = FROMASCII(mod1found);
+               *pmodkey = FROMASCII(mod1found);
            } else
 #endif
                *pmodkey = mod1found;
@@ -1219,7 +1242,7 @@
        if (pmodkey) {
 #ifdef NOT_ASCII
            if (mod1found < 256) {
-               pmodkey = FROMASCII(mod1found);
+               *pmodkey = FROMASCII(mod1found);
            } else
 #endif
                *pmodkey = mod1found;
Index: 2.24/src/LYKeymap.h
--- 2.24/src/LYKeymap.h Thu, 25 Nov 1999 11:29:56 -0600
+++ 2.24(w)/src/LYKeymap.h Sun, 28 Nov 1999 18:44:58 -0600
@@ -12,6 +12,7 @@
 extern int LYReverseKeymap PARAMS((int KeyName));
 extern int lookup_keymap PARAMS((int code));
 extern int lacname_to_lac PARAMS((CONST char *func));
+extern int lecname_to_lec PARAMS((CONST char *func));
 extern int lkcstring_to_lkc PARAMS((CONST char *src));
 extern int remap PARAMS((char *key, char *func, BOOLEAN for_dired));
 extern void print_keymap PARAMS((char **newfile));
@@ -45,10 +46,13 @@
 #endif
 
 /* * *  LynxKeyCodes  * * */
+#define LKC_ISLECLAC   0x8000  /* flag: contains lynxaction + editaction */
 #define LKC_MOD1       0x4000  /* a modifier bit - currently for ^x-map */
 #define LKC_MOD2       0x2000  /* another one - currently for esc-map */
 #define LKC_MOD3       0x1000  /* another one - currently for double-map */
 #define LKC_ISLAC      0x0800  /* flag: lynxkeycode already lynxactioncode */
+
+/* Used to distinguish internal Lynx keycodes of (say) extended ncurses once. 
*/
 #define LKC_ISLKC      0x0400  /* flag: already lynxkeycode (not native) */
                     /* 0x0400  is MOUSE_KEYSYM for slang in LYStrings.c */
 #define LKC_MASK       0x07FF  /* mask for lynxkeycode proper */
@@ -56,27 +60,48 @@
 #define LKC_DONE       0x07FE  /* special value - operation done, not-a-key */
 
 /* * *  LynxActionCodes  * * */
-#define LAC_MASK       0x00FF  /* mask for lynxactioncode - must cover all
+#define LAC_SHIFT      8       /* shift for lynxactioncode - must not
+                                  overwrite any assigned LYK_* values */
+#define LAC_MASK       ((1<<LAC_SHIFT)-1)
+                               /* mask for lynxactioncode - must cover all
                                   assigned LYK_* values */
 
 
+#if 0
+/*  Substitute a single actioncode given a double one - NOT USED */
+#define LKC2_TO_LKC(c,n)   (((c) == -1 || !((c) & LKC_ISLECLAC)) ? (c) : \
+                           ((n) == 1) ? (((c) & LAC_MASK) | LKC_ISLAC) : \
+                           (((((c)&~LKC_ISLECLAC)>>LAC_SHIFT) & LAC_MASK) | 
LKC_ISLECLAC))
+#endif /* 0 */
+
+/*  Return lkc masking single actioncode, given an lkc masking a lac + lec */
+#define LKC2_TO_LKC(c)   (((c) == -1 || !((c) & LKC_ISLECLAC)) ? (c) : \
+                           (((c) & LAC_MASK) | LKC_ISLAC))
+
+/*  Return lynxeditactioncode, given an lkc masking a lac + lec */
+#define LKC2_TO_LEC(c)   (((c) == -1 || !((c) & LKC_ISLECLAC)) ? (c) : \
+                           ((((c)&~LKC_ISLECLAC)>>LAC_SHIFT) & LAC_MASK))
+
 /*  Convert lynxkeycode to lynxactioncode.  Modifiers are dropped.  */
 #define LKC_TO_LAC(ktab,c) (((c) == -1) ? ktab[0] : \
-                           ((c) & LKC_ISLAC) ? ((c) & LAC_MASK) : \
+                           ((c) & (LKC_ISLECLAC|LKC_ISLAC)) ? ((c) & LAC_MASK) 
: \
                            ktab[((c) & LKC_MASK) + 1])
 
 
 /*  Mask lynxactioncode as a lynxkeycode.  */
 #define LAC_TO_LKC0(a) ((a)|LKC_ISLAC)
 
+/*  Mask a lynxactioncode and an editactioncode as a lynxkeycode.  */
+#define LACLEC_TO_LKC0(a,b) ((a)|((b)<<LAC_SHIFT)|LKC_ISLECLAC)
+
 /*  Convert lynxactioncode to a lynxkeycode, attempting reverse mapping.  */
 #define LAC_TO_LKC(a) 
((LYReverseKeymap(a)>=0)?LYReverseKeymap(a):LAC_TO_LKC0(a))
 
 /*  Simplify a lynxkeycode:
-    attempt reverse mapping if a masked lynxactioncode, drop modifiers.  */
-#define LKC_TO_C(c) ((c&LKC_ISLAC)? LAC_TO_LKC(c&LAC_MASK) : (c&LKC_MASK))
+    attempt reverse mapping if a single masked lynxactioncode, drop modifiers. 
 */
+#define LKC_TO_C(c) ((c&LKC_ISLECLAC)? c : (c&LKC_ISLAC)? 
LAC_TO_LKC(c&LAC_MASK) : (c&LKC_MASK))
 
-#define LKC_HAS_ESC_MOD(c) (c >= 0 && (c&LKC_MOD2))
+#define LKC_HAS_ESC_MOD(c) (c >= 0 && !(c&LKC_ISLECLAC) && (c&LKC_MOD2))
 
 
 /* *  The defined LynxActionCodes  * */
Index: 2.24/src/LYStrings.h
--- 2.24/src/LYStrings.h Thu, 25 Nov 1999 06:54:09 -0600
+++ 2.24(w)/src/LYStrings.h Sun, 28 Nov 1999 17:38:26 -0600
@@ -277,7 +277,10 @@
 extern void LYRefreshEdit PARAMS((
        EditFieldData * edit));
 extern int EditBinding PARAMS((int ch));                  /* in LYEditmap.c */
-extern int LYRemapEditBinding PARAMS((int xlkc, int lec)); /* in LYEditmap.c */
+extern BOOL LYRemapEditBinding PARAMS((
+       int             xlkc,
+       int             lec,
+       int             select_edi));                      /* in LYEditmap.c */
 extern int LYKeyForEditAction PARAMS((int lec));          /* in LYEditmap.c */
 extern int LYEditKeyForAction PARAMS((int lac, int *pmodkey));/* LYEditmap.c */
 extern int LYEdit1 PARAMS((
Index: 2.24/src/LYReadCFG.c
--- 2.24/src/LYReadCFG.c Thu, 25 Nov 1999 11:29:56 -0600
+++ 2.24(w)/src/LYReadCFG.c Sun, 28 Nov 1999 17:34:27 -0600
@@ -652,6 +652,8 @@
                fprintf(stderr,
                        gettext("key remapping of %s to %s for %s failed\n"),
                        key, func, efunc + 1);
+           } else if (func && !strcmp("TOGGLE_HELP", func)) {
+               LYUseNoviceLineTwo = FALSE;
            }
            return 0;
        } else if (!remap(key, strtok(func, " \t\n:#"), FALSE)) {
@@ -667,9 +669,19 @@
                BOOLEAN success = FALSE;
                int lkc = lkcstring_to_lkc(key);
                int lec = -1;
-               if (!success && strncasecomp(efunc, "DIRED", 5) == 0) {
-                   lec = LYE_FORM_PASS;
-                   success = (BOOL) LYRemapEditBinding(lkc, lec);
+               int select_edi = 0;
+               char *sselect_edi = strtok(NULL, " \t\n:#");
+               char **endp = &sselect_edi;
+               if (sselect_edi) {
+                   if (*sselect_edi)
+                       select_edi = strtol(sselect_edi, endp, 10);
+                   if (**endp != '\0') {
+                       fprintf(stderr,
+                               gettext(
+       "invalid line-editor selection %s for key %s, selecting all\n"),
+                               sselect_edi, key);
+                       select_edi = 0;
+                   }
                }
                /*
                 *  PASS! tries to enter the key into the LYLineEditors
@@ -688,7 +700,7 @@
                if (!success && strcasecomp(efunc, "PASS!") == 0) {
                    if (func) {
                        lec = LYE_FORM_LAC|lacname_to_lac(func);
-                       success = (BOOL) LYRemapEditBinding(lkc, lec);
+                       success = (BOOL) LYRemapEditBinding(lkc, lec, 
select_edi);
                    }
                    if (!success)
                        fprintf(stderr,
@@ -698,9 +710,9 @@
                    else
                        return 0;
                }
-               if (!success && strncasecomp(efunc, "PASS", 4) == 0) {
-                   lec = LYE_FORM_PASS;
-                   success = (BOOL) LYRemapEditBinding(lkc, lec);
+               if (!success) {
+                   lec = lecname_to_lec(efunc);
+                   success = (BOOL) LYRemapEditBinding(lkc, lec, select_edi);
                }
                if (!success) {
                    if (lec != -1) {


reply via email to

[Prev in Thread] Current Thread [Next in Thread]