~ubuntu-branches/debian/sid/neovim/sid

« back to all changes in this revision

Viewing changes to src/nvim/edit.c

  • Committer: Package Import Robot
  • Author(s): James McCoy
  • Date: 2016-04-18 21:42:19 UTC
  • mfrom: (1.1.2)
  • Revision ID: package-import@ubuntu.com-20160418214219-1e6d4o1fwqarzk46
Tags: 0.1.3-1
* New upstream release.  (Closes: #820562)
* debian/control:
  + Remove unnecessary luarocks Build-Depends
  + Add libkvm-dev Build-Depends for kfreebsd-*
  + Add python(3)-neovim to Recommends.  (Closes: #812737)
  + Declare compiance with policy 3.9.8, no changes needed.

Show diffs side-by-side

added added

removed removed

Lines of Context:
165
165
 * FALSE the word to be completed must be located. */
166
166
static int compl_started = FALSE;
167
167
 
168
 
/* Set when doing something for completion that may call edit() recursively,
169
 
 * which is not allowed. */
170
 
static int compl_busy = FALSE;
171
 
 
172
168
static int compl_matches = 0;
173
169
static char_u     *compl_pattern = NULL;
174
170
static int compl_direction = FORWARD;
887
883
 
888
884
  case Ctrl_T:        // Make indent one shiftwidth greater.
889
885
    if (s->c == Ctrl_T && ctrl_x_mode == CTRL_X_THESAURUS) {
890
 
      if (has_compl_option(false)) {
 
886
      if (check_compl_option(false)) {
891
887
        insert_do_complete(s);
892
888
      }
893
889
      break;
1102
1098
 
1103
1099
  case Ctrl_K:        // digraph or keyword completion
1104
1100
    if (ctrl_x_mode == CTRL_X_DICTIONARY) {
1105
 
      if (has_compl_option(true)) {
 
1101
      if (check_compl_option(true)) {
1106
1102
        insert_do_complete(s);
1107
1103
      }
1108
1104
      break;
1247
1243
static void insert_do_complete(InsertState *s)
1248
1244
{
1249
1245
  compl_busy = true;
1250
 
  if (ins_complete(s->c) == FAIL) {
 
1246
  if (ins_complete(s->c, true) == FAIL) {
1251
1247
    compl_cont_status = 0;
1252
1248
  }
1253
1249
  compl_busy = false;
1264
1260
  }
1265
1261
}
1266
1262
 
1267
 
/*
1268
 
 * edit(): Start inserting text.
1269
 
 *
1270
 
 * "cmdchar" can be:
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.
1276
 
 * 'g'  "gI" command.
1277
 
 * 'V'  "gR" command for Virtual Replace mode.
1278
 
 * 'v'  "gr" command for single character Virtual Replace mode.
1279
 
 *
1280
 
 * This function is not called recursively.  For CTRL-O commands, it returns
1281
 
 * and lets the caller handle the Normal-mode command.
1282
 
 *
1283
 
 * Return TRUE if a CTRL-O command caused the return (insert mode pending).
1284
 
 */
1285
 
int
1286
 
edit (
1287
 
    int cmdchar,
1288
 
    int startln,                    /* if set, insert at start of line */
1289
 
    long count
1290
 
)
 
1263
/// edit(): Start inserting text.
 
1264
///
 
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.
 
1275
///
 
1276
/// This function is not called recursively.  For CTRL-O commands, it returns
 
1277
/// and lets the caller handle the Normal-mode command.
 
1278
///
 
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
 
1282
///
 
1283
/// @return true if a CTRL-O command caused the return (insert mode pending).
 
1284
bool edit(int cmdchar, bool startln, long count)
1291
1285
{
1292
1286
  if (curbuf->terminal) {
1293
1287
    if (ex_normal_busy) {
1795
1789
  }
1796
1790
}
1797
1791
 
1798
 
/*
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.
1802
 
 */
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.
 
1794
///
 
1795
/// @param  limit_col  only delete the character if it is after this column
 
1796
//
 
1797
/// @return true when something was deleted.
 
1798
static bool del_char_after_col(int limit_col)
1804
1799
{
1805
1800
  if (enc_utf8 && limit_col >= 0) {
1806
1801
    colnr_T ecol = curwin->w_cursor.col + 1;
1807
1802
 
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());
1814
1809
 
1815
 
      if (l == 0)        /* end of line */
 
1810
      if (l == 0) {  // end of line
1816
1811
        break;
 
1812
      }
1817
1813
      curwin->w_cursor.col += l;
1818
1814
    }
1819
 
    if (*get_cursor_pos_ptr() == NUL || curwin->w_cursor.col == ecol)
1820
 
      return FALSE;
1821
 
    del_bytes((long)((int)ecol - curwin->w_cursor.col), FALSE, TRUE);
1822
 
  } else
1823
 
    (void)del_char(FALSE);
1824
 
  return TRUE;
 
1815
    if (*get_cursor_pos_ptr() == NUL || curwin->w_cursor.col == ecol) {
 
1816
      return false;
 
1817
    }
 
1818
    del_bytes((long)(ecol - curwin->w_cursor.col), false, true);
 
1819
  } else {
 
1820
    del_char(false);
 
1821
  }
 
1822
  return true;
1825
1823
}
1826
1824
 
1827
1825
/*
1846
1844
  }
1847
1845
}
1848
1846
 
1849
 
/*
1850
 
 * Return TRUE if the 'dict' or 'tsr' option can be used.
1851
 
 */
1852
 
static int has_compl_option(int dict_opt)
 
1847
/// Check that the "dict" or "tsr" option can be used.
 
1848
///
 
1849
/// @param  dict_opt  check "dict" when true, "tsr" when false.
 
1850
static bool check_compl_option(bool dict_opt)
1853
1851
{
1854
 
  if (dict_opt ? (*curbuf->b_p_dict == NUL && *p_dict == NUL
1855
 
                  && !curwin->w_p_spell
1856
 
                  )
 
1852
  if (dict_opt
 
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"),
1862
 
        hl_attr(HLF_E));
 
1858
             : (char_u *)_("'thesaurus' option is empty"), hl_attr(HLF_E));
1863
1859
    if (emsg_silent == 0) {
1864
1860
      vim_beep(BO_COMPL);
1865
1861
      setcursor();
1866
1862
      ui_flush();
1867
1863
      os_delay(2000L, false);
1868
1864
    }
1869
 
    return FALSE;
 
1865
    return false;
1870
1866
  }
1871
 
  return TRUE;
 
1867
  return true;
1872
1868
}
1873
1869
 
1874
 
/*
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.
1877
 
 */
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.
 
1872
///
 
1873
/// @param  c  character to check
 
1874
bool vim_is_ctrl_x_key(int c)
 
1875
  FUNC_ATTR_WARN_UNUSED_RESULT
1879
1876
{
1880
 
  /* Always allow ^R - let it's results then be checked */
1881
 
  if (c == Ctrl_R)
1882
 
    return TRUE;
 
1877
  // Always allow ^R - let its results then be checked
 
1878
  if (c == Ctrl_R) {
 
1879
    return true;
 
1880
  }
1883
1881
 
1884
 
  /* Accept <PageUp> and <PageDown> if the popup menu is visible. */
1885
 
  if (ins_compl_pum_key(c))
1886
 
    return TRUE;
 
1882
  // Accept <PageUp> and <PageDown> if the popup menu is visible.
 
1883
  if (ins_compl_pum_key(c)) {
 
1884
    return true;
 
1885
  }
1887
1886
 
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);
1925
1924
  }
1926
1925
  EMSG(_(e_internal));
1927
 
  return FALSE;
 
1926
  return false;
1928
1927
}
1929
1928
 
1930
 
/*
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
1933
 
 * is visible.
1934
 
 */
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
 
1931
/// is visible.
 
1932
///
 
1933
/// @param  c  character to check
 
1934
static bool ins_compl_accept_char(int c)
 
1935
  FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
1936
1936
{
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);
 
1940
  }
