[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     ! 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 */