Mercurial > vim
comparison src/evalvars.c @ 19181:94eda51ba9ba v8.2.0149
patch 8.2.0149: maintaining a Vim9 branch separately is more work
Commit: https://github.com/vim/vim/commit/8a7d6542b33e5d2b352262305c3bfdb2d14e1cf8
Author: Bram Moolenaar <Bram@vim.org>
Date: Sun Jan 26 15:56:19 2020 +0100
patch 8.2.0149: maintaining a Vim9 branch separately is more work
Problem: Maintaining a Vim9 branch separately is more work.
Solution: Merge the Vim9 script changes.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sun, 26 Jan 2020 16:00:05 +0100 |
parents | 44c6498535c9 |
children | 133ef7ba4e4e |
comparison
equal
deleted
inserted
replaced
19180:8edf0aeb71b9 | 19181:94eda51ba9ba |
---|---|
13 | 13 |
14 #include "vim.h" | 14 #include "vim.h" |
15 | 15 |
16 #if defined(FEAT_EVAL) || defined(PROTO) | 16 #if defined(FEAT_EVAL) || defined(PROTO) |
17 | 17 |
18 static char *e_letunexp = N_("E18: Unexpected characters in :let"); | |
19 | |
20 static dictitem_T globvars_var; // variable used for g: | 18 static dictitem_T globvars_var; // variable used for g: |
21 static dict_T globvardict; // Dictionary with g: variables | 19 static dict_T globvardict; // Dictionary with g: variables |
22 #define globvarht globvardict.dv_hashtab | 20 #define globvarht globvardict.dv_hashtab |
23 | 21 |
24 /* | 22 /* |
38 #define VV_COMPAT 1 // compatible, also used without "v:" | 36 #define VV_COMPAT 1 // compatible, also used without "v:" |
39 #define VV_RO 2 // read-only | 37 #define VV_RO 2 // read-only |
40 #define VV_RO_SBX 4 // read-only in the sandbox | 38 #define VV_RO_SBX 4 // read-only in the sandbox |
41 | 39 |
42 #define VV_NAME(s, t) s, {{t, 0, {0}}, 0, {0}} | 40 #define VV_NAME(s, t) s, {{t, 0, {0}}, 0, {0}} |
41 | |
42 typedef struct vimvar vimvar_T; | |
43 | 43 |
44 static struct vimvar | 44 static struct vimvar |
45 { | 45 { |
46 char *vv_name; // name of variable, without v: | 46 char *vv_name; // name of variable, without v: |
47 dictitem16_T vv_di; // value and name for key (max 16 chars!) | 47 dictitem16_T vv_di; // value and name for key (max 16 chars!) |
161 #define vimvarht vimvardict.dv_hashtab | 161 #define vimvarht vimvardict.dv_hashtab |
162 | 162 |
163 // for VIM_VERSION_ defines | 163 // for VIM_VERSION_ defines |
164 #include "version.h" | 164 #include "version.h" |
165 | 165 |
166 #define SCRIPT_SV(id) (SCRIPT_ITEM(id).sn_vars) | |
167 #define SCRIPT_VARS(id) (SCRIPT_SV(id)->sv_dict.dv_hashtab) | |
168 | |
169 static void ex_let_const(exarg_T *eap, int is_const); | 166 static void ex_let_const(exarg_T *eap, int is_const); |
170 static char_u *skip_var_one(char_u *arg); | 167 static char_u *skip_var_one(char_u *arg, int include_type); |
171 static void list_glob_vars(int *first); | 168 static void list_glob_vars(int *first); |
172 static void list_buf_vars(int *first); | 169 static void list_buf_vars(int *first); |
173 static void list_win_vars(int *first); | 170 static void list_win_vars(int *first); |
174 static void list_tab_vars(int *first); | 171 static void list_tab_vars(int *first); |
175 static char_u *list_arg_vars(exarg_T *eap, char_u *arg, int *first); | 172 static char_u *list_arg_vars(exarg_T *eap, char_u *arg, int *first); |
176 static char_u *ex_let_one(char_u *arg, typval_T *tv, int copy, int is_const, char_u *endchars, char_u *op); | 173 static char_u *ex_let_one(char_u *arg, typval_T *tv, int copy, int flags, char_u *endchars, char_u *op); |
177 static void ex_unletlock(exarg_T *eap, char_u *argstart, int deep); | 174 static void ex_unletlock(exarg_T *eap, char_u *argstart, int deep); |
178 static int do_unlet_var(lval_T *lp, char_u *name_end, int forceit); | 175 static int do_unlet_var(lval_T *lp, char_u *name_end, int forceit); |
179 static int do_lock_var(lval_T *lp, char_u *name_end, int deep, int lock); | 176 static int do_lock_var(lval_T *lp, char_u *name_end, int deep, int lock); |
180 static void item_lock(typval_T *tv, int deep, int lock); | 177 static void item_lock(typval_T *tv, int deep, int lock); |
181 static void delete_var(hashtab_T *ht, hashitem_T *hi); | 178 static void delete_var(hashtab_T *ht, hashitem_T *hi); |
542 * The {marker} is a string. If the optional 'trim' word is supplied before the | 539 * The {marker} is a string. If the optional 'trim' word is supplied before the |
543 * marker, then the leading indentation before the lines (matching the | 540 * marker, then the leading indentation before the lines (matching the |
544 * indentation in the 'cmd' line) is stripped. | 541 * indentation in the 'cmd' line) is stripped. |
545 * Returns a List with {lines} or NULL. | 542 * Returns a List with {lines} or NULL. |
546 */ | 543 */ |
547 static list_T * | 544 list_T * |
548 heredoc_get(exarg_T *eap, char_u *cmd) | 545 heredoc_get(exarg_T *eap, char_u *cmd) |
549 { | 546 { |
550 char_u *theline; | 547 char_u *theline; |
551 char_u *marker; | 548 char_u *marker; |
552 list_T *l; | 549 list_T *l; |
667 * ":let var /= expr" assignment command. | 664 * ":let var /= expr" assignment command. |
668 * ":let var %= expr" assignment command. | 665 * ":let var %= expr" assignment command. |
669 * ":let var .= expr" assignment command. | 666 * ":let var .= expr" assignment command. |
670 * ":let var ..= expr" assignment command. | 667 * ":let var ..= expr" assignment command. |
671 * ":let [var1, var2] = expr" unpack list. | 668 * ":let [var1, var2] = expr" unpack list. |
669 * ":let var =<< ..." heredoc | |
672 */ | 670 */ |
673 void | 671 void |
674 ex_let(exarg_T *eap) | 672 ex_let(exarg_T *eap) |
675 { | 673 { |
676 ex_let_const(eap, FALSE); | 674 ex_let_const(eap, FALSE); |
699 int semicolon = 0; | 697 int semicolon = 0; |
700 char_u op[2]; | 698 char_u op[2]; |
701 char_u *argend; | 699 char_u *argend; |
702 int first = TRUE; | 700 int first = TRUE; |
703 int concat; | 701 int concat; |
704 | 702 int flags = is_const ? LET_IS_CONST : 0; |
705 argend = skip_var_list(arg, &var_count, &semicolon); | 703 |
704 // detect Vim9 assignment without ":let" or ":const" | |
705 if (eap->arg == eap->cmd) | |
706 flags |= LET_NO_COMMAND; | |
707 | |
708 argend = skip_var_list(arg, TRUE, &var_count, &semicolon); | |
706 if (argend == NULL) | 709 if (argend == NULL) |
707 return; | 710 return; |
708 if (argend > arg && argend[-1] == '.') // for var.='str' | 711 if (argend > arg && argend[-1] == '.') // for var.='str' |
709 --argend; | 712 --argend; |
710 expr = skipwhite(argend); | 713 expr = skipwhite(argend); |
747 if (!eap->skip) | 750 if (!eap->skip) |
748 { | 751 { |
749 op[0] = '='; | 752 op[0] = '='; |
750 op[1] = NUL; | 753 op[1] = NUL; |
751 (void)ex_let_vars(eap->arg, &rettv, FALSE, semicolon, var_count, | 754 (void)ex_let_vars(eap->arg, &rettv, FALSE, semicolon, var_count, |
752 is_const, op); | 755 flags, op); |
753 } | 756 } |
754 clear_tv(&rettv); | 757 clear_tv(&rettv); |
755 } | 758 } |
756 } | 759 } |
757 else | 760 else |
781 --emsg_skip; | 784 --emsg_skip; |
782 } | 785 } |
783 else if (i != FAIL) | 786 else if (i != FAIL) |
784 { | 787 { |
785 (void)ex_let_vars(eap->arg, &rettv, FALSE, semicolon, var_count, | 788 (void)ex_let_vars(eap->arg, &rettv, FALSE, semicolon, var_count, |
786 is_const, op); | 789 flags, op); |
787 clear_tv(&rettv); | 790 clear_tv(&rettv); |
788 } | 791 } |
789 } | 792 } |
790 } | 793 } |
791 | 794 |
802 char_u *arg_start, | 805 char_u *arg_start, |
803 typval_T *tv, | 806 typval_T *tv, |
804 int copy, // copy values from "tv", don't move | 807 int copy, // copy values from "tv", don't move |
805 int semicolon, // from skip_var_list() | 808 int semicolon, // from skip_var_list() |
806 int var_count, // from skip_var_list() | 809 int var_count, // from skip_var_list() |
807 int is_const, // lock variables for const | 810 int flags, // LET_IS_CONST and/or LET_NO_COMMAND |
808 char_u *op) | 811 char_u *op) |
809 { | 812 { |
810 char_u *arg = arg_start; | 813 char_u *arg = arg_start; |
811 list_T *l; | 814 list_T *l; |
812 int i; | 815 int i; |
814 typval_T ltv; | 817 typval_T ltv; |
815 | 818 |
816 if (*arg != '[') | 819 if (*arg != '[') |
817 { | 820 { |
818 // ":let var = expr" or ":for var in list" | 821 // ":let var = expr" or ":for var in list" |
819 if (ex_let_one(arg, tv, copy, is_const, op, op) == NULL) | 822 if (ex_let_one(arg, tv, copy, flags, op, op) == NULL) |
820 return FAIL; | 823 return FAIL; |
821 return OK; | 824 return OK; |
822 } | 825 } |
823 | 826 |
824 // ":let [v1, v2] = list" or ":for [v1, v2] in listlist" | 827 // ":let [v1, v2] = list" or ":for [v1, v2] in listlist" |
842 | 845 |
843 item = l->lv_first; | 846 item = l->lv_first; |
844 while (*arg != ']') | 847 while (*arg != ']') |
845 { | 848 { |
846 arg = skipwhite(arg + 1); | 849 arg = skipwhite(arg + 1); |
847 arg = ex_let_one(arg, &item->li_tv, TRUE, is_const, | 850 arg = ex_let_one(arg, &item->li_tv, TRUE, flags, (char_u *)",;]", op); |
848 (char_u *)",;]", op); | |
849 item = item->li_next; | 851 item = item->li_next; |
850 if (arg == NULL) | 852 if (arg == NULL) |
851 return FAIL; | 853 return FAIL; |
852 | 854 |
853 arg = skipwhite(arg); | 855 arg = skipwhite(arg); |
867 ltv.v_type = VAR_LIST; | 869 ltv.v_type = VAR_LIST; |
868 ltv.v_lock = 0; | 870 ltv.v_lock = 0; |
869 ltv.vval.v_list = l; | 871 ltv.vval.v_list = l; |
870 l->lv_refcount = 1; | 872 l->lv_refcount = 1; |
871 | 873 |
872 arg = ex_let_one(skipwhite(arg + 1), <v, FALSE, is_const, | 874 arg = ex_let_one(skipwhite(arg + 1), <v, FALSE, flags, |
873 (char_u *)"]", op); | 875 (char_u *)"]", op); |
874 clear_tv(<v); | 876 clear_tv(<v); |
875 if (arg == NULL) | 877 if (arg == NULL) |
876 return FAIL; | 878 return FAIL; |
877 break; | 879 break; |
894 * Return NULL for an error. | 896 * Return NULL for an error. |
895 */ | 897 */ |
896 char_u * | 898 char_u * |
897 skip_var_list( | 899 skip_var_list( |
898 char_u *arg, | 900 char_u *arg, |
901 int include_type, | |
899 int *var_count, | 902 int *var_count, |
900 int *semicolon) | 903 int *semicolon) |
901 { | 904 { |
902 char_u *p, *s; | 905 char_u *p, *s; |
903 | 906 |
906 // "[var, var]": find the matching ']'. | 909 // "[var, var]": find the matching ']'. |
907 p = arg; | 910 p = arg; |
908 for (;;) | 911 for (;;) |
909 { | 912 { |
910 p = skipwhite(p + 1); // skip whites after '[', ';' or ',' | 913 p = skipwhite(p + 1); // skip whites after '[', ';' or ',' |
911 s = skip_var_one(p); | 914 s = skip_var_one(p, TRUE); |
912 if (s == p) | 915 if (s == p) |
913 { | 916 { |
914 semsg(_(e_invarg2), p); | 917 semsg(_(e_invarg2), p); |
915 return NULL; | 918 return NULL; |
916 } | 919 } |
935 } | 938 } |
936 } | 939 } |
937 return p + 1; | 940 return p + 1; |
938 } | 941 } |
939 else | 942 else |
940 return skip_var_one(arg); | 943 return skip_var_one(arg, include_type); |
941 } | 944 } |
942 | 945 |
943 /* | 946 /* |
944 * Skip one (assignable) variable name, including @r, $VAR, &option, d.key, | 947 * Skip one (assignable) variable name, including @r, $VAR, &option, d.key, |
945 * l[idx]. | 948 * l[idx]. |
949 * In Vim9 script also skip over ": type" if "include_type" is TRUE. | |
946 */ | 950 */ |
947 static char_u * | 951 static char_u * |
948 skip_var_one(char_u *arg) | 952 skip_var_one(char_u *arg, int include_type) |
949 { | 953 { |
954 char_u *end; | |
955 | |
950 if (*arg == '@' && arg[1] != NUL) | 956 if (*arg == '@' && arg[1] != NUL) |
951 return arg + 2; | 957 return arg + 2; |
952 return find_name_end(*arg == '$' || *arg == '&' ? arg + 1 : arg, | 958 end = find_name_end(*arg == '$' || *arg == '&' ? arg + 1 : arg, |
953 NULL, NULL, FNE_INCL_BR | FNE_CHECK_START); | 959 NULL, NULL, FNE_INCL_BR | FNE_CHECK_START); |
960 if (include_type && current_sctx.sc_version == SCRIPT_VERSION_VIM9 | |
961 && *end == ':') | |
962 { | |
963 end = skip_type(skipwhite(end + 1)); | |
964 } | |
965 return end; | |
954 } | 966 } |
955 | 967 |
956 /* | 968 /* |
957 * List variables for hashtab "ht" with prefix "prefix". | 969 * List variables for hashtab "ht" with prefix "prefix". |
958 * If "empty" is TRUE also list NULL strings as empty strings. | 970 * If "empty" is TRUE also list NULL strings as empty strings. |
1139 static char_u * | 1151 static char_u * |
1140 ex_let_one( | 1152 ex_let_one( |
1141 char_u *arg, // points to variable name | 1153 char_u *arg, // points to variable name |
1142 typval_T *tv, // value to assign to variable | 1154 typval_T *tv, // value to assign to variable |
1143 int copy, // copy value from "tv" | 1155 int copy, // copy value from "tv" |
1144 int is_const, // lock variable for const | 1156 int flags, // LET_IS_CONST and/or LET_NO_COMMAND |
1145 char_u *endchars, // valid chars after variable name or NULL | 1157 char_u *endchars, // valid chars after variable name or NULL |
1146 char_u *op) // "+", "-", "." or NULL | 1158 char_u *op) // "+", "-", "." or NULL |
1147 { | 1159 { |
1148 int c1; | 1160 int c1; |
1149 char_u *name; | 1161 char_u *name; |
1154 char_u *tofree = NULL; | 1166 char_u *tofree = NULL; |
1155 | 1167 |
1156 // ":let $VAR = expr": Set environment variable. | 1168 // ":let $VAR = expr": Set environment variable. |
1157 if (*arg == '$') | 1169 if (*arg == '$') |
1158 { | 1170 { |
1159 if (is_const) | 1171 if (flags & LET_IS_CONST) |
1160 { | 1172 { |
1161 emsg(_("E996: Cannot lock an environment variable")); | 1173 emsg(_("E996: Cannot lock an environment variable")); |
1162 return NULL; | 1174 return NULL; |
1163 } | 1175 } |
1164 // Find the end of the name. | 1176 // Find the end of the name. |
1212 // ":let &option = expr": Set option value. | 1224 // ":let &option = expr": Set option value. |
1213 // ":let &l:option = expr": Set local option value. | 1225 // ":let &l:option = expr": Set local option value. |
1214 // ":let &g:option = expr": Set global option value. | 1226 // ":let &g:option = expr": Set global option value. |
1215 else if (*arg == '&') | 1227 else if (*arg == '&') |
1216 { | 1228 { |
1217 if (is_const) | 1229 if (flags & LET_IS_CONST) |
1218 { | 1230 { |
1219 emsg(_("E996: Cannot lock an option")); | 1231 emsg(_(e_const_option)); |
1220 return NULL; | 1232 return NULL; |
1221 } | 1233 } |
1222 // Find the end of the name. | 1234 // Find the end of the name. |
1223 p = find_option_end(&arg, &opt_flags); | 1235 p = find_option_end(&arg, &opt_flags); |
1224 if (p == NULL || (endchars != NULL | 1236 if (p == NULL || (endchars != NULL |
1279 } | 1291 } |
1280 | 1292 |
1281 // ":let @r = expr": Set register contents. | 1293 // ":let @r = expr": Set register contents. |
1282 else if (*arg == '@') | 1294 else if (*arg == '@') |
1283 { | 1295 { |
1284 if (is_const) | 1296 if (flags & LET_IS_CONST) |
1285 { | 1297 { |
1286 emsg(_("E996: Cannot lock a register")); | 1298 emsg(_("E996: Cannot lock a register")); |
1287 return NULL; | 1299 return NULL; |
1288 } | 1300 } |
1289 ++arg; | 1301 ++arg; |
1315 vim_free(ptofree); | 1327 vim_free(ptofree); |
1316 } | 1328 } |
1317 } | 1329 } |
1318 | 1330 |
1319 // ":let var = expr": Set internal variable. | 1331 // ":let var = expr": Set internal variable. |
1332 // ":let var: type = expr": Set internal variable with type. | |
1320 // ":let {expr} = expr": Idem, name made with curly braces | 1333 // ":let {expr} = expr": Idem, name made with curly braces |
1321 else if (eval_isnamec1(*arg) || *arg == '{') | 1334 else if (eval_isnamec1(*arg) || *arg == '{') |
1322 { | 1335 { |
1323 lval_T lv; | 1336 lval_T lv; |
1324 | 1337 |
1325 p = get_lval(arg, tv, &lv, FALSE, FALSE, 0, FNE_CHECK_START); | 1338 p = get_lval(arg, tv, &lv, FALSE, FALSE, 0, FNE_CHECK_START); |
1326 if (p != NULL && lv.ll_name != NULL) | 1339 if (p != NULL && lv.ll_name != NULL) |
1327 { | 1340 { |
1328 if (endchars != NULL && vim_strchr(endchars, *skipwhite(p)) == NULL) | 1341 if (endchars != NULL && vim_strchr(endchars, |
1342 *skipwhite(lv.ll_name_end)) == NULL) | |
1329 emsg(_(e_letunexp)); | 1343 emsg(_(e_letunexp)); |
1330 else | 1344 else |
1331 { | 1345 { |
1332 set_var_lval(&lv, p, tv, copy, is_const, op); | 1346 set_var_lval(&lv, p, tv, copy, flags, op); |
1333 arg_end = p; | 1347 arg_end = p; |
1334 } | 1348 } |
1335 } | 1349 } |
1336 clear_lval(&lv); | 1350 clear_lval(&lv); |
1337 } | 1351 } |
1655 tv->v_lock &= ~VAR_LOCKED; | 1669 tv->v_lock &= ~VAR_LOCKED; |
1656 | 1670 |
1657 switch (tv->v_type) | 1671 switch (tv->v_type) |
1658 { | 1672 { |
1659 case VAR_UNKNOWN: | 1673 case VAR_UNKNOWN: |
1674 case VAR_VOID: | |
1660 case VAR_NUMBER: | 1675 case VAR_NUMBER: |
1676 case VAR_BOOL: | |
1661 case VAR_STRING: | 1677 case VAR_STRING: |
1662 case VAR_FUNC: | 1678 case VAR_FUNC: |
1663 case VAR_PARTIAL: | 1679 case VAR_PARTIAL: |
1664 case VAR_FLOAT: | 1680 case VAR_FLOAT: |
1665 case VAR_BOOL: | |
1666 case VAR_SPECIAL: | 1681 case VAR_SPECIAL: |
1667 case VAR_JOB: | 1682 case VAR_JOB: |
1668 case VAR_CHANNEL: | 1683 case VAR_CHANNEL: |
1669 break; | 1684 break; |
1670 | 1685 |
1899 { | 1914 { |
1900 return &vimvardict; | 1915 return &vimvardict; |
1901 } | 1916 } |
1902 | 1917 |
1903 /* | 1918 /* |
1919 * Returns the index of a v:variable. Negative if not found. | |
1920 */ | |
1921 int | |
1922 find_vim_var(char_u *name) | |
1923 { | |
1924 dictitem_T *di = find_var_in_ht(&vimvarht, 0, name, TRUE); | |
1925 struct vimvar *vv; | |
1926 | |
1927 if (di == NULL) | |
1928 return -1; | |
1929 vv = (struct vimvar *)((char *)di - offsetof(vimvar_T, vv_di)); | |
1930 return (int)(vv - vimvars); | |
1931 } | |
1932 | |
1933 | |
1934 /* | |
1904 * Set type of v: variable to "type". | 1935 * Set type of v: variable to "type". |
1905 */ | 1936 */ |
1906 void | 1937 void |
1907 set_vim_var_type(int idx, vartype_T type) | 1938 set_vim_var_type(int idx, vartype_T type) |
1908 { | 1939 { |
1915 */ | 1946 */ |
1916 void | 1947 void |
1917 set_vim_var_nr(int idx, varnumber_T val) | 1948 set_vim_var_nr(int idx, varnumber_T val) |
1918 { | 1949 { |
1919 vimvars[idx].vv_nr = val; | 1950 vimvars[idx].vv_nr = val; |
1951 } | |
1952 | |
1953 char * | |
1954 get_vim_var_name(int idx) | |
1955 { | |
1956 return vimvars[idx].vv_name; | |
1920 } | 1957 } |
1921 | 1958 |
1922 /* | 1959 /* |
1923 * Get typval_T v: variable value. | 1960 * Get typval_T v: variable value. |
1924 */ | 1961 */ |
2243 tv = &v->di_tv; | 2280 tv = &v->di_tv; |
2244 if (dip != NULL) | 2281 if (dip != NULL) |
2245 *dip = v; | 2282 *dip = v; |
2246 } | 2283 } |
2247 | 2284 |
2285 if (tv == NULL && current_sctx.sc_version == SCRIPT_VERSION_VIM9) | |
2286 { | |
2287 imported_T *import = find_imported(name, NULL); | |
2288 | |
2289 // imported variable from another script | |
2290 if (import != NULL) | |
2291 { | |
2292 scriptitem_T *si = &SCRIPT_ITEM(import->imp_sid); | |
2293 svar_T *sv = ((svar_T *)si->sn_var_vals.ga_data) | |
2294 + import->imp_var_vals_idx; | |
2295 tv = sv->sv_tv; | |
2296 } | |
2297 } | |
2298 | |
2248 if (tv == NULL) | 2299 if (tv == NULL) |
2249 { | 2300 { |
2250 if (rettv != NULL && verbose) | 2301 if (rettv != NULL && verbose) |
2251 semsg(_(e_undefvar), name); | 2302 semsg(_(e_undefvar), name); |
2252 ret = FAIL; | 2303 ret = FAIL; |
2364 } | 2415 } |
2365 return HI2DI(hi); | 2416 return HI2DI(hi); |
2366 } | 2417 } |
2367 | 2418 |
2368 /* | 2419 /* |
2420 * Get the script-local hashtab. NULL if not in a script context. | |
2421 */ | |
2422 hashtab_T * | |
2423 get_script_local_ht(void) | |
2424 { | |
2425 scid_T sid = current_sctx.sc_sid; | |
2426 | |
2427 if (sid > 0 && sid <= script_items.ga_len) | |
2428 return &SCRIPT_VARS(sid); | |
2429 return NULL; | |
2430 } | |
2431 | |
2432 /* | |
2433 * Look for "name[len]" in script-local variables. | |
2434 * Return -1 when not found. | |
2435 */ | |
2436 int | |
2437 lookup_scriptvar(char_u *name, size_t len, cctx_T *dummy UNUSED) | |
2438 { | |
2439 hashtab_T *ht = get_script_local_ht(); | |
2440 char_u buffer[30]; | |
2441 char_u *p; | |
2442 int res; | |
2443 hashitem_T *hi; | |
2444 | |
2445 if (ht == NULL) | |
2446 return -1; | |
2447 if (len < sizeof(buffer) - 1) | |
2448 { | |
2449 vim_strncpy(buffer, name, len); | |
2450 p = buffer; | |
2451 } | |
2452 else | |
2453 { | |
2454 p = vim_strnsave(name, (int)len); | |
2455 if (p == NULL) | |
2456 return -1; | |
2457 } | |
2458 | |
2459 hi = hash_find(ht, p); | |
2460 res = HASHITEM_EMPTY(hi) ? -1 : 1; | |
2461 | |
2462 // if not script-local, then perhaps imported | |
2463 if (res == -1 && find_imported(p, NULL) != NULL) | |
2464 res = 1; | |
2465 | |
2466 if (p != buffer) | |
2467 vim_free(p); | |
2468 return res; | |
2469 } | |
2470 | |
2471 /* | |
2369 * Find the hashtab used for a variable name. | 2472 * Find the hashtab used for a variable name. |
2370 * Return NULL if the name is not valid. | 2473 * Return NULL if the name is not valid. |
2371 * Set "varname" to the start of name without ':'. | 2474 * Set "varname" to the start of name without ':'. |
2372 */ | 2475 */ |
2373 hashtab_T * | 2476 hashtab_T * |
2393 if (!HASHITEM_EMPTY(hi)) | 2496 if (!HASHITEM_EMPTY(hi)) |
2394 return &compat_hashtab; | 2497 return &compat_hashtab; |
2395 } | 2498 } |
2396 | 2499 |
2397 ht = get_funccal_local_ht(); | 2500 ht = get_funccal_local_ht(); |
2398 if (ht == NULL) | 2501 if (ht != NULL) |
2399 return &globvarht; // global variable | 2502 return ht; // local variable |
2400 return ht; // local variable | 2503 |
2504 // in Vim9 script items at the script level are script-local | |
2505 if (current_sctx.sc_version == SCRIPT_VERSION_VIM9) | |
2506 { | |
2507 ht = get_script_local_ht(); | |
2508 if (ht != NULL) | |
2509 return ht; | |
2510 } | |
2511 | |
2512 return &globvarht; // global variable | |
2401 } | 2513 } |
2402 *varname = name + 2; | 2514 *varname = name + 2; |
2403 if (*name == 'g') // global variable | 2515 if (*name == 'g') // global variable |
2404 return &globvarht; | 2516 return &globvarht; |
2405 // There must be no ':' or '#' in the rest of the name, unless g: is used | 2517 // There must be no ':' or '#' in the rest of the name, unless g: is used |
2412 return &curwin->w_vars->dv_hashtab; | 2524 return &curwin->w_vars->dv_hashtab; |
2413 if (*name == 't') // tab page variable | 2525 if (*name == 't') // tab page variable |
2414 return &curtab->tp_vars->dv_hashtab; | 2526 return &curtab->tp_vars->dv_hashtab; |
2415 if (*name == 'v') // v: variable | 2527 if (*name == 'v') // v: variable |
2416 return &vimvarht; | 2528 return &vimvarht; |
2417 if (*name == 'a') // a: function argument | 2529 if (current_sctx.sc_version != SCRIPT_VERSION_VIM9) |
2418 return get_funccal_args_ht(); | 2530 { |
2419 if (*name == 'l') // l: local function variable | 2531 if (*name == 'a') // a: function argument |
2420 return get_funccal_local_ht(); | 2532 return get_funccal_args_ht(); |
2421 if (*name == 's' // script variable | 2533 if (*name == 'l') // l: local function variable |
2422 && current_sctx.sc_sid > 0 | 2534 return get_funccal_local_ht(); |
2423 && current_sctx.sc_sid <= script_items.ga_len) | 2535 } |
2424 return &SCRIPT_VARS(current_sctx.sc_sid); | 2536 if (*name == 's') // script variable |
2537 { | |
2538 ht = get_script_local_ht(); | |
2539 if (ht != NULL) | |
2540 return ht; | |
2541 } | |
2425 return NULL; | 2542 return NULL; |
2426 } | 2543 } |
2427 | 2544 |
2428 /* | 2545 /* |
2429 * Get the string value of a (global/local) variable. | 2546 * Get the string value of a (global/local) variable. |
2615 set_var( | 2732 set_var( |
2616 char_u *name, | 2733 char_u *name, |
2617 typval_T *tv, | 2734 typval_T *tv, |
2618 int copy) // make copy of value in "tv" | 2735 int copy) // make copy of value in "tv" |
2619 { | 2736 { |
2620 set_var_const(name, tv, copy, FALSE); | 2737 set_var_const(name, NULL, tv, copy, 0); |
2621 } | 2738 } |
2622 | 2739 |
2623 /* | 2740 /* |
2624 * Set variable "name" to value in "tv". | 2741 * Set variable "name" to value in "tv". |
2625 * If the variable already exists and "is_const" is FALSE the value is updated. | 2742 * If the variable already exists and "is_const" is FALSE the value is updated. |
2626 * Otherwise the variable is created. | 2743 * Otherwise the variable is created. |
2627 */ | 2744 */ |
2628 void | 2745 void |
2629 set_var_const( | 2746 set_var_const( |
2630 char_u *name, | 2747 char_u *name, |
2748 type_T *type, | |
2631 typval_T *tv, | 2749 typval_T *tv, |
2632 int copy, // make copy of value in "tv" | 2750 int copy, // make copy of value in "tv" |
2633 int is_const) // disallow to modify existing variable | 2751 int flags) // LET_IS_CONST and/or LET_NO_COMMAND |
2634 { | 2752 { |
2635 dictitem_T *v; | 2753 dictitem_T *di; |
2636 char_u *varname; | 2754 char_u *varname; |
2637 hashtab_T *ht; | 2755 hashtab_T *ht; |
2756 int is_script_local; | |
2638 | 2757 |
2639 ht = find_var_ht(name, &varname); | 2758 ht = find_var_ht(name, &varname); |
2640 if (ht == NULL || *varname == NUL) | 2759 if (ht == NULL || *varname == NUL) |
2641 { | 2760 { |
2642 semsg(_(e_illvar), name); | 2761 semsg(_(e_illvar), name); |
2643 return; | 2762 return; |
2644 } | 2763 } |
2645 v = find_var_in_ht(ht, 0, varname, TRUE); | 2764 is_script_local = ht == get_script_local_ht(); |
2765 | |
2766 di = find_var_in_ht(ht, 0, varname, TRUE); | |
2646 | 2767 |
2647 // Search in parent scope which is possible to reference from lambda | 2768 // Search in parent scope which is possible to reference from lambda |
2648 if (v == NULL) | 2769 if (di == NULL) |
2649 v = find_var_in_scoped_ht(name, TRUE); | 2770 di = find_var_in_scoped_ht(name, TRUE); |
2650 | 2771 |
2651 if ((tv->v_type == VAR_FUNC || tv->v_type == VAR_PARTIAL) | 2772 if ((tv->v_type == VAR_FUNC || tv->v_type == VAR_PARTIAL) |
2652 && var_check_func_name(name, v == NULL)) | 2773 && var_check_func_name(name, di == NULL)) |
2653 return; | 2774 return; |
2654 | 2775 |
2655 if (v != NULL) | 2776 if (di != NULL) |
2656 { | 2777 { |
2657 if (is_const) | 2778 if ((di->di_flags & DI_FLAGS_RELOAD) == 0) |
2658 { | 2779 { |
2659 emsg(_(e_cannot_mod)); | 2780 if (flags & LET_IS_CONST) |
2660 return; | 2781 { |
2661 } | 2782 emsg(_(e_cannot_mod)); |
2783 return; | |
2784 } | |
2785 | |
2786 if (var_check_ro(di->di_flags, name, FALSE) | |
2787 || var_check_lock(di->di_tv.v_lock, name, FALSE)) | |
2788 return; | |
2789 | |
2790 if ((flags & LET_NO_COMMAND) == 0 | |
2791 && is_script_local | |
2792 && current_sctx.sc_version == SCRIPT_VERSION_VIM9) | |
2793 { | |
2794 semsg(_("E1041: Redefining script item %s"), name); | |
2795 return; | |
2796 } | |
2797 } | |
2798 else | |
2799 // can only redefine once | |
2800 di->di_flags &= ~DI_FLAGS_RELOAD; | |
2662 | 2801 |
2663 // existing variable, need to clear the value | 2802 // existing variable, need to clear the value |
2664 if (var_check_ro(v->di_flags, name, FALSE) | 2803 |
2665 || var_check_lock(v->di_tv.v_lock, name, FALSE)) | 2804 // Handle setting internal di: variables separately where needed to |
2666 return; | |
2667 | |
2668 // Handle setting internal v: variables separately where needed to | |
2669 // prevent changing the type. | 2805 // prevent changing the type. |
2670 if (ht == &vimvarht) | 2806 if (ht == &vimvarht) |
2671 { | 2807 { |
2672 if (v->di_tv.v_type == VAR_STRING) | 2808 if (di->di_tv.v_type == VAR_STRING) |
2673 { | 2809 { |
2674 VIM_CLEAR(v->di_tv.vval.v_string); | 2810 VIM_CLEAR(di->di_tv.vval.v_string); |
2675 if (copy || tv->v_type != VAR_STRING) | 2811 if (copy || tv->v_type != VAR_STRING) |
2676 { | 2812 { |
2677 char_u *val = tv_get_string(tv); | 2813 char_u *val = tv_get_string(tv); |
2678 | 2814 |
2679 // Careful: when assigning to v:errmsg and tv_get_string() | 2815 // Careful: when assigning to v:errmsg and tv_get_string() |
2680 // causes an error message the variable will alrady be set. | 2816 // causes an error message the variable will alrady be set. |
2681 if (v->di_tv.vval.v_string == NULL) | 2817 if (di->di_tv.vval.v_string == NULL) |
2682 v->di_tv.vval.v_string = vim_strsave(val); | 2818 di->di_tv.vval.v_string = vim_strsave(val); |
2683 } | 2819 } |
2684 else | 2820 else |
2685 { | 2821 { |
2686 // Take over the string to avoid an extra alloc/free. | 2822 // Take over the string to avoid an extra alloc/free. |
2687 v->di_tv.vval.v_string = tv->vval.v_string; | 2823 di->di_tv.vval.v_string = tv->vval.v_string; |
2688 tv->vval.v_string = NULL; | 2824 tv->vval.v_string = NULL; |
2689 } | 2825 } |
2690 return; | 2826 return; |
2691 } | 2827 } |
2692 else if (v->di_tv.v_type == VAR_NUMBER) | 2828 else if (di->di_tv.v_type == VAR_NUMBER) |
2693 { | 2829 { |
2694 v->di_tv.vval.v_number = tv_get_number(tv); | 2830 di->di_tv.vval.v_number = tv_get_number(tv); |
2695 if (STRCMP(varname, "searchforward") == 0) | 2831 if (STRCMP(varname, "searchforward") == 0) |
2696 set_search_direction(v->di_tv.vval.v_number ? '/' : '?'); | 2832 set_search_direction(di->di_tv.vval.v_number ? '/' : '?'); |
2697 #ifdef FEAT_SEARCH_EXTRA | 2833 #ifdef FEAT_SEARCH_EXTRA |
2698 else if (STRCMP(varname, "hlsearch") == 0) | 2834 else if (STRCMP(varname, "hlsearch") == 0) |
2699 { | 2835 { |
2700 no_hlsearch = !v->di_tv.vval.v_number; | 2836 no_hlsearch = !di->di_tv.vval.v_number; |
2701 redraw_all_later(SOME_VALID); | 2837 redraw_all_later(SOME_VALID); |
2702 } | 2838 } |
2703 #endif | 2839 #endif |
2704 return; | 2840 return; |
2705 } | 2841 } |
2706 else if (v->di_tv.v_type != tv->v_type) | 2842 else if (di->di_tv.v_type != tv->v_type) |
2707 { | 2843 { |
2708 semsg(_("E963: setting %s to value with wrong type"), name); | 2844 semsg(_("E963: setting %s to value with wrong type"), name); |
2709 return; | 2845 return; |
2710 } | 2846 } |
2711 } | 2847 } |
2712 | 2848 |
2713 clear_tv(&v->di_tv); | 2849 clear_tv(&di->di_tv); |
2714 } | 2850 } |
2715 else // add a new variable | 2851 else // add a new variable |
2716 { | 2852 { |
2717 // Can't add "v:" or "a:" variable. | 2853 // Can't add "v:" or "a:" variable. |
2718 if (ht == &vimvarht || ht == get_funccal_args_ht()) | 2854 if (ht == &vimvarht || ht == get_funccal_args_ht()) |
2723 | 2859 |
2724 // Make sure the variable name is valid. | 2860 // Make sure the variable name is valid. |
2725 if (!valid_varname(varname)) | 2861 if (!valid_varname(varname)) |
2726 return; | 2862 return; |
2727 | 2863 |
2728 v = alloc(sizeof(dictitem_T) + STRLEN(varname)); | 2864 di = alloc(sizeof(dictitem_T) + STRLEN(varname)); |
2729 if (v == NULL) | 2865 if (di == NULL) |
2730 return; | 2866 return; |
2731 STRCPY(v->di_key, varname); | 2867 STRCPY(di->di_key, varname); |
2732 if (hash_add(ht, DI2HIKEY(v)) == FAIL) | 2868 if (hash_add(ht, DI2HIKEY(di)) == FAIL) |
2733 { | 2869 { |
2734 vim_free(v); | 2870 vim_free(di); |
2735 return; | 2871 return; |
2736 } | 2872 } |
2737 v->di_flags = DI_FLAGS_ALLOC; | 2873 di->di_flags = DI_FLAGS_ALLOC; |
2738 if (is_const) | 2874 if (flags & LET_IS_CONST) |
2739 v->di_flags |= DI_FLAGS_LOCK; | 2875 di->di_flags |= DI_FLAGS_LOCK; |
2876 | |
2877 if (is_script_local && current_sctx.sc_version == SCRIPT_VERSION_VIM9) | |
2878 { | |
2879 scriptitem_T *si = &SCRIPT_ITEM(current_sctx.sc_sid); | |
2880 | |
2881 // Store a pointer to the typval_T, so that it can be found by | |
2882 // index instead of using a hastab lookup. | |
2883 if (ga_grow(&si->sn_var_vals, 1) == OK) | |
2884 { | |
2885 svar_T *sv = ((svar_T *)si->sn_var_vals.ga_data) | |
2886 + si->sn_var_vals.ga_len; | |
2887 sv->sv_name = di->di_key; | |
2888 sv->sv_tv = &di->di_tv; | |
2889 sv->sv_type = type == NULL ? &t_any : type; | |
2890 sv->sv_const = (flags & LET_IS_CONST); | |
2891 sv->sv_export = is_export; | |
2892 ++si->sn_var_vals.ga_len; | |
2893 | |
2894 // let ex_export() know the export worked. | |
2895 is_export = FALSE; | |
2896 } | |
2897 } | |
2740 } | 2898 } |
2741 | 2899 |
2742 if (copy || tv->v_type == VAR_NUMBER || tv->v_type == VAR_FLOAT) | 2900 if (copy || tv->v_type == VAR_NUMBER || tv->v_type == VAR_FLOAT) |
2743 copy_tv(tv, &v->di_tv); | 2901 copy_tv(tv, &di->di_tv); |
2744 else | 2902 else |
2745 { | 2903 { |
2746 v->di_tv = *tv; | 2904 di->di_tv = *tv; |
2747 v->di_tv.v_lock = 0; | 2905 di->di_tv.v_lock = 0; |
2748 init_tv(tv); | 2906 init_tv(tv); |
2749 } | 2907 } |
2750 | 2908 |
2751 if (is_const) | 2909 if (flags & LET_IS_CONST) |
2752 v->di_tv.v_lock |= VAR_LOCKED; | 2910 di->di_tv.v_lock |= VAR_LOCKED; |
2753 } | 2911 } |
2754 | 2912 |
2755 /* | 2913 /* |
2756 * Return TRUE if di_flags "flags" indicates variable "name" is read-only. | 2914 * Return TRUE if di_flags "flags" indicates variable "name" is read-only. |
2757 * Also give an error message. | 2915 * Also give an error message. |
3128 save_emsg = did_emsg; | 3286 save_emsg = did_emsg; |
3129 did_emsg = FALSE; | 3287 did_emsg = FALSE; |
3130 tv.v_type = VAR_STRING; | 3288 tv.v_type = VAR_STRING; |
3131 tv.vval.v_string = (char_u *)""; | 3289 tv.vval.v_string = (char_u *)""; |
3132 if (append) | 3290 if (append) |
3133 set_var_lval(redir_lval, redir_endp, &tv, TRUE, FALSE, (char_u *)"."); | 3291 set_var_lval(redir_lval, redir_endp, &tv, TRUE, 0, (char_u *)"."); |
3134 else | 3292 else |
3135 set_var_lval(redir_lval, redir_endp, &tv, TRUE, FALSE, (char_u *)"="); | 3293 set_var_lval(redir_lval, redir_endp, &tv, TRUE, 0, (char_u *)"="); |
3136 clear_lval(redir_lval); | 3294 clear_lval(redir_lval); |
3137 err = did_emsg; | 3295 err = did_emsg; |
3138 did_emsg |= save_emsg; | 3296 did_emsg |= save_emsg; |
3139 if (err) | 3297 if (err) |
3140 { | 3298 { |
3203 // Call get_lval() again, if it's inside a Dict or List it may | 3361 // Call get_lval() again, if it's inside a Dict or List it may |
3204 // have changed. | 3362 // have changed. |
3205 redir_endp = get_lval(redir_varname, NULL, redir_lval, | 3363 redir_endp = get_lval(redir_varname, NULL, redir_lval, |
3206 FALSE, FALSE, 0, FNE_CHECK_START); | 3364 FALSE, FALSE, 0, FNE_CHECK_START); |
3207 if (redir_endp != NULL && redir_lval->ll_name != NULL) | 3365 if (redir_endp != NULL && redir_lval->ll_name != NULL) |
3208 set_var_lval(redir_lval, redir_endp, &tv, FALSE, FALSE, | 3366 set_var_lval(redir_lval, redir_endp, &tv, FALSE, 0, |
3209 (char_u *)"."); | 3367 (char_u *)"."); |
3210 clear_lval(redir_lval); | 3368 clear_lval(redir_lval); |
3211 } | 3369 } |
3212 | 3370 |
3213 // free the collected output | 3371 // free the collected output |