1940
1941
 
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);
1947
1948
 
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);
1953
1954
 
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);
1957
1958
  }
1958
1959
  return vim_iswordc(c);
2197
2198
  return OK;
2198
2199
}
2199
2200
 
2200
 
/*
2201
 
 * Return TRUE if "str[len]" matches with match->cp_str, considering
2202
 
 * match->cp_icase.
2203
 
 */
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".
 
2203
///
 
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
2205
2209
{
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;
 
2212
  }
 
2213
  return STRNCMP(match->cp_str, str, len) == 0;
2209
2214
}
2210
2215
 
2211
2216
/*
2321
2326
 */
2322
2327
void set_completion(colnr_T startcol, list_T *list)
2323
2328
{
2324
 
  /* If already doing completions stop it. */
2325
 
  if (ctrl_x_mode != 0)
 
2329
  // If already doing completions stop it.
 
2330
  if (ctrl_x_mode != 0) {
2326
2331
    ins_compl_prep(' ');
 
2332
  }
2327
2333
  ins_compl_clear();
2328
2334
 
2329
2335
  if (stop_arrow() == FAIL)
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;
2352
2359
 
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);
2356
2363
  } else {
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);
2360
2367
    }
2361
2368
  }
 
2369
 
 
2370
  // Lazily show the popup menu, unless we got interrupted.
 
2371
  if (!compl_interrupted) {
 
2372
    show_pum(save_w_wrow);
 
2373
  }
 
2374
 
2362
2375
  ui_flush();
2363
2376
}
2364
2377
 
2395
2408
  }
2396
2409
}
2397
2410
 
2398
 
/*
2399
 
 * Return TRUE if the popup menu should be displayed.
2400
 
 */
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
2402
2414
{
2403
 
  /* 'completeopt' must contain "menu" or "menuone" */
2404
 
  if (vim_strchr(p_cot, 'm') == NULL)
2405
 
    return FALSE;
2406
 
 
2407
 
  /* The display looks bad on a B&W display. */
2408
 
  if (t_colors < 8
2409
 
      )
2410
 
    return FALSE;
2411
 
  return TRUE;
 
2415
  // "completeopt" must contain "menu" or "menuone"
 
2416
  return vim_strchr(p_cot, 'm') != NULL;
2412
2417
}
2413
2418
 
2414
 
