165
165
* FALSE the word to be completed must be located. */
166
166
static int compl_started = FALSE;
168
/* Set when doing something for completion that may call edit() recursively,
169
* which is not allowed. */
170
static int compl_busy = FALSE;
172
168
static int compl_matches = 0;
173
169
static char_u *compl_pattern = NULL;
174
170
static int compl_direction = FORWARD;
1268
* edit(): Start inserting text.
1271
* 'i' normal insert command
1272
* 'a' normal append command
1273
* 'R' replace command
1274
* 'r' "r<CR>" command: insert one <CR>. Note: count can be > 1, for redo,
1275
* but still only one <CR> is inserted. The <Esc> is not used for redo.
1277
* 'V' "gR" command for Virtual Replace mode.
1278
* 'v' "gr" command for single character Virtual Replace mode.
1280
* This function is not called recursively. For CTRL-O commands, it returns
1281
* and lets the caller handle the Normal-mode command.
1283
* Return TRUE if a CTRL-O command caused the return (insert mode pending).
1288
int startln, /* if set, insert at start of line */
1263
/// edit(): Start inserting text.
1265
/// "cmdchar" can be:
1266
/// 'i' normal insert command
1267
/// 'a' normal append command
1268
/// 'R' replace command
1269
/// 'r' "r<CR>" command: insert one <CR>.
1270
/// Note: count can be > 1, for redo, but still only one <CR> is inserted.
1271
/// <Esc> is not used for redo.
1272
/// 'g' "gI" command.
1273
/// 'V' "gR" command for Virtual Replace mode.
1274
/// 'v' "gr" command for single character Virtual Replace mode.
1276
/// This function is not called recursively. For CTRL-O commands, it returns
1277
/// and lets the caller handle the Normal-mode command.
1279
/// @param cmdchar command that started the insert
1280
/// @param startln if true, insert at start of line
1281
/// @param count repeat count for the command
1283
/// @return true if a CTRL-O command caused the return (insert mode pending).
1284
bool edit(int cmdchar, bool startln, long count)
1292
1286
if (curbuf->terminal) {
1293
1287
if (ex_normal_busy) {
1799
* Like del_char(), but make sure not to go before column "limit_col".
1800
* Only matters when there are composing characters.
1801
* Return TRUE when something was deleted.
1803
static int del_char_after_col(int limit_col)
1792
/// Like del_char(), but make sure not to go before column "limit_col".
1793
/// Only matters when there are composing characters.
1795
/// @param limit_col only delete the character if it is after this column
1797
/// @return true when something was deleted.
1798
static bool del_char_after_col(int limit_col)
1805
1800
if (enc_utf8 && limit_col >= 0) {
1806
1801
colnr_T ecol = curwin->w_cursor.col + 1;
1808
/* Make sure the cursor is at the start of a character, but
1809
* skip forward again when going too far back because of a
1810
* composing character. */
1803
// Make sure the cursor is at the start of a character, but
1804
// skip forward again when going too far back because of a
1805
// composing character.
1811
1806
mb_adjust_cursor();
1812
1807
while (curwin->w_cursor.col < (colnr_T)limit_col) {
1813
1808
int l = utf_ptr2len(get_cursor_pos_ptr());
1815
if (l == 0) /* end of line */
1810
if (l == 0) { // end of line
1817
1813
curwin->w_cursor.col += l;
1819
if (*get_cursor_pos_ptr() == NUL || curwin->w_cursor.col == ecol)
1821
del_bytes((long)((int)ecol - curwin->w_cursor.col), FALSE, TRUE);
1823
(void)del_char(FALSE);
1815
if (*get_cursor_pos_ptr() == NUL || curwin->w_cursor.col == ecol) {
1818
del_bytes((long)(ecol - curwin->w_cursor.col), false, true);
1850
* Return TRUE if the 'dict' or 'tsr' option can be used.
1852
static int has_compl_option(int dict_opt)
1847
/// Check that the "dict" or "tsr" option can be used.
1849
/// @param dict_opt check "dict" when true, "tsr" when false.
1850
static bool check_compl_option(bool dict_opt)
1854
if (dict_opt ? (*curbuf->b_p_dict == NUL && *p_dict == NUL
1855
&& !curwin->w_p_spell
1853
? (*curbuf->b_p_dict == NUL && *p_dict == NUL && !curwin->w_p_spell)
1857
1854
: (*curbuf->b_p_tsr == NUL && *p_tsr == NUL)) {
1858
1855
ctrl_x_mode = 0;
1859
1856
edit_submode = NULL;
1860
1857
msg_attr(dict_opt ? (char_u *)_("'dictionary' option is empty")
1861
: (char_u *)_("'thesaurus' option is empty"),
1858
: (char_u *)_("'thesaurus' option is empty"), hl_attr(HLF_E));
1863
1859
if (emsg_silent == 0) {
1864
1860
vim_beep(BO_COMPL);
1867
1863
os_delay(2000L, false);
1875
* Is the character 'c' a valid key to go to or keep us in CTRL-X mode?
1876
* This depends on the current mode.
1878
int vim_is_ctrl_x_key(int c)
1870
/// Check that the character "c" a valid key to go to or keep us in CTRL-X mode?
1871
/// This depends on the current mode.
1873
/// @param c character to check
1874
bool vim_is_ctrl_x_key(int c)
1875
FUNC_ATTR_WARN_UNUSED_RESULT
1880
/* Always allow ^R - let it's results then be checked */
1877
// Always allow ^R - let its results then be checked
1884
/* Accept <PageUp> and <PageDown> if the popup menu is visible. */
1885
if (ins_compl_pum_key(c))
1882
// Accept <PageUp> and <PageDown> if the popup menu is visible.
1883
if (ins_compl_pum_key(c)) {
1888
1887
switch (ctrl_x_mode) {
1889
case 0: /* Not in any CTRL-X mode */
1888
case 0: // Not in any CTRL-X mode
1890
1889
return c == Ctrl_N || c == Ctrl_P || c == Ctrl_X;
1891
1890
case CTRL_X_NOT_DEFINED_YET:
1892
1891
return c == Ctrl_X || c == Ctrl_Y || c == Ctrl_E
1924
1923
return (c == Ctrl_P || c == Ctrl_N);
1926
1925
EMSG(_(e_internal));
1931
* Return TRUE when character "c" is part of the item currently being
1932
* completed. Used to decide whether to abandon complete mode when the menu
1935
static int ins_compl_accept_char(int c)
1929
/// Check that character "c" is part of the item currently being
1930
/// completed. Used to decide whether to abandon complete mode when the menu
1933
/// @param c character to check
1934
static bool ins_compl_accept_char(int c)
1935
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
1937
if (ctrl_x_mode & CTRL_X_WANT_IDENT)
1938
/* When expanding an identifier only accept identifier chars. */
1937
if (ctrl_x_mode & CTRL_X_WANT_IDENT) {
1938
// When expanding an identifier only accept identifier chars.
1939
1939
return vim_isIDc(c);
1941
1942
switch (ctrl_x_mode) {
1942
1943
case CTRL_X_FILES:
1943
/* When expanding file name only accept file name chars. But not
1944
* path separators, so that "proto/<Tab>" expands files in
1945
* "proto", not "proto/" as a whole */
1944
// When expanding file name only accept file name chars. But not
1945
// path separators, so that "proto/<Tab>" expands files in
1946
// "proto", not "proto/" as a whole
1946
1947
return vim_isfilec(c) && !vim_ispathsep(c);
1948
1949
case CTRL_X_CMDLINE:
1949
1950
case CTRL_X_OMNI:
1950
/* Command line and Omni completion can work with just about any
1951
* printable character, but do stop at white space. */
1951
// Command line and Omni completion can work with just about any
1952
// printable character, but do stop at white space.
1952
1953
return vim_isprintc(c) && !ascii_iswhite(c);
1954
1955
case CTRL_X_WHOLE_LINE:
1955
/* For while line completion a space can be part of the line. */
1956
// For while line completion a space can be part of the line.
1956
1957
return vim_isprintc(c);
1958
1959
return vim_iswordc(c);
2201
* Return TRUE if "str[len]" matches with match->cp_str, considering
2204
static int ins_compl_equal(compl_T *match, char_u *str, int len)
2201
/// Check that "str[len]" matches with "match->cp_str", considering
2202
/// "match->cp_icase".
2204
/// @param match completion match
2205
/// @param str character string to check
2206
/// @param len lenth of "str"
2207
static bool ins_compl_equal(compl_T *match, char_u *str, size_t len)
2208
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
2206
if (match->cp_icase)
2207
return STRNICMP(match->cp_str, str, (size_t)len) == 0;
2208
return STRNCMP(match->cp_str, str, (size_t)len) == 0;
2210
if (match->cp_icase) {
2211
return STRNICMP(match->cp_str, str, len) == 0;
2213
return STRNCMP(match->cp_str, str, len) == 0;
2349
2355
compl_started = TRUE;
2350
2356
compl_used_match = TRUE;
2351
2357
compl_cont_status = 0;
2358
int save_w_wrow = curwin->w_wrow;
2353
2360
compl_curr_match = compl_first_match;
2354
2361
if (compl_no_insert) {
2355
ins_complete(K_DOWN);
2362
ins_complete(K_DOWN, false);
2357
ins_complete(Ctrl_N);
2364
ins_complete(Ctrl_N, false);
2358
2365
if (compl_no_select) {
2359
ins_complete(Ctrl_P);
2366
ins_complete(Ctrl_P, false);
2370
// Lazily show the popup menu, unless we got interrupted.
2371
if (!compl_interrupted) {
2372
show_pum(save_w_wrow);
2399
* Return TRUE if the popup menu should be displayed.
2401
static int pum_wanted(void)
2411
/// Check if the popup menu should be displayed.
2412
static bool pum_wanted(void)
2413
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
2403
/* 'completeopt' must contain "menu" or "menuone" */
2404
if (vim_strchr(p_cot, 'm') == NULL)
2407
/* The display looks bad on a B&W display. */
2415
// "completeopt" must contain "menu" or "menuone"
2416
return vim_strchr(p_cot, 'm') != NULL;
2415
* Return TRUE if there are two or more matches to be shown in the popup menu.
2416
* One if 'completopt' contains "menuone".
2418
static int pum_enough_matches(void)
2419
/// Check that there are two or more matches to be shown in the popup menu.
2420
/// One if "completopt" contains "menuone".
2421
static bool pum_enough_matches(void)
2422
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
2423
/* Don't display the popup menu if there are no matches or there is only
2424
* one (ignoring the original text). */
2425
compl = compl_first_match;
2424
// Don't display the popup menu if there are no matches or there is only
2425
// one (ignoring the original text).
2426
compl_T *comp = compl_first_match;
2429
|| ((compl->cp_flags & ORIGINAL_TEXT) == 0 && ++i == 2))
2429
if (comp == NULL || ((comp->cp_flags & ORIGINAL_TEXT) == 0 && ++i == 2)) {
2431
compl = compl->cp_next;
2432
} while (compl != compl_first_match);
2432
comp = comp->cp_next;
2433
} while (comp != compl_first_match);
2434
if (strstr((char *)p_cot, "menuone") != NULL)
2435
if (strstr((char *)p_cot, "menuone") != NULL) {
2464
2466
/* Need to build the popup menu list. */
2465
2467
compl_match_arraysize = 0;
2466
2468
compl = compl_first_match;
2470
* If it's user complete function and refresh_always,
2471
* not use "compl_leader" as prefix filter.
2473
if (ins_compl_need_restart()){
2474
xfree(compl_leader);
2475
compl_leader = NULL;
2467
2477
if (compl_leader != NULL)
2468
2478
lead_len = (int)STRLEN(compl_leader);
2906
* Return TRUE when we need to find matches again, ins_compl_restart() is to
2909
static int ins_compl_need_restart(void)
2914
/// Check that we need to find matches again, ins_compl_restart() is to
2916
static bool ins_compl_need_restart(void)
2911
/* Return TRUE if we didn't complete finding matches or when the
2912
* 'completefunc' returned "always" in the "refresh" dictionary item. */
2919
// Return true if we didn't complete finding matches or when the
2920
// "completefunc" returned "always" in the "refresh" dictionary item.
2913
2921
return compl_was_interrupted
2914
2922
|| ((ctrl_x_mode == CTRL_X_FUNCTION || ctrl_x_mode == CTRL_X_OMNI)
2915
2923
&& compl_opt_refresh_always);
2927
2935
ins_bytes(compl_leader + ins_compl_len());
2928
2936
compl_used_match = FALSE;
2938
if (compl_started) {
2931
2939
ins_compl_set_original_text(compl_leader);
2933
spell_bad_len = 0; /* need to redetect bad word */
2935
* Matches were cleared, need to search for them now. First display
2936
* the changed text before the cursor. Set "compl_restarting" to
2937
* avoid that the first match is inserted.
2940
compl_restarting = TRUE;
2941
if (ins_complete(Ctrl_N) == FAIL)
2941
spell_bad_len = 0; // need to redetect bad word
2942
// Matches were cleared, need to search for them now.
2943
// Set "compl_restarting" to avoid that the first match is inserted.
2944
compl_restarting = true;
2945
if (ins_complete(Ctrl_N, true) == FAIL) {
2942
2946
compl_cont_status = 0;
2943
compl_restarting = FALSE;
2948
compl_restarting = false;
2946
2951
compl_enter_selects = !compl_used_match;
2980
2986
(*mb_char2bytes)(c, buf);
2982
2988
ins_char_bytes(buf, cc);
2983
if (compl_opt_refresh_always)
2984
AppendToRedobuff(buf);
2987
if (compl_opt_refresh_always)
2988
AppendCharToRedobuff(c);
2991
2993
/* If we didn't complete finding matches we must search again. */
2992
2994
if (ins_compl_need_restart())
2993
2995
ins_compl_restart();
2995
/* When 'always' is set, don't reset compl_leader. While completing,
2996
* cursor doesn't point original position, changing compl_leader would
2998
if (!compl_opt_refresh_always) {
2999
xfree(compl_leader);
3000
compl_leader = vim_strnsave(get_cursor_line_ptr() + compl_col,
3001
(int)(curwin->w_cursor.col - compl_col));
3002
ins_compl_new_leader();
2997
xfree(compl_leader);
2998
compl_leader = vim_strnsave(get_cursor_line_ptr() + compl_col,
2999
(int)(curwin->w_cursor.col - compl_col));
3000
ins_compl_new_leader();
3064
3065
ins_compl_addleader(c);
3068
* Prepare for Insert mode completion, or stop it.
3069
* Called just after typing a character in Insert mode.
3070
* Returns TRUE when the character is not to be inserted;
3072
static int ins_compl_prep(int c)
3068
/// Prepare for Insert mode completion, or stop it.
3069
/// Called just after typing a character in Insert mode.
3071
/// @param c character that was typed
3073
/// @return true when the character is not to be inserted;
3074
static bool ins_compl_prep(int c)
3077
bool retval = false;
3078
3079
/* Forget any previous 'special' messages if this is actually
3079
3080
* a ^X mode key - bar ^R, in which case we wait to see what it gives us.
3238
3241
ins_compl_fixRedoBufForLeader(ptr);
3241
want_cindent = (can_cindent && cindent_on());
3243
* When completing whole lines: fix indent for 'cindent'.
3244
* Otherwise, break line if it's too long.
3244
bool want_cindent = (can_cindent && cindent_on());
3245
// When completing whole lines: fix indent for 'cindent'.
3246
// Otherwise, break line if it's too long.
3246
3247
if (compl_cont_mode == CTRL_X_WHOLE_LINE) {
3247
3248
/* re-indent the current line */
3248
3249
if (want_cindent) {
3265
/* If the popup menu is displayed pressing CTRL-Y means accepting
3266
* the selection without inserting anything. When
3267
* compl_enter_selects is set the Enter key does the same. */
3266
// If the popup menu is displayed pressing CTRL-Y means accepting
3267
// the selection without inserting anything. When
3268
// compl_enter_selects is set the Enter key does the same.
3268
3269
if ((c == Ctrl_Y || (compl_enter_selects
3269
3270
&& (c == CAR || c == K_KENTER || c == NL)))
3273
3275
/* CTRL-E means completion is Ended, go back to the typed text. */
3274
3276
if (c == Ctrl_E) {
3275
3277
ins_compl_delete();
3276
if (compl_leader != NULL)
3278
if (compl_leader != NULL) {
3277
3279
ins_bytes(compl_leader + ins_compl_len());
3278
else if (compl_first_match != NULL)
3280
} else if (compl_first_match != NULL) {
3279
3281
ins_bytes(compl_orig_text + ins_compl_len());
3283
3286
auto_format(FALSE, TRUE);
4242
4245
return FORWARD;
4246
* Return TRUE for keys that are used for completion only when the popup menu
4249
static int ins_compl_pum_key(int c)
4248
/// Check that "c" is a valid completion key only while the popup menu is shown
4250
/// @param c character to check
4251
static bool ins_compl_pum_key(int c)
4252
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
4251
4254
return pum_visible() && (c == K_PAGEUP || c == K_KPAGEUP || c == K_S_UP
4252
|| c == K_PAGEDOWN || c == K_KPAGEDOWN || c ==
4254
|| c == K_UP || c == K_DOWN);
4255
|| c == K_PAGEDOWN || c == K_KPAGEDOWN
4256
|| c == K_S_DOWN || c == K_UP || c == K_DOWN);
4275
* Return TRUE if completion with "c" should insert the match, FALSE if only
4276
* to change the currently selected completion.
4278
static int ins_compl_use_match(int c)
4276
/// Check that completion with "c" should insert the match, false if only
4277
/// to change the currently selected completion.
4279
/// @param c character to check
4280
static bool ins_compl_use_match(int c)
4281
FUNC_ATTR_CONST FUNC_ATTR_WARN_UNUSED_RESULT
4782
/* Show the popup menu, unless we got interrupted. */
4783
if (!compl_interrupted) {
4784
/* RedrawingDisabled may be set when invoked through complete(). */
4785
n = RedrawingDisabled;
4786
RedrawingDisabled = 0;
4788
/* If the cursor moved we need to remove the pum first. */
4790
if (save_w_wrow != curwin->w_wrow)
4791
ins_compl_del_pum();
4793
ins_compl_show_pum();
4795
RedrawingDisabled = n;
4785
// Show the popup menu, unless we got interrupted.
4786
if (enable_pum && !compl_interrupted) {
4787
show_pum(save_w_wrow);
4797
4789
compl_was_interrupted = compl_interrupted;
4798
4790
compl_interrupted = FALSE;
6321
* Check the word in front of the cursor for an abbreviation.
6322
* Called when the non-id character "c" has been entered.
6323
* When an abbreviation is recognized it is removed from the text and
6324
* the replacement string is inserted in typebuf.tb_buf[], followed by "c".
6326
static int echeck_abbr(int c)
6310
/// Check the word in front of the cursor for an abbreviation.
6311
/// Called when the non-id character "c" has been entered.
6312
/// When an abbreviation is recognized it is removed from the text and
6313
/// the replacement string is inserted in typebuf.tb_buf[], followed by "c".
6315
/// @param c character
6317
/// @return true if the word is a known abbreviation.
6318
static bool echeck_abbr(int c)
6319
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
6328
/* Don't check for abbreviation in paste mode, when disabled and just
6329
* after moving around with cursor keys. */
6330
if (p_paste || no_abbr || arrow_used)
6321
// Don't check for abbreviation in paste mode, when disabled and just
6322
// after moving around with cursor keys.
6323
if (p_paste || no_abbr || arrow_used) {
6333
6327
return check_abbr(c, get_cursor_line_ptr(), curwin->w_cursor.col,
6334
6328
curwin->w_cursor.lnum == Insstart.lnum ? Insstart.col : 0);
6564
6558
(void)del_char_after_col(limit_col);
6568
* Return TRUE if C-indenting is on.
6570
static int cindent_on(void) {
6571
return !p_paste && (curbuf->b_p_cin
6572
|| *curbuf->b_p_inde != NUL
6561
/// Check that C-indenting is on.
6562
static bool cindent_on(void)
6563
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
6565
return !p_paste && (curbuf->b_p_cin || *curbuf->b_p_inde != NUL);
6600
6592
do_c_expr_indent();
6604
* return TRUE if 'cinkeys' contains the key "keytyped",
6605
* when == '*': Only if key is preceded with '*' (indent before insert)
6606
* when == '!': Only if key is preceded with '!' (don't insert)
6607
* when == ' ': Only if key is not preceded with '*'(indent afterwards)
6609
* "keytyped" can have a few special values:
6612
* KEY_COMPLETE just finished completion.
6614
* If line_is_empty is TRUE accept keys with '0' before them.
6616
int in_cinkeys(int keytyped, int when, int line_is_empty)
6595
/// Check that "cinkeys" contains the key "keytyped",
6596
/// when == '*': Only if key is preceded with '*' (indent before insert)
6597
/// when == '!': Only if key is preceded with '!' (don't insert)
6598
/// when == ' ': Only if key is not preceded with '*' (indent afterwards)
6600
/// "keytyped" can have a few special values:
6603
/// KEY_COMPLETE : Just finished completion.
6605
/// @param keytyped key that was typed
6606
/// @param when condition on when to perform the check
6607
/// @param line_is_empty when true, accept keys with '0' before them.
6608
bool in_cinkeys(int keytyped, int when, bool line_is_empty)
6620
6612
int try_match_word;
6626
if (keytyped == NUL)
6627
/* Can happen with CTRL-Y and CTRL-E on a short line. */
6618
if (keytyped == NUL) {
6619
// Can happen with CTRL-Y and CTRL-E on a short line.
6630
6623
if (*curbuf->b_p_inde != NUL)
6631
6624
look = curbuf->b_p_indk; /* 'indentexpr' set: use 'indentkeys' */
6641
6634
case '!': try_match = (*look == '!'); break;
6642
6635
default: try_match = (*look != '*'); break;
6644
if (*look == '*' || *look == '!')
6637
if (*look == '*' || *look == '!') {
6648
* If there is a '0', only accept a match if the line is empty.
6649
* But may still match when typing last char of a word.
6641
// If there is a '0', only accept a match if the line is empty.
6642
// But may still match when typing last char of a word.
6651
6643
if (*look == '0') {
6652
6644
try_match_word = try_match;
6657
try_match_word = FALSE;
6645
if (!line_is_empty) {
6650
try_match_word = false;
6660
* does it look like a control character?
6663
&& look[1] >= '?' && look[1] <= '_'
6665
if (try_match && keytyped == Ctrl_chr(look[1]))
6653
// Does it look like a control character?
6654
if (*look == '^' && look[1] >= '?' && look[1] <= '_') {
6655
if (try_match && keytyped == Ctrl_chr(look[1])) {
6670
* 'o' means "o" command, open forward.
6671
* 'O' means "O" command, open backward.
6673
else if (*look == 'o') {
6674
if (try_match && keytyped == KEY_OPEN_FORW)
6660
// 'o' means "o" command, open forward.
6661
// 'O' means "O" command, open backward.
6662
} else if (*look == 'o') {
6663
if (try_match && keytyped == KEY_OPEN_FORW) {
6677
6667
} else if (*look == 'O') {
6678
if (try_match && keytyped == KEY_OPEN_BACK)
6683
* 'e' means to check for "else" at start of line and just before the
6686
else if (*look == 'e') {
6668
if (try_match && keytyped == KEY_OPEN_BACK) {
6673
// 'e' means to check for "else" at start of line and just before the
6675
} else if (*look == 'e') {
6687
6676
if (try_match && keytyped == 'e' && curwin->w_cursor.col >= 4) {
6688
6677
p = get_cursor_line_ptr();
6689
6678
if (skipwhite(p) == p + curwin->w_cursor.col - 4 &&
6690
STRNCMP(p + curwin->w_cursor.col - 4, "else", 4) == 0)
6679
STRNCMP(p + curwin->w_cursor.col - 4, "else", 4) == 0) {
6696
* ':' only causes an indent if it is at the end of a label or case
6697
* statement, or when it was before typing the ':' (to fix
6698
* class::method for C++).
6700
else if (*look == ':') {
6685
// ':' only causes an indent if it is at the end of a label or case
6686
// statement, or when it was before typing the ':' (to fix
6687
// class::method for C++).
6688
} else if (*look == ':') {
6701
6689
if (try_match && keytyped == ':') {
6702
6690
p = get_cursor_line_ptr();
6703
if (cin_iscase(p, FALSE) || cin_isscopedecl(p) || cin_islabel())
6705
/* Need to get the line again after cin_islabel(). */
6691
if (cin_iscase(p, false) || cin_isscopedecl(p) || cin_islabel()) {
6694
// Need to get the line again after cin_islabel().
6706
6695
p = get_cursor_line_ptr();
6707
6696
if (curwin->w_cursor.col > 2
6708
6697
&& p[curwin->w_cursor.col - 1] == ':'
6712
6701
|| cin_islabel());
6713
6702
p = get_cursor_line_ptr();
6714
6703
p[curwin->w_cursor.col - 1] = ':';
6722
* Is it a key in <>, maybe?
6724
else if (*look == '<') {
6711
// Is it a key in <>, maybe?
6712
} else if (*look == '<') {
6725
6713
if (try_match) {
6727
* make up some named keys <o>, <O>, <e>, <0>, <>>, <<>, <*>,
6728
* <:> and <!> so that people can re-indent on o, O, e, 0, <,
6729
* >, *, : and ! keys if they really really want to.
6714
// make up some named keys <o>, <O>, <e>, <0>, <>>, <<>, <*>,
6715
// <:> and <!> so that people can re-indent on o, O, e, 0, <,
6716
// >, *, : and ! keys if they really really want to.
6731
6717
if (vim_strchr((char_u *)"<>!*oOe0:", look[1]) != NULL
6732
&& keytyped == look[1])
6718
&& keytyped == look[1]) {
6735
if (keytyped == get_special_key_code(look + 1))
6722
if (keytyped == get_special_key_code(look + 1)) {
6738
6726
while (*look && *look != '>')
7050
7038
status_redraw_curbuf();
7054
* Handle ESC in insert mode.
7055
* Returns TRUE when leaving insert mode, FALSE when going to repeat the
7062
int nomove /* don't move cursor */
7041
/// Handle ESC in insert mode.
7043
/// @param[in,out] count repeat count of the insert command
7044
/// @param cmdchar command that started the insert
7045
/// @param nomove when true, don't move the cursor
7047
/// @return true when leaving insert mode, false when repeating the insert.
7048
static bool ins_esc(long *count, int cmdchar, bool nomove)
7049
FUNC_ATTR_NONNULL_ARG(1)
7066
static int disabled_redraw = FALSE;
7051
static bool disabled_redraw = false;
7068
7053
check_spell_redraw();
7070
temp = curwin->w_cursor.col;
7055
int temp = curwin->w_cursor.col;
7071
7056
if (disabled_redraw) {
7072
--RedrawingDisabled;
7073
disabled_redraw = FALSE;
7057
RedrawingDisabled--;
7058
disabled_redraw = false;
7075
7060
if (!arrow_used) {
7153
7139
ui_cursor_shape(); /* may show different cursor shape */
7156
* When recording or for CTRL-O, need to display the new mode.
7157
* Otherwise remove the mode message.
7159
if (Recording || restart_edit != NUL)
7141
// When recording or for CTRL-O, need to display the new mode.
7142
// Otherwise remove the mode message.
7143
if (Recording || restart_edit != NUL) {
7164
return TRUE; /* exit Insert mode */
7203
* If 'keymodel' contains "startsel", may start selection.
7204
* Returns TRUE when a CTRL-O and other keys stuffed.
7206
static int ins_start_select(int c)
7187
/// If 'keymodel' contains "startsel", may start selection.
7189
/// @param c character to check
7191
/// @return true when a CTRL-O and other keys stuffed.
7192
static bool ins_start_select(int c)
7193
FUNC_ATTR_WARN_UNUSED_RESULT
7208
7195
if (!km_startsel) {
7217
7204
case K_KPAGEDOWN:
7218
7205
if (!(mod_mask & MOD_MASK_SHIFT))
7222
7209
case K_S_RIGHT:
7227
/* Start selection right away, the cursor can move with
7228
* CTRL-O when beyond the end of the line. */
7214
// Start selection right away, the cursor can move with
7215
// CTRL-O when beyond the end of the line.
7229
7216
start_selection();
7231
/* Execute the key in (insert) Select mode. */
7218
// Execute the key in (insert) Select mode.
7232
7219
stuffcharReadbuff(Ctrl_O);
7233
7220
if (mod_mask) {
7237
buf[1] = KS_MODIFIER;
7221
char_u buf[4] = { K_SPECIAL, KS_MODIFIER, mod_mask, NUL };
7240
7222
stuffReadbuff(buf);
7242
7224
stuffcharReadbuff(c);
7366
7348
(void)del_char(FALSE);
7370
* Handle Backspace, delete-word and delete-line in Insert mode.
7371
* Return TRUE when backspace was actually used.
7373
static int ins_bs(int c, int mode, int *inserted_space_p)
7351
/// Handle Backspace, delete-word and delete-line in Insert mode.
7353
/// @param c charcter that was typed
7354
/// @param mode backspace mode to use
7355
/// @param[in,out] inserted_space_p whether a space was the last
7356
// character inserted
7358
/// @return true when backspace was actually used.
7359
static bool ins_bs(int c, int mode, int *inserted_space_p)
7360
FUNC_ATTR_NONNULL_ARG(3)
7377
7364
int temp = 0; /* init for GCC */
7378
7365
colnr_T save_col;
7379
7366
colnr_T mincol;
7380
int did_backspace = FALSE;
7367
bool did_backspace = false;
7383
7370
int cpc[MAX_MCO]; /* composing characters */
7406
if (stop_arrow() == FAIL)
7393
if (stop_arrow() == FAIL) {
7408
7396
in_indent = inindent(0);
7410
can_cindent = FALSE;
7411
end_comment_pending = NUL; /* After BS, don't auto-end comment */
7412
if (revins_on) /* put cursor after last inserted char */
7398
can_cindent = false;
7400
end_comment_pending = NUL; // After BS, don't auto-end comment
7401
if (revins_on) { // put cursor after last inserted char
7416
* BACKSPACE_CHAR eats a virtual space
7417
* BACKSPACE_WORD eats all coladd
7418
* BACKSPACE_LINE eats all coladd and keeps going
7405
// BACKSPACE_CHAR eats a virtual space
7406
// BACKSPACE_WORD eats all coladd
7407
// BACKSPACE_LINE eats all coladd and keeps going
7420
7408
if (curwin->w_cursor.coladd > 0) {
7421
7409
if (mode == BACKSPACE_CHAR) {
7422
--curwin->w_cursor.coladd;
7410
curwin->w_cursor.coladd--;
7425
7413
if (mode == BACKSPACE_WORD) {
7426
7414
curwin->w_cursor.coladd = 0;
7429
7417
curwin->w_cursor.coladd = 0;
8009
* Handle TAB in Insert or Replace mode.
8010
* Return TRUE when the TAB needs to be inserted like a normal character.
8012
static int ins_tab(void)
7996
/// Handle TAB in Insert or Replace mode.
7998
/// @return true when the TAB needs to be inserted like a normal character.
7999
static bool ins_tab(void)
8000
FUNC_ATTR_WARN_UNUSED_RESULT
8018
if (Insstart_blank_vcol == MAXCOL && curwin->w_cursor.lnum == Insstart.lnum)
8005
if (Insstart_blank_vcol == MAXCOL && curwin->w_cursor.lnum == Insstart.lnum) {
8019
8006
Insstart_blank_vcol = get_nolist_virtcol();
8020
if (echeck_abbr(TAB + ABBR_OFF))
8025
can_cindent = FALSE;
8028
* When nothing special, insert TAB like a normal character
8008
if (echeck_abbr(TAB + ABBR_OFF)) {
8012
int ind = inindent(0);
8014
can_cindent = false;
8017
// When nothing special, insert TAB like a normal character
8030
8018
if (!curbuf->b_p_et
8031
8019
&& !(p_sta && ind && curbuf->b_p_ts != get_sw_value(curbuf))
8032
&& get_sts_value() == 0)
8020
&& get_sts_value() == 0) {
8035
if (stop_arrow() == FAIL)
8024
if (stop_arrow() == FAIL) {
8038
8028
did_ai = FALSE;
8039
8029
did_si = FALSE;
8041
8031
can_si_back = FALSE;
8042
8032
AppendToRedobuff((char_u *)"\t");
8044
if (p_sta && ind) /* insert tab in indent, use 'shiftwidth' */
8034
if (p_sta && ind) { // insert tab in indent, use "shiftwidth"
8045
8035
temp = get_sw_value(curbuf);
8046
else if (curbuf->b_p_sts != 0) /* use 'softtabstop' when set */
8036
} else if (curbuf->b_p_sts != 0) { // use "softtabstop" when set
8047
8037
temp = get_sts_value();
8048
else /* otherwise use 'tabstop' */
8038
} else { // otherwise use "tabstop"
8049
8039
temp = (int)curbuf->b_p_ts;
8050
8041
temp -= get_nolist_virtcol() % temp;
8186
8177
curwin->w_p_list = save_list;
8193
* Handle CR or NL in insert mode.
8194
* Return TRUE when it can't undo.
8196
static int ins_eol(int c)
8183
/// Handle CR or NL in insert mode.
8185
/// @return true when it can't undo.
8186
static bool ins_eol(int c)
8200
if (echeck_abbr(c + ABBR_OFF))
8202
if (stop_arrow() == FAIL)
8188
if (echeck_abbr(c + ABBR_OFF)) {
8191
if (stop_arrow() == FAIL) {
8204
8194
undisplay_dollar();