comparison src/list.c @ 25591:ea69398b40d1 v8.2.3332

patch 8.2.3332: Vim9: cannot assign to range in list Commit: https://github.com/vim/vim/commit/4f0884d6e24d1d45ec83fd86b372b403177d3298 Author: Bram Moolenaar <Bram@vim.org> Date: Wed Aug 11 21:49:23 2021 +0200 patch 8.2.3332: Vim9: cannot assign to range in list Problem: Vim9: cannot assign to range in list. Solution: Implement overwriting a list range.
author Bram Moolenaar <Bram@vim.org>
date Wed, 11 Aug 2021 22:00:06 +0200
parents 0082503ff2ff
children 0fdacd8f0cf3
comparison
equal deleted inserted replaced
25590:db8dfe879ef8 25591:ea69398b40d1
757 l->lv_u.mat.lv_idx_item = NULL; 757 l->lv_u.mat.lv_idx_item = NULL;
758 } 758 }
759 item->li_prev = ni; 759 item->li_prev = ni;
760 ++l->lv_len; 760 ++l->lv_len;
761 } 761 }
762 }
763
764 /*
765 * Get the list item in "l" with index "n1". "n1" is adjusted if needed.
766 * In Vim9, it is at the end of the list, add an item.
767 * Return NULL if there is no such item.
768 */
769 listitem_T *
770 check_range_index_one(list_T *l, long *n1, int quiet)
771 {
772 listitem_T *li = list_find_index(l, n1);
773
774 if (li == NULL)
775 {
776 // Vim9: Allow for adding an item at the end.
777 if (in_vim9script() && *n1 == l->lv_len && l->lv_lock == 0)
778 {
779 list_append_number(l, 0);
780 li = list_find_index(l, n1);
781 }
782 if (li == NULL)
783 {
784 if (!quiet)
785 semsg(_(e_listidx), *n1);
786 return NULL;
787 }
788 }
789 return li;
790 }
791
792 /*
793 * Check that "n2" can be used as the second index in a range of list "l".
794 * If "n1" or "n2" is negative it is changed to the positive index.
795 * "li1" is the item for item "n1".
796 * Return OK or FAIL.
797 */
798 int
799 check_range_index_two(
800 list_T *l,
801 long *n1,
802 listitem_T *li1,
803 long *n2,
804 int quiet)
805 {
806 if (*n2 < 0)
807 {
808 listitem_T *ni = list_find(l, *n2);
809
810 if (ni == NULL)
811 {
812 if (!quiet)
813 semsg(_(e_listidx), *n2);
814 return FAIL;
815 }
816 *n2 = list_idx_of_item(l, ni);
817 }
818
819 // Check that n2 isn't before n1.
820 if (*n1 < 0)
821 *n1 = list_idx_of_item(l, li1);
822 if (*n2 < *n1)
823 {
824 if (!quiet)
825 semsg(_(e_listidx), *n2);
826 return FAIL;
827 }
828 return OK;
829 }
830
831 /*
832 * Assign values from list "src" into a range of "dest".
833 * "idx1_arg" is the index of the first item in "dest" to be replaced.
834 * "idx2" is the index of last item to be replaced, but when "empty_idx2" is
835 * TRUE then replace all items after "idx1".
836 * "op" is the operator, normally "=" but can be "+=" and the like.
837 * "varname" is used for error messages.
838 * Returns OK or FAIL.
839 */
840 int
841 list_assign_range(
842 list_T *dest,
843 list_T *src,
844 long idx1_arg,
845 long idx2,
846 int empty_idx2,
847 char_u *op,
848 char_u *varname)
849 {
850 listitem_T *src_li;
851 listitem_T *dest_li;
852 long idx1 = idx1_arg;
853 listitem_T *first_li = list_find_index(dest, &idx1);
854 long idx;
855
856 /*
857 * Check whether any of the list items is locked before making any changes.
858 */
859 idx = idx1;
860 dest_li = first_li;
861 for (src_li = src->lv_first; src_li != NULL && dest_li != NULL; )
862 {
863 if (value_check_lock(dest_li->li_tv.v_lock, varname, FALSE))
864 return FAIL;
865 src_li = src_li->li_next;
866 if (src_li == NULL || (!empty_idx2 && idx2 == idx))
867 break;
868 dest_li = dest_li->li_next;
869 ++idx;
870 }
871
872 /*
873 * Assign the List values to the list items.
874 */
875 idx = idx1;
876 dest_li = first_li;
877 for (src_li = src->lv_first; src_li != NULL; )
878 {
879 if (op != NULL && *op != '=')
880 tv_op(&dest_li->li_tv, &src_li->li_tv, op);
881 else
882 {
883 clear_tv(&dest_li->li_tv);
884 copy_tv(&src_li->li_tv, &dest_li->li_tv);
885 }
886 src_li = src_li->li_next;
887 if (src_li == NULL || (!empty_idx2 && idx2 == idx))
888 break;
889 if (dest_li->li_next == NULL)
890 {
891 // Need to add an empty item.
892 if (list_append_number(dest, 0) == FAIL)
893 {
894 src_li = NULL;
895 break;
896 }
897 }
898 dest_li = dest_li->li_next;
899 ++idx;
900 }
901 if (src_li != NULL)
902 {
903 emsg(_(e_list_value_has_more_items_than_targets));
904 return FAIL;
905 }
906 if (empty_idx2
907 ? (dest_li != NULL && dest_li->li_next != NULL)
908 : idx != idx2)
909 {
910 emsg(_(e_list_value_does_not_have_enough_items));
911 return FAIL;
912 }
913 return OK;
762 } 914 }
763 915
764 /* 916 /*
765 * Flatten "list" to depth "maxdepth". 917 * Flatten "list" to depth "maxdepth".
766 * It does nothing if "maxdepth" is 0. 918 * It does nothing if "maxdepth" is 0.