/*
2415
 
 * Return TRUE if there are two or more matches to be shown in the popup menu.
2416
 
 * One if 'completopt' contains "menuone".
2417
 
 */
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
2419
2423
{
2420
 
  compl_T     *compl;
2421
 
  int i;
2422
 
 
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;
2426
 
  i = 0;
 
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;
 
2427
  int i = 0;
2427
2428
  do {
2428
 
    if (compl == NULL
2429
 
        || ((compl->cp_flags & ORIGINAL_TEXT) == 0 && ++i == 2))
 
2429
    if (comp == NULL || ((comp->cp_flags & ORIGINAL_TEXT) == 0 && ++i == 2)) {
2430
2430
      break;
2431
 
    compl = compl->cp_next;
2432
 
  } while (compl != compl_first_match);
 
2431
    }
 
2432
    comp = comp->cp_next;
 
2433
  } while (comp != compl_first_match);
2433
2434
 
2434
 
  if (strstr((char *)p_cot, "menuone") != NULL)
 
2435
  if (strstr((char *)p_cot, "menuone") != NULL) {
2435
2436
    return i >= 1;
 
2437
  }
2436
2438
  return i >= 2;
2437
2439
}
2438
2440
 
2464
2466
    /* Need to build the popup menu list. */
2465
2467
    compl_match_arraysize = 0;
2466
2468
    compl = compl_first_match;
 
2469
    /*
 
2470
     * If it's user complete function and refresh_always,
 
2471
     * not use "compl_leader" as prefix filter.
 
2472
     */
 
2473
    if (ins_compl_need_restart()){
 
2474
      xfree(compl_leader);
 
2475
      compl_leader = NULL;
 
2476
    }
2467
2477
    if (compl_leader != NULL)
2468
2478
      lead_len = (int)STRLEN(compl_leader);
2469
2479
    do {
2855
2865
  set_vim_var_dict(VV_COMPLETED_ITEM, dict_alloc());
2856
2866
}
2857
2867
 
2858
 
/*
2859
 
 * Return TRUE when Insert completion is active.
2860
 
 */
2861
 
int ins_compl_active(void)
 
2868
/// Check that Insert completion is active.
 
2869
bool ins_compl_active(void)
 
2870
  FUNC_ATTR_PURE
2862
2871
{
2863
2872
  return compl_started;
2864
2873
}
2902
2911
  return NUL;
2903
2912
}
2904
2913
 
2905
 
/*
2906
 
 * Return TRUE when we need to find matches again, ins_compl_restart() is to
2907
 
 * be called.
2908
 
 */
2909
 
static int ins_compl_need_restart(void)
 
2914
/// Check that we need to find matches again, ins_compl_restart() is to
 
2915
/// be called.
 
2916
static bool ins_compl_need_restart(void)
 
2917
  FUNC_ATTR_PURE
2910
2918
{
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;
2929
2937
 
2930
 
  if (compl_started)
 
2938
  if (compl_started) {
2931
2939
    ins_compl_set_original_text(compl_leader);
2932
 
  else {
2933
 
    spell_bad_len = 0;          /* need to redetect bad word */
2934
 
    /*
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.
2938
 
     */
2939
 
    update_screen(0);
2940
 
    compl_restarting = TRUE;
2941
 
    if (ins_complete(Ctrl_N) == FAIL)
 
2940
  } else {
 
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;
 
2947
    }
 
2948
    compl_restarting = false;
2944
2949
  }
2945
2950
 
2946
2951
  compl_enter_selects = !compl_used_match;
2948
2953
  /* Show the popup menu with a different set of matches. */
2949
2954
  ins_compl_show_pum();
2950
2955
 
2951
 
  /* Don't let Enter select the original text when there is no popup menu. */
2952
 
  if (compl_match_array == NULL)
 
2956
  /* Don't let Enter select the original text when there is no popup menu.
 
2957
   * Don't let Enter select when use user function and refresh_always is set */
 
2958
  if (compl_match_array == NULL || ins_compl_need_restart())
2953
2959
    compl_enter_selects = FALSE;
2954
2960
}
2955
2961
 
2980
2986
    (*mb_char2bytes)(c, buf);
2981
2987
    buf[cc] = NUL;
2982
2988
    ins_char_bytes(buf, cc);
2983
 
    if (compl_opt_refresh_always)
2984
 
      AppendToRedobuff(buf);
2985
2989
  } else {
2986
2990
    ins_char(c);
2987
 
    if (compl_opt_refresh_always)
2988
 
      AppendCharToRedobuff(c);
2989
2991
  }
2990
2992
 
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();
2994
2996
 
2995
 
  /* When 'always' is set, don't reset compl_leader. While completing,
2996
 
   * cursor doesn't point original position, changing compl_leader would
2997
 
   * break redo. */
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();
3003
 
  }
 
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();
3004
3001
}
3005
3002
 
3006
3003
/*
3009
3006
 */
3010
3007
static void ins_compl_restart(void)
3011
3008
{
 
3009
  /* update screen before restart.
 
3010
   * so if complete is blocked,
 
3011
   * will stay to the last popup menu and reduce flicker */
 
3012
  update_screen(0);
3012
3013
  ins_compl_free();
3013
3014
  compl_started = FALSE;
3014
3015
  compl_matches = 0;
3064
3065
  ins_compl_addleader(c);
3065
3066
}
3066
3067
 
