📄 misc2.c
字号:
ga_init2(gap, itemsize, growsize)
struct growarray *gap;
int itemsize;
int growsize;
{
ga_init(gap);
gap->ga_itemsize = itemsize;
gap->ga_growsize = growsize;
}
/*
* Make room in growing array "ga" for at least "n" items.
* Return FAIL for failure, OK otherwise.
*/
int
ga_grow(ga, n)
struct growarray *ga;
int n;
{
size_t len;
char_u *pp;
if (ga->ga_room < n)
{
if (n < ga->ga_growsize)
n = ga->ga_growsize;
len = ga->ga_itemsize * (ga->ga_len + n);
pp = alloc_clear((unsigned)len);
if (pp == NULL)
return FAIL;
ga->ga_room = n;
if (ga->ga_data != NULL)
{
mch_memmove(pp, ga->ga_data,
(size_t)(ga->ga_itemsize * ga->ga_len));
vim_free(ga->ga_data);
}
ga->ga_data = pp;
}
return OK;
}
/************************************************************************
* functions that use lookup tables for various things, generally to do with
* special key codes.
*/
/*
* Some useful tables.
*/
static struct modmasktable
{
int mod_mask; /* Bit-mask for particular key modifier */
char_u name; /* Single letter name of modifier */
} mod_mask_table[] =
{
{MOD_MASK_ALT, (char_u)'M'},
{MOD_MASK_CTRL, (char_u)'C'},
{MOD_MASK_SHIFT, (char_u)'S'},
{MOD_MASK_2CLICK, (char_u)'2'},
{MOD_MASK_3CLICK, (char_u)'3'},
{MOD_MASK_4CLICK, (char_u)'4'},
#ifdef macintosh
{MOD_MASK_CMD, (char_u)'D'},
#endif
{0x0, NUL}
};
/*
* Shifted key terminal codes and their unshifted equivalent.
* Don't add mouse codes here, they are handled seperately!
*/
static char_u shifted_keys_table[] =
{
/* shifted unshifted */
'&', '9', '@', '1', /* begin */
'&', '0', '@', '2', /* cancel */
'*', '1', '@', '4', /* command */
'*', '2', '@', '5', /* copy */
'*', '3', '@', '6', /* create */
'*', '4', 'k', 'D', /* delete char */
'*', '5', 'k', 'L', /* delete line */
'*', '7', '@', '7', /* end */
'*', '9', '@', '9', /* exit */
'*', '0', '@', '0', /* find */
'#', '1', '%', '1', /* help */
'#', '2', 'k', 'h', /* home */
'#', '3', 'k', 'I', /* insert */
'#', '4', 'k', 'l', /* left arrow */
'%', 'a', '%', '3', /* message */
'%', 'b', '%', '4', /* move */
'%', 'c', '%', '5', /* next */
'%', 'd', '%', '7', /* options */
'%', 'e', '%', '8', /* previous */
'%', 'f', '%', '9', /* print */
'%', 'g', '%', '0', /* redo */
'%', 'h', '&', '3', /* replace */
'%', 'i', 'k', 'r', /* right arrow */
'%', 'j', '&', '5', /* resume */
'!', '1', '&', '6', /* save */
'!', '2', '&', '7', /* suspend */
'!', '3', '&', '8', /* undo */
KS_EXTRA, (int)KE_S_UP, 'k', 'u', /* up arrow */
KS_EXTRA, (int)KE_S_DOWN, 'k', 'd', /* down arrow */
KS_EXTRA, (int)KE_S_F1, 'k', '1', /* F1 */
KS_EXTRA, (int)KE_S_F2, 'k', '2',
KS_EXTRA, (int)KE_S_F3, 'k', '3',
KS_EXTRA, (int)KE_S_F4, 'k', '4',
KS_EXTRA, (int)KE_S_F5, 'k', '5',
KS_EXTRA, (int)KE_S_F6, 'k', '6',
KS_EXTRA, (int)KE_S_F7, 'k', '7',
KS_EXTRA, (int)KE_S_F8, 'k', '8',
KS_EXTRA, (int)KE_S_F9, 'k', '9',
KS_EXTRA, (int)KE_S_F10, 'k', ';', /* F10 */
KS_EXTRA, (int)KE_S_F11, 'F', '1',
KS_EXTRA, (int)KE_S_F12, 'F', '2',
KS_EXTRA, (int)KE_S_F13, 'F', '3',
KS_EXTRA, (int)KE_S_F14, 'F', '4',
KS_EXTRA, (int)KE_S_F15, 'F', '5',
KS_EXTRA, (int)KE_S_F16, 'F', '6',
KS_EXTRA, (int)KE_S_F17, 'F', '7',
KS_EXTRA, (int)KE_S_F18, 'F', '8',
KS_EXTRA, (int)KE_S_F19, 'F', '9',
KS_EXTRA, (int)KE_S_F20, 'F', 'A',
KS_EXTRA, (int)KE_S_F21, 'F', 'B',
KS_EXTRA, (int)KE_S_F22, 'F', 'C',
KS_EXTRA, (int)KE_S_F23, 'F', 'D',
KS_EXTRA, (int)KE_S_F24, 'F', 'E',
KS_EXTRA, (int)KE_S_F25, 'F', 'F',
KS_EXTRA, (int)KE_S_F26, 'F', 'G',
KS_EXTRA, (int)KE_S_F27, 'F', 'H',
KS_EXTRA, (int)KE_S_F28, 'F', 'I',
KS_EXTRA, (int)KE_S_F29, 'F', 'J',
KS_EXTRA, (int)KE_S_F30, 'F', 'K',
KS_EXTRA, (int)KE_S_F31, 'F', 'L',
KS_EXTRA, (int)KE_S_F32, 'F', 'M',
KS_EXTRA, (int)KE_S_F33, 'F', 'N',
KS_EXTRA, (int)KE_S_F34, 'F', 'O',
KS_EXTRA, (int)KE_S_F35, 'F', 'P',
KS_EXTRA, (int)KE_S_TAB, KS_EXTRA, (int)KE_TAB, /* TAB pseudo code*/
NUL
};
static struct key_name_entry
{
int key; /* Special key code or ascii value */
char_u *name; /* Name of key */
} key_names_table[] =
{
{' ', (char_u *)"Space"},
{TAB, (char_u *)"Tab"},
{K_TAB, (char_u *)"Tab"},
{NL, (char_u *)"NL"},
{NL, (char_u *)"NewLine"}, /* Alternative name */
{NL, (char_u *)"LineFeed"}, /* Alternative name */
{NL, (char_u *)"LF"}, /* Alternative name */
{CR, (char_u *)"CR"},
{CR, (char_u *)"Return"}, /* Alternative name */
{K_BS, (char_u *)"BS"},
{K_BS, (char_u *)"BackSpace"}, /* Alternative name */
{ESC, (char_u *)"Esc"},
{'|', (char_u *)"Bar"},
{'\\', (char_u *)"Bslash"},
{K_DEL, (char_u *)"Del"},
{K_DEL, (char_u *)"Delete"}, /* Alternative name */
{K_UP, (char_u *)"Up"},
{K_DOWN, (char_u *)"Down"},
{K_LEFT, (char_u *)"Left"},
{K_RIGHT, (char_u *)"Right"},
{K_F1, (char_u *)"F1"},
{K_F2, (char_u *)"F2"},
{K_F3, (char_u *)"F3"},
{K_F4, (char_u *)"F4"},
{K_F5, (char_u *)"F5"},
{K_F6, (char_u *)"F6"},
{K_F7, (char_u *)"F7"},
{K_F8, (char_u *)"F8"},
{K_F9, (char_u *)"F9"},
{K_F10, (char_u *)"F10"},
{K_F11, (char_u *)"F11"},
{K_F12, (char_u *)"F12"},
{K_F13, (char_u *)"F13"},
{K_F14, (char_u *)"F14"},
{K_F15, (char_u *)"F15"},
{K_F16, (char_u *)"F16"},
{K_F17, (char_u *)"F17"},
{K_F18, (char_u *)"F18"},
{K_F19, (char_u *)"F19"},
{K_F20, (char_u *)"F20"},
{K_F21, (char_u *)"F21"},
{K_F22, (char_u *)"F22"},
{K_F23, (char_u *)"F23"},
{K_F24, (char_u *)"F24"},
{K_F25, (char_u *)"F25"},
{K_F26, (char_u *)"F26"},
{K_F27, (char_u *)"F27"},
{K_F28, (char_u *)"F28"},
{K_F29, (char_u *)"F29"},
{K_F30, (char_u *)"F30"},
{K_F31, (char_u *)"F31"},
{K_F32, (char_u *)"F32"},
{K_F33, (char_u *)"F33"},
{K_F34, (char_u *)"F34"},
{K_F35, (char_u *)"F35"},
{K_XF1, (char_u *)"F1"},
{K_XF2, (char_u *)"F2"},
{K_XF3, (char_u *)"F3"},
{K_XF4, (char_u *)"F4"},
{K_HELP, (char_u *)"Help"},
{K_UNDO, (char_u *)"Undo"},
{K_INS, (char_u *)"Insert"},
{K_INS, (char_u *)"Ins"}, /* Alternative name */
{K_HOME, (char_u *)"Home"},
{K_END, (char_u *)"End"},
{K_PAGEUP, (char_u *)"PageUp"},
{K_PAGEDOWN, (char_u *)"PageDown"},
{K_KHOME, (char_u *)"kHome"},
{K_KEND, (char_u *)"kEnd"},
{K_KPAGEUP, (char_u *)"kPageUp"},
{K_KPAGEDOWN, (char_u *)"kPageDown"},
{K_KPLUS, (char_u *)"kPlus"},
{K_KMINUS, (char_u *)"kMinus"},
{K_KDIVIDE, (char_u *)"kDivide"},
{K_KMULTIPLY, (char_u *)"kMultiply"},
{K_KENTER, (char_u *)"kEnter"},
{'<', (char_u *)"lt"},
{K_MOUSE, (char_u *)"Mouse"},
{K_LEFTMOUSE, (char_u *)"LeftMouse"},
{K_LEFTDRAG, (char_u *)"LeftDrag"},
{K_LEFTRELEASE, (char_u *)"LeftRelease"},
{K_MIDDLEMOUSE, (char_u *)"MiddleMouse"},
{K_MIDDLEDRAG, (char_u *)"MiddleDrag"},
{K_MIDDLERELEASE, (char_u *)"MiddleRelease"},
{K_RIGHTMOUSE, (char_u *)"RightMouse"},
{K_RIGHTDRAG, (char_u *)"RightDrag"},
{K_RIGHTRELEASE, (char_u *)"RightRelease"},
{K_ZERO, (char_u *)"Nul"},
{0, NULL}
};
#define KEY_NAMES_TABLE_LEN (sizeof(key_names_table) / sizeof(struct key_name_entry))
#ifdef USE_MOUSE
static struct mousetable
{
int pseudo_code; /* Code for pseudo mouse event */
int button; /* Which mouse button is it? */
int is_click; /* Is it a mouse button click event? */
int is_drag; /* Is it a mouse drag event? */
} mouse_table[] =
{
{(int)KE_LEFTMOUSE, MOUSE_LEFT, TRUE, FALSE},
{(int)KE_LEFTDRAG, MOUSE_LEFT, FALSE, TRUE},
{(int)KE_LEFTRELEASE, MOUSE_LEFT, FALSE, FALSE},
{(int)KE_MIDDLEMOUSE, MOUSE_MIDDLE, TRUE, FALSE},
{(int)KE_MIDDLEDRAG, MOUSE_MIDDLE, FALSE, TRUE},
{(int)KE_MIDDLERELEASE, MOUSE_MIDDLE, FALSE, FALSE},
{(int)KE_RIGHTMOUSE, MOUSE_RIGHT, TRUE, FALSE},
{(int)KE_RIGHTDRAG, MOUSE_RIGHT, FALSE, TRUE},
{(int)KE_RIGHTRELEASE, MOUSE_RIGHT, FALSE, FALSE},
/* DRAG without CLICK */
{(int)KE_IGNORE, MOUSE_RELEASE, FALSE, TRUE},
/* RELEASE without CLICK */
{(int)KE_IGNORE, MOUSE_RELEASE, FALSE, FALSE},
{0, 0, 0, 0},
};
#endif /* USE_MOUSE */
/*
* Return the modifier mask bit (MOD_MASK_*) which corresponds to the given
* modifier name ('S' for Shift, 'C' for Ctrl etc).
*/
int
name_to_mod_mask(c)
int c;
{
int i;
for (i = 0; mod_mask_table[i].mod_mask; i++)
if (TO_LOWER(c) == TO_LOWER(mod_mask_table[i].name))
return mod_mask_table[i].mod_mask;
return 0x0;
}
/*
* Decide whether the given key code (K_*) is a shifted special
* key (by looking at mod_mask). If it is, then return the appropriate shifted
* key code, otherwise just return the character as is.
*/
int
check_shifted_spec_key(c)
int c;
{
return simplify_key(c, &mod_mask);
}
/*
* Check if if there is a special key code for "key" that includes the
* modifiers specified.
*/
int
simplify_key(key, modifiers)
int key;
int *modifiers;
{
int i;
int key0;
int key1;
if (*modifiers & MOD_MASK_SHIFT)
{
if (key == TAB) /* TAB is a special case */
{
*modifiers &= ~MOD_MASK_SHIFT;
return K_S_TAB;
}
key0 = KEY2TERMCAP0(key);
key1 = KEY2TERMCAP1(key);
for (i = 0; shifted_keys_table[i] != NUL; i += 4)
if (key0 == shifted_keys_table[i + 2] &&
key1 == shifted_keys_table[i + 3])
{
*modifiers &= ~MOD_MASK_SHIFT;
return TERMCAP2KEY(shifted_keys_table[i],
shifted_keys_table[i + 1]);
}
}
return key;
}
/*
* Return a string which contains the name of the given key when the given
* modifiers are down.
*/
char_u *
get_special_key_name(c, modifiers)
int c;
int modifiers;
{
static char_u string[MAX_KEY_NAME_LEN + 1];
int i, idx;
int table_idx;
char_u *s;
string[0] = '<';
idx = 1;
/*
* Translate shifted special keys into unshifted keys and set modifier.
*/
if (IS_SPECIAL(c))
{
for (i = 0; shifted_keys_table[i]; i += 4)
if ( KEY2TERMCAP0(c) == shifted_keys_table[i]
&& KEY2TERMCAP1(c) == shifted_keys_table[i + 1])
{
modifiers |= MOD_MASK_SHIFT;
c = TERMCAP2KEY(shifted_keys_table[i + 2],
shifted_keys_table[i + 3]);
break;
}
}
/* try to find the key in the special key table */
table_idx = find_special_key_in_table(c);
/*
* When not a known special key, and not a printable character, try to
* extract modifiers.
*/
if (table_idx < 0 && (!vim_isprintc(c) || (c & 0x7f) == ' ') && (c & 0x80))
{
c &= 0x7f;
modifiers |= MOD_MASK_ALT;
/* try again, to find the un-alted key in the special key table */
table_idx = find_special_key_in_table(c);
}
if (table_idx < 0 && !vim_isprintc(c) && c < ' ')
{
c += '@';
modifiers |= MOD_MASK_CTRL;
}
/* translate the modifier into a string */
for (i = 0; mod_mask_table[i].mod_mask; i++)
if (modifiers & mod_mask_table[i].mod_mask)
{
string[idx++] = mod_mask_table[i].name;
string[idx++] = (char_u)'-';
}
if (table_idx < 0) /* unknown special key, output t_xx */
{
if (IS_SPECIAL(c))
{
string[idx++] = 't';
string[idx++] = '_';
string[idx++] = KEY2TERMCAP0(c);
string[idx++] = KEY2TERMCAP1(c);
}
/* Not a special key, only modifiers, output directly */
else
{
if (vim_isprintc(c))
string[idx++] = c;
else
{
s = transchar(c);
while (*s)
string[idx++] = *s++;
}
}
}
else /* use name of special key */
{
STRCPY(string + idx, key_names_table[table_idx].name);
idx = STRLEN(string);
}
string[idx++] = '>';
string[idx] = NUL;
return string;
}
/*
* Try translating a <> name at (*srcp)[] to dst[].
* Return the number of characters added to dst[], zero for no match.
* If there is a match, srcp is advanced to after the <> name.
* dst[] must be big enough to hold the result (up to six characters)!
*/
int
trans_special(srcp, dst, keycode)
char_u **srcp;
char_u *dst;
int keycode; /* prefer key code, e.g. K_DEL instead of DEL */
{
int modifiers;
int key;
int dlen = 0;
key = find_special_key(srcp, &modifiers, keycode);
if (key == 0)
return 0;
/* Put the appropriate modifier in a string */
if (modifiers != 0)
{
dst[dlen++] = K_SPECIAL;
dst[dlen++] = KS_MODIFIER;
dst[dlen++] = modifiers;
}
if (IS_SPECIAL(key))
{
dst[dlen++] = K_SPECIAL;
dst[dlen++] = KEY2TERMCAP0(key);
dst[dlen++] = KEY2TERMCAP1(key);
}
else
dst[dlen++] = key;
return dlen;
}
/*
* Try translating a <> name at (*srcp)[], return the key and modifiers.
* srcp is advanced to after the <> name.
* returns 0 if there is no match.
*/
int
find_special_key(srcp, modp, keycode)
char_u **srcp;
int *modp;
int keycode; /* prefer key code, e.g. K_DEL instead of DEL */
{
char_u *last_dash;
char_u *end_of_name;
char_u *src;
char_u *bp;
int modifiers;
int bit;
int key;
src = *srcp;
if (src[0] != '<')
return 0;
/* Find end of modifier list */
last_dash = src;
for (bp = src + 1; *bp == '-' || vim_isIDc(*bp); bp++)
{
if (*bp == '-')
{
last_dash = bp;
if (bp[1] != NUL && bp[2] == '>')
++bp; /* anything accepted, like <C-?> */
}
if (bp[0] == 't' && bp[1] == '_' && bp[2] && bp[3])
bp += 3; /* skip t_xx, xx may be '-' or '>' */
}
if (*bp == '>') /* found matching '>' */
{
end_of_name = bp + 1;
/* Which modifiers are given? */
modifiers = 0x0;
for (bp = src + 1; bp < last_dash; bp++)
{
if (*bp != '-')
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -