diff options
Diffstat (limited to 'src/nvim/edit.c')
-rw-r--r-- | src/nvim/edit.c | 143 |
1 files changed, 91 insertions, 52 deletions
diff --git a/src/nvim/edit.c b/src/nvim/edit.c index b5d5d67e90..56b563cba0 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -597,7 +597,10 @@ static int insert_check(VimState *state) s->mincol = curwin->w_wcol; validate_cursor_col(); - if (curwin->w_wcol < s->mincol - curbuf->b_p_ts + if ( + curwin->w_wcol < s->mincol - tabstop_at(get_nolist_virtcol(), + curbuf->b_p_ts, + curbuf->b_p_vts_array) && curwin->w_wrow == curwin->w_winrow + curwin->w_height_inner - 1 - get_scrolloff_value(curwin) && (curwin->w_cursor.lnum != curwin->w_topline @@ -989,6 +992,7 @@ static int insert_handle_key(InsertState *s) case K_LEFTDRAG: case K_LEFTRELEASE: case K_LEFTRELEASE_NM: + case K_MOUSEMOVE: case K_MIDDLEMOUSE: case K_MIDDLEDRAG: case K_MIDDLERELEASE: @@ -1601,13 +1605,20 @@ void edit_putchar(int c, bool highlight) } } +/// Return the effective prompt for the specified buffer. +char_u *buf_prompt_text(const buf_T *const buf) + FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT +{ + if (buf->b_prompt_text == NULL) { + return (char_u *)"% "; + } + return buf->b_prompt_text; +} + // Return the effective prompt for the current buffer. -char_u *prompt_text(void) +char_u *prompt_text(void) FUNC_ATTR_WARN_UNUSED_RESULT { - if (curbuf->b_prompt_text == NULL) { - return (char_u *)"% "; - } - return curbuf->b_prompt_text; + return buf_prompt_text(curbuf); } // Prepare for prompt mode: Make sure the last line has the prompt text. @@ -2055,7 +2066,7 @@ static bool check_compl_option(bool dict_opt) vim_beep(BO_COMPL); setcursor(); ui_flush(); - os_delay(2000L, false); + os_delay(2004L, false); } return false; } @@ -2316,7 +2327,11 @@ static int ins_compl_add(char_u *const str, int len, const Direction dir = (cdir == kDirectionNotSet ? compl_direction : cdir); int flags = flags_arg; - os_breakcheck(); + if (flags & CP_FAST) { + fast_breakcheck(); + } else { + os_breakcheck(); + } #define FREE_CPTEXT(cptext, cptext_allocated) \ do { \ if (cptext != NULL && cptext_allocated) { \ @@ -2520,7 +2535,8 @@ static void ins_compl_add_matches(int num_matches, char_u **matches, int icase) for (int i = 0; i < num_matches && add_r != FAIL; i++) { if ((add_r = ins_compl_add(matches[i], -1, NULL, NULL, false, NULL, dir, - icase ? CP_ICASE : 0, false)) == OK) { + CP_FAST | (icase ? CP_ICASE : 0), + false)) == OK) { // If dir was BACKWARD then honor it just once. dir = FORWARD; } @@ -2595,7 +2611,7 @@ void set_completion(colnr_T startcol, list_T *list) flags |= CP_ICASE; } if (ins_compl_add(compl_orig_text, -1, NULL, NULL, false, NULL, 0, - flags, false) != OK) { + flags | CP_FAST, false) != OK) { return; } @@ -3315,8 +3331,8 @@ static int ins_compl_bs(void) // allow the word to be deleted, we won't match everything. // Respect the 'backspace' option. if ((int)(p - line) - (int)compl_col < 0 - || ((int)(p - line) - (int)compl_col == 0 - && ctrl_x_mode != CTRL_X_OMNI) || ctrl_x_mode == CTRL_X_EVAL + || ((int)(p - line) - (int)compl_col == 0 && ctrl_x_mode != CTRL_X_OMNI) + || ctrl_x_mode == CTRL_X_EVAL || (!can_bs(BS_START) && (int)(p - line) - (int)compl_col - compl_length < 0)) { return K_BS; @@ -3931,7 +3947,7 @@ static void ins_compl_add_list(list_T *const list) // Go through the List with matches and add each of them. TV_LIST_ITER(list, li, { - if (ins_compl_add_tv(TV_LIST_ITEM_TV(li), dir) == OK) { + if (ins_compl_add_tv(TV_LIST_ITEM_TV(li), dir, true) == OK) { // If dir was BACKWARD then honor it just once. dir = FORWARD; } else if (did_emsg) { @@ -3970,17 +3986,18 @@ static void ins_compl_add_dict(dict_T *dict) /// /// @param[in] tv Object to get matches from. /// @param[in] dir Completion direction. +/// @param[in] fast use fast_breakcheck() instead of os_breakcheck(). /// /// @return NOTDONE if the given string is already in the list of completions, /// otherwise it is added to the list and OK is returned. FAIL will be /// returned in case of error. -int ins_compl_add_tv(typval_T *const tv, const Direction dir) +int ins_compl_add_tv(typval_T *const tv, const Direction dir, bool fast) FUNC_ATTR_NONNULL_ALL { const char *word; bool dup = false; bool empty = false; - int flags = 0; + int flags = fast ? CP_FAST : 0; char *(cptext[CPT_COUNT]); typval_T user_data; @@ -7266,7 +7283,6 @@ bool in_cinkeys(int keytyped, int when, bool line_is_empty) char_u *p; char_u *line; int icase; - int i; if (keytyped == NUL) { // Can happen with CTRL-Y and CTRL-E on a short line. @@ -7351,8 +7367,9 @@ bool in_cinkeys(int keytyped, int when, bool line_is_empty) && p[curwin->w_cursor.col - 1] == ':' && p[curwin->w_cursor.col - 2] == ':') { p[curwin->w_cursor.col - 1] = ' '; - i = (cin_iscase(p, FALSE) || cin_isscopedecl(p) - || cin_islabel()); + const bool i = cin_iscase(p, false) + || cin_isscopedecl(p) + || cin_islabel(); p = get_cursor_line_ptr(); p[curwin->w_cursor.col - 1] = ':'; if (i) { @@ -8178,24 +8195,20 @@ static bool ins_bs(int c, int mode, int *inserted_space_p) /* * Handle deleting one 'shiftwidth' or 'softtabstop'. */ - if ( mode == BACKSPACE_CHAR - && ((p_sta && in_indent) - || (get_sts_value() != 0 - && curwin->w_cursor.col > 0 - && (*(get_cursor_pos_ptr() - 1) == TAB - || (*(get_cursor_pos_ptr() - 1) == ' ' - && (!*inserted_space_p - || arrow_used)))))) { + if (mode == BACKSPACE_CHAR + && ((p_sta && in_indent) + || ((get_sts_value() != 0 + || tabstop_count(curbuf->b_p_vsts_array)) + && curwin->w_cursor.col > 0 + && (*(get_cursor_pos_ptr() - 1) == TAB + || (*(get_cursor_pos_ptr() - 1) == ' ' + && (!*inserted_space_p || arrow_used)))))) { int ts; colnr_T vcol; colnr_T want_vcol; colnr_T start_vcol; - *inserted_space_p = FALSE; - if (p_sta && in_indent) - ts = get_sw_value(curbuf); - else - ts = get_sts_value(); + *inserted_space_p = false; // Compute the virtual column where we want to be. Since // 'showbreak' may get in the way, need to get the last column of // the previous character. @@ -8204,7 +8217,14 @@ static bool ins_bs(int c, int mode, int *inserted_space_p) dec_cursor(); getvcol(curwin, &curwin->w_cursor, NULL, NULL, &want_vcol); inc_cursor(); - want_vcol = (want_vcol / ts) * ts; + if (p_sta && in_indent) { + ts = (int)get_sw_value(curbuf); + want_vcol = (want_vcol / ts) * ts; + } else { + want_vcol = tabstop_start(want_vcol, + get_sts_value(), + curbuf->b_p_vsts_array); + } // delete characters until we are at or before want_vcol while (vcol > want_vcol @@ -8669,10 +8689,19 @@ static bool ins_tab(void) can_cindent = false; } - // When nothing special, insert TAB like a normal character + // When nothing special, insert TAB like a normal character. if (!curbuf->b_p_et - && !(p_sta && ind && curbuf->b_p_ts != get_sw_value(curbuf)) - && get_sts_value() == 0) { + && !( + p_sta + && ind + // These five lines mean 'tabstop' != 'shiftwidth' + && ((tabstop_count(curbuf->b_p_vts_array) > 1) + || (tabstop_count(curbuf->b_p_vts_array) == 1 + && tabstop_first(curbuf->b_p_vts_array) + != get_sw_value(curbuf)) + || (tabstop_count(curbuf->b_p_vts_array) == 0 + && curbuf->b_p_ts != get_sw_value(curbuf)))) + && tabstop_count(curbuf->b_p_vsts_array) == 0 && get_sts_value() == 0) { return true; } @@ -8686,16 +8715,22 @@ static bool ins_tab(void) can_si_back = false; AppendToRedobuff("\t"); - if (p_sta && ind) { // insert tab in indent, use "shiftwidth" - temp = get_sw_value(curbuf); - } else if (curbuf->b_p_sts != 0) { // use "softtabstop" when set - temp = get_sts_value(); - } else { // otherwise use "tabstop" - temp = (int)curbuf->b_p_ts; + if (p_sta && ind) { // insert tab in indent, use 'shiftwidth' + temp = (int)get_sw_value(curbuf); + temp -= get_nolist_virtcol() % temp; + } else if (tabstop_count(curbuf->b_p_vsts_array) > 0 + || curbuf->b_p_sts != 0) { + // use 'softtabstop' when set + temp = tabstop_padding(get_nolist_virtcol(), + get_sts_value(), + curbuf->b_p_vsts_array); + } else { + // otherwise use 'tabstop' + temp = tabstop_padding(get_nolist_virtcol(), + curbuf->b_p_ts, + curbuf->b_p_vts_array); } - temp -= get_nolist_virtcol() % temp; - /* * Insert the first space with ins_char(). It will delete one char in * replace mode. Insert the rest with ins_str(); it will not delete any @@ -8716,7 +8751,9 @@ static bool ins_tab(void) /* * When 'expandtab' not set: Replace spaces by TABs where possible. */ - if (!curbuf->b_p_et && (get_sts_value() || (p_sta && ind))) { + if (!curbuf->b_p_et && (tabstop_count(curbuf->b_p_vsts_array) > 0 + || get_sts_value() > 0 + || (p_sta && ind))) { char_u *ptr; char_u *saved_line = NULL; // init for GCC pos_T pos; @@ -8764,10 +8801,6 @@ static bool ins_tab(void) getvcol(curwin, &fpos, &vcol, NULL, NULL); getvcol(curwin, cursor, &want_vcol, NULL, NULL); - // save start of changed region for extmark_splice - int start_row = fpos.lnum; - colnr_T start_col = fpos.col; - // Use as many TABs as possible. Beware of 'breakindent', 'showbreak' // and 'linebreak' adding extra virtual columns. while (ascii_iswhite(*ptr)) { @@ -8818,8 +8851,8 @@ static bool ins_tab(void) } } if (!(State & VREPLACE_FLAG)) { - extmark_splice_cols(curbuf, start_row - 1, start_col, - cursor->col - start_col, fpos.col - start_col, + extmark_splice_cols(curbuf, fpos.lnum - 1, change_col, + cursor->col - change_col, fpos.col - change_col, kExtmarkUndo); } } @@ -9133,10 +9166,16 @@ static void ins_try_si(int c) * Get the value that w_virtcol would have when 'list' is off. * Unless 'cpo' contains the 'L' flag. */ -static colnr_T get_nolist_virtcol(void) +colnr_T get_nolist_virtcol(void) { - if (curwin->w_p_list && vim_strchr(p_cpo, CPO_LISTWM) == NULL) + // check validity of cursor in current buffer + if (curwin->w_buffer == NULL || curwin->w_buffer->b_ml.ml_mfp == NULL + || curwin->w_cursor.lnum > curwin->w_buffer->b_ml.ml_line_count) { + return 0; + } + if (curwin->w_p_list && vim_strchr(p_cpo, CPO_LISTWM) == NULL) { return getvcol_nolist(&curwin->w_cursor); + } validate_virtcol(); return curwin->w_virtcol; } |