3067
 
/*
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;
3071
 
 */
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.
 
3070
///
 
3071
/// @param  c  character that was typed
 
3072
///
 
3073
/// @return true when the character is not to be inserted;
 
3074
static bool ins_compl_prep(int c)
3073
3075
{
3074
 
  char_u      *ptr;
3075
 
  int want_cindent;
3076
 
  int retval = FALSE;
 
3076
  char_u *ptr;
 
3077
  bool retval = false;
3077
3078
 
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.
3083
3084
 
3084
3085
  /* Ignore end of Select mode mapping and mouse scroll buttons. */
3085
3086
  if (c == K_SELECT || c == K_MOUSEDOWN || c == K_MOUSEUP
3086
 
      || c == K_MOUSELEFT || c == K_MOUSERIGHT)
 
3087
      || c == K_MOUSELEFT || c == K_MOUSERIGHT || c == K_EVENT
 
3088
      || c == K_FOCUSGAINED || c == K_FOCUSLOST) {
3087
3089
    return retval;
 
3090
  }
3088
3091
 
3089
3092
  /* Set "compl_get_longest" when finding the first matches. */
3090
3093
  if (ctrl_x_mode == CTRL_X_NOT_DEFINED_YET
3238
3241
        ins_compl_fixRedoBufForLeader(ptr);
3239
3242
      }
3240
3243
 
3241
 
      want_cindent = (can_cindent && cindent_on());
3242
 
      /*
3243
 
       * When completing whole lines: fix indent for 'cindent'.
3244
 
       * Otherwise, break line if it's too long.
3245
 
       */
 
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) {
3262
3263
          inc_cursor();
3263
3264
      }
3264
3265
 
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)))
3270
 
          && pum_visible())
3271
 
        retval = TRUE;
 
3271
          && pum_visible()) {
 
3272
        retval = true;
 
3273
      }
3272
3274
 
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());
3280
 
        retval = TRUE;
 
3282
        }
 
3283
        retval = true;
3281
3284
      }
3282
3285
 
3283
3286
      auto_format(FALSE, TRUE);
4242
4245
  return FORWARD;
4243
4246
}
4244
4247
 
4245
 
/*
4246
 
 * Return TRUE for keys that are used for completion only when the popup menu
4247
 
 * is visible.
4248
 
 */
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
 
4249
///
 
4250
/// @param  c  character to check
 
4251
static bool ins_compl_pum_key(int c)
 
4252
  FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
4250
4253
{
4251
4254
  return pum_visible() && (c == K_PAGEUP || c == K_KPAGEUP || c == K_S_UP
4252
 
                           || c == K_PAGEDOWN || c == K_KPAGEDOWN || c ==
4253
 
                           K_S_DOWN
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);
4255
4257
}
4256
4258
 
4257
4259
/*
4271
4273
  return 1;
4272
4274
}
4273
4275
 
4274
 
/*
4275
 
 * Return TRUE if completion with "c" should insert the match, FALSE if only
4276
 
 * to change the currently selected completion.
4277
 
 */
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.
 
4278
///
 
4279
/// @param  c  character to check
 
4280
static bool ins_compl_use_match(int c)
 
4281
  FUNC_ATTR_CONST FUNC_ATTR_WARN_UNUSED_RESULT
4279
4282
{
4280
4283
  switch (c) {
4281
4284
  case K_UP:
4286
4289
  case K_PAGEUP:
4287
4290
  case K_KPAGEUP:
4288
4291
  case K_S_UP:
4289
 
    return FALSE;
 
4292
    return false;
4290
4293
  }
4291
 
  return TRUE;
 
4294
  return true;
4292
4295
}
4293
4296
 
4294
4297
/*
4296
4299
 * Called when character "c" was typed, which has a meaning for completion.
4297
4300
 * Returns OK if completion was done, FAIL if something failed.
4298
4301
 */
4299
 
static int ins_complete(int c)
 
4302
static int ins_complete(int c, bool enable_pum)
4300
4303
{
4301
4304
  char_u      *line;
4302
4305
  int startcol = 0;                 /* column where searched text starts */
4779
4782
    }
4780
4783
  }
4781
4784
 
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;
4787
 
 
4788
 
    /* If the cursor moved we need to remove the pum first. */
4789
 
    setcursor();
4790
 
    if (save_w_wrow != curwin->w_wrow)
4791
 
      ins_compl_del_pum();
4792
 
 
4793
 
    ins_compl_show_pum();
4794
 
    setcursor();
4795
 
    RedrawingDisabled = n;
 
4785
  // Show the popup menu, unless we got interrupted.
 
4786
  if (enable_pum && !compl_interrupted) {
 
4787
    show_pum(save_w_wrow);
4796
4788
  }
4797
4789
  compl_was_interrupted = compl_interrupted;
4798
4790
  compl_interrupted = FALSE;
4945
4937
  return cc;
4946
4938
}
4947
4939
 
4948
 
/*
4949
 
 * Insert character, taking care of special keys and mod_mask
4950
 
 */
4951
 
static void
4952
 
insert_special (
4953
 
    int c,
4954
 
    int allow_modmask,
4955
 
    int ctrlv                  /* c was typed after CTRL-V */
4956
 
)
 
