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