13b6eaa7bSAndrey A. Chernov /* $Header: /src/pub/tcsh/tc.bind.c,v 3.35 2000/11/11 23:03:38 christos Exp $ */ 2c80476e4SDavid E. O'Brien /* 3c80476e4SDavid E. O'Brien * tc.bind.c: Key binding functions 4c80476e4SDavid E. O'Brien */ 5c80476e4SDavid E. O'Brien /*- 6c80476e4SDavid E. O'Brien * Copyright (c) 1980, 1991 The Regents of the University of California. 7c80476e4SDavid E. O'Brien * All rights reserved. 8c80476e4SDavid E. O'Brien * 9c80476e4SDavid E. O'Brien * Redistribution and use in source and binary forms, with or without 10c80476e4SDavid E. O'Brien * modification, are permitted provided that the following conditions 11c80476e4SDavid E. O'Brien * are met: 12c80476e4SDavid E. O'Brien * 1. Redistributions of source code must retain the above copyright 13c80476e4SDavid E. O'Brien * notice, this list of conditions and the following disclaimer. 14c80476e4SDavid E. O'Brien * 2. Redistributions in binary form must reproduce the above copyright 15c80476e4SDavid E. O'Brien * notice, this list of conditions and the following disclaimer in the 16c80476e4SDavid E. O'Brien * documentation and/or other materials provided with the distribution. 17c80476e4SDavid E. O'Brien * 3. All advertising materials mentioning features or use of this software 18c80476e4SDavid E. O'Brien * must display the following acknowledgement: 19c80476e4SDavid E. O'Brien * This product includes software developed by the University of 20c80476e4SDavid E. O'Brien * California, Berkeley and its contributors. 21c80476e4SDavid E. O'Brien * 4. Neither the name of the University nor the names of its contributors 22c80476e4SDavid E. O'Brien * may be used to endorse or promote products derived from this software 23c80476e4SDavid E. O'Brien * without specific prior written permission. 24c80476e4SDavid E. O'Brien * 25c80476e4SDavid E. O'Brien * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 26c80476e4SDavid E. O'Brien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27c80476e4SDavid E. O'Brien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28c80476e4SDavid E. O'Brien * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 29c80476e4SDavid E. O'Brien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30c80476e4SDavid E. O'Brien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31c80476e4SDavid E. O'Brien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32c80476e4SDavid E. O'Brien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33c80476e4SDavid E. O'Brien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34c80476e4SDavid E. O'Brien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35c80476e4SDavid E. O'Brien * SUCH DAMAGE. 36c80476e4SDavid E. O'Brien */ 37c80476e4SDavid E. O'Brien #include "sh.h" 38c80476e4SDavid E. O'Brien 393b6eaa7bSAndrey A. Chernov RCSID("$Id: tc.bind.c,v 3.35 2000/11/11 23:03:38 christos Exp $") 40c80476e4SDavid E. O'Brien 41c80476e4SDavid E. O'Brien #include "ed.h" 42c80476e4SDavid E. O'Brien #include "ed.defns.h" 43c80476e4SDavid E. O'Brien 44c80476e4SDavid E. O'Brien #ifdef OBSOLETE 45c80476e4SDavid E. O'Brien static int tocontrol __P((int)); 46c80476e4SDavid E. O'Brien static char *unparsekey __P((int)); 47c80476e4SDavid E. O'Brien static KEYCMD getkeycmd __P((Char **)); 48c80476e4SDavid E. O'Brien static int parsekey __P((Char **)); 49c80476e4SDavid E. O'Brien static void pkeys __P((int, int)); 50c80476e4SDavid E. O'Brien #endif /* OBSOLETE */ 51c80476e4SDavid E. O'Brien 52c80476e4SDavid E. O'Brien static void printkey __P((KEYCMD *, CStr *)); 53c80476e4SDavid E. O'Brien static KEYCMD parsecmd __P((Char *)); 54c80476e4SDavid E. O'Brien static void bad_spec __P((Char *)); 55c80476e4SDavid E. O'Brien static CStr *parsestring __P((Char *, CStr *)); 56c80476e4SDavid E. O'Brien static CStr *parsebind __P((Char *, CStr *)); 57c80476e4SDavid E. O'Brien static void print_all_keys __P((void)); 58c80476e4SDavid E. O'Brien static void printkeys __P((KEYCMD *, int, int)); 59c80476e4SDavid E. O'Brien static void bindkey_usage __P((void)); 60c80476e4SDavid E. O'Brien static void list_functions __P((void)); 61c80476e4SDavid E. O'Brien 62c80476e4SDavid E. O'Brien extern int MapsAreInited; 63c80476e4SDavid E. O'Brien 64c80476e4SDavid E. O'Brien 65c80476e4SDavid E. O'Brien 66c80476e4SDavid E. O'Brien 67c80476e4SDavid E. O'Brien /*ARGSUSED*/ 68c80476e4SDavid E. O'Brien void 69c80476e4SDavid E. O'Brien dobindkey(v, c) 70c80476e4SDavid E. O'Brien Char **v; 71c80476e4SDavid E. O'Brien struct command *c; 72c80476e4SDavid E. O'Brien { 73c80476e4SDavid E. O'Brien KEYCMD *map; 74c80476e4SDavid E. O'Brien int ntype, no, remove, key, bind; 75c80476e4SDavid E. O'Brien Char *par; 76c80476e4SDavid E. O'Brien Char p; 77c80476e4SDavid E. O'Brien KEYCMD cmd; 78c80476e4SDavid E. O'Brien CStr in; 79c80476e4SDavid E. O'Brien CStr out; 80c80476e4SDavid E. O'Brien Char inbuf[200]; 81c80476e4SDavid E. O'Brien Char outbuf[200]; 82c80476e4SDavid E. O'Brien uChar ch; 83c80476e4SDavid E. O'Brien in.buf = inbuf; 84c80476e4SDavid E. O'Brien out.buf = outbuf; 85c80476e4SDavid E. O'Brien in.len = 0; 86c80476e4SDavid E. O'Brien out.len = 0; 87c80476e4SDavid E. O'Brien 88c80476e4SDavid E. O'Brien USE(c); 89c80476e4SDavid E. O'Brien if (!MapsAreInited) 90c80476e4SDavid E. O'Brien ed_InitMaps(); 91c80476e4SDavid E. O'Brien 92c80476e4SDavid E. O'Brien map = CcKeyMap; 93c80476e4SDavid E. O'Brien ntype = XK_CMD; 94c80476e4SDavid E. O'Brien key = remove = bind = 0; 95c80476e4SDavid E. O'Brien for (no = 1, par = v[no]; 96c80476e4SDavid E. O'Brien par != NULL && (*par++ & CHAR) == '-'; no++, par = v[no]) { 97c80476e4SDavid E. O'Brien if ((p = (*par & CHAR)) == '-') { 98c80476e4SDavid E. O'Brien no++; 99c80476e4SDavid E. O'Brien break; 100c80476e4SDavid E. O'Brien } 101c80476e4SDavid E. O'Brien else 102c80476e4SDavid E. O'Brien switch (p) { 103c80476e4SDavid E. O'Brien case 'b': 104c80476e4SDavid E. O'Brien bind = 1; 105c80476e4SDavid E. O'Brien break; 106c80476e4SDavid E. O'Brien case 'k': 107c80476e4SDavid E. O'Brien key = 1; 108c80476e4SDavid E. O'Brien break; 109c80476e4SDavid E. O'Brien case 'a': 110c80476e4SDavid E. O'Brien map = CcAltMap; 111c80476e4SDavid E. O'Brien break; 112c80476e4SDavid E. O'Brien case 's': 113c80476e4SDavid E. O'Brien ntype = XK_STR; 114c80476e4SDavid E. O'Brien break; 115c80476e4SDavid E. O'Brien case 'c': 116c80476e4SDavid E. O'Brien ntype = XK_EXE; 117c80476e4SDavid E. O'Brien break; 118c80476e4SDavid E. O'Brien case 'r': 119c80476e4SDavid E. O'Brien remove = 1; 120c80476e4SDavid E. O'Brien break; 121c80476e4SDavid E. O'Brien case 'v': 122c80476e4SDavid E. O'Brien ed_InitVIMaps(); 123c80476e4SDavid E. O'Brien return; 124c80476e4SDavid E. O'Brien case 'e': 125c80476e4SDavid E. O'Brien ed_InitEmacsMaps(); 126c80476e4SDavid E. O'Brien return; 127c80476e4SDavid E. O'Brien case 'd': 128c80476e4SDavid E. O'Brien #ifdef VIDEFAULT 129c80476e4SDavid E. O'Brien ed_InitVIMaps(); 130c80476e4SDavid E. O'Brien #else /* EMACSDEFAULT */ 131c80476e4SDavid E. O'Brien ed_InitEmacsMaps(); 132c80476e4SDavid E. O'Brien #endif /* VIDEFAULT */ 133c80476e4SDavid E. O'Brien return; 134c80476e4SDavid E. O'Brien case 'l': 135c80476e4SDavid E. O'Brien list_functions(); 136c80476e4SDavid E. O'Brien return; 137c80476e4SDavid E. O'Brien default: 138c80476e4SDavid E. O'Brien bindkey_usage(); 139c80476e4SDavid E. O'Brien return; 140c80476e4SDavid E. O'Brien } 141c80476e4SDavid E. O'Brien } 142c80476e4SDavid E. O'Brien 143c80476e4SDavid E. O'Brien if (!v[no]) { 144c80476e4SDavid E. O'Brien print_all_keys(); 145c80476e4SDavid E. O'Brien return; 146c80476e4SDavid E. O'Brien } 147c80476e4SDavid E. O'Brien 148c80476e4SDavid E. O'Brien if (key) { 149c80476e4SDavid E. O'Brien if (!IsArrowKey(v[no])) 150c80476e4SDavid E. O'Brien xprintf(CGETS(20, 1, "Invalid key name `%S'\n"), v[no]); 151c80476e4SDavid E. O'Brien in.buf = v[no++]; 152c80476e4SDavid E. O'Brien in.len = Strlen(in.buf); 153c80476e4SDavid E. O'Brien } 154c80476e4SDavid E. O'Brien else { 155c80476e4SDavid E. O'Brien if (bind) { 156c80476e4SDavid E. O'Brien if (parsebind(v[no++], &in) == NULL) 157c80476e4SDavid E. O'Brien return; 158c80476e4SDavid E. O'Brien } 159c80476e4SDavid E. O'Brien else { 160c80476e4SDavid E. O'Brien if (parsestring(v[no++], &in) == NULL) 161c80476e4SDavid E. O'Brien return; 162c80476e4SDavid E. O'Brien } 163c80476e4SDavid E. O'Brien } 164c80476e4SDavid E. O'Brien 165c80476e4SDavid E. O'Brien ch = (uChar) in.buf[0]; 166c80476e4SDavid E. O'Brien 167c80476e4SDavid E. O'Brien if (remove) { 168c80476e4SDavid E. O'Brien if (key) { 169c80476e4SDavid E. O'Brien (void) ClearArrowKeys(&in); 170c80476e4SDavid E. O'Brien return; 171c80476e4SDavid E. O'Brien } 172c80476e4SDavid E. O'Brien if (in.len > 1) { 173c80476e4SDavid E. O'Brien (void) DeleteXkey(&in); 174c80476e4SDavid E. O'Brien } 175c80476e4SDavid E. O'Brien else if (map[ch] == F_XKEY) { 176c80476e4SDavid E. O'Brien (void) DeleteXkey(&in); 177c80476e4SDavid E. O'Brien map[ch] = F_UNASSIGNED; 178c80476e4SDavid E. O'Brien } 179c80476e4SDavid E. O'Brien else { 180c80476e4SDavid E. O'Brien map[ch] = F_UNASSIGNED; 181c80476e4SDavid E. O'Brien } 182c80476e4SDavid E. O'Brien return; 183c80476e4SDavid E. O'Brien } 184c80476e4SDavid E. O'Brien if (!v[no]) { 185c80476e4SDavid E. O'Brien if (key) 186c80476e4SDavid E. O'Brien PrintArrowKeys(&in); 187c80476e4SDavid E. O'Brien else 188c80476e4SDavid E. O'Brien printkey(map, &in); 189c80476e4SDavid E. O'Brien return; 190c80476e4SDavid E. O'Brien } 191c80476e4SDavid E. O'Brien if (v[no + 1]) { 192c80476e4SDavid E. O'Brien bindkey_usage(); 193c80476e4SDavid E. O'Brien return; 194c80476e4SDavid E. O'Brien } 195c80476e4SDavid E. O'Brien switch (ntype) { 196c80476e4SDavid E. O'Brien case XK_STR: 197c80476e4SDavid E. O'Brien case XK_EXE: 198c80476e4SDavid E. O'Brien if (parsestring(v[no], &out) == NULL) 199c80476e4SDavid E. O'Brien return; 200c80476e4SDavid E. O'Brien if (key) { 201c80476e4SDavid E. O'Brien if (SetArrowKeys(&in, XmapStr(&out), ntype) == -1) 202c80476e4SDavid E. O'Brien xprintf(CGETS(20, 2, "Bad key name: %S\n"), in); 203c80476e4SDavid E. O'Brien } 204c80476e4SDavid E. O'Brien else 205c80476e4SDavid E. O'Brien AddXkey(&in, XmapStr(&out), ntype); 206c80476e4SDavid E. O'Brien map[ch] = F_XKEY; 207c80476e4SDavid E. O'Brien break; 208c80476e4SDavid E. O'Brien case XK_CMD: 209c80476e4SDavid E. O'Brien if ((cmd = parsecmd(v[no])) == 0) 210c80476e4SDavid E. O'Brien return; 211c80476e4SDavid E. O'Brien if (key) 212c80476e4SDavid E. O'Brien (void) SetArrowKeys(&in, XmapCmd((int) cmd), ntype); 213c80476e4SDavid E. O'Brien else { 214c80476e4SDavid E. O'Brien if (in.len > 1) { 215c80476e4SDavid E. O'Brien AddXkey(&in, XmapCmd((int) cmd), ntype); 216c80476e4SDavid E. O'Brien map[ch] = F_XKEY; 217c80476e4SDavid E. O'Brien } 218c80476e4SDavid E. O'Brien else { 219c80476e4SDavid E. O'Brien ClearXkey(map, &in); 220c80476e4SDavid E. O'Brien map[ch] = cmd; 221c80476e4SDavid E. O'Brien } 222c80476e4SDavid E. O'Brien } 223c80476e4SDavid E. O'Brien break; 224c80476e4SDavid E. O'Brien default: 225c80476e4SDavid E. O'Brien abort(); 226c80476e4SDavid E. O'Brien break; 227c80476e4SDavid E. O'Brien } 228c80476e4SDavid E. O'Brien if (key) 229c80476e4SDavid E. O'Brien BindArrowKeys(); 230c80476e4SDavid E. O'Brien } 231c80476e4SDavid E. O'Brien 232c80476e4SDavid E. O'Brien static void 233c80476e4SDavid E. O'Brien printkey(map, in) 234c80476e4SDavid E. O'Brien KEYCMD *map; 235c80476e4SDavid E. O'Brien CStr *in; 236c80476e4SDavid E. O'Brien { 237c80476e4SDavid E. O'Brien unsigned char outbuf[100]; 238c80476e4SDavid E. O'Brien register struct KeyFuncs *fp; 239c80476e4SDavid E. O'Brien 240c80476e4SDavid E. O'Brien if (in->len < 2) { 241c80476e4SDavid E. O'Brien (void) unparsestring(in, outbuf, STRQQ); 242c80476e4SDavid E. O'Brien for (fp = FuncNames; fp->name; fp++) { 243c80476e4SDavid E. O'Brien if (fp->func == map[(uChar) *(in->buf)]) { 244c80476e4SDavid E. O'Brien xprintf("%s\t->\t%s\n", outbuf, fp->name); 245c80476e4SDavid E. O'Brien } 246c80476e4SDavid E. O'Brien } 247c80476e4SDavid E. O'Brien } 248c80476e4SDavid E. O'Brien else 249c80476e4SDavid E. O'Brien PrintXkey(in); 250c80476e4SDavid E. O'Brien } 251c80476e4SDavid E. O'Brien 252c80476e4SDavid E. O'Brien static KEYCMD 253c80476e4SDavid E. O'Brien parsecmd(str) 254c80476e4SDavid E. O'Brien Char *str; 255c80476e4SDavid E. O'Brien { 256c80476e4SDavid E. O'Brien register struct KeyFuncs *fp; 257c80476e4SDavid E. O'Brien 258c80476e4SDavid E. O'Brien for (fp = FuncNames; fp->name; fp++) { 259c80476e4SDavid E. O'Brien if (strcmp(short2str(str), fp->name) == 0) { 260c80476e4SDavid E. O'Brien return (KEYCMD) fp->func; 261c80476e4SDavid E. O'Brien } 262c80476e4SDavid E. O'Brien } 263c80476e4SDavid E. O'Brien xprintf(CGETS(20, 3, "Bad command name: %S\n"), str); 264c80476e4SDavid E. O'Brien return 0; 265c80476e4SDavid E. O'Brien } 266c80476e4SDavid E. O'Brien 267c80476e4SDavid E. O'Brien 268c80476e4SDavid E. O'Brien static void 269c80476e4SDavid E. O'Brien bad_spec(str) 270c80476e4SDavid E. O'Brien Char *str; 271c80476e4SDavid E. O'Brien { 272c80476e4SDavid E. O'Brien xprintf(CGETS(20, 4, "Bad key spec %S\n"), str); 273c80476e4SDavid E. O'Brien } 274c80476e4SDavid E. O'Brien 275c80476e4SDavid E. O'Brien static CStr * 276c80476e4SDavid E. O'Brien parsebind(s, str) 277c80476e4SDavid E. O'Brien Char *s; 278c80476e4SDavid E. O'Brien CStr *str; 279c80476e4SDavid E. O'Brien { 280c80476e4SDavid E. O'Brien #ifdef DSPMBYTE 281c80476e4SDavid E. O'Brien extern bool NoNLSRebind; 282c80476e4SDavid E. O'Brien #endif /* DSPMBYTE */ 283c80476e4SDavid E. O'Brien Char *b = str->buf; 284c80476e4SDavid E. O'Brien 285c80476e4SDavid E. O'Brien if (Iscntrl(*s)) { 286c80476e4SDavid E. O'Brien *b++ = *s; 287c80476e4SDavid E. O'Brien *b = '\0'; 288c80476e4SDavid E. O'Brien str->len = (int) (b - str->buf); 289c80476e4SDavid E. O'Brien return str; 290c80476e4SDavid E. O'Brien } 291c80476e4SDavid E. O'Brien 292c80476e4SDavid E. O'Brien switch (*s) { 293c80476e4SDavid E. O'Brien case '^': 294c80476e4SDavid E. O'Brien s++; 2953b6eaa7bSAndrey A. Chernov #ifdef IS_ASCII 296c80476e4SDavid E. O'Brien *b++ = (*s == '?') ? '\177' : ((*s & CHAR) & 0237); 2973b6eaa7bSAndrey A. Chernov #else 298c80476e4SDavid E. O'Brien *b++ = (*s == '?') ? CTL_ESC('\177') : _toebcdic[_toascii[*s & CHAR] & 0237]; 2993b6eaa7bSAndrey A. Chernov #endif 300c80476e4SDavid E. O'Brien *b = '\0'; 301c80476e4SDavid E. O'Brien break; 302c80476e4SDavid E. O'Brien 303c80476e4SDavid E. O'Brien case 'F': 304c80476e4SDavid E. O'Brien case 'M': 305c80476e4SDavid E. O'Brien case 'X': 306c80476e4SDavid E. O'Brien case 'C': 3073b6eaa7bSAndrey A. Chernov #ifdef WINNT_NATIVE 308c80476e4SDavid E. O'Brien case 'N': 3093b6eaa7bSAndrey A. Chernov #endif /* WINNT_NATIVE */ 310c80476e4SDavid E. O'Brien if (s[1] != '-' || s[2] == '\0') { 311c80476e4SDavid E. O'Brien bad_spec(s); 312c80476e4SDavid E. O'Brien return NULL; 313c80476e4SDavid E. O'Brien } 314c80476e4SDavid E. O'Brien s += 2; 315c80476e4SDavid E. O'Brien switch (s[-2]) { 316c80476e4SDavid E. O'Brien case 'F': case 'f': /* Turn into ^[str */ 317c80476e4SDavid E. O'Brien *b++ = CTL_ESC('\033'); 318c80476e4SDavid E. O'Brien while ((*b++ = *s++) != '\0') 319c80476e4SDavid E. O'Brien continue; 320c80476e4SDavid E. O'Brien b--; 321c80476e4SDavid E. O'Brien break; 322c80476e4SDavid E. O'Brien 323c80476e4SDavid E. O'Brien case 'C': case 'c': /* Turn into ^c */ 3243b6eaa7bSAndrey A. Chernov #ifdef IS_ASCII 325c80476e4SDavid E. O'Brien *b++ = (*s == '?') ? '\177' : ((*s & CHAR) & 0237); 3263b6eaa7bSAndrey A. Chernov #else 327c80476e4SDavid E. O'Brien *b++ = (*s == '?') ? CTL_ESC('\177') : _toebcdic[_toascii[*s & CHAR] & 0237]; 3283b6eaa7bSAndrey A. Chernov #endif 329c80476e4SDavid E. O'Brien *b = '\0'; 330c80476e4SDavid E. O'Brien break; 331c80476e4SDavid E. O'Brien 332c80476e4SDavid E. O'Brien case 'X' : case 'x': /* Turn into ^Xc */ 3333b6eaa7bSAndrey A. Chernov #ifdef IS_ASCII 334c80476e4SDavid E. O'Brien *b++ = 'X' & 0237; 3353b6eaa7bSAndrey A. Chernov #else 336c80476e4SDavid E. O'Brien *b++ = _toebcdic[_toascii['X'] & 0237]; 3373b6eaa7bSAndrey A. Chernov #endif 338c80476e4SDavid E. O'Brien *b++ = *s; 339c80476e4SDavid E. O'Brien *b = '\0'; 340c80476e4SDavid E. O'Brien break; 341c80476e4SDavid E. O'Brien 342c80476e4SDavid E. O'Brien case 'M' : case 'm': /* Turn into 0x80|c */ 343c80476e4SDavid E. O'Brien #ifdef DSPMBYTE 344c80476e4SDavid E. O'Brien if (!NoNLSRebind) { 345c80476e4SDavid E. O'Brien *b++ = CTL_ESC('\033'); 346c80476e4SDavid E. O'Brien *b++ = *s; 347c80476e4SDavid E. O'Brien } else { 348c80476e4SDavid E. O'Brien #endif /* DSPMBYTE */ 3493b6eaa7bSAndrey A. Chernov #ifdef IS_ASCII 350c80476e4SDavid E. O'Brien *b++ = *s | 0x80; 3513b6eaa7bSAndrey A. Chernov #else 352c80476e4SDavid E. O'Brien *b++ = _toebcdic[_toascii[*s] | 0x80]; 3533b6eaa7bSAndrey A. Chernov #endif 354c80476e4SDavid E. O'Brien #ifdef DSPMBYTE 355c80476e4SDavid E. O'Brien } 356c80476e4SDavid E. O'Brien #endif /* DSPMBYTE */ 357c80476e4SDavid E. O'Brien *b = '\0'; 358c80476e4SDavid E. O'Brien break; 3593b6eaa7bSAndrey A. Chernov #ifdef WINNT_NATIVE 360c80476e4SDavid E. O'Brien case 'N' : case 'n': /* NT */ 361c80476e4SDavid E. O'Brien { 362c80476e4SDavid E. O'Brien Char bnt; 363c80476e4SDavid E. O'Brien 364c80476e4SDavid E. O'Brien bnt = nt_translate_bindkey(s); 365c80476e4SDavid E. O'Brien if (bnt != 0) 366c80476e4SDavid E. O'Brien *b++ = bnt; 367c80476e4SDavid E. O'Brien else 368c80476e4SDavid E. O'Brien bad_spec(s); 369c80476e4SDavid E. O'Brien } 370c80476e4SDavid E. O'Brien break; 3713b6eaa7bSAndrey A. Chernov #endif /* WINNT_NATIVE */ 372c80476e4SDavid E. O'Brien 373c80476e4SDavid E. O'Brien default: 374c80476e4SDavid E. O'Brien abort(); 375c80476e4SDavid E. O'Brien /*NOTREACHED*/ 376c80476e4SDavid E. O'Brien return NULL; 377c80476e4SDavid E. O'Brien } 378c80476e4SDavid E. O'Brien break; 379c80476e4SDavid E. O'Brien 380c80476e4SDavid E. O'Brien default: 381c80476e4SDavid E. O'Brien bad_spec(s); 382c80476e4SDavid E. O'Brien return NULL; 383c80476e4SDavid E. O'Brien } 384c80476e4SDavid E. O'Brien 385c80476e4SDavid E. O'Brien str->len = (int) (b - str->buf); 386c80476e4SDavid E. O'Brien return str; 387c80476e4SDavid E. O'Brien } 388c80476e4SDavid E. O'Brien 389c80476e4SDavid E. O'Brien 390c80476e4SDavid E. O'Brien static CStr * 391c80476e4SDavid E. O'Brien parsestring(str, buf) 392c80476e4SDavid E. O'Brien Char *str; 393c80476e4SDavid E. O'Brien CStr *buf; 394c80476e4SDavid E. O'Brien { 395c80476e4SDavid E. O'Brien Char *b; 396c80476e4SDavid E. O'Brien const Char *p; 397c80476e4SDavid E. O'Brien int es; 398c80476e4SDavid E. O'Brien 399c80476e4SDavid E. O'Brien b = buf->buf; 400c80476e4SDavid E. O'Brien if (*str == 0) { 401c80476e4SDavid E. O'Brien xprintf(CGETS(20, 5, "Null string specification\n")); 402c80476e4SDavid E. O'Brien return NULL; 403c80476e4SDavid E. O'Brien } 404c80476e4SDavid E. O'Brien 405c80476e4SDavid E. O'Brien for (p = str; *p != 0; p++) { 406c80476e4SDavid E. O'Brien if ((*p & CHAR) == '\\' || (*p & CHAR) == '^') { 407c80476e4SDavid E. O'Brien if ((es = parseescape(&p)) == -1) 408c80476e4SDavid E. O'Brien return 0; 409c80476e4SDavid E. O'Brien else 410c80476e4SDavid E. O'Brien *b++ = (Char) es; 411c80476e4SDavid E. O'Brien } 412c80476e4SDavid E. O'Brien else 413c80476e4SDavid E. O'Brien *b++ = *p & CHAR; 414c80476e4SDavid E. O'Brien } 415c80476e4SDavid E. O'Brien *b = 0; 416c80476e4SDavid E. O'Brien buf->len = (int) (b - buf->buf); 417c80476e4SDavid E. O'Brien return buf; 418c80476e4SDavid E. O'Brien } 419c80476e4SDavid E. O'Brien 420c80476e4SDavid E. O'Brien static void 421c80476e4SDavid E. O'Brien print_all_keys() 422c80476e4SDavid E. O'Brien { 423c80476e4SDavid E. O'Brien int prev, i; 424c80476e4SDavid E. O'Brien CStr nilstr; 425c80476e4SDavid E. O'Brien nilstr.buf = NULL; 426c80476e4SDavid E. O'Brien nilstr.len = 0; 427c80476e4SDavid E. O'Brien 428c80476e4SDavid E. O'Brien 429c80476e4SDavid E. O'Brien xprintf(CGETS(20, 6, "Standard key bindings\n")); 430c80476e4SDavid E. O'Brien prev = 0; 431c80476e4SDavid E. O'Brien for (i = 0; i < 256; i++) { 432c80476e4SDavid E. O'Brien if (CcKeyMap[prev] == CcKeyMap[i]) 433c80476e4SDavid E. O'Brien continue; 434c80476e4SDavid E. O'Brien printkeys(CcKeyMap, prev, i - 1); 435c80476e4SDavid E. O'Brien prev = i; 436c80476e4SDavid E. O'Brien } 437c80476e4SDavid E. O'Brien printkeys(CcKeyMap, prev, i - 1); 438c80476e4SDavid E. O'Brien 439c80476e4SDavid E. O'Brien xprintf(CGETS(20, 7, "Alternative key bindings\n")); 440c80476e4SDavid E. O'Brien prev = 0; 441c80476e4SDavid E. O'Brien for (i = 0; i < 256; i++) { 442c80476e4SDavid E. O'Brien if (CcAltMap[prev] == CcAltMap[i]) 443c80476e4SDavid E. O'Brien continue; 444c80476e4SDavid E. O'Brien printkeys(CcAltMap, prev, i - 1); 445c80476e4SDavid E. O'Brien prev = i; 446c80476e4SDavid E. O'Brien } 447c80476e4SDavid E. O'Brien printkeys(CcAltMap, prev, i - 1); 448c80476e4SDavid E. O'Brien xprintf(CGETS(20, 8, "Multi-character bindings\n")); 449c80476e4SDavid E. O'Brien PrintXkey(NULL); /* print all Xkey bindings */ 450c80476e4SDavid E. O'Brien xprintf(CGETS(20, 9, "Arrow key bindings\n")); 451c80476e4SDavid E. O'Brien PrintArrowKeys(&nilstr); 452c80476e4SDavid E. O'Brien } 453c80476e4SDavid E. O'Brien 454c80476e4SDavid E. O'Brien static void 455c80476e4SDavid E. O'Brien printkeys(map, first, last) 456c80476e4SDavid E. O'Brien KEYCMD *map; 457c80476e4SDavid E. O'Brien int first, last; 458c80476e4SDavid E. O'Brien { 459c80476e4SDavid E. O'Brien register struct KeyFuncs *fp; 460c80476e4SDavid E. O'Brien Char firstbuf[2], lastbuf[2]; 461c80476e4SDavid E. O'Brien CStr fb, lb; 462c80476e4SDavid E. O'Brien unsigned char unparsbuf[10], extrabuf[10]; 463c80476e4SDavid E. O'Brien fb.buf = firstbuf; 464c80476e4SDavid E. O'Brien lb.buf = lastbuf; 465c80476e4SDavid E. O'Brien 466c80476e4SDavid E. O'Brien firstbuf[0] = (Char) first; 467c80476e4SDavid E. O'Brien firstbuf[1] = 0; 468c80476e4SDavid E. O'Brien lastbuf[0] = (Char) last; 469c80476e4SDavid E. O'Brien lastbuf[1] = 0; 470c80476e4SDavid E. O'Brien fb.len = 1; 471c80476e4SDavid E. O'Brien lb.len = 1; 472c80476e4SDavid E. O'Brien 473c80476e4SDavid E. O'Brien if (map[first] == F_UNASSIGNED) { 474c80476e4SDavid E. O'Brien if (first == last) 475c80476e4SDavid E. O'Brien xprintf(CGETS(20, 10, "%-15s-> is undefined\n"), 476c80476e4SDavid E. O'Brien unparsestring(&fb, unparsbuf, STRQQ)); 477c80476e4SDavid E. O'Brien return; 478c80476e4SDavid E. O'Brien } 479c80476e4SDavid E. O'Brien 480c80476e4SDavid E. O'Brien for (fp = FuncNames; fp->name; fp++) { 481c80476e4SDavid E. O'Brien if (fp->func == map[first]) { 482c80476e4SDavid E. O'Brien if (first == last) { 483c80476e4SDavid E. O'Brien xprintf("%-15s-> %s\n", 484c80476e4SDavid E. O'Brien unparsestring(&fb, unparsbuf, STRQQ), fp->name); 485c80476e4SDavid E. O'Brien } 486c80476e4SDavid E. O'Brien else { 487c80476e4SDavid E. O'Brien xprintf("%-4s to %-7s-> %s\n", 488c80476e4SDavid E. O'Brien unparsestring(&fb, unparsbuf, STRQQ), 489c80476e4SDavid E. O'Brien unparsestring(&lb, extrabuf, STRQQ), fp->name); 490c80476e4SDavid E. O'Brien } 491c80476e4SDavid E. O'Brien return; 492c80476e4SDavid E. O'Brien } 493c80476e4SDavid E. O'Brien } 494c80476e4SDavid E. O'Brien if (map == CcKeyMap) { 495c80476e4SDavid E. O'Brien xprintf(CGETS(20, 11, "BUG!!! %s isn't bound to anything.\n"), 496c80476e4SDavid E. O'Brien unparsestring(&fb, unparsbuf, STRQQ)); 497c80476e4SDavid E. O'Brien xprintf("CcKeyMap[%d] == %d\n", first, CcKeyMap[first]); 498c80476e4SDavid E. O'Brien } 499c80476e4SDavid E. O'Brien else { 500c80476e4SDavid E. O'Brien xprintf(CGETS(20, 11, "BUG!!! %s isn't bound to anything.\n"), 501c80476e4SDavid E. O'Brien unparsestring(&fb, unparsbuf, STRQQ)); 502c80476e4SDavid E. O'Brien xprintf("CcAltMap[%d] == %d\n", first, CcAltMap[first]); 503c80476e4SDavid E. O'Brien } 504c80476e4SDavid E. O'Brien } 505c80476e4SDavid E. O'Brien 506c80476e4SDavid E. O'Brien static void 507c80476e4SDavid E. O'Brien bindkey_usage() 508c80476e4SDavid E. O'Brien { 509c80476e4SDavid E. O'Brien xprintf(CGETS(20, 12, 510c80476e4SDavid E. O'Brien "Usage: bindkey [options] [--] [KEY [COMMAND]]\n")); 511c80476e4SDavid E. O'Brien xprintf(CGETS(20, 13, 512c80476e4SDavid E. O'Brien " -a list or bind KEY in alternative key map\n")); 513c80476e4SDavid E. O'Brien xprintf(CGETS(20, 14, 514c80476e4SDavid E. O'Brien " -b interpret KEY as a C-, M-, F- or X- key name\n")); 515c80476e4SDavid E. O'Brien xprintf(CGETS(20, 15, 516c80476e4SDavid E. O'Brien " -s interpret COMMAND as a literal string to be output\n")); 517c80476e4SDavid E. O'Brien xprintf(CGETS(20, 16, 518c80476e4SDavid E. O'Brien " -c interpret COMMAND as a builtin or external command\n")); 519c80476e4SDavid E. O'Brien xprintf(CGETS(20, 17, 520c80476e4SDavid E. O'Brien " -v bind all keys to vi bindings\n")); 521c80476e4SDavid E. O'Brien xprintf(CGETS(20, 18, 522c80476e4SDavid E. O'Brien " -e bind all keys to emacs bindings\n")); 523c80476e4SDavid E. O'Brien xprintf(CGETS(20, 19, 524c80476e4SDavid E. O'Brien " -d bind all keys to default editor's bindings\n")); 525c80476e4SDavid E. O'Brien xprintf(CGETS(20, 20, 526c80476e4SDavid E. O'Brien " -l list editor commands with descriptions\n")); 527c80476e4SDavid E. O'Brien xprintf(CGETS(20, 21, 528c80476e4SDavid E. O'Brien " -r remove KEY's binding\n")); 529c80476e4SDavid E. O'Brien xprintf(CGETS(20, 22, 530c80476e4SDavid E. O'Brien " -k interpret KEY as a symbolic arrow-key name\n")); 531c80476e4SDavid E. O'Brien xprintf(CGETS(20, 23, 532c80476e4SDavid E. O'Brien " -- force a break from option processing\n")); 533c80476e4SDavid E. O'Brien xprintf(CGETS(20, 24, 534c80476e4SDavid E. O'Brien " -u (or any invalid option) this message\n")); 535c80476e4SDavid E. O'Brien xprintf("\n"); 536c80476e4SDavid E. O'Brien xprintf(CGETS(20, 25, 537c80476e4SDavid E. O'Brien "Without KEY or COMMAND, prints all bindings\n")); 538c80476e4SDavid E. O'Brien xprintf(CGETS(20, 26, 539c80476e4SDavid E. O'Brien "Without COMMAND, prints the binding for KEY.\n")); 540c80476e4SDavid E. O'Brien } 541c80476e4SDavid E. O'Brien 542c80476e4SDavid E. O'Brien static void 543c80476e4SDavid E. O'Brien list_functions() 544c80476e4SDavid E. O'Brien { 545c80476e4SDavid E. O'Brien register struct KeyFuncs *fp; 546c80476e4SDavid E. O'Brien 547c80476e4SDavid E. O'Brien for (fp = FuncNames; fp->name; fp++) { 548c80476e4SDavid E. O'Brien xprintf("%s\n %s\n", fp->name, fp->desc); 549c80476e4SDavid E. O'Brien } 550c80476e4SDavid E. O'Brien } 551c80476e4SDavid E. O'Brien 552c80476e4SDavid E. O'Brien #ifdef OBSOLETE 553c80476e4SDavid E. O'Brien 554c80476e4SDavid E. O'Brien /* 555c80476e4SDavid E. O'Brien * Unfortunately the apollo optimizer does not like & operations 556c80476e4SDavid E. O'Brien * with 0377, and produces illegal instructions. So we make it 557c80476e4SDavid E. O'Brien * an unsigned char, and hope for the best. 558c80476e4SDavid E. O'Brien * Of-course the compiler is smart enough to produce bad assembly 559c80476e4SDavid E. O'Brien * language instructions, but dumb when it comes to fold the constant :-) 560c80476e4SDavid E. O'Brien */ 561c80476e4SDavid E. O'Brien #ifdef apollo 562c80476e4SDavid E. O'Brien static unsigned char APOLLO_0377 = 0377; 563c80476e4SDavid E. O'Brien #else /* sane */ 564c80476e4SDavid E. O'Brien # define APOLLO_0377 0377 565c80476e4SDavid E. O'Brien #endif /* apollo */ 566c80476e4SDavid E. O'Brien 567c80476e4SDavid E. O'Brien static int 568c80476e4SDavid E. O'Brien tocontrol(c) 569c80476e4SDavid E. O'Brien int c; 570c80476e4SDavid E. O'Brien { 571c80476e4SDavid E. O'Brien c &= CHAR; 572c80476e4SDavid E. O'Brien if (Islower(c)) 573c80476e4SDavid E. O'Brien c = Toupper(c); 574c80476e4SDavid E. O'Brien else if (c == ' ') 575c80476e4SDavid E. O'Brien c = '@'; 576c80476e4SDavid E. O'Brien if (c == '?') 577c80476e4SDavid E. O'Brien c = CTL_ESC('\177'); 578c80476e4SDavid E. O'Brien else 5793b6eaa7bSAndrey A. Chernov #ifdef IS_ASCII 580c80476e4SDavid E. O'Brien c &= 037; 5813b6eaa7bSAndrey A. Chernov #else 5823b6eaa7bSAndrey A. Chernov /* EBCDIC: simulate ASCII-behavior by transforming to ASCII and back */ 583c80476e4SDavid E. O'Brien c = _toebcdic[_toascii[c] & 037]; 584c80476e4SDavid E. O'Brien #endif 585c80476e4SDavid E. O'Brien return (c); 586c80476e4SDavid E. O'Brien } 587c80476e4SDavid E. O'Brien 588c80476e4SDavid E. O'Brien static char * 589c80476e4SDavid E. O'Brien unparsekey(c) /* 'c' -> "c", '^C' -> "^" + "C" */ 590c80476e4SDavid E. O'Brien register int c; 591c80476e4SDavid E. O'Brien { 592c80476e4SDavid E. O'Brien register char *cp; 593c80476e4SDavid E. O'Brien static char tmp[10]; 594c80476e4SDavid E. O'Brien 595c80476e4SDavid E. O'Brien cp = tmp; 596c80476e4SDavid E. O'Brien 597c80476e4SDavid E. O'Brien if (c & 0400) { 598c80476e4SDavid E. O'Brien *cp++ = 'A'; 599c80476e4SDavid E. O'Brien *cp++ = '-'; 600c80476e4SDavid E. O'Brien c &= APOLLO_0377; 601c80476e4SDavid E. O'Brien } 602c80476e4SDavid E. O'Brien if ((c & META) && !(Isprint(c) || (Iscntrl(c) && Isprint(c | 0100)))) { 603c80476e4SDavid E. O'Brien *cp++ = 'M'; 604c80476e4SDavid E. O'Brien *cp++ = '-'; 605c80476e4SDavid E. O'Brien c &= ASCII; 606c80476e4SDavid E. O'Brien } 607c80476e4SDavid E. O'Brien if (Isprint(c)) { 608c80476e4SDavid E. O'Brien *cp++ = (char) c; 609c80476e4SDavid E. O'Brien *cp = '\0'; 610c80476e4SDavid E. O'Brien return (tmp); 611c80476e4SDavid E. O'Brien } 612c80476e4SDavid E. O'Brien switch (c) { 613c80476e4SDavid E. O'Brien case ' ': 614c80476e4SDavid E. O'Brien (void) strcpy(cp, "Spc"); 615c80476e4SDavid E. O'Brien return (tmp); 616c80476e4SDavid E. O'Brien case '\n': 617c80476e4SDavid E. O'Brien (void) strcpy(cp, "Lfd"); 618c80476e4SDavid E. O'Brien return (tmp); 619c80476e4SDavid E. O'Brien case '\r': 620c80476e4SDavid E. O'Brien (void) strcpy(cp, "Ret"); 621c80476e4SDavid E. O'Brien return (tmp); 622c80476e4SDavid E. O'Brien case '\t': 623c80476e4SDavid E. O'Brien (void) strcpy(cp, "Tab"); 624c80476e4SDavid E. O'Brien return (tmp); 6253b6eaa7bSAndrey A. Chernov #ifdef IS_ASCII 626c80476e4SDavid E. O'Brien case '\033': 627c80476e4SDavid E. O'Brien (void) strcpy(cp, "Esc"); 628c80476e4SDavid E. O'Brien return (tmp); 629c80476e4SDavid E. O'Brien case '\177': 630c80476e4SDavid E. O'Brien (void) strcpy(cp, "Del"); 631c80476e4SDavid E. O'Brien return (tmp); 632c80476e4SDavid E. O'Brien default: 633c80476e4SDavid E. O'Brien *cp++ = '^'; 634c80476e4SDavid E. O'Brien if (c == '\177') { 635c80476e4SDavid E. O'Brien *cp++ = '?'; 636c80476e4SDavid E. O'Brien } 637c80476e4SDavid E. O'Brien else { 638c80476e4SDavid E. O'Brien *cp++ = c | 0100; 639c80476e4SDavid E. O'Brien } 640c80476e4SDavid E. O'Brien *cp = '\0'; 641c80476e4SDavid E. O'Brien return (tmp); 6423b6eaa7bSAndrey A. Chernov #else /* IS_ASCII */ 643c80476e4SDavid E. O'Brien default: 644c80476e4SDavid E. O'Brien if (*cp == CTL_ESC('\033')) { 645c80476e4SDavid E. O'Brien (void) strcpy(cp, "Esc"); 646c80476e4SDavid E. O'Brien return (tmp); 647c80476e4SDavid E. O'Brien } 648c80476e4SDavid E. O'Brien else if (*cp == CTL_ESC('\177')) { 649c80476e4SDavid E. O'Brien (void) strcpy(cp, "Del"); 650c80476e4SDavid E. O'Brien return (tmp); 651c80476e4SDavid E. O'Brien } 652c80476e4SDavid E. O'Brien else if (Isupper(_toebcdic[_toascii[c]|0100]) 653c80476e4SDavid E. O'Brien || strchr("@[\\]^_", _toebcdic[_toascii[c]|0100]) != NULL) { 654c80476e4SDavid E. O'Brien *cp++ = '^'; 655c80476e4SDavid E. O'Brien *cp++ = _toebcdic[_toascii[c]|0100] 656c80476e4SDavid E. O'Brien } 657c80476e4SDavid E. O'Brien else { 658c80476e4SDavid E. O'Brien xsnprintf(cp, 3, "\\%3.3o", c); 659c80476e4SDavid E. O'Brien cp += 4; 660c80476e4SDavid E. O'Brien } 6613b6eaa7bSAndrey A. Chernov #endif /* IS_ASCII */ 662c80476e4SDavid E. O'Brien } 663c80476e4SDavid E. O'Brien } 664c80476e4SDavid E. O'Brien 665c80476e4SDavid E. O'Brien static KEYCMD 666c80476e4SDavid E. O'Brien getkeycmd(sp) 667c80476e4SDavid E. O'Brien Char **sp; 668c80476e4SDavid E. O'Brien { 669c80476e4SDavid E. O'Brien register Char *s = *sp; 670c80476e4SDavid E. O'Brien register char c; 671c80476e4SDavid E. O'Brien register KEYCMD keycmd = F_UNASSIGNED; 672c80476e4SDavid E. O'Brien KEYCMD *map; 673c80476e4SDavid E. O'Brien int meta = 0; 674c80476e4SDavid E. O'Brien Char *ret_sp = s; 675c80476e4SDavid E. O'Brien 676c80476e4SDavid E. O'Brien map = CcKeyMap; 677c80476e4SDavid E. O'Brien 678c80476e4SDavid E. O'Brien while (*s) { 679c80476e4SDavid E. O'Brien if (*s == '^' && s[1]) { 680c80476e4SDavid E. O'Brien s++; 681c80476e4SDavid E. O'Brien c = tocontrol(*s++); 682c80476e4SDavid E. O'Brien } 683c80476e4SDavid E. O'Brien else 684c80476e4SDavid E. O'Brien c = *s++; 685c80476e4SDavid E. O'Brien 686c80476e4SDavid E. O'Brien if (*s == '\0') 687c80476e4SDavid E. O'Brien break; 688c80476e4SDavid E. O'Brien 689c80476e4SDavid E. O'Brien switch (map[c | meta]) { 690c80476e4SDavid E. O'Brien case F_METANEXT: 691c80476e4SDavid E. O'Brien meta = META; 692c80476e4SDavid E. O'Brien keycmd = F_METANEXT; 693c80476e4SDavid E. O'Brien ret_sp = s; 694c80476e4SDavid E. O'Brien break; 695c80476e4SDavid E. O'Brien 696c80476e4SDavid E. O'Brien case F_XKEY: 697c80476e4SDavid E. O'Brien keycmd = F_XKEY; 698c80476e4SDavid E. O'Brien ret_sp = s; 699c80476e4SDavid E. O'Brien /* FALLTHROUGH */ 700c80476e4SDavid E. O'Brien 701c80476e4SDavid E. O'Brien default: 702c80476e4SDavid E. O'Brien *sp = ret_sp; 703c80476e4SDavid E. O'Brien return (keycmd); 704c80476e4SDavid E. O'Brien 705c80476e4SDavid E. O'Brien } 706c80476e4SDavid E. O'Brien } 707c80476e4SDavid E. O'Brien *sp = ret_sp; 708c80476e4SDavid E. O'Brien return (keycmd); 709c80476e4SDavid E. O'Brien } 710c80476e4SDavid E. O'Brien 711c80476e4SDavid E. O'Brien static int 712c80476e4SDavid E. O'Brien parsekey(sp) 713c80476e4SDavid E. O'Brien Char **sp; /* Return position of first unparsed character 714c80476e4SDavid E. O'Brien * for return value -2 (xkeynext) */ 715c80476e4SDavid E. O'Brien { 716c80476e4SDavid E. O'Brien register int c, meta = 0, control = 0, ctrlx = 0; 717c80476e4SDavid E. O'Brien Char *s = *sp; 718c80476e4SDavid E. O'Brien KEYCMD keycmd; 719c80476e4SDavid E. O'Brien 720c80476e4SDavid E. O'Brien if (s == NULL) { 721c80476e4SDavid E. O'Brien xprintf(CGETS(20, 27, "bad key specification -- null string\n")); 722c80476e4SDavid E. O'Brien return -1; 723c80476e4SDavid E. O'Brien } 724c80476e4SDavid E. O'Brien if (*s == 0) { 725c80476e4SDavid E. O'Brien xprintf(CGETS(20, 28, "bad key specification -- empty string\n")); 726c80476e4SDavid E. O'Brien return -1; 727c80476e4SDavid E. O'Brien } 728c80476e4SDavid E. O'Brien 729c80476e4SDavid E. O'Brien (void) strip(s); /* trim to 7 bits. */ 730c80476e4SDavid E. O'Brien 731c80476e4SDavid E. O'Brien if (s[1] == 0) /* single char */ 732c80476e4SDavid E. O'Brien return (s[0] & APOLLO_0377); 733c80476e4SDavid E. O'Brien 734c80476e4SDavid E. O'Brien if ((s[0] == 'F' || s[0] == 'f') && s[1] == '-') { 735c80476e4SDavid E. O'Brien if (s[2] == 0) { 736c80476e4SDavid E. O'Brien xprintf(CGETS(20, 29, 737c80476e4SDavid E. O'Brien "Bad function-key specification. Null key not allowed\n")); 738c80476e4SDavid E. O'Brien return (-1); 739c80476e4SDavid E. O'Brien } 740c80476e4SDavid E. O'Brien *sp = s + 2; 741c80476e4SDavid E. O'Brien return (-2); 742c80476e4SDavid E. O'Brien } 743c80476e4SDavid E. O'Brien 744c80476e4SDavid E. O'Brien if (s[0] == '0' && s[1] == 'x') { /* if 0xn, then assume number */ 745c80476e4SDavid E. O'Brien c = 0; 746c80476e4SDavid E. O'Brien for (s += 2; *s; s++) { /* convert to hex; skip the first 0 */ 747c80476e4SDavid E. O'Brien c *= 16; 748c80476e4SDavid E. O'Brien if (!Isxdigit(*s)) { 749c80476e4SDavid E. O'Brien xprintf(CGETS(20, 30, 750c80476e4SDavid E. O'Brien "bad key specification -- malformed hex number\n")); 751c80476e4SDavid E. O'Brien return -1; /* error */ 752c80476e4SDavid E. O'Brien } 753c80476e4SDavid E. O'Brien if (Isdigit(*s)) 754c80476e4SDavid E. O'Brien c += *s - '0'; 755c80476e4SDavid E. O'Brien else if (*s >= 'a' && *s <= 'f') 756c80476e4SDavid E. O'Brien c += *s - 'a' + 0xA; 757c80476e4SDavid E. O'Brien else if (*s >= 'F' && *s <= 'F') 758c80476e4SDavid E. O'Brien c += *s - 'A' + 0xA; 759c80476e4SDavid E. O'Brien } 760c80476e4SDavid E. O'Brien } 761c80476e4SDavid E. O'Brien else if (s[0] == '0' && Isdigit(s[1])) { /* if 0n, then assume number */ 762c80476e4SDavid E. O'Brien c = 0; 763c80476e4SDavid E. O'Brien for (s++; *s; s++) { /* convert to octal; skip the first 0 */ 764c80476e4SDavid E. O'Brien if (!Isdigit(*s) || *s == '8' || *s == '9') { 765c80476e4SDavid E. O'Brien xprintf(CGETS(20, 31, 766c80476e4SDavid E. O'Brien "bad key specification -- malformed octal number\n")); 767c80476e4SDavid E. O'Brien return -1; /* error */ 768c80476e4SDavid E. O'Brien } 769c80476e4SDavid E. O'Brien c = (c * 8) + *s - '0'; 770c80476e4SDavid E. O'Brien } 771c80476e4SDavid E. O'Brien } 772c80476e4SDavid E. O'Brien else if (Isdigit(s[0]) && Isdigit(s[1])) { /* decimal number */ 773c80476e4SDavid E. O'Brien c = 0; 774c80476e4SDavid E. O'Brien for (; *s; s++) { /* convert to octal; skip the first 0 */ 775c80476e4SDavid E. O'Brien if (!Isdigit(*s)) { 776c80476e4SDavid E. O'Brien xprintf(CGETS(20, 32, 777c80476e4SDavid E. O'Brien "bad key specification -- malformed decimal number\n")); 778c80476e4SDavid E. O'Brien return -1; /* error */ 779c80476e4SDavid E. O'Brien } 780c80476e4SDavid E. O'Brien c = (c * 10) + *s - '0'; 781c80476e4SDavid E. O'Brien } 782c80476e4SDavid E. O'Brien } 783c80476e4SDavid E. O'Brien else { 784c80476e4SDavid E. O'Brien keycmd = getkeycmd(&s); 785c80476e4SDavid E. O'Brien 786c80476e4SDavid E. O'Brien if ((s[0] == 'X' || s[0] == 'x') && s[1] == '-') { /* X- */ 787c80476e4SDavid E. O'Brien ctrlx++; 788c80476e4SDavid E. O'Brien s += 2; 789c80476e4SDavid E. O'Brien keycmd = getkeycmd(&s); 790c80476e4SDavid E. O'Brien } 791c80476e4SDavid E. O'Brien if ((*s == 'm' || *s == 'M') && s[1] == '-') { /* meta */ 792c80476e4SDavid E. O'Brien meta++; 793c80476e4SDavid E. O'Brien s += 2; 794c80476e4SDavid E. O'Brien keycmd = getkeycmd(&s); 795c80476e4SDavid E. O'Brien } 796c80476e4SDavid E. O'Brien else if (keycmd == F_METANEXT && *s) { /* meta */ 797c80476e4SDavid E. O'Brien meta++; 798c80476e4SDavid E. O'Brien keycmd = getkeycmd(&s); 799c80476e4SDavid E. O'Brien } 800c80476e4SDavid E. O'Brien if (*s == '^' && s[1]) { 801c80476e4SDavid E. O'Brien control++; 802c80476e4SDavid E. O'Brien s++; 803c80476e4SDavid E. O'Brien keycmd = getkeycmd(&s); 804c80476e4SDavid E. O'Brien } 805c80476e4SDavid E. O'Brien else if ((*s == 'c' || *s == 'C') && s[1] == '-') { /* control */ 806c80476e4SDavid E. O'Brien control++; 807c80476e4SDavid E. O'Brien s += 2; 808c80476e4SDavid E. O'Brien keycmd = getkeycmd(&s); 809c80476e4SDavid E. O'Brien } 810c80476e4SDavid E. O'Brien 811c80476e4SDavid E. O'Brien if (keycmd == F_XKEY) { 812c80476e4SDavid E. O'Brien if (*s == 0) { 813c80476e4SDavid E. O'Brien xprintf(CGETS(20, 33, 814c80476e4SDavid E. O'Brien "Bad function-key specification.\n")); 815c80476e4SDavid E. O'Brien xprintf(CGETS(20, 34, "Null key not allowed\n")); 816c80476e4SDavid E. O'Brien return (-1); 817c80476e4SDavid E. O'Brien } 818c80476e4SDavid E. O'Brien *sp = s; 819c80476e4SDavid E. O'Brien return (-2); 820c80476e4SDavid E. O'Brien } 821c80476e4SDavid E. O'Brien 822c80476e4SDavid E. O'Brien if (s[1] != 0) { /* if symbolic name */ 823c80476e4SDavid E. O'Brien char *ts; 824c80476e4SDavid E. O'Brien 825c80476e4SDavid E. O'Brien ts = short2str(s); 826c80476e4SDavid E. O'Brien if (!strcmp(ts, "space") || !strcmp(ts, "Spc")) 827c80476e4SDavid E. O'Brien c = ' '; 828c80476e4SDavid E. O'Brien else if (!strcmp(ts, "return") || !strcmp(ts, "Ret")) 829c80476e4SDavid E. O'Brien c = '\r'; 830c80476e4SDavid E. O'Brien else if (!strcmp(ts, "newline") || !strcmp(ts, "Lfd")) 831c80476e4SDavid E. O'Brien c = '\n'; 832c80476e4SDavid E. O'Brien else if (!strcmp(ts, "linefeed")) 833c80476e4SDavid E. O'Brien c = '\n'; 834c80476e4SDavid E. O'Brien else if (!strcmp(ts, "tab")) 835c80476e4SDavid E. O'Brien c = '\t'; 836c80476e4SDavid E. O'Brien else if (!strcmp(ts, "escape") || !strcmp(ts, "Esc")) 837c80476e4SDavid E. O'Brien c = CTL_ESC('\033'); 838c80476e4SDavid E. O'Brien else if (!strcmp(ts, "backspace")) 839c80476e4SDavid E. O'Brien c = '\b'; 840c80476e4SDavid E. O'Brien else if (!strcmp(ts, "delete")) 841c80476e4SDavid E. O'Brien c = CTL_ESC('\177'); 842c80476e4SDavid E. O'Brien else { 843c80476e4SDavid E. O'Brien xprintf(CGETS(20, 35, 844c80476e4SDavid E. O'Brien "bad key specification -- unknown name \"%S\"\n"), s); 845c80476e4SDavid E. O'Brien return -1; /* error */ 846c80476e4SDavid E. O'Brien } 847c80476e4SDavid E. O'Brien } 848c80476e4SDavid E. O'Brien else 849c80476e4SDavid E. O'Brien c = *s; /* just a single char */ 850c80476e4SDavid E. O'Brien 851c80476e4SDavid E. O'Brien if (control) 852c80476e4SDavid E. O'Brien c = tocontrol(c); 853c80476e4SDavid E. O'Brien if (meta) 854c80476e4SDavid E. O'Brien c |= META; 855c80476e4SDavid E. O'Brien if (ctrlx) 856c80476e4SDavid E. O'Brien c |= 0400; 857c80476e4SDavid E. O'Brien } 858c80476e4SDavid E. O'Brien return (c & 0777); 859c80476e4SDavid E. O'Brien } 860c80476e4SDavid E. O'Brien 861c80476e4SDavid E. O'Brien 862c80476e4SDavid E. O'Brien /*ARGSUSED*/ 863c80476e4SDavid E. O'Brien void 864c80476e4SDavid E. O'Brien dobind(v, dummy) 865c80476e4SDavid E. O'Brien register Char **v; 866c80476e4SDavid E. O'Brien struct command *dummy; 867c80476e4SDavid E. O'Brien { 868c80476e4SDavid E. O'Brien register int c; 869c80476e4SDavid E. O'Brien register struct KeyFuncs *fp; 870c80476e4SDavid E. O'Brien register int i, prev; 871c80476e4SDavid E. O'Brien Char *p, *l; 872c80476e4SDavid E. O'Brien CStr cstr; 873c80476e4SDavid E. O'Brien Char buf[1000]; 874c80476e4SDavid E. O'Brien 875c80476e4SDavid E. O'Brien USE(dummy); 876c80476e4SDavid E. O'Brien /* 877c80476e4SDavid E. O'Brien * Assume at this point that i'm given 2 or 3 args - 'bind', the f-name, 878c80476e4SDavid E. O'Brien * and the key; or 'bind' key to print the func for that key. 879c80476e4SDavid E. O'Brien */ 880c80476e4SDavid E. O'Brien 881c80476e4SDavid E. O'Brien if (!MapsAreInited) 882c80476e4SDavid E. O'Brien ed_InitMaps(); 883c80476e4SDavid E. O'Brien 884c80476e4SDavid E. O'Brien if (v[1] && v[2] && v[3]) { 885c80476e4SDavid E. O'Brien xprintf(CGETS(20, 36, 886c80476e4SDavid E. O'Brien "usage: bind [KEY | COMMAND KEY | \"emacs\" | \"vi\" | \"-a\"]\n")); 887c80476e4SDavid E. O'Brien return; 888c80476e4SDavid E. O'Brien } 889c80476e4SDavid E. O'Brien 890c80476e4SDavid E. O'Brien if (v[1] && v[2]) { /* if bind FUNCTION KEY */ 891c80476e4SDavid E. O'Brien for (fp = FuncNames; fp->name; fp++) { 892c80476e4SDavid E. O'Brien if (strcmp(short2str(v[1]), fp->name) == 0) { 893c80476e4SDavid E. O'Brien Char *s = v[2]; 894c80476e4SDavid E. O'Brien 895c80476e4SDavid E. O'Brien if ((c = parsekey(&s)) == -1) 896c80476e4SDavid E. O'Brien return; 897c80476e4SDavid E. O'Brien if (c == -2) { /* extended key */ 898c80476e4SDavid E. O'Brien for (i = 0; i < 256; i++) { 899c80476e4SDavid E. O'Brien if (i != CTL_ESC('\033') && (CcKeyMap[i] == F_XKEY || 900c80476e4SDavid E. O'Brien CcAltMap[i] == F_XKEY)) { 901c80476e4SDavid E. O'Brien p = buf; 9023b6eaa7bSAndrey A. Chernov #ifdef IS_ASCII 903c80476e4SDavid E. O'Brien if (i > 0177) { 904c80476e4SDavid E. O'Brien *p++ = 033; 905c80476e4SDavid E. O'Brien *p++ = i & ASCII; 906c80476e4SDavid E. O'Brien } 907c80476e4SDavid E. O'Brien else { 908c80476e4SDavid E. O'Brien *p++ = (Char) i; 909c80476e4SDavid E. O'Brien } 9103b6eaa7bSAndrey A. Chernov #else 911c80476e4SDavid E. O'Brien *p++ = (Char) i; 9123b6eaa7bSAndrey A. Chernov #endif 913c80476e4SDavid E. O'Brien for (l = s; *l != 0; l++) { 914c80476e4SDavid E. O'Brien *p++ = *l; 915c80476e4SDavid E. O'Brien } 916c80476e4SDavid E. O'Brien *p = 0; 917c80476e4SDavid E. O'Brien cstr.buf = buf; 918c80476e4SDavid E. O'Brien cstr.len = Strlen(buf); 919c80476e4SDavid E. O'Brien AddXkey(&cstr, XmapCmd(fp->func), XK_CMD); 920c80476e4SDavid E. O'Brien } 921c80476e4SDavid E. O'Brien } 922c80476e4SDavid E. O'Brien return; 923c80476e4SDavid E. O'Brien } 924c80476e4SDavid E. O'Brien if (c & 0400) { 925c80476e4SDavid E. O'Brien if (VImode) { 926c80476e4SDavid E. O'Brien CcAltMap[c & APOLLO_0377] = fp->func; 927c80476e4SDavid E. O'Brien /* bind the vi cmd mode key */ 928c80476e4SDavid E. O'Brien if (c & META) { 929c80476e4SDavid E. O'Brien buf[0] = CTL_ESC('\033'); 930c80476e4SDavid E. O'Brien buf[1] = c & ASCII; 931c80476e4SDavid E. O'Brien buf[2] = 0; 932c80476e4SDavid E. O'Brien cstr.buf = buf; 933c80476e4SDavid E. O'Brien cstr.len = Strlen(buf); 934c80476e4SDavid E. O'Brien AddXkey(&cstr, XmapCmd(fp->func), XK_CMD); 935c80476e4SDavid E. O'Brien } 936c80476e4SDavid E. O'Brien } 937c80476e4SDavid E. O'Brien else { 938c80476e4SDavid E. O'Brien buf[0] = CTL_ESC('\030'); /* ^X */ 939c80476e4SDavid E. O'Brien buf[1] = c & APOLLO_0377; 940c80476e4SDavid E. O'Brien buf[2] = 0; 941c80476e4SDavid E. O'Brien cstr.buf = buf; 942c80476e4SDavid E. O'Brien cstr.len = Strlen(buf); 943c80476e4SDavid E. O'Brien AddXkey(&cstr, XmapCmd(fp->func), XK_CMD); 944c80476e4SDavid E. O'Brien CcKeyMap[CTL_ESC('\030')] = F_XKEY; 945c80476e4SDavid E. O'Brien } 946c80476e4SDavid E. O'Brien } 947c80476e4SDavid E. O'Brien else { 948c80476e4SDavid E. O'Brien CcKeyMap[c] = fp->func; /* bind the key */ 949c80476e4SDavid E. O'Brien if (c & META) { 950c80476e4SDavid E. O'Brien buf[0] = CTL_ESC('\033'); 951c80476e4SDavid E. O'Brien buf[1] = c & ASCII; 952c80476e4SDavid E. O'Brien buf[2] = 0; 953c80476e4SDavid E. O'Brien cstr.buf = buf; 954c80476e4SDavid E. O'Brien cstr.len = Strlen(buf); 955c80476e4SDavid E. O'Brien AddXkey(&cstr, XmapCmd(fp->func), XK_CMD); 956c80476e4SDavid E. O'Brien } 957c80476e4SDavid E. O'Brien } 958c80476e4SDavid E. O'Brien return; 959c80476e4SDavid E. O'Brien } 960c80476e4SDavid E. O'Brien } 961c80476e4SDavid E. O'Brien stderror(ERR_NAME | ERR_STRING, CGETS(20, 37, "Invalid function")); 962c80476e4SDavid E. O'Brien } 963c80476e4SDavid E. O'Brien else if (v[1]) { 964c80476e4SDavid E. O'Brien char *cv = short2str(v[1]); 965c80476e4SDavid E. O'Brien 966c80476e4SDavid E. O'Brien if (strcmp(cv, "list") == 0) { 967c80476e4SDavid E. O'Brien for (fp = FuncNames; fp->name; fp++) { 968c80476e4SDavid E. O'Brien xprintf("%s\n", fp->name); 969c80476e4SDavid E. O'Brien } 970c80476e4SDavid E. O'Brien return; 971c80476e4SDavid E. O'Brien } 972c80476e4SDavid E. O'Brien if ((strcmp(cv, "emacs") == 0) || 973c80476e4SDavid E. O'Brien #ifndef VIDEFAULT 974c80476e4SDavid E. O'Brien (strcmp(cv, "defaults") == 0) || 975c80476e4SDavid E. O'Brien (strcmp(cv, "default") == 0) || 976c80476e4SDavid E. O'Brien #endif 977c80476e4SDavid E. O'Brien (strcmp(cv, "mg") == 0) || 978c80476e4SDavid E. O'Brien (strcmp(cv, "gnumacs") == 0)) { 979c80476e4SDavid E. O'Brien /* reset keys to default */ 980c80476e4SDavid E. O'Brien ed_InitEmacsMaps(); 981c80476e4SDavid E. O'Brien #ifdef VIDEFAULT 982c80476e4SDavid E. O'Brien } 983c80476e4SDavid E. O'Brien else if ((strcmp(cv, "vi") == 0) 984c80476e4SDavid E. O'Brien || (strcmp(cv, "default") == 0) 985c80476e4SDavid E. O'Brien || (strcmp(cv, "defaults") == 0)) { 986c80476e4SDavid E. O'Brien #else 987c80476e4SDavid E. O'Brien } 988c80476e4SDavid E. O'Brien else if (strcmp(cv, "vi") == 0) { 989c80476e4SDavid E. O'Brien #endif 990c80476e4SDavid E. O'Brien ed_InitVIMaps(); 991c80476e4SDavid E. O'Brien } 992c80476e4SDavid E. O'Brien else { /* want to know what this key does */ 993c80476e4SDavid E. O'Brien Char *s = v[1]; 994c80476e4SDavid E. O'Brien 995c80476e4SDavid E. O'Brien if ((c = parsekey(&s)) == -1) 996c80476e4SDavid E. O'Brien return; 997c80476e4SDavid E. O'Brien if (c == -2) { /* extended key */ 998c80476e4SDavid E. O'Brien cstr.buf = s; 999c80476e4SDavid E. O'Brien cstr.len = Strlen(s); 1000c80476e4SDavid E. O'Brien PrintXkey(&cstr); 1001c80476e4SDavid E. O'Brien return; 1002c80476e4SDavid E. O'Brien } 1003c80476e4SDavid E. O'Brien pkeys(c, c); /* must be regular key */ 1004c80476e4SDavid E. O'Brien } 1005c80476e4SDavid E. O'Brien } 1006c80476e4SDavid E. O'Brien else { /* list all the bindings */ 1007c80476e4SDavid E. O'Brien prev = 0; 1008c80476e4SDavid E. O'Brien for (i = 0; i < 256; i++) { 1009c80476e4SDavid E. O'Brien if (CcKeyMap[prev] == CcKeyMap[i]) 1010c80476e4SDavid E. O'Brien continue; 1011c80476e4SDavid E. O'Brien pkeys(prev, i - 1); 1012c80476e4SDavid E. O'Brien prev = i; 1013c80476e4SDavid E. O'Brien } 1014c80476e4SDavid E. O'Brien pkeys(prev, i - 1); 1015c80476e4SDavid E. O'Brien prev = 0; 1016c80476e4SDavid E. O'Brien for (i = 256; i < 512; i++) { 1017c80476e4SDavid E. O'Brien if (CcAltMap[prev & APOLLO_0377] == CcAltMap[i & APOLLO_0377]) 1018c80476e4SDavid E. O'Brien continue; 1019c80476e4SDavid E. O'Brien pkeys(prev, i - 1); 1020c80476e4SDavid E. O'Brien prev = i; 1021c80476e4SDavid E. O'Brien } 1022c80476e4SDavid E. O'Brien pkeys(prev, i - 1); 1023c80476e4SDavid E. O'Brien cstr.buf = NULL; 1024c80476e4SDavid E. O'Brien cstr.len = 0; 1025c80476e4SDavid E. O'Brien PrintXkey(&cstr); /* print all Xkey bindings */ 1026c80476e4SDavid E. O'Brien } 1027c80476e4SDavid E. O'Brien return; 1028c80476e4SDavid E. O'Brien } 1029c80476e4SDavid E. O'Brien 1030c80476e4SDavid E. O'Brien static void 1031c80476e4SDavid E. O'Brien pkeys(first, last) 1032c80476e4SDavid E. O'Brien register int first, last; 1033c80476e4SDavid E. O'Brien { 1034c80476e4SDavid E. O'Brien register struct KeyFuncs *fp; 1035c80476e4SDavid E. O'Brien register KEYCMD *map; 1036c80476e4SDavid E. O'Brien int mask; 1037c80476e4SDavid E. O'Brien char buf[8]; 1038c80476e4SDavid E. O'Brien 1039c80476e4SDavid E. O'Brien if (last & 0400) { 1040c80476e4SDavid E. O'Brien map = CcAltMap; 1041c80476e4SDavid E. O'Brien first &= APOLLO_0377; 1042c80476e4SDavid E. O'Brien last &= APOLLO_0377; 1043c80476e4SDavid E. O'Brien mask = 0400; 1044c80476e4SDavid E. O'Brien } 1045c80476e4SDavid E. O'Brien else { 1046c80476e4SDavid E. O'Brien map = CcKeyMap; 1047c80476e4SDavid E. O'Brien mask = 0; 1048c80476e4SDavid E. O'Brien } 1049c80476e4SDavid E. O'Brien if (map[first] == F_UNASSIGNED) { 1050c80476e4SDavid E. O'Brien if (first == last) 1051c80476e4SDavid E. O'Brien xprintf(CGETS(20, 38, " %s\t\tis undefined\n"), 1052c80476e4SDavid E. O'Brien unparsekey(first | mask)); 1053c80476e4SDavid E. O'Brien return; 1054c80476e4SDavid E. O'Brien } 1055c80476e4SDavid E. O'Brien 1056c80476e4SDavid E. O'Brien for (fp = FuncNames; fp->name; fp++) { 1057c80476e4SDavid E. O'Brien if (fp->func == map[first]) { 1058c80476e4SDavid E. O'Brien if (first == last) 1059c80476e4SDavid E. O'Brien xprintf(" %s\t\t%s\n", 1060c80476e4SDavid E. O'Brien unparsekey((first & APOLLO_0377) | mask), fp->name); 1061c80476e4SDavid E. O'Brien else { 1062c80476e4SDavid E. O'Brien (void) strcpy(buf, unparsekey((first & APOLLO_0377) | mask)); 1063c80476e4SDavid E. O'Brien xprintf(" %s..%s\t\t%s\n", buf, 1064c80476e4SDavid E. O'Brien unparsekey((last & APOLLO_0377) | mask), fp->name); 1065c80476e4SDavid E. O'Brien } 1066c80476e4SDavid E. O'Brien return; 1067c80476e4SDavid E. O'Brien } 1068c80476e4SDavid E. O'Brien } 1069c80476e4SDavid E. O'Brien if (map == CcKeyMap) { 1070c80476e4SDavid E. O'Brien xprintf(CGETS(20, 11, "BUG!!! %s isn't bound to anything.\n"), 1071c80476e4SDavid E. O'Brien unparsekey(first)); 1072c80476e4SDavid E. O'Brien xprintf("CcKeyMap[%d] == %d\n", first, CcKeyMap[first]); 1073c80476e4SDavid E. O'Brien } 1074c80476e4SDavid E. O'Brien else { 1075c80476e4SDavid E. O'Brien xprintf(CGETS(20, 11, "BUG!!! %s isn't bound to anything.\n"), 1076c80476e4SDavid E. O'Brien unparsekey(first & 0400)); 1077c80476e4SDavid E. O'Brien xprintf("CcAltMap[%d] == %d\n", first, CcAltMap[first]); 1078c80476e4SDavid E. O'Brien } 1079c80476e4SDavid E. O'Brien } 1080c80476e4SDavid E. O'Brien #endif /* OBSOLETE */ 1081