4940
/// Insert character, taking care of special keys and mod_mask
 
4941
///
 
4942
/// @param ctrlv `c` was typed after CTRL-V
 
4943
static void insert_special(int c, int allow_modmask, int ctrlv)
4957
4944
{
4958
4945
  char_u  *p;
4959
4946
  int len;
4965
4952
   * Only use mod_mask for special keys, to avoid things like <S-Space>,
4966
4953
   * unless 'allow_modmask' is TRUE.
4967
4954
   */
 
4955
  if (mod_mask & MOD_MASK_CMD) {  // Command-key never produces a normal key.
 
4956
    allow_modmask = true;
 
4957
  }
4968
4958
  if (IS_SPECIAL(c) || (mod_mask && allow_modmask)) {
4969
4959
    p = get_special_key_name(c, mod_mask);
4970
4960
    len = (int)STRLEN(p);
6317
6307
  return s;
6318
6308
}
6319
6309
 
6320
 
/*
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".
6325
 
 */
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".
 
6314
///
 
6315
/// @param  c  character
 
6316
///
 
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
6327
6320
{
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)
6331
 
    return FALSE;
 
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) {
 
6324
    return false;
 
6325
  }
6332
6326
 
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);
6565
6559
}
6566
6560
 
6567
 
/*
6568
 
 * Return TRUE if C-indenting is on.
6569
 
 */
6570
 
static int cindent_on(void) {
6571
 
  return !p_paste && (curbuf->b_p_cin
6572
 
                      || *curbuf->b_p_inde != NUL
6573
 
                      );
 
6561
/// Check that C-indenting is on.
 
6562
static bool cindent_on(void)
 
6563
  FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
 
6564
{
 
6565
  return !p_paste && (curbuf->b_p_cin || *curbuf->b_p_inde != NUL);
6574
6566
}
6575
6567
 
6576
6568
/*
6600
6592
    do_c_expr_indent();
6601
6593
}
6602
6594
 
6603
 
/*
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)
6608
 
 *
6609
 
 * "keytyped" can have a few special values:
6610
 
 * KEY_OPEN_FORW
6611
 
 * KEY_OPEN_BACK
6612
 
 * KEY_COMPLETE     just finished completion.
6613
 
 *
6614
 
 * If line_is_empty is TRUE accept keys with '0' before them.
6615
 
 */
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)
 
6599
///
 
6600
/// "keytyped" can have a few special values:
 
6601
/// KEY_OPEN_FORW :
 
6602
/// KEY_OPEN_BACK :
 
6603
/// KEY_COMPLETE  : Just finished completion.
 
6604
///
 
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)
6617
6609
{
6618
 
  char_u      *look;
 
6610
  char_u *look;
6619
6611
  int try_match;
6620
6612
  int try_match_word;
6621
 
  char_u      *p;
6622
 
  char_u      *line;
 
6613
  char_u *p;
 
6614
  char_u *line;
6623
6615
  int icase;
6624
6616
  int i;
6625
6617
 
6626
 
  if (keytyped == NUL)
6627
 
    /* Can happen with CTRL-Y and CTRL-E on a short line. */
6628
 
    return FALSE;
 
6618
  if (keytyped == NUL) {
 
6619
    // Can happen with CTRL-Y and CTRL-E on a short line.
 
6620
    return false;
 
6621
  }
6629
6622
 
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;
6643
6636
    }
6644
 
    if (*look == '*' || *look == '!')
6645
 
      ++look;
 
6637
    if (*look == '*' || *look == '!') {
 
6638
      look++;
 
6639
    }
6646
6640
 
6647
 
    /*
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.
6650
 
     */
 
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;
6653
 
      if (!line_is_empty)
6654
 
        try_match = FALSE;
6655
 
      ++look;
6656
 
    } else
6657
 
      try_match_word = FALSE;
 
6645
      if (!line_is_empty) {
 
6646
        try_match = false;
 
6647
      }
 
6648
      look++;
 
6649
    } else {
 
6650
      try_match_word = false;
 
6651
    }
6658
6652
 
6659
 
    /*
6660
 
     * does it look like a control character?
6661
 
     */
6662
 
    if (*look == '^'
6663
 
        && look[1] >= '?' && look[1] <= '_'
6664
 
        ) {
6665
 
      if (try_match && keytyped == Ctrl_chr(look[1]))
6666
 
        return TRUE;
 
6653
    // Does it look like a control character?
 
6654
    if (*look == '^' && look[1] >= '?' && look[1] <= '_') {
 
6655
      if (try_match && keytyped == Ctrl_chr(look[1])) {
 
6656
        return true;
 
6657
      }
6667
6658
      look += 2;
6668
 
    }
6669
 
    /*
6670
 
     * 'o' means "o" command, open forward.
6671
 
     * 'O' means "O" command, open backward.
6672
 
     */
6673
 
    else if (*look == 'o') {
6674
 
      if (try_match && keytyped == KEY_OPEN_FORW)
6675
 
        return TRUE;
6676
 
      ++look;
 
6659
 
 
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) {
 
6664
        return true;
 
6665
      }
 
6666
      look++;
6677
6667
    } else if (*look == 'O') {
6678
 
      if (try_match && keytyped == KEY_OPEN_BACK)
6679
 
        return TRUE;
6680
 
      ++look;
6681
 
    }
