diff options
author | VVKot <volodymyr.kot.ua@gmail.com> | 2021-02-13 19:06:37 +0000 |
---|---|---|
committer | VVKot <volodymyr.kot.ua@gmail.com> | 2021-03-28 08:37:01 +0100 |
commit | 6752ac49682d63dfc7960e518ecbd6517c88392d (patch) | |
tree | b0e4a27d32f23ea52f11ae1a6a4f24617f79a5e6 /src/nvim/ex_cmds.c | |
parent | b79596eb5e942a299aa021a0f9a3f2db909294da (diff) | |
download | rneovim-6752ac49682d63dfc7960e518ecbd6517c88392d.tar.gz rneovim-6752ac49682d63dfc7960e518ecbd6517c88392d.tar.bz2 rneovim-6752ac49682d63dfc7960e518ecbd6517c88392d.zip |
vim-patch:8.1.0105: all tab stops are the same
Problem: All tab stops are the same.
Solution: Add the variable tabstop feature. (Christian Brabandt,
closes vim/vim#2711)
https://github.com/vim/vim/commit/04958cbaf25eea27eceedaa987adfb354ad5f7fd
Diffstat (limited to 'src/nvim/ex_cmds.c')
-rw-r--r-- | src/nvim/ex_cmds.c | 80 |
1 files changed, 59 insertions, 21 deletions
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index 854faf5377..d679a3c8f8 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -712,14 +712,15 @@ void ex_retab(exarg_T *eap) long len; long col; long vcol; - long start_col = 0; /* For start of white-space string */ - long start_vcol = 0; /* For start of white-space string */ - int temp; + long start_col = 0; // For start of white-space string + long start_vcol = 0; // For start of white-space string long old_len; char_u *ptr; - char_u *new_line = (char_u *)1; /* init to non-NULL */ - int did_undo; /* called u_save for current line */ - int new_ts; + char_u *new_line = (char_u *)1; // init to non-NULL + int did_undo; // called u_save for current line + long *new_ts = 0; + char_u *new_ts_str; // string value of tab argument + int save_list; linenr_T first_line = 0; /* first changed line */ linenr_T last_line = 0; /* last changed line */ @@ -727,14 +728,23 @@ void ex_retab(exarg_T *eap) save_list = curwin->w_p_list; curwin->w_p_list = 0; /* don't want list mode here */ - new_ts = getdigits_int(&(eap->arg), false, -1); - if (new_ts < 0) { - EMSG(_(e_positive)); + new_ts_str = eap->arg; + if (!tabstop_set(eap->arg, &new_ts)) { return; } - if (new_ts == 0) - new_ts = curbuf->b_p_ts; - for (lnum = eap->line1; !got_int && lnum <= eap->line2; ++lnum) { + while (ascii_isdigit(*(eap->arg)) || *(eap->arg) == ',') { + (eap->arg)++; + } + + // This ensures that either new_ts and new_ts_str are freshly allocated, + // or new_ts points to an existing array and new_ts_str is null. + if (new_ts == 0) { + new_ts = curbuf->b_p_vts_array; + new_ts_str = NULL; + } else { + new_ts_str = vim_strnsave(new_ts_str, eap->arg - new_ts_str); + } + for (lnum = eap->line1; !got_int && lnum <= eap->line2; lnum++) { ptr = ml_get(lnum); col = 0; vcol = 0; @@ -758,13 +768,14 @@ void ex_retab(exarg_T *eap) len = num_spaces = vcol - start_vcol; num_tabs = 0; if (!curbuf->b_p_et) { - temp = new_ts - (start_vcol % new_ts); - if (num_spaces >= temp) { - num_spaces -= temp; - num_tabs++; - } - num_tabs += num_spaces / new_ts; - num_spaces -= (num_spaces / new_ts) * new_ts; + int t, s; + + tabstop_fromto(start_vcol, vcol, + tabstop_count(new_ts) ? 0 : curbuf->b_p_ts, + new_ts, + &t, &s); + num_tabs = t; + num_spaces = s; } if (curbuf->b_p_et || got_tab || (num_spaces + num_tabs < len)) { @@ -817,15 +828,42 @@ void ex_retab(exarg_T *eap) if (got_int) EMSG(_(e_interr)); - if (curbuf->b_p_ts != new_ts) + // If a single value was given then it can be considered equal to + // either the value of 'tabstop' or the value of 'vartabstop'. + if (tabstop_count(curbuf->b_p_vts_array) == 0 + && tabstop_count(new_ts) == 1 + && curbuf->b_p_ts == tabstop_first(new_ts)) { + // not changed + } else if (tabstop_count(curbuf->b_p_vts_array) > 0 + && tabstop_eq(curbuf->b_p_vts_array, new_ts)) { + // not changed + } else { redraw_curbuf_later(NOT_VALID); + } if (first_line != 0) { changed_lines(first_line, 0, last_line + 1, 0L, true); } curwin->w_p_list = save_list; /* restore 'list' */ - curbuf->b_p_ts = new_ts; + if (new_ts_str != NULL) { // set the new tabstop + // If 'vartabstop' is in use or if the value given to retab has more + // than one tabstop then update 'vartabstop'. + long *old_vts_ary = curbuf->b_p_vts_array; + + if (tabstop_count(old_vts_ary) > 0 || tabstop_count(new_ts) > 1) { + set_string_option_direct("vts", -1, new_ts_str, + OPT_FREE | OPT_LOCAL, 0); + xfree(new_ts_str); + curbuf->b_p_vts_array = new_ts; + xfree(old_vts_ary); + } else { + // 'vartabstop' wasn't in use and a single value was given to + // retab then update 'tabstop'. + curbuf->b_p_ts = tabstop_first(new_ts); + xfree(new_ts); + } + } coladvance(curwin->w_curswant); u_clearline(); |