Mercurial > vim
comparison src/ex_cmds.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 | bcda3b864c31 |
children | 20468fb49f9b |
comparison
equal
deleted
inserted
replaced
14174:d36eedd19166 | 14175:2ad722003b36 |
---|---|
671 long len; | 671 long len; |
672 long col; | 672 long col; |
673 long vcol; | 673 long vcol; |
674 long start_col = 0; /* For start of white-space string */ | 674 long start_col = 0; /* For start of white-space string */ |
675 long start_vcol = 0; /* For start of white-space string */ | 675 long start_vcol = 0; /* For start of white-space string */ |
676 int temp; | |
677 long old_len; | 676 long old_len; |
678 char_u *ptr; | 677 char_u *ptr; |
679 char_u *new_line = (char_u *)1; /* init to non-NULL */ | 678 char_u *new_line = (char_u *)1; /* init to non-NULL */ |
680 int did_undo; /* called u_save for current line */ | 679 int did_undo; /* called u_save for current line */ |
680 #ifdef FEAT_VARTABS | |
681 int *new_ts = 0; | |
682 char_u *new_ts_str; /* string value of tab argument */ | |
683 #else | |
684 int temp; | |
681 int new_ts; | 685 int new_ts; |
686 #endif | |
682 int save_list; | 687 int save_list; |
683 linenr_T first_line = 0; /* first changed line */ | 688 linenr_T first_line = 0; /* first changed line */ |
684 linenr_T last_line = 0; /* last changed line */ | 689 linenr_T last_line = 0; /* last changed line */ |
685 | 690 |
686 save_list = curwin->w_p_list; | 691 save_list = curwin->w_p_list; |
687 curwin->w_p_list = 0; /* don't want list mode here */ | 692 curwin->w_p_list = 0; /* don't want list mode here */ |
688 | 693 |
694 #ifdef FEAT_VARTABS | |
695 new_ts_str = eap->arg; | |
696 if (!tabstop_set(eap->arg, &new_ts)) | |
697 return; | |
698 while (vim_isdigit(*(eap->arg)) || *(eap->arg) == ',') | |
699 ++(eap->arg); | |
700 | |
701 // This ensures that either new_ts and new_ts_str are freshly allocated, | |
702 // or new_ts points to an existing array and new_ts_str is null. | |
703 if (new_ts == 0) | |
704 { | |
705 new_ts = curbuf->b_p_vts_array; | |
706 new_ts_str = NULL; | |
707 } | |
708 else | |
709 new_ts_str = vim_strnsave(new_ts_str, eap->arg - new_ts_str); | |
710 #else | |
689 new_ts = getdigits(&(eap->arg)); | 711 new_ts = getdigits(&(eap->arg)); |
690 if (new_ts < 0) | 712 if (new_ts < 0) |
691 { | 713 { |
692 EMSG(_(e_positive)); | 714 EMSG(_(e_positive)); |
693 return; | 715 return; |
694 } | 716 } |
695 if (new_ts == 0) | 717 if (new_ts == 0) |
696 new_ts = curbuf->b_p_ts; | 718 new_ts = curbuf->b_p_ts; |
719 #endif | |
697 for (lnum = eap->line1; !got_int && lnum <= eap->line2; ++lnum) | 720 for (lnum = eap->line1; !got_int && lnum <= eap->line2; ++lnum) |
698 { | 721 { |
699 ptr = ml_get(lnum); | 722 ptr = ml_get(lnum); |
700 col = 0; | 723 col = 0; |
701 vcol = 0; | 724 vcol = 0; |
724 /* len is virtual length of white string */ | 747 /* len is virtual length of white string */ |
725 len = num_spaces = vcol - start_vcol; | 748 len = num_spaces = vcol - start_vcol; |
726 num_tabs = 0; | 749 num_tabs = 0; |
727 if (!curbuf->b_p_et) | 750 if (!curbuf->b_p_et) |
728 { | 751 { |
752 #ifdef FEAT_VARTABS | |
753 int t, s; | |
754 | |
755 tabstop_fromto(start_vcol, vcol, | |
756 tabstop_count(new_ts)? 0: curbuf->b_p_ts, | |
757 new_ts, | |
758 &t, &s); | |
759 num_tabs = t; | |
760 num_spaces = s; | |
761 #else | |
729 temp = new_ts - (start_vcol % new_ts); | 762 temp = new_ts - (start_vcol % new_ts); |
730 if (num_spaces >= temp) | 763 if (num_spaces >= temp) |
731 { | 764 { |
732 num_spaces -= temp; | 765 num_spaces -= temp; |
733 num_tabs++; | 766 num_tabs++; |
734 } | 767 } |
735 num_tabs += num_spaces / new_ts; | 768 num_tabs += num_spaces / new_ts; |
736 num_spaces -= (num_spaces / new_ts) * new_ts; | 769 num_spaces -= (num_spaces / new_ts) * new_ts; |
770 #endif | |
737 } | 771 } |
738 if (curbuf->b_p_et || got_tab || | 772 if (curbuf->b_p_et || got_tab || |
739 (num_spaces + num_tabs < len)) | 773 (num_spaces + num_tabs < len)) |
740 { | 774 { |
741 if (did_undo == FALSE) | 775 if (did_undo == FALSE) |
789 line_breakcheck(); | 823 line_breakcheck(); |
790 } | 824 } |
791 if (got_int) | 825 if (got_int) |
792 EMSG(_(e_interr)); | 826 EMSG(_(e_interr)); |
793 | 827 |
828 #ifdef FEAT_VARTABS | |
829 // If a single value was given then it can be considered equal to | |
830 // either the value of 'tabstop' or the value of 'vartabstop'. | |
831 if (tabstop_count(curbuf->b_p_vts_array) == 0 | |
832 && tabstop_count(new_ts) == 1 | |
833 && curbuf->b_p_ts == tabstop_first(new_ts)) | |
834 ; /* not changed */ | |
835 else if (tabstop_count(curbuf->b_p_vts_array) > 0 | |
836 && tabstop_eq(curbuf->b_p_vts_array, new_ts)) | |
837 ; /* not changed */ | |
838 else | |
839 redraw_curbuf_later(NOT_VALID); | |
840 #else | |
794 if (curbuf->b_p_ts != new_ts) | 841 if (curbuf->b_p_ts != new_ts) |
795 redraw_curbuf_later(NOT_VALID); | 842 redraw_curbuf_later(NOT_VALID); |
843 #endif | |
796 if (first_line != 0) | 844 if (first_line != 0) |
797 changed_lines(first_line, 0, last_line + 1, 0L); | 845 changed_lines(first_line, 0, last_line + 1, 0L); |
798 | 846 |
799 curwin->w_p_list = save_list; /* restore 'list' */ | 847 curwin->w_p_list = save_list; /* restore 'list' */ |
800 | 848 |
849 #ifdef FEAT_VARTABS | |
850 if (new_ts_str != NULL) /* set the new tabstop */ | |
851 { | |
852 // If 'vartabstop' is in use or if the value given to retab has more | |
853 // than one tabstop then update 'vartabstop'. | |
854 int *old_vts_ary = curbuf->b_p_vts_array; | |
855 | |
856 if (tabstop_count(old_vts_ary) > 0 || tabstop_count(new_ts) > 1) | |
857 { | |
858 set_string_option_direct((char_u *)"vts", -1, new_ts_str, | |
859 OPT_FREE|OPT_LOCAL, 0); | |
860 vim_free(new_ts_str); | |
861 curbuf->b_p_vts_array = new_ts; | |
862 vim_free(old_vts_ary); | |
863 } | |
864 else | |
865 { | |
866 // 'vartabstop' wasn't in use and a single value was given to | |
867 // retab then update 'tabstop'. | |
868 curbuf->b_p_ts = tabstop_first(new_ts); | |
869 vim_free(new_ts); | |
870 } | |
871 } | |
872 #else | |
801 curbuf->b_p_ts = new_ts; | 873 curbuf->b_p_ts = new_ts; |
874 #endif | |
802 coladvance(curwin->w_curswant); | 875 coladvance(curwin->w_curswant); |
803 | 876 |
804 u_clearline(); | 877 u_clearline(); |
805 } | 878 } |
806 | 879 |