6682
 
    /*
6683
 
     * 'e' means to check for "else" at start of line and just before the
6684
 
     * cursor.
6685
 
     */
6686
 
    else if (*look == 'e') {
 
6668
      if (try_match && keytyped == KEY_OPEN_BACK) {
 
6669
        return true;
 
6670
      }
 
6671
      look++;
 
6672
 
 
6673
    // 'e' means to check for "else" at start of line and just before the
 
6674
    // cursor.
 
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)
6691
 
          return TRUE;
 
6679
            STRNCMP(p + curwin->w_cursor.col - 4, "else", 4) == 0) {
 
6680
          return true;
 
6681
        }
6692
6682
      }
6693
 
      ++look;
6694
 
    }
6695
 
    /*
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++).
6699
 
     */
6700
 
    else if (*look == ':') {
 
6683
      look++;
 
6684
 
 
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())
6704
 
          return TRUE;
6705
 
        /* Need to get the line again after cin_islabel(). */
 
6691
        if (cin_iscase(p, false) || cin_isscopedecl(p) || cin_islabel()) {
 
6692
          return true;
 
6693
        }
 
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] = ':';
6715
 
          if (i)
6716
 
            return TRUE;
 
6704
          if (i) {
 
6705
            return true;
 
6706
          }
6717
6707
        }
6718
6708
      }
6719
 
      ++look;
6720
 
    }
6721
 
    /*
6722
 
     * Is it a key in <>, maybe?
6723
 
     */
6724
 
    else if (*look == '<') {
 
6709
      look++;
 
6710
 
 
6711
    // Is it a key in <>, maybe?
 
6712
    } else if (*look == '<') {
6725
6713
      if (try_match) {
6726
 
        /*
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.
6730
 
         */
 
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])
6733
 
          return TRUE;
 
6718
            && keytyped == look[1]) {
 
6719
          return true;
 
6720
        }
6734
6721
 
6735
 
        if (keytyped == get_special_key_code(look + 1))
6736
 
          return TRUE;
 
6722
        if (keytyped == get_special_key_code(look + 1)) {
 
6723
          return true;
 
6724
        }
6737
6725
      }
6738
6726
      while (*look && *look != '>')
6739
6727
        look++;
6804
6792
              (int)(curwin->w_cursor.col - (p - look)))
6805
6793
            match = FALSE;
6806
6794
        }
6807
 
        if (match)
6808
 
          return TRUE;
 
6795
        if (match) {
 
6796
          return true;
 
6797
        }
6809
6798
      }
6810
6799
      look = p;
6811
 
    }
6812
 
    /*
6813
 
     * ok, it's a boring generic character.
6814
 
     */
6815
 
    else {
6816
 
      if (try_match && *look == keytyped)
6817
 
        return TRUE;
6818
 
      ++look;
 
6800
 
 
6801
    // Ok, it's a boring generic character.
 
6802
    } else {
 
6803
      if (try_match && *look == keytyped) {
 
6804
        return true;
 
6805
      }
 
6806
      look++;
6819
6807
    }
6820
6808
 
6821
6809
    /*
6823
6811
     */
6824
6812
    look = skip_to_option_part(look);
6825
6813
  }
6826
 
  return FALSE;
 
6814
  return false;
6827
6815
}
6828
6816
 
6829
6817
/*
7050
7038
  status_redraw_curbuf();
7051
7039
}
7052
7040
 
7053
 
/*
7054
 
 * Handle ESC in insert mode.
7055
 
 * Returns TRUE when leaving insert mode, FALSE when going to repeat the
7056
 
 * insert.
7057
 
 */
7058
 
static int
7059
 
ins_esc (
7060
 
    long *count,
7061
 
    int cmdchar,
7062
 
    int nomove                 /* don't move cursor */
7063
 
)
 
7041
/// Handle ESC in insert mode.
 
7042
///
 
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
 
7046
///
 
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)
7064
7050
{
7065
 
  int temp;
7066
 
  static int disabled_redraw = FALSE;
 
7051
  static bool disabled_redraw = false;
7067
7052
 
7068
7053
  check_spell_redraw();
7069
7054
 
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;
7074
7059
  }
7075
7060
  if (!arrow_used) {
7076
7061
    /*
7100
7085
      if (cmdchar == 'r' || cmdchar == 'v') {
7101
7086
        stuffRedoReadbuff(ESC_STR);  // No ESC in redo buffer
7102
7087
      }
7103
 
      ++RedrawingDisabled;
7104
 
      disabled_redraw = TRUE;
7105
 
      return FALSE;             /* repeat the insert */
 
7088
      RedrawingDisabled++;
 
7089
      disabled_redraw = true;
 
7090
      // Repeat the insert
 
7091
      return false;
7106
7092
    }
7107
7093
    stop_insert(&curwin->w_cursor, TRUE, nomove);
7108
7094
    undisplay_dollar();
7152
7138
  setmouse();
7153
7139
  ui_cursor_shape();            /* may show different cursor shape */
7154
7140
 
7155
 
  /*
7156
 
   * When recording or for CTRL-O, need to display the new mode.
7157
 
   * Otherwise remove the mode message.
7158
 
   */
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) {
7160
7144
    showmode();
7161
 
  else if (p_smd)
 
7145
  } else if (p_smd) {
7162
7146
    MSG("");
7163
 
 
7164
 
  return TRUE;              /* exit Insert mode */
 
7147
  }
 
7148
  // Exit Insert mode
 
7149
  return true;
7165
7150
}
7166
7151
 
7167
7152
/*
7199
7184
  showmode();
7200
7185
}
7201
7186
 
7202
 
/*
7203
 
 * If 'keymodel' contains "startsel", may start selection.
7204
 
 * Returns TRUE when a CTRL-O and other keys stuffed.
7205
 
 */
7206
 
static int ins_start_select(int c)
 
7187
/// If 'keymodel' contains "startsel", may start selection.
 
7188
///
 
7189
/// @param  c  character to check
 
7190
//
 
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
7207
7194
{
7208
7195
  if (!km_startsel) {
7209
 
    return FALSE;
 
7196
    return false;
7210
7197
  }
7211
7198
  switch (c) {
7212
7199
  case K_KHOME:
7217
7204
  case K_KPAGEDOWN:
7218
7205
    if (!(mod_mask & MOD_MASK_SHIFT))
7219
7206
      break;
7220
 
  /* FALLTHROUGH */
 
7207
  // FALLTHROUGH
7221
7208
  case K_S_LEFT:
7222
7209
  case K_S_RIGHT:
7223
7210
  case K_S_UP:
7224
7211
  case K_S_DOWN:
7225
7212
  case K_S_END:
7226
7213
  case K_S_HOME:
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();
7230
7217
 
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) {
7234
 
      char_u buf[4];
7235
 
 
7236
 
      buf[0] = K_SPECIAL;
7237
 
      buf[1] = KS_MODIFIER;
7238
 
      buf[2] = mod_mask;
7239
 
      buf[3] = NUL;
 
7221
      char_u buf[4] = { K_SPECIAL, KS_MODIFIER, mod_mask, NUL };
7240
7222
      stuffReadbuff(buf);
7241
7223
    }
7242
7224
    stuffcharReadbuff(c);
7243
 
    return TRUE;
 
7225
    return true;
7244
7226
  }
7245
 
  return FALSE;
 
7227
  return false;
7246
7228
}
7247
7229
 
7248
7230
/*
7366
7348
    (void)del_char(FALSE);
7367
7349
}
7368
7350
 
7369
 
/*
7370
 
 * Handle Backspace, delete-word and delete-line in Insert mode.
7371
 
 * Return TRUE when backspace was actually used.
7372
 
 */
7373
 
static int ins_bs(int c, int mode, int *inserted_space_p)
 
7351
/// Handle Backspace, delete-word and delete-line in Insert mode.
 
7352
///
 
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
 
7357
///
 
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)
7374
7361
{
7375
7362
  linenr_T lnum;
7376
7363
  int cc;
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;
7381
7368
  int in_indent;
7382
7369
  int oldState;
7383
7370
  int cpc[MAX_MCO];                 /* composing characters */
7403
7390
    return false;
7404
7391
  }
7405
7392
 
7406
 
  if (stop_arrow() == FAIL)
7407
 
    return FALSE;
 
7393
  if (stop_arrow() == FAIL) {
 
7394
    return false;
 
7395
  }
7408
7396
  in_indent = inindent(0);
7409
 
  if (in_indent)
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 */
 
7397
  if (in_indent) {
 
7398
    can_cindent = false;
 
7399
  }
 
7400
  end_comment_pending = NUL;  // After BS, don't auto-end comment
 
7401
  if (revins_on) {            // put cursor after last inserted char
7413
7402
    inc_cursor();
7414
 
 
7415
 
  /* Virtualedit:
7416
 
   *    BACKSPACE_CHAR eats a virtual space
7417
 
   *    BACKSPACE_WORD eats all coladd
7418
 
   *    BACKSPACE_LINE eats all coladd and keeps going
7419
 
   */
 
7403
  }
 
7404
  // Virtualedit:
 
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;
7423
 
      return TRUE;
 
7410
      curwin->w_cursor.coladd--;
 
7411
      return true;
7424
7412
    }
7425
7413
    if (mode == BACKSPACE_WORD) {
7426
7414
      curwin->w_cursor.coladd = 0;
7427
 
      return TRUE;
 
7415
      return true;
7428
7416
    }
7429
7417
    curwin->w_cursor.coladd = 0;
7430
7418
  }
7436
7424
    lnum = Insstart.lnum;
7437
7425
    if (curwin->w_cursor.lnum == lnum || revins_on) {
7438
7426
      if (u_save((linenr_T)(curwin->w_cursor.lnum - 2),
7439
 
              (linenr_T)(curwin->w_cursor.lnum + 1)) == FAIL) {
7440
 
        return FALSE;
 
7427
                 (linenr_T)(curwin->w_cursor.lnum + 1)) == FAIL) {
 
7428
        return false;
7441
7429
      }
7442
 
      --Insstart.lnum;
 
7430
      Insstart.lnum--;
7443
7431
      Insstart.col = MAXCOL;
7444
7432
    }
7445
7433
    /*
7681
7669
  if (vim_strchr(p_cpo, CPO_BACKSPACE) != NULL && dollar_vcol == -1)
7682
7670
    dollar_vcol = curwin->w_virtcol;
7683
7671
 
7684
 
  /* When deleting a char the cursor line must never be in a closed fold.
7685
 
   * E.g., when 'foldmethod' is indent and deleting the first non-white
7686
 
   * char before a Tab. */
7687
 
  if (did_backspace)
 
7672
  // When deleting a char the cursor line must never be in a closed fold.
 
7673
  // E.g., when 'foldmethod' is indent and deleting the first non-white
 
7674
  // char before a Tab.
 
7675
  if (did_backspace) {
7688
7676
    foldOpenCursor();
7689
 
 
 
7677
  }
7690
7678
  return did_backspace;
7691
7679
}
7692
7680
 
8005
7993
  }
8006
7994
}
8007
7995
 
8008
 
/*
8009
 
 * Handle TAB in Insert or Replace mode.
8010
 
 * Return TRUE when the TAB needs to be inserted like a normal character.
8011
 
 */
8012
 
static int ins_tab(void)
 
7996
/// Handle TAB in Insert or Replace mode.
 
7997
///
 
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
8013
8001
{
8014
 
  int ind;
8015
8002
  int i;
8016
8003
  int temp;
8017
8004
 
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))
8021
 
    return FALSE;
8022
 
 
8023
 
  ind = inindent(0);
8024
 
  if (ind)
8025
 
    can_cindent = FALSE;
8026
 
 
8027
 
  /*
8028
 
   * When nothing special, insert TAB like a normal character
8029
 
   */
 
8007
  }
 
8008
  if (echeck_abbr(TAB + ABBR_OFF)) {
 
8009
    return false;
 
8010
  }
 
8011
 
 
8012
  int ind = inindent(0);
 
8013
  if (ind) {
 
8014
    can_cindent = false;
 
8015
  }
 
8016
 
 
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)
8033
 
    return TRUE;
 
8020
      && get_sts_value() == 0) {
 
8021
    return true;
 
8022
  }
8034
8023
 
8035
 
  if (stop_arrow() == FAIL)
8036
 
    return TRUE;
 
8024
  if (stop_arrow() == FAIL) {
 
8025
    return true;
 
8026
  }
8037
8027
 
8038
8028
  did_ai = FALSE;
8039
8029
  did_si = FALSE;
8041
8031
  can_si_back = FALSE;
8042
8032
  AppendToRedobuff((char_u *)"\t");
8043
8033
 
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;
 
8040
  }
8050
8041
  temp -= get_nolist_virtcol() % temp;
8051
8042
 
8052
8043
  /*
8186
8177
    curwin->w_p_list = save_list;
8187
8178
  }
8188
8179
 
8189
 
  return FALSE;
 
8180
  return false;
8190
8181
}
8191
8182
 
8192
 
/*
8193
 
 * Handle CR or NL in insert mode.
8194
 
 * Return TRUE when it can't undo.
8195
 
 */
8196
 
static int ins_eol(int c)
 
8183
/// Handle CR or NL in insert mode.
 
8184
///
 
8185
/// @return true when it can't undo.
 
8186
static bool ins_eol(int c)
8197
8187
{
8198
 
  int i;
8199
 
 
8200
 
  if (echeck_abbr(c + ABBR_OFF))
8201
 
    return FALSE;
8202
 
  if (stop_arrow() == FAIL)
8203
 
    return TRUE;
 
8188
  if (echeck_abbr(c + ABBR_OFF)) {
 
8189
    return false;
 
8190
  }
 
8191
  if (stop_arrow() == FAIL) {
 
8192
    return true;
 
8193
  }
8204
8194
  undisplay_dollar();
8205
8195
 
8206
8196
  /*
8233
8223
    curwin->w_cursor.col += (colnr_T)STRLEN(get_cursor_pos_ptr());
8234
8224
 
8235
8225
  AppendToRedobuff(NL_STR);
8236
 
  i = open_line(FORWARD,
8237
 
      has_format_option(FO_RET_COMS) ? OPENLINE_DO_COM :
8238
 
      0, old_indent);
 
8226
  bool i = open_line(FORWARD,
 
8227
                     has_format_option(FO_RET_COMS) ? OPENLINE_DO_COM : 0,
 
8228
                     old_indent);
8239
8229
  old_indent = 0;
8240
8230
  can_cindent = TRUE;
8241
8231
  /* When inserting a line the cursor line must never be in a closed fold. */
8520
8510
 
8521
8511
  return res;
8522
8512
}
 
8513
 
 
8514
static void show_pum(int save_w_wrow)
 
8515
{
 
8516
  // RedrawingDisabled may be set when invoked through complete().
 
8517
  int n = RedrawingDisabled;
 
8518
  RedrawingDisabled = 0;
 
8519
 
 
8520
  // If the cursor moved we need to remove the pum first.
 
8521
  setcursor();
 
8522
  if (save_w_wrow != curwin->w_wrow) {
 
8523
    ins_compl_del_pum();
 
8524
  }
 
8525
 
 
8526
  ins_compl_show_pum();
 
8527
  setcursor();
 
8528
  RedrawingDisabled = n;
 
8529
}