diff options
author | Bram Moolenaar <Bram@vim.org> | 2018-06-23 19:23:02 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2018-06-23 19:23:02 +0200 |
commit | 04958cbaf25eea27eceedaa987adfb354ad5f7fd (patch) | |
tree | 9a47e4e99b5b702e12d08c0424a91ae701eabb4d /src/ex_cmds.c | |
parent | 5ec7414a1c0512832f60c17437d6374cbf4b08e9 (diff) | |
download | vim-git-04958cbaf25eea27eceedaa987adfb354ad5f7fd.tar.gz |
patch 8.1.0105: all tab stops are the samev8.1.0105
Problem: All tab stops are the same.
Solution: Add the variable tabstop feature. (Christian Brabandt,
closes #2711)
Diffstat (limited to 'src/ex_cmds.c')
-rw-r--r-- | src/ex_cmds.c | 75 |
1 files changed, 74 insertions, 1 deletions
diff --git a/src/ex_cmds.c b/src/ex_cmds.c index 60d72023c..53334342c 100644 --- a/src/ex_cmds.c +++ b/src/ex_cmds.c @@ -673,12 +673,17 @@ ex_retab(exarg_T *eap) 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 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 */ +#ifdef FEAT_VARTABS + int *new_ts = 0; + char_u *new_ts_str; /* string value of tab argument */ +#else + int temp; int new_ts; +#endif int save_list; linenr_T first_line = 0; /* first changed line */ linenr_T last_line = 0; /* last changed line */ @@ -686,6 +691,23 @@ ex_retab(exarg_T *eap) save_list = curwin->w_p_list; curwin->w_p_list = 0; /* don't want list mode here */ +#ifdef FEAT_VARTABS + new_ts_str = eap->arg; + if (!tabstop_set(eap->arg, &new_ts)) + return; + while (vim_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); +#else new_ts = getdigits(&(eap->arg)); if (new_ts < 0) { @@ -694,6 +716,7 @@ ex_retab(exarg_T *eap) } if (new_ts == 0) new_ts = curbuf->b_p_ts; +#endif for (lnum = eap->line1; !got_int && lnum <= eap->line2; ++lnum) { ptr = ml_get(lnum); @@ -726,6 +749,16 @@ ex_retab(exarg_T *eap) num_tabs = 0; if (!curbuf->b_p_et) { +#ifdef FEAT_VARTABS + 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; +#else temp = new_ts - (start_vcol % new_ts); if (num_spaces >= temp) { @@ -734,6 +767,7 @@ ex_retab(exarg_T *eap) } num_tabs += num_spaces / new_ts; num_spaces -= (num_spaces / new_ts) * new_ts; +#endif } if (curbuf->b_p_et || got_tab || (num_spaces + num_tabs < len)) @@ -791,14 +825,53 @@ ex_retab(exarg_T *eap) if (got_int) EMSG(_(e_interr)); +#ifdef FEAT_VARTABS + // 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); +#else if (curbuf->b_p_ts != new_ts) redraw_curbuf_later(NOT_VALID); +#endif if (first_line != 0) changed_lines(first_line, 0, last_line + 1, 0L); curwin->w_p_list = save_list; /* restore 'list' */ +#ifdef FEAT_VARTABS + 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'. + int *old_vts_ary = curbuf->b_p_vts_array; + + if (tabstop_count(old_vts_ary) > 0 || tabstop_count(new_ts) > 1) + { + set_string_option_direct((char_u *)"vts", -1, new_ts_str, + OPT_FREE|OPT_LOCAL, 0); + vim_free(new_ts_str); + curbuf->b_p_vts_array = new_ts; + vim_free(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); + vim_free(new_ts); + } + } +#else curbuf->b_p_ts = new_ts; +#endif coladvance(curwin->w_curswant); u_clearline(); |