comparison src/option.c @ 14175:2ad722003b36 v8.1.0105

patch 8.1.0105: all tab stops are the same commit https://github.com/vim/vim/commit/04958cbaf25eea27eceedaa987adfb354ad5f7fd Author: Bram Moolenaar <Bram@vim.org> Date: Sat Jun 23 19:23:02 2018 +0200 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 #2711)
author Christian Brabandt <cb@256bit.org>
date Sat, 23 Jun 2018 19:30:07 +0200
parents 1157f16150b3
children ab64a4fb5edd
comparison
equal deleted inserted replaced
14174:d36eedd19166 14175:2ad722003b36
180 #define PV_TX OPT_BUF(BV_TX) 180 #define PV_TX OPT_BUF(BV_TX)
181 #ifdef FEAT_PERSISTENT_UNDO 181 #ifdef FEAT_PERSISTENT_UNDO
182 # define PV_UDF OPT_BUF(BV_UDF) 182 # define PV_UDF OPT_BUF(BV_UDF)
183 #endif 183 #endif
184 #define PV_WM OPT_BUF(BV_WM) 184 #define PV_WM OPT_BUF(BV_WM)
185 #ifdef FEAT_VARTABS
186 # define PV_VSTS OPT_BUF(BV_VSTS)
187 # define PV_VTS OPT_BUF(BV_VTS)
188 #endif
185 189
186 /* 190 /*
187 * Definition of the PV_ values for window-local options. 191 * Definition of the PV_ values for window-local options.
188 * The WV_ values are defined in option.h. 192 * The WV_ values are defined in option.h.
189 */ 193 */
369 static int p_tx; 373 static int p_tx;
370 #ifdef FEAT_PERSISTENT_UNDO 374 #ifdef FEAT_PERSISTENT_UNDO
371 static int p_udf; 375 static int p_udf;
372 #endif 376 #endif
373 static long p_wm; 377 static long p_wm;
378 #ifdef FEAT_VARTABS
379 static char_u *p_vsts;
380 static char_u *p_vts;
381 #endif
374 #ifdef FEAT_KEYMAP 382 #ifdef FEAT_KEYMAP
375 static char_u *p_keymap; 383 static char_u *p_keymap;
376 #endif 384 #endif
377 #ifdef FEAT_TERMINAL 385 #ifdef FEAT_TERMINAL
378 static long p_twsl; /* 'termwinscroll' */ 386 static long p_twsl; /* 'termwinscroll' */
388 static int p_ai_nopaste; 396 static int p_ai_nopaste;
389 static int p_et_nopaste; 397 static int p_et_nopaste;
390 static long p_sts_nopaste; 398 static long p_sts_nopaste;
391 static long p_tw_nopaste; 399 static long p_tw_nopaste;
392 static long p_wm_nopaste; 400 static long p_wm_nopaste;
401 #ifdef FEAT_VARTABS
402 static char_u *p_vsts_nopaste;
403 #endif
393 404
394 struct vimoption 405 struct vimoption
395 { 406 {
396 char *fullname; /* full option name */ 407 char *fullname; /* full option name */
397 char *shortname; /* permissible abbreviation */ 408 char *shortname; /* permissible abbreviation */
2923 (char_u *)&p_uc, PV_NONE, 2934 (char_u *)&p_uc, PV_NONE,
2924 {(char_u *)200L, (char_u *)0L} SCRIPTID_INIT}, 2935 {(char_u *)200L, (char_u *)0L} SCRIPTID_INIT},
2925 {"updatetime", "ut", P_NUM|P_VI_DEF, 2936 {"updatetime", "ut", P_NUM|P_VI_DEF,
2926 (char_u *)&p_ut, PV_NONE, 2937 (char_u *)&p_ut, PV_NONE,
2927 {(char_u *)4000L, (char_u *)0L} SCRIPTID_INIT}, 2938 {(char_u *)4000L, (char_u *)0L} SCRIPTID_INIT},
2939 {"varsofttabstop", "vsts", P_STRING|P_VI_DEF|P_VIM|P_COMMA,
2940 #ifdef FEAT_VARTABS
2941 (char_u *)&p_vsts, PV_VSTS,
2942 {(char_u *)"", (char_u *)0L}
2943 #else
2944 (char_u *)NULL, PV_NONE,
2945 {(char_u *)"", (char_u *)NULL}
2946 #endif
2947 SCRIPTID_INIT},
2948 {"vartabstop", "vts", P_STRING|P_VI_DEF|P_VIM|P_RBUF|P_COMMA,
2949 #ifdef FEAT_VARTABS
2950 (char_u *)&p_vts, PV_VTS,
2951 {(char_u *)"", (char_u *)0L}
2952 #else
2953 (char_u *)NULL, PV_NONE,
2954 {(char_u *)"", (char_u *)NULL}
2955 #endif
2956 SCRIPTID_INIT},
2928 {"verbose", "vbs", P_NUM|P_VI_DEF, 2957 {"verbose", "vbs", P_NUM|P_VI_DEF,
2929 (char_u *)&p_verbose, PV_NONE, 2958 (char_u *)&p_verbose, PV_NONE,
2930 {(char_u *)0L, (char_u *)0L} SCRIPTID_INIT}, 2959 {(char_u *)0L, (char_u *)0L} SCRIPTID_INIT},
2931 {"verbosefile", "vfile", P_STRING|P_EXPAND|P_VI_DEF|P_SECURE, 2960 {"verbosefile", "vfile", P_STRING|P_EXPAND|P_VI_DEF|P_SECURE,
2932 (char_u *)&p_vfile, PV_NONE, 2961 (char_u *)&p_vfile, PV_NONE,
5606 5635
5607 #ifdef FEAT_CLIPBOARD 5636 #ifdef FEAT_CLIPBOARD
5608 /* Parse default for 'clipboard' */ 5637 /* Parse default for 'clipboard' */
5609 (void)check_clipboard_option(); 5638 (void)check_clipboard_option();
5610 #endif 5639 #endif
5640 #ifdef FEAT_VARTABS
5641 tabstop_set(curbuf->b_p_vsts, &curbuf->b_p_vsts_array);
5642 tabstop_set(curbuf->b_p_vts, &curbuf->b_p_vts_array);
5643 #endif
5611 } 5644 }
5612 5645
5613 /* 5646 /*
5614 * Check for string options that are NULL (normally only termcap options). 5647 * Check for string options that are NULL (normally only termcap options).
5615 */ 5648 */
5722 check_string_option(&buf->b_p_lw); 5755 check_string_option(&buf->b_p_lw);
5723 #endif 5756 #endif
5724 check_string_option(&buf->b_p_bkc); 5757 check_string_option(&buf->b_p_bkc);
5725 #ifdef FEAT_MBYTE 5758 #ifdef FEAT_MBYTE
5726 check_string_option(&buf->b_p_menc); 5759 check_string_option(&buf->b_p_menc);
5760 #endif
5761 #ifdef FEAT_VARTABS
5762 check_string_option(&buf->b_p_vsts);
5763 check_string_option(&buf->b_p_vts);
5727 #endif 5764 #endif
5728 } 5765 }
5729 5766
5730 /* 5767 /*
5731 * Free the string allocated for an option. 5768 * Free the string allocated for an option.
7470 errmsg = e_invarg; 7507 errmsg = e_invarg;
7471 } 7508 }
7472 } 7509 }
7473 #endif 7510 #endif
7474 7511
7512 #ifdef FEAT_VARTABS
7513 /* 'varsofttabstop' */
7514 else if (varp == &(curbuf->b_p_vsts))
7515 {
7516 char_u *cp;
7517
7518 if (!(*varp)[0] || ((*varp)[0] == '0' && !(*varp)[1]))
7519 {
7520 if (curbuf->b_p_vsts_array)
7521 {
7522 vim_free(curbuf->b_p_vsts_array);
7523 curbuf->b_p_vsts_array = 0;
7524 }
7525 }
7526 else
7527 {
7528 for (cp = *varp; *cp; ++cp)
7529 {
7530 if (vim_isdigit(*cp))
7531 continue;
7532 if (*cp == ',' && cp > *varp && *(cp-1) != ',')
7533 continue;
7534 errmsg = e_invarg;
7535 break;
7536 }
7537 if (errmsg == NULL)
7538 {
7539 int *oldarray = curbuf->b_p_vsts_array;
7540 if (tabstop_set(*varp, &(curbuf->b_p_vsts_array)))
7541 {
7542 if (oldarray)
7543 vim_free(oldarray);
7544 }
7545 else
7546 errmsg = e_invarg;
7547 }
7548 }
7549 }
7550
7551 /* 'vartabstop' */
7552 else if (varp == &(curbuf->b_p_vts))
7553 {
7554 char_u *cp;
7555
7556 if (!(*varp)[0] || ((*varp)[0] == '0' && !(*varp)[1]))
7557 {
7558 if (curbuf->b_p_vts_array)
7559 {
7560 vim_free(curbuf->b_p_vts_array);
7561 curbuf->b_p_vts_array = NULL;
7562 }
7563 }
7564 else
7565 {
7566 for (cp = *varp; *cp; ++cp)
7567 {
7568 if (vim_isdigit(*cp))
7569 continue;
7570 if (*cp == ',' && cp > *varp && *(cp-1) != ',')
7571 continue;
7572 errmsg = e_invarg;
7573 break;
7574 }
7575 if (errmsg == NULL)
7576 {
7577 int *oldarray = curbuf->b_p_vts_array;
7578 if (tabstop_set(*varp, &(curbuf->b_p_vts_array)))
7579 {
7580 if (oldarray)
7581 vim_free(oldarray);
7582 #ifdef FEAT_FOLDING
7583 if (foldmethodIsIndent(curwin))
7584 foldUpdateAll(curwin);
7585 #endif /* FEAT_FOLDING */
7586 }
7587 else
7588 errmsg = e_invarg;
7589 }
7590 }
7591 }
7592 #endif
7593
7475 /* Options that are a list of flags. */ 7594 /* Options that are a list of flags. */
7476 else 7595 else
7477 { 7596 {
7478 p = NULL; 7597 p = NULL;
7479 if (varp == &p_ww) /* 'whichwrap' */ 7598 if (varp == &p_ww) /* 'whichwrap' */
8778 #endif 8897 #endif
8779 8898
8780 if (curbuf->b_p_sw < 0) 8899 if (curbuf->b_p_sw < 0)
8781 { 8900 {
8782 errmsg = e_positive; 8901 errmsg = e_positive;
8902 #ifdef FEAT_VARTABS
8903 // Use the first 'vartabstop' value, or 'tabstop' if vts isn't in use.
8904 curbuf->b_p_sw = tabstop_count(curbuf->b_p_vts_array) > 0
8905 ? tabstop_first(curbuf->b_p_vts_array)
8906 : curbuf->b_p_ts;
8907 #else
8783 curbuf->b_p_sw = curbuf->b_p_ts; 8908 curbuf->b_p_sw = curbuf->b_p_ts;
8909 #endif
8784 } 8910 }
8785 8911
8786 /* 8912 /*
8787 * Number options that need some action when changed 8913 * Number options that need some action when changed
8788 */ 8914 */
10812 case PV_KMAP: return (char_u *)&(curbuf->b_p_keymap); 10938 case PV_KMAP: return (char_u *)&(curbuf->b_p_keymap);
10813 #endif 10939 #endif
10814 #ifdef FEAT_SIGNS 10940 #ifdef FEAT_SIGNS
10815 case PV_SCL: return (char_u *)&(curwin->w_p_scl); 10941 case PV_SCL: return (char_u *)&(curwin->w_p_scl);
10816 #endif 10942 #endif
10943 #ifdef FEAT_VARTABS
10944 case PV_VSTS: return (char_u *)&(curbuf->b_p_vsts);
10945 case PV_VTS: return (char_u *)&(curbuf->b_p_vts);
10946 #endif
10817 default: IEMSG(_("E356: get_varp ERROR")); 10947 default: IEMSG(_("E356: get_varp ERROR"));
10818 } 10948 }
10819 /* always return a valid pointer to avoid a crash! */ 10949 /* always return a valid pointer to avoid a crash! */
10820 return (char_u *)&(curbuf->b_p_wm); 10950 return (char_u *)&(curbuf->b_p_wm);
10821 } 10951 }
11136 buf->b_p_cfu = vim_strsave(p_cfu); 11266 buf->b_p_cfu = vim_strsave(p_cfu);
11137 buf->b_p_ofu = vim_strsave(p_ofu); 11267 buf->b_p_ofu = vim_strsave(p_ofu);
11138 #endif 11268 #endif
11139 buf->b_p_sts = p_sts; 11269 buf->b_p_sts = p_sts;
11140 buf->b_p_sts_nopaste = p_sts_nopaste; 11270 buf->b_p_sts_nopaste = p_sts_nopaste;
11271 #ifdef FEAT_VARTABS
11272 buf->b_p_vsts = vim_strsave(p_vsts);
11273 if (p_vsts && p_vsts != empty_option)
11274 tabstop_set(p_vsts, &buf->b_p_vsts_array);
11275 else
11276 buf->b_p_vsts_array = 0;
11277 buf->b_p_vsts_nopaste = p_vsts_nopaste
11278 ? vim_strsave(p_vsts_nopaste) : NULL;
11279 #endif
11141 buf->b_p_sn = p_sn; 11280 buf->b_p_sn = p_sn;
11142 #ifdef FEAT_COMMENTS 11281 #ifdef FEAT_COMMENTS
11143 buf->b_p_com = vim_strsave(p_com); 11282 buf->b_p_com = vim_strsave(p_com);
11144 #endif 11283 #endif
11145 #ifdef FEAT_FOLDING 11284 #ifdef FEAT_FOLDING
11257 * when going from a help buffer to a non-help buffer. 11396 * when going from a help buffer to a non-help buffer.
11258 * Don't touch these at all when BCO_NOHELP is used and going from 11397 * Don't touch these at all when BCO_NOHELP is used and going from
11259 * or to a help buffer. 11398 * or to a help buffer.
11260 */ 11399 */
11261 if (dont_do_help) 11400 if (dont_do_help)
11401 {
11262 buf->b_p_isk = save_p_isk; 11402 buf->b_p_isk = save_p_isk;
11403 #ifdef FEAT_VARTABS
11404 if (p_vts && p_vts != empty_option && !buf->b_p_vts_array)
11405 tabstop_set(p_vts, &buf->b_p_vts_array);
11406 else
11407 buf->b_p_vts_array = NULL;
11408 #endif
11409 }
11263 else 11410 else
11264 { 11411 {
11265 buf->b_p_isk = vim_strsave(p_isk); 11412 buf->b_p_isk = vim_strsave(p_isk);
11266 did_isk = TRUE; 11413 did_isk = TRUE;
11267 buf->b_p_ts = p_ts; 11414 buf->b_p_ts = p_ts;
11415 #ifdef FEAT_VARTABS
11416 buf->b_p_vts = vim_strsave(p_vts);
11417 if (p_vts && p_vts != empty_option && !buf->b_p_vts_array)
11418 tabstop_set(p_vts, &buf->b_p_vts_array);
11419 else
11420 buf->b_p_vts_array = NULL;
11421 #endif
11268 buf->b_help = FALSE; 11422 buf->b_help = FALSE;
11269 if (buf->b_p_bt[0] == 'h') 11423 if (buf->b_p_bt[0] == 'h')
11270 clear_string_option(&buf->b_p_bt); 11424 clear_string_option(&buf->b_p_bt);
11271 buf->b_p_ma = p_ma; 11425 buf->b_p_ma = p_ma;
11272 } 11426 }
12082 buf->b_p_tw_nopaste = buf->b_p_tw; 12236 buf->b_p_tw_nopaste = buf->b_p_tw;
12083 buf->b_p_wm_nopaste = buf->b_p_wm; 12237 buf->b_p_wm_nopaste = buf->b_p_wm;
12084 buf->b_p_sts_nopaste = buf->b_p_sts; 12238 buf->b_p_sts_nopaste = buf->b_p_sts;
12085 buf->b_p_ai_nopaste = buf->b_p_ai; 12239 buf->b_p_ai_nopaste = buf->b_p_ai;
12086 buf->b_p_et_nopaste = buf->b_p_et; 12240 buf->b_p_et_nopaste = buf->b_p_et;
12241 #ifdef FEAT_VARTABS
12242 if (buf->b_p_vsts_nopaste)
12243 vim_free(buf->b_p_vsts_nopaste);
12244 buf->b_p_vsts_nopaste = buf->b_p_vsts && buf->b_p_vsts != empty_option
12245 ? vim_strsave(buf->b_p_vsts) : NULL;
12246 #endif
12087 } 12247 }
12088 12248
12089 /* save global options */ 12249 /* save global options */
12090 save_sm = p_sm; 12250 save_sm = p_sm;
12091 save_sta = p_sta; 12251 save_sta = p_sta;
12100 p_ai_nopaste = p_ai; 12260 p_ai_nopaste = p_ai;
12101 p_et_nopaste = p_et; 12261 p_et_nopaste = p_et;
12102 p_sts_nopaste = p_sts; 12262 p_sts_nopaste = p_sts;
12103 p_tw_nopaste = p_tw; 12263 p_tw_nopaste = p_tw;
12104 p_wm_nopaste = p_wm; 12264 p_wm_nopaste = p_wm;
12265 #ifdef FEAT_VARTABS
12266 if (p_vsts_nopaste)
12267 vim_free(p_vsts_nopaste);
12268 p_vsts_nopaste = p_vsts && p_vsts != empty_option ? vim_strsave(p_vsts) : NULL;
12269 #endif
12105 } 12270 }
12106 12271
12107 /* 12272 /*
12108 * Always set the option values, also when 'paste' is set when it is 12273 * Always set the option values, also when 'paste' is set when it is
12109 * already on. 12274 * already on.
12114 buf->b_p_tw = 0; /* textwidth is 0 */ 12279 buf->b_p_tw = 0; /* textwidth is 0 */
12115 buf->b_p_wm = 0; /* wrapmargin is 0 */ 12280 buf->b_p_wm = 0; /* wrapmargin is 0 */
12116 buf->b_p_sts = 0; /* softtabstop is 0 */ 12281 buf->b_p_sts = 0; /* softtabstop is 0 */
12117 buf->b_p_ai = 0; /* no auto-indent */ 12282 buf->b_p_ai = 0; /* no auto-indent */
12118 buf->b_p_et = 0; /* no expandtab */ 12283 buf->b_p_et = 0; /* no expandtab */
12284 #ifdef FEAT_VARTABS
12285 if (buf->b_p_vsts)
12286 free_string_option(buf->b_p_vsts);
12287 buf->b_p_vsts = empty_option;
12288 if (buf->b_p_vsts_array)
12289 vim_free(buf->b_p_vsts_array);
12290 buf->b_p_vsts_array = 0;
12291 #endif
12119 } 12292 }
12120 12293
12121 /* set global options */ 12294 /* set global options */
12122 p_sm = 0; /* no showmatch */ 12295 p_sm = 0; /* no showmatch */
12123 p_sta = 0; /* no smarttab */ 12296 p_sta = 0; /* no smarttab */
12133 /* set global values for local buffer options */ 12306 /* set global values for local buffer options */
12134 p_tw = 0; 12307 p_tw = 0;
12135 p_wm = 0; 12308 p_wm = 0;
12136 p_sts = 0; 12309 p_sts = 0;
12137 p_ai = 0; 12310 p_ai = 0;
12311 #ifdef FEAT_VARTABS
12312 if (p_vsts)
12313 free_string_option(p_vsts);
12314 p_vsts = empty_option;
12315 #endif
12138 } 12316 }
12139 12317
12140 /* 12318 /*
12141 * Paste switched from on to off: Restore saved values. 12319 * Paste switched from on to off: Restore saved values.
12142 */ 12320 */
12148 buf->b_p_tw = buf->b_p_tw_nopaste; 12326 buf->b_p_tw = buf->b_p_tw_nopaste;
12149 buf->b_p_wm = buf->b_p_wm_nopaste; 12327 buf->b_p_wm = buf->b_p_wm_nopaste;
12150 buf->b_p_sts = buf->b_p_sts_nopaste; 12328 buf->b_p_sts = buf->b_p_sts_nopaste;
12151 buf->b_p_ai = buf->b_p_ai_nopaste; 12329 buf->b_p_ai = buf->b_p_ai_nopaste;
12152 buf->b_p_et = buf->b_p_et_nopaste; 12330 buf->b_p_et = buf->b_p_et_nopaste;
12331 #ifdef FEAT_VARTABS
12332 if (buf->b_p_vsts)
12333 free_string_option(buf->b_p_vsts);
12334 buf->b_p_vsts = buf->b_p_vsts_nopaste
12335 ? vim_strsave(buf->b_p_vsts_nopaste) : empty_option;
12336 if (buf->b_p_vsts_array)
12337 vim_free(buf->b_p_vsts_array);
12338 if (buf->b_p_vsts && buf->b_p_vsts != empty_option)
12339 tabstop_set(buf->b_p_vsts, &buf->b_p_vsts_array);
12340 else
12341 buf->b_p_vsts_array = 0;
12342 #endif
12153 } 12343 }
12154 12344
12155 /* restore global options */ 12345 /* restore global options */
12156 p_sm = save_sm; 12346 p_sm = save_sm;
12157 p_sta = save_sta; 12347 p_sta = save_sta;
12168 p_ai = p_ai_nopaste; 12358 p_ai = p_ai_nopaste;
12169 p_et = p_et_nopaste; 12359 p_et = p_et_nopaste;
12170 p_sts = p_sts_nopaste; 12360 p_sts = p_sts_nopaste;
12171 p_tw = p_tw_nopaste; 12361 p_tw = p_tw_nopaste;
12172 p_wm = p_wm_nopaste; 12362 p_wm = p_wm_nopaste;
12363 #ifdef FEAT_VARTABS
12364 if (p_vsts)
12365 free_string_option(p_vsts);
12366 p_vsts = p_vsts_nopaste ? vim_strsave(p_vsts_nopaste) : empty_option;
12367 #endif
12173 } 12368 }
12174 12369
12175 old_p_paste = p_paste; 12370 old_p_paste = p_paste;
12176 } 12371 }
12177 12372
12507 int 12702 int
12508 check_ff_value(char_u *p) 12703 check_ff_value(char_u *p)
12509 { 12704 {
12510 return check_opt_strings(p, p_ff_values, FALSE); 12705 return check_opt_strings(p, p_ff_values, FALSE);
12511 } 12706 }
12707
12708 #ifdef FEAT_VARTABS
12709
12710 /*
12711 * Set the integer values corresponding to the string setting of 'vartabstop'.
12712 */
12713 int
12714 tabstop_set(char_u *var, int **array)
12715 {
12716 int valcount = 1;
12717 int t;
12718 char_u *cp;
12719
12720 if ((!var[0] || (var[0] == '0' && !var[1])))
12721 {
12722 *array = NULL;
12723 return TRUE;
12724 }
12725
12726 for (cp = var; *cp; ++cp)
12727 {
12728 if (cp == var || *(cp - 1) == ',')
12729 {
12730 char_u *end;
12731 if (strtol((char *)cp, (char **)&end, 10) <= 0)
12732 {
12733 if (cp != end)
12734 EMSG(_(e_positive));
12735 else
12736 EMSG(_(e_invarg));
12737 return FALSE;
12738 }
12739 }
12740
12741 if (VIM_ISDIGIT(*cp))
12742 continue;
12743 if (*cp == ',' && cp > var && *(cp - 1) != ',')
12744 {
12745 ++valcount;
12746 continue;
12747 }
12748 EMSG(_(e_invarg));
12749 return FALSE;
12750 }
12751
12752 *array = (int *) alloc((unsigned) ((valcount + 1) * sizeof(int)));
12753 (*array)[0] = valcount;
12754
12755 t = 1;
12756 for (cp = var; *cp;)
12757 {
12758 (*array)[t++] = atoi((char *)cp);
12759 while (*cp && *cp != ',')
12760 ++cp;
12761 if (*cp)
12762 ++cp;
12763 }
12764
12765 return TRUE;
12766 }
12767
12768 /*
12769 * Calculate the number of screen spaces a tab will occupy.
12770 * If "vts" is set then the tab widths are taken from that array,
12771 * otherwise the value of ts is used.
12772 */
12773 int
12774 tabstop_padding(colnr_T col, int ts_arg, int *vts)
12775 {
12776 int ts = ts_arg == 0 ? 8 : ts_arg;
12777 int tabcount;
12778 colnr_T tabcol = 0;
12779 int t;
12780 int padding = 0;
12781
12782 if (vts == NULL || vts[0] == 0)
12783 return ts - (col % ts);
12784
12785 tabcount = vts[0];
12786
12787 for (t = 1; t <= tabcount; ++t)
12788 {
12789 tabcol += vts[t];
12790 if (tabcol > col)
12791 {
12792 padding = (int)(tabcol - col);
12793 break;
12794 }
12795 }
12796 if (t > tabcount)
12797 padding = vts[tabcount] - (int)((col - tabcol) % vts[tabcount]);
12798
12799 return padding;
12800 }
12801
12802 /*
12803 * Find the size of the tab that covers a particular column.
12804 */
12805 int
12806 tabstop_at(colnr_T col, int ts, int *vts)
12807 {
12808 int tabcount;
12809 colnr_T tabcol = 0;
12810 int t;
12811 int tab_size = 0;
12812
12813 if (vts == 0 || vts[0] == 0)
12814 return ts;
12815
12816 tabcount = vts[0];
12817 for (t = 1; t <= tabcount; ++t)
12818 {
12819 tabcol += vts[t];
12820 if (tabcol > col)
12821 {
12822 tab_size = vts[t];
12823 break;
12824 }
12825 }
12826 if (t > tabcount)
12827 tab_size = vts[tabcount];
12828
12829 return tab_size;
12830 }
12831
12832 /*
12833 * Find the column on which a tab starts.
12834 */
12835 colnr_T
12836 tabstop_start(colnr_T col, int ts, int *vts)
12837 {
12838 int tabcount;
12839 colnr_T tabcol = 0;
12840 int t;
12841 int excess;
12842
12843 if (vts == 0 || vts[0] == 0)
12844 return (col / ts) * ts;
12845
12846 tabcount = vts[0];
12847 for (t = 1; t <= tabcount; ++t)
12848 {
12849 tabcol += vts[t];
12850 if (tabcol > col)
12851 return tabcol - vts[t];
12852 }
12853
12854 excess = tabcol % vts[tabcount];
12855 return excess + ((col - excess) / vts[tabcount]) * vts[tabcount];
12856 }
12857
12858 /*
12859 * Find the number of tabs and spaces necessary to get from one column
12860 * to another.
12861 */
12862 void
12863 tabstop_fromto(
12864 colnr_T start_col,
12865 colnr_T end_col,
12866 int ts,
12867 int *vts,
12868 int *ntabs,
12869 int *nspcs)
12870 {
12871 int spaces = end_col - start_col;
12872 colnr_T tabcol = 0;
12873 int padding = 0;
12874 int tabcount;
12875 int t;
12876
12877 if (vts == 0 || vts[0] == 0)
12878 {
12879 int tabs = 0;
12880 int initspc = ts - (start_col % ts);
12881 if (spaces >= initspc)
12882 {
12883 spaces -= initspc;
12884 tabs++;
12885 }
12886 tabs += spaces / ts;
12887 spaces -= (spaces / ts) * ts;
12888
12889 *ntabs = tabs;
12890 *nspcs = spaces;
12891 return;
12892 }
12893
12894 /* Find the padding needed to reach the next tabstop. */
12895 tabcount = vts[0];
12896 for (t = 1; t <= tabcount; ++t)
12897 {
12898 tabcol += vts[t];
12899 if (tabcol > start_col)
12900 {
12901 padding = (int)(tabcol - start_col);
12902 break;
12903 }
12904 }
12905 if (t > tabcount)
12906 padding = vts[tabcount] - (int)((start_col - tabcol) % vts[tabcount]);
12907
12908 /* If the space needed is less than the padding no tabs can be used. */
12909 if (spaces < padding)
12910 {
12911 *ntabs = 0;
12912 *nspcs = spaces;
12913 return;
12914 }
12915
12916 *ntabs = 1;
12917 spaces -= padding;
12918
12919 /* At least one tab has been used. See if any more will fit. */
12920 while (spaces != 0 && ++t <= tabcount)
12921 {
12922 padding = vts[t];
12923 if (spaces < padding)
12924 {
12925 *nspcs = spaces;
12926 return;
12927 }
12928 ++*ntabs;
12929 spaces -= padding;
12930 }
12931
12932 *ntabs += spaces / vts[tabcount];
12933 *nspcs = spaces % vts[tabcount];
12934 }
12935
12936 /*
12937 * See if two tabstop arrays contain the same values.
12938 */
12939 int
12940 tabstop_eq(int *ts1, int *ts2)
12941 {
12942 int t;
12943
12944 if ((ts1 == 0 && ts2) || (ts1 && ts2 == 0))
12945 return FALSE;
12946 if (ts1 == ts2)
12947 return TRUE;
12948 if (ts1[0] != ts2[0])
12949 return FALSE;
12950
12951 for (t = 1; t <= ts1[0]; ++t)
12952 if (ts1[t] != ts2[t])
12953 return FALSE;
12954
12955 return TRUE;
12956 }
12957
12958 /*
12959 * Copy a tabstop array, allocating space for the new array.
12960 */
12961 int *
12962 tabstop_copy(int *oldts)
12963 {
12964 int *newts;
12965 int t;
12966
12967 if (oldts == 0)
12968 return 0;
12969
12970 newts = (int *) alloc((unsigned) ((oldts[0] + 1) * sizeof(int)));
12971 for (t = 0; t <= oldts[0]; ++t)
12972 newts[t] = oldts[t];
12973
12974 return newts;
12975 }
12976
12977 /*
12978 * Return a count of the number of tabstops.
12979 */
12980 int
12981 tabstop_count(int *ts)
12982 {
12983 return ts != NULL ? ts[0] : 0;
12984 }
12985
12986 /*
12987 * Return the first tabstop, or 8 if there are no tabstops defined.
12988 */
12989 int
12990 tabstop_first(int *ts)
12991 {
12992 return ts != NULL ? ts[1] : 8;
12993 }
12994
12995 #endif
12512 12996
12513 /* 12997 /*
12514 * Return the effective shiftwidth value for current buffer, using the 12998 * Return the effective shiftwidth value for current buffer, using the
12515 * 'tabstop' value when 'shiftwidth' is zero. 12999 * 'tabstop' value when 'shiftwidth' is zero.
12516 */ 13000 */