[BACK]Return to tables.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / vim

Annotation of src/usr.bin/vim/tables.c, Revision 1.1.1.1

1.1       downsj      1: /* $OpenBSD$   */
                      2: /* vi:set ts=4 sw=4:
                      3:  *
                      4:  * VIM - Vi IMproved       by Bram Moolenaar
                      5:  *                         This file by Robert Webb
                      6:  *
                      7:  * Do ":help uganda"  in Vim to read copying and usage conditions.
                      8:  * Do ":help credits" in Vim to see a list of people who contributed.
                      9:  */
                     10:
                     11: /*
                     12:  * tables.c: functions that use lookup tables for various things, generally to
                     13:  * do with special key codes.
                     14:  */
                     15:
                     16: #include "vim.h"
                     17: #include "globals.h"
                     18: #include "proto.h"
                     19: #include "option.h"
                     20:
                     21: /*
                     22:  * Some useful tables.
                     23:  */
                     24:
                     25: static struct
                     26: {
                     27:    int     mod_mask;       /* Bit-mask for particular key modifier */
                     28:    char_u  name;           /* Single letter name of modifier */
                     29: } mod_mask_table[] =
                     30: {
                     31:    {MOD_MASK_ALT,      (char_u)'M'},
                     32:    {MOD_MASK_CTRL,     (char_u)'C'},
                     33:    {MOD_MASK_SHIFT,    (char_u)'S'},
                     34:    {MOD_MASK_2CLICK,   (char_u)'2'},
                     35:    {MOD_MASK_3CLICK,   (char_u)'3'},
                     36:    {MOD_MASK_4CLICK,   (char_u)'4'},
                     37:    {0x0,               NUL}
                     38: };
                     39:
                     40: /*
                     41:  * Shifted key terminal codes and their unshifted equivalent.
                     42:  * Don't add mouse codes here, they are handled seperately!
                     43:  */
                     44: static char_u shifted_keys_table[] =
                     45: {
                     46: /*  shifted                unshifted  */
                     47:    '&', '9',               '@', '1',           /* begin */
                     48:    '&', '0',               '@', '2',           /* cancel */
                     49:    '*', '1',               '@', '4',           /* command */
                     50:    '*', '2',               '@', '5',           /* copy */
                     51:    '*', '3',               '@', '6',           /* create */
                     52:    '*', '4',               'k', 'D',           /* delete char */
                     53:    '*', '5',               'k', 'L',           /* delete line */
                     54:    '*', '7',               '@', '7',           /* end */
                     55:    '*', '9',               '@', '9',           /* exit */
                     56:    '*', '0',               '@', '0',           /* find */
                     57:    '#', '1',               '%', '1',           /* help */
                     58:    '#', '2',               'k', 'h',           /* home */
                     59:    '#', '3',               'k', 'I',           /* insert */
                     60:    '#', '4',               'k', 'l',           /* left arrow */
                     61:    '%', 'a',               '%', '3',           /* message */
                     62:    '%', 'b',               '%', '4',           /* move */
                     63:    '%', 'c',               '%', '5',           /* next */
                     64:    '%', 'd',               '%', '7',           /* options */
                     65:    '%', 'e',               '%', '8',           /* previous */
                     66:    '%', 'f',               '%', '9',           /* print */
                     67:    '%', 'g',               '%', '0',           /* redo */
                     68:    '%', 'h',               '&', '3',           /* replace */
                     69:    '%', 'i',               'k', 'r',           /* right arrow */
                     70:    '%', 'j',               '&', '5',           /* resume */
                     71:    '!', '1',               '&', '6',           /* save */
                     72:    '!', '2',               '&', '7',           /* suspend */
                     73:    '!', '3',               '&', '8',           /* undo */
                     74:    KS_EXTRA, KE_S_UP,      'k', 'u',           /* up arrow */
                     75:    KS_EXTRA, KE_S_DOWN,    'k', 'd',           /* down arrow */
                     76:
                     77:    KS_EXTRA, KE_S_F1,      'k', '1',           /* F1 */
                     78:    KS_EXTRA, KE_S_F2,      'k', '2',
                     79:    KS_EXTRA, KE_S_F3,      'k', '3',
                     80:    KS_EXTRA, KE_S_F4,      'k', '4',
                     81:    KS_EXTRA, KE_S_F5,      'k', '5',
                     82:    KS_EXTRA, KE_S_F6,      'k', '6',
                     83:    KS_EXTRA, KE_S_F7,      'k', '7',
                     84:    KS_EXTRA, KE_S_F8,      'k', '8',
                     85:    KS_EXTRA, KE_S_F9,      'k', '9',
                     86:    KS_EXTRA, KE_S_F10,     'k', ';',           /* F10 */
                     87:
                     88:    KS_EXTRA, KE_S_F11,     'F', '1',
                     89:    KS_EXTRA, KE_S_F12,     'F', '2',
                     90:    KS_EXTRA, KE_S_F13,     'F', '3',
                     91:    KS_EXTRA, KE_S_F14,     'F', '4',
                     92:    KS_EXTRA, KE_S_F15,     'F', '5',
                     93:    KS_EXTRA, KE_S_F16,     'F', '6',
                     94:    KS_EXTRA, KE_S_F17,     'F', '7',
                     95:    KS_EXTRA, KE_S_F18,     'F', '8',
                     96:    KS_EXTRA, KE_S_F19,     'F', '9',
                     97:    KS_EXTRA, KE_S_F20,     'F', 'A',
                     98:
                     99:    KS_EXTRA, KE_S_F21,     'F', 'B',
                    100:    KS_EXTRA, KE_S_F22,     'F', 'C',
                    101:    KS_EXTRA, KE_S_F23,     'F', 'D',
                    102:    KS_EXTRA, KE_S_F24,     'F', 'E',
                    103:    KS_EXTRA, KE_S_F25,     'F', 'F',
                    104:    KS_EXTRA, KE_S_F26,     'F', 'G',
                    105:    KS_EXTRA, KE_S_F27,     'F', 'H',
                    106:    KS_EXTRA, KE_S_F28,     'F', 'I',
                    107:    KS_EXTRA, KE_S_F29,     'F', 'J',
                    108:    KS_EXTRA, KE_S_F30,     'F', 'K',
                    109:
                    110:    KS_EXTRA, KE_S_F31,     'F', 'L',
                    111:    KS_EXTRA, KE_S_F32,     'F', 'M',
                    112:    KS_EXTRA, KE_S_F33,     'F', 'N',
                    113:    KS_EXTRA, KE_S_F34,     'F', 'O',
                    114:    KS_EXTRA, KE_S_F35,     'F', 'P',
                    115:
                    116:    KS_EXTRA, KE_S_TAB,     KS_EXTRA, KE_TAB,   /* TAB */
                    117:    NUL
                    118: };
                    119:
                    120: static struct key_name_entry
                    121: {
                    122:    int     key;        /* Special key code or ascii value */
                    123:    char_u  *name;      /* Name of key */
                    124: } key_names_table[] =
                    125: {
                    126:    {' ',               (char_u *)"Space"},
                    127:    {TAB,               (char_u *)"Tab"},
                    128:    {K_TAB,             (char_u *)"Tab"},
                    129:    {NL,                (char_u *)"NL"},
                    130:    {NL,                (char_u *)"NewLine"},   /* Alternative name */
                    131:    {NL,                (char_u *)"LineFeed"},  /* Alternative name */
                    132:    {NL,                (char_u *)"LF"},        /* Alternative name */
                    133:    {CR,                (char_u *)"CR"},
                    134:    {CR,                (char_u *)"Return"},    /* Alternative name */
                    135:    {ESC,               (char_u *)"Esc"},
                    136:    {K_UP,              (char_u *)"Up"},
                    137:    {K_DOWN,            (char_u *)"Down"},
                    138:    {K_LEFT,            (char_u *)"Left"},
                    139:    {K_RIGHT,           (char_u *)"Right"},
                    140:
                    141:    {K_F1,              (char_u *)"F1"},
                    142:    {K_F2,              (char_u *)"F2"},
                    143:    {K_F3,              (char_u *)"F3"},
                    144:    {K_F4,              (char_u *)"F4"},
                    145:    {K_F5,              (char_u *)"F5"},
                    146:    {K_F6,              (char_u *)"F6"},
                    147:    {K_F7,              (char_u *)"F7"},
                    148:    {K_F8,              (char_u *)"F8"},
                    149:    {K_F9,              (char_u *)"F9"},
                    150:    {K_F10,             (char_u *)"F10"},
                    151:
                    152:    {K_F11,             (char_u *)"F11"},
                    153:    {K_F12,             (char_u *)"F12"},
                    154:    {K_F13,             (char_u *)"F13"},
                    155:    {K_F14,             (char_u *)"F14"},
                    156:    {K_F15,             (char_u *)"F15"},
                    157:    {K_F16,             (char_u *)"F16"},
                    158:    {K_F17,             (char_u *)"F17"},
                    159:    {K_F18,             (char_u *)"F18"},
                    160:    {K_F19,             (char_u *)"F19"},
                    161:    {K_F20,             (char_u *)"F20"},
                    162:
                    163:    {K_F21,             (char_u *)"F21"},
                    164:    {K_F22,             (char_u *)"F22"},
                    165:    {K_F23,             (char_u *)"F23"},
                    166:    {K_F24,             (char_u *)"F24"},
                    167:    {K_F25,             (char_u *)"F25"},
                    168:    {K_F26,             (char_u *)"F26"},
                    169:    {K_F27,             (char_u *)"F27"},
                    170:    {K_F28,             (char_u *)"F28"},
                    171:    {K_F29,             (char_u *)"F29"},
                    172:    {K_F30,             (char_u *)"F30"},
                    173:
                    174:    {K_F31,             (char_u *)"F31"},
                    175:    {K_F32,             (char_u *)"F32"},
                    176:    {K_F33,             (char_u *)"F33"},
                    177:    {K_F34,             (char_u *)"F34"},
                    178:    {K_F35,             (char_u *)"F35"},
                    179:
                    180:    {K_HELP,            (char_u *)"Help"},
                    181:    {K_UNDO,            (char_u *)"Undo"},
                    182:    {K_BS,              (char_u *)"BS"},
                    183:    {K_BS,              (char_u *)"BackSpace"}, /* Alternative name */
                    184:    {K_INS,             (char_u *)"Insert"},
                    185:    {K_INS,             (char_u *)"Ins"},       /* Alternative name */
                    186:    {K_DEL,             (char_u *)"Del"},
                    187:    {K_DEL,             (char_u *)"Delete"},    /* Alternative name */
                    188:    {K_HOME,            (char_u *)"Home"},
                    189:    {K_END,             (char_u *)"End"},
                    190:    {K_PAGEUP,          (char_u *)"PageUp"},
                    191:    {K_PAGEDOWN,        (char_u *)"PageDown"},
                    192:    {K_MOUSE,           (char_u *)"Mouse"},
                    193:    {K_LEFTMOUSE,       (char_u *)"LeftMouse"},
                    194:    {K_LEFTDRAG,        (char_u *)"LeftDrag"},
                    195:    {K_LEFTRELEASE,     (char_u *)"LeftRelease"},
                    196:    {K_MIDDLEMOUSE,     (char_u *)"MiddleMouse"},
                    197:    {K_MIDDLEDRAG,      (char_u *)"MiddleDrag"},
                    198:    {K_MIDDLERELEASE,   (char_u *)"MiddleRelease"},
                    199:    {K_RIGHTMOUSE,      (char_u *)"RightMouse"},
                    200:    {K_RIGHTDRAG,       (char_u *)"RightDrag"},
                    201:    {K_RIGHTRELEASE,    (char_u *)"RightRelease"},
                    202:    {K_ZERO,            (char_u *)"Nul"},
                    203:    {0,                 NULL}
                    204: };
                    205:
                    206: #define KEY_NAMES_TABLE_LEN (sizeof(key_names_table) / sizeof(struct key_name_entry))
                    207:
                    208: #ifdef USE_MOUSE
                    209: static struct
                    210: {
                    211:    int     pseudo_code;        /* Code for pseudo mouse event */
                    212:    int     button;             /* Which mouse button is it? */
                    213:    int     is_click;           /* Is it a mouse button click event? */
                    214:    int     is_drag;            /* Is it a mouse drag event? */
                    215: } mouse_table[] =
                    216: {
                    217:    {KE_LEFTMOUSE,      MOUSE_LEFT,     TRUE,   FALSE},
                    218:    {KE_LEFTDRAG,       MOUSE_LEFT,     FALSE,  TRUE},
                    219:    {KE_LEFTRELEASE,    MOUSE_LEFT,     FALSE,  FALSE},
                    220:    {KE_MIDDLEMOUSE,    MOUSE_MIDDLE,   TRUE,   FALSE},
                    221:    {KE_MIDDLEDRAG,     MOUSE_MIDDLE,   FALSE,  TRUE},
                    222:    {KE_MIDDLERELEASE,  MOUSE_MIDDLE,   FALSE,  FALSE},
                    223:    {KE_RIGHTMOUSE,     MOUSE_RIGHT,    TRUE,   FALSE},
                    224:    {KE_RIGHTDRAG,      MOUSE_RIGHT,    FALSE,  TRUE},
                    225:    {KE_RIGHTRELEASE,   MOUSE_RIGHT,    FALSE,  FALSE},
                    226:    {KE_IGNORE,         MOUSE_RELEASE,  FALSE,  TRUE},  /* DRAG without CLICK */
                    227:    {KE_IGNORE,         MOUSE_RELEASE,  FALSE,  FALSE}, /* RELEASE without CLICK */
                    228:    {0,                 0,              0,      0},
                    229: };
                    230: #endif /* USE_MOUSE */
                    231:
                    232: /*
                    233:  * Return the modifier mask bit (MOD_MASK_*) which corresponds to the given
                    234:  * modifier name ('S' for Shift, 'C' for Ctrl etc).
                    235:  */
                    236:    int
                    237: name_to_mod_mask(c)
                    238:    int     c;
                    239: {
                    240:    int     i;
                    241:
                    242:    for (i = 0; mod_mask_table[i].mod_mask; i++)
                    243:        if (TO_LOWER(c) == TO_LOWER(mod_mask_table[i].name))
                    244:            return mod_mask_table[i].mod_mask;
                    245:    return 0x0;
                    246: }
                    247:
                    248: /*
                    249:  * Decide whether the given key code (K_*) is a shifted special
                    250:  * key (by looking at mod_mask).  If it is, then return the appropriate shifted
                    251:  * key code, otherwise just return the character as is.
                    252:  */
                    253:    int
                    254: check_shifted_spec_key(c)
                    255:    int     c;
                    256: {
                    257:    int     i;
                    258:    int     key0;
                    259:    int     key1;
                    260:
                    261:    if (mod_mask & MOD_MASK_SHIFT)
                    262:    {
                    263:        if (c == TAB)           /* TAB is not in the table, K_TAB is */
                    264:            return K_S_TAB;
                    265:        key0 = KEY2TERMCAP0(c);
                    266:        key1 = KEY2TERMCAP1(c);
                    267:        for (i = 0; shifted_keys_table[i] != NUL; i += 4)
                    268:            if (key0 == shifted_keys_table[i + 2] &&
                    269:                                            key1 == shifted_keys_table[i + 3])
                    270:                return TERMCAP2KEY(shifted_keys_table[i],
                    271:                                                   shifted_keys_table[i + 1]);
                    272:    }
                    273:    return c;
                    274: }
                    275:
                    276: /*
                    277:  * Decide whether the given special key is shifted or not.  If it is we
                    278:  * return OK and change it to the equivalent unshifted special key code,
                    279:  * otherwise we leave it as is and return FAIL.
                    280:  */
                    281:    int
                    282: unshift_special_key(p)
                    283:    char_u  *p;
                    284: {
                    285:    int     i;
                    286:
                    287:    for (i = 0; shifted_keys_table[i]; i += 4)
                    288:        if (p[0] == shifted_keys_table[i] && p[1] == shifted_keys_table[i + 1])
                    289:        {
                    290:            p[0] = shifted_keys_table[i + 2];
                    291:            p[1] = shifted_keys_table[i + 3];
                    292:            return OK;
                    293:        }
                    294:    return FAIL;
                    295: }
                    296:
                    297: /*
                    298:  * Return a string which contains the name of the given key when the given
                    299:  * modifiers are down.
                    300:  */
                    301:    char_u *
                    302: get_special_key_name(c, modifiers)
                    303:    int     c;
                    304:    int     modifiers;
                    305: {
                    306:    static char_u string[MAX_KEY_NAME_LEN + 1];
                    307:
                    308:    int     i, idx;
                    309:    char_u  *s;
                    310:    char_u  name[2];
                    311:
                    312:    string[0] = '<';
                    313:    idx = 1;
                    314:
                    315:    /* translate shifted keys into unshifted keys and set modifier */
                    316:    if (IS_SPECIAL(c))
                    317:    {
                    318:        name[0] = KEY2TERMCAP0(c);
                    319:        name[1] = KEY2TERMCAP1(c);
                    320:        if (unshift_special_key(&name[0]))
                    321:            modifiers |= MOD_MASK_SHIFT;
                    322:        c = TERMCAP2KEY(name[0], name[1]);
                    323:    }
                    324:
                    325:    /* translate the modifier into a string */
                    326:    for (i = 0; mod_mask_table[i].mod_mask; i++)
                    327:        if (modifiers & mod_mask_table[i].mod_mask)
                    328:        {
                    329:            string[idx++] = mod_mask_table[i].name;
                    330:            string[idx++] = (char_u)'-';
                    331:        }
                    332:
                    333:    /* try to find the key in the special key table */
                    334:    i = find_special_key_in_table(c);
                    335:    if (i < 0)          /* unknown special key, output t_xx */
                    336:    {
                    337:        if (IS_SPECIAL(c))
                    338:        {
                    339:            string[idx++] = 't';
                    340:            string[idx++] = '_';
                    341:            string[idx++] = KEY2TERMCAP0(c);
                    342:            string[idx++] = KEY2TERMCAP1(c);
                    343:        }
                    344:        /* Not a special key, only modifiers, output directly */
                    345:        else
                    346:        {
                    347:            if (isprintchar(c))
                    348:                string[idx++] = c;
                    349:            else
                    350:            {
                    351:                s = transchar(c);
                    352:                while (*s)
                    353:                    string[idx++] = *s++;
                    354:            }
                    355:        }
                    356:    }
                    357:    else                /* use name of special key */
                    358:    {
                    359:        STRCPY(string + idx, key_names_table[i].name);
                    360:        idx = STRLEN(string);
                    361:    }
                    362:    string[idx++] = '>';
                    363:    string[idx] = NUL;
                    364:    return string;
                    365: }
                    366:
                    367: /*
                    368:  * Try to find key "c" in the special key table.
                    369:  * Return the index when found, -1 when not found.
                    370:  */
                    371:    int
                    372: find_special_key_in_table(c)
                    373:    int     c;
                    374: {
                    375:    int     i;
                    376:
                    377:    for (i = 0; key_names_table[i].name != NULL; i++)
                    378:        if (c == key_names_table[i].key)
                    379:            break;
                    380:    if (key_names_table[i].name == NULL)
                    381:        i = -1;
                    382:    return i;
                    383: }
                    384:
                    385: /*
                    386:  * Find the special key with the given name (the given string does not have to
                    387:  * end with NUL, the name is assumed to end before the first non-idchar).
                    388:  * If the name starts with "t_" the next two characters are interpreted as a
                    389:  * termcap name.
                    390:  * Return the key code, or 0 if not found.
                    391:  */
                    392:    int
                    393: get_special_key_code(name)
                    394:    char_u  *name;
                    395: {
                    396:    char_u  *table_name;
                    397:    char_u  string[3];
                    398:    int     i, j;
                    399:
                    400:    /*
                    401:     * If it's <t_xx> we get the code for xx from the termcap
                    402:     */
                    403:    if (name[0] == 't' && name[1] == '_' && name[2] != NUL && name[3] != NUL)
                    404:    {
                    405:        string[0] = name[2];
                    406:        string[1] = name[3];
                    407:        string[2] = NUL;
                    408:        if (add_termcap_entry(string, FALSE) == OK)
                    409:            return TERMCAP2KEY(name[2], name[3]);
                    410:    }
                    411:    else
                    412:        for (i = 0; key_names_table[i].name != NULL; i++)
                    413:        {
                    414:            table_name = key_names_table[i].name;
                    415:            for (j = 0; isidchar(name[j]) && table_name[j] != NUL; j++)
                    416:                if (TO_LOWER(table_name[j]) != TO_LOWER(name[j]))
                    417:                    break;
                    418:            if (!isidchar(name[j]) && table_name[j] == NUL)
                    419:                return key_names_table[i].key;
                    420:        }
                    421:    return 0;
                    422: }
                    423:
                    424:    char_u *
                    425: get_key_name(i)
                    426:    int     i;
                    427: {
                    428:    if (i >= KEY_NAMES_TABLE_LEN)
                    429:        return NULL;
                    430:    return  key_names_table[i].name;
                    431: }
                    432:
                    433: #ifdef USE_MOUSE
                    434: /*
                    435:  * Look up the given mouse code to return the relevant information in the other
                    436:  * arguments.  Return which button is down or was released.
                    437:  */
                    438:    int
                    439: get_mouse_button(code, is_click, is_drag)
                    440:    int     code;
                    441:    int     *is_click;
                    442:    int     *is_drag;
                    443: {
                    444:    int     i;
                    445:
                    446:    for (i = 0; mouse_table[i].pseudo_code; i++)
                    447:        if (code == mouse_table[i].pseudo_code)
                    448:        {
                    449:            *is_click = mouse_table[i].is_click;
                    450:            *is_drag = mouse_table[i].is_drag;
                    451:            return mouse_table[i].button;
                    452:        }
                    453:    return 0;       /* Shouldn't get here */
                    454: }
                    455:
                    456: /*
                    457:  * Return the appropriate pseudo mouse event token (KE_LEFTMOUSE etc) based on
                    458:  * the given information about which mouse button is down, and whether the
                    459:  * mouse was clicked, dragged or released.
                    460:  */
                    461:    int
                    462: get_pseudo_mouse_code(button, is_click, is_drag)
                    463:    int     button;     /* eg MOUSE_LEFT */
                    464:    int     is_click;
                    465:    int     is_drag;
                    466: {
                    467:    int     i;
                    468:
                    469:    for (i = 0; mouse_table[i].pseudo_code; i++)
                    470:        if (button == mouse_table[i].button
                    471:            && is_click == mouse_table[i].is_click
                    472:            && is_drag == mouse_table[i].is_drag)
                    473:        {
                    474:            return mouse_table[i].pseudo_code;
                    475:        }
                    476:    return KE_IGNORE;       /* not recongnized, ignore it */
                    477: }
                    478: #endif /* USE_MOUSE */