Mercurial > vim
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 */ |