Mercurial > vim
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. |