comparison src/textprop.c @ 28526:171f9def0398 v8.2.4787

patch 8.2.4787: prop_find() does not find the right property Commit: https://github.com/vim/vim/commit/9bd3ce22e36b5760a5e22e7d34d1bd6a3411258e Author: LemonBoy <thatlemon@gmail.com> Date: Mon Apr 18 21:54:02 2022 +0100 patch 8.2.4787: prop_find() does not find the right property Problem: prop_find() does not find the right property. Solution: Fix the scan order. (closes https://github.com/vim/vim/issues/10220)
author Bram Moolenaar <Bram@vim.org>
date Mon, 18 Apr 2022 23:00:03 +0200
parents 62cc3b60493b
children 92736a673e3c
comparison
equal deleted inserted replaced
28525:ea09c444fb6b 28526:171f9def0398
711 dict_T *dict; 711 dict_T *dict;
712 buf_T *buf = curbuf; 712 buf_T *buf = curbuf;
713 dictitem_T *di; 713 dictitem_T *di;
714 int lnum_start; 714 int lnum_start;
715 int start_pos_has_prop = 0; 715 int start_pos_has_prop = 0;
716 int seen_end = 0; 716 int seen_end = FALSE;
717 int id = 0; 717 int id = 0;
718 int id_found = FALSE; 718 int id_found = FALSE;
719 int type_id = -1; 719 int type_id = -1;
720 int skipstart = 0; 720 int skipstart = FALSE;
721 int lnum = -1; 721 int lnum = -1;
722 int col = -1; 722 int col = -1;
723 int dir = 1; // 1 = forward, -1 = backward 723 int dir = FORWARD; // FORWARD == 1, BACKWARD == -1
724 int both; 724 int both;
725 725
726 if (in_vim9script() 726 if (in_vim9script()
727 && (check_for_dict_arg(argvars, 0) == FAIL 727 && (check_for_dict_arg(argvars, 0) == FAIL
728 || check_for_opt_string_arg(argvars, 1) == FAIL)) 728 || check_for_opt_string_arg(argvars, 1) == FAIL))
743 if (argvars[1].v_type != VAR_UNKNOWN) 743 if (argvars[1].v_type != VAR_UNKNOWN)
744 { 744 {
745 char_u *dir_s = tv_get_string(&argvars[1]); 745 char_u *dir_s = tv_get_string(&argvars[1]);
746 746
747 if (*dir_s == 'b') 747 if (*dir_s == 'b')
748 dir = -1; 748 dir = BACKWARD;
749 else if (*dir_s != 'f') 749 else if (*dir_s != 'f')
750 { 750 {
751 emsg(_(e_invalid_argument)); 751 emsg(_(e_invalid_argument));
752 return; 752 return;
753 } 753 }
817 int i; 817 int i;
818 textprop_T prop; 818 textprop_T prop;
819 int prop_start; 819 int prop_start;
820 int prop_end; 820 int prop_end;
821 821
822 for (i = 0; i < count; ++i) 822 for (i = dir == BACKWARD ? count - 1 : 0; i >= 0 && i < count; i += dir)
823 { 823 {
824 mch_memmove(&prop, text + textlen + i * sizeof(textprop_T), 824 mch_memmove(&prop, text + textlen + i * sizeof(textprop_T),
825 sizeof(textprop_T)); 825 sizeof(textprop_T));
826 826
827 // For the very first line try to find the first property before or
828 // after `col`, depending on the search direction.
827 if (lnum == lnum_start) 829 if (lnum == lnum_start)
828 { 830 {
829 if (dir < 0) 831 if (dir == BACKWARD)
830 { 832 {
831 if (col < prop.tp_col) 833 if (prop.tp_col > col)
832 break; 834 continue;
833 } 835 }
834 else if (prop.tp_col + prop.tp_len - (prop.tp_len != 0) < col) 836 else if (prop.tp_col + prop.tp_len - (prop.tp_len != 0) < col)
835 continue; 837 continue;
836 } 838 }
837 if (both ? prop.tp_id == id && prop.tp_type == type_id 839 if (both ? prop.tp_id == id && prop.tp_type == type_id
843 && col >= prop.tp_col 845 && col >= prop.tp_col
844 && (col <= prop.tp_col + prop.tp_len 846 && (col <= prop.tp_col + prop.tp_len
845 - (prop.tp_len != 0))) 847 - (prop.tp_len != 0)))
846 start_pos_has_prop = 1; 848 start_pos_has_prop = 1;
847 849
850 // The property was not continued from last line, it starts on
851 // this line.
848 prop_start = !(prop.tp_flags & TP_FLAG_CONT_PREV); 852 prop_start = !(prop.tp_flags & TP_FLAG_CONT_PREV);
853 // The property does not continue on the next line, it ends on
854 // this line.
849 prop_end = !(prop.tp_flags & TP_FLAG_CONT_NEXT); 855 prop_end = !(prop.tp_flags & TP_FLAG_CONT_NEXT);
850 if (!prop_start && prop_end && dir > 0) 856 if (!prop_start && prop_end && dir == FORWARD)
851 seen_end = 1; 857 seen_end = 1;
852 858
853 // Skip lines without the start flag. 859 // Skip lines without the start flag.
854 if (!prop_start) 860 if (!prop_start)
855 { 861 {
856 // Always search backwards for start when search started 862 // Always search backwards for start when search started
857 // on a prop and we're not skipping. 863 // on a prop and we're not skipping.
858 if (start_pos_has_prop && !skipstart) 864 if (start_pos_has_prop && !skipstart)
859 dir = -1; 865 dir = BACKWARD;
860 continue; 866 continue;
861 } 867 }
862 868
863 // If skipstart is true, skip the prop at start pos (even if 869 // If skipstart is true, skip the prop at start pos (even if
864 // continued from another line). 870 // continued from another line).
885 { 891 {
886 if (lnum <= 1) 892 if (lnum <= 1)
887 break; 893 break;
888 lnum--; 894 lnum--;
889 } 895 }
890 // Adjust col to indicate that we're continuing from prev/next line.
891 col = dir < 0 ? buf->b_ml.ml_line_len : 1;
892 } 896 }
893 } 897 }
894 898
895 /* 899 /*
896 * Returns TRUE if 'type_or_id' is in the 'types_or_ids' list. 900 * Returns TRUE if 'type_or_id' is in the 'types_or_ids' list.