comparison src/optionstr.c @ 31859:8b15e4161605 v9.0.1262

patch 9.0.1262: the did_set_string_option function is too long Commit: https://github.com/vim/vim/commit/f2e30d0c448b9754d0d4daa901b51fbbf4c30747 Author: Yegappan Lakshmanan <yegappan@yahoo.com> Date: Mon Jan 30 13:04:42 2023 +0000 patch 9.0.1262: the did_set_string_option function is too long Problem: The did_set_string_option function is too long. Solution: Split off functionality to individual functions. (Yegappan Lakshmanan, Lewis Russell, closes #11904)
author Bram Moolenaar <Bram@vim.org>
date Mon, 30 Jan 2023 14:15:05 +0100
parents 2ce8e7c4acf4
children 789ac0814945
comparison
equal deleted inserted replaced
31858:42a6cf1933f9 31859:8b15e4161605
638 return NULL; 638 return NULL;
639 } 639 }
640 #endif 640 #endif
641 641
642 /* 642 /*
643 * The 'term' option is changed.
644 */
645 static char *
646 did_set_term(int *opt_idx, long_u *free_oldval)
647 {
648 char *errmsg = NULL;
649
650 if (T_NAME[0] == NUL)
651 errmsg = e_cannot_set_term_to_empty_string;
652 #ifdef FEAT_GUI
653 else if (gui.in_use)
654 errmsg = e_cannot_change_term_in_GUI;
655 else if (term_is_gui(T_NAME))
656 errmsg = e_use_gui_to_start_GUI;
657 #endif
658 else if (set_termname(T_NAME) == FAIL)
659 errmsg = e_not_found_in_termcap;
660 else
661 {
662 // Screen colors may have changed.
663 redraw_later_clear();
664
665 // Both 'term' and 'ttytype' point to T_NAME, only set the
666 // P_ALLOCED flag on 'term'.
667 *opt_idx = findoption((char_u *)"term");
668 *free_oldval = (get_option_flags(*opt_idx) & P_ALLOCED);
669 }
670
671 return errmsg;
672 }
673
674 /*
675 * The 'backupcopy' option is changed.
676 */
677 static char *
678 did_set_backupcopy(
679 char_u *oldval,
680 int opt_flags)
681 {
682 char_u *bkc = p_bkc;
683 unsigned int *flags = &bkc_flags;
684 char *errmsg = NULL;
685
686 if (opt_flags & OPT_LOCAL)
687 {
688 bkc = curbuf->b_p_bkc;
689 flags = &curbuf->b_bkc_flags;
690 }
691
692 if ((opt_flags & OPT_LOCAL) && *bkc == NUL)
693 // make the local value empty: use the global value
694 *flags = 0;
695 else
696 {
697 if (opt_strings_flags(bkc, p_bkc_values, flags, TRUE) != OK)
698 errmsg = e_invalid_argument;
699 if ((((int)*flags & BKC_AUTO) != 0)
700 + (((int)*flags & BKC_YES) != 0)
701 + (((int)*flags & BKC_NO) != 0) != 1)
702 {
703 // Must have exactly one of "auto", "yes" and "no".
704 (void)opt_strings_flags(oldval, p_bkc_values, flags, TRUE);
705 errmsg = e_invalid_argument;
706 }
707 }
708
709 return errmsg;
710 }
711
712 /*
713 * The 'backupext' or the 'patchmode' option is changed.
714 */
715 static char *
716 did_set_backupext_or_patchmode(void)
717 {
718 if (STRCMP(*p_bex == '.' ? p_bex + 1 : p_bex,
719 *p_pm == '.' ? p_pm + 1 : p_pm) == 0)
720 return e_backupext_and_patchmode_are_equal;
721
722 return NULL;
723 }
724
725 #ifdef FEAT_LINEBREAK
726 /*
727 * The 'breakindentopt' option is changed.
728 */
729 static char *
730 did_set_breakindentopt(void)
731 {
732 char *errmsg = NULL;
733
734 if (briopt_check(curwin) == FAIL)
735 errmsg = e_invalid_argument;
736 // list setting requires a redraw
737 if (curwin->w_briopt_list)
738 redraw_all_later(UPD_NOT_VALID);
739
740 return errmsg;
741 }
742 #endif
743
744 /*
745 * The 'isident' or the 'iskeyword' or the 'isprint' or the 'isfname' option is
746 * changed.
747 */
748 static char *
749 did_set_isopt(int *did_chartab)
750 {
751 if (init_chartab() == FAIL)
752 {
753 *did_chartab = TRUE; // need to restore it below
754 return e_invalid_argument; // error in value
755 }
756
757 return NULL;
758 }
759
760 /*
761 * The 'helpfile' option is changed.
762 */
763 static void
764 did_set_helpfile(void)
765 {
766 // May compute new values for $VIM and $VIMRUNTIME
767 if (didset_vim)
768 vim_unsetenv_ext((char_u *)"VIM");
769 if (didset_vimruntime)
770 vim_unsetenv_ext((char_u *)"VIMRUNTIME");
771 }
772
773 #ifdef FEAT_SYN_HL
774 /*
775 * The 'cursorlineopt' option is changed.
776 */
777 static char *
778 did_set_cursorlineopt(char_u **varp)
779 {
780 if (**varp == NUL || fill_culopt_flags(*varp, curwin) != OK)
781 return e_invalid_argument;
782
783 return NULL;
784 }
785 #endif
786
787 #ifdef FEAT_MULTI_LANG
788 /*
789 * The 'helplang' option is changed.
790 */
791 static char *
792 did_set_helplang(void)
793 {
794 char *errmsg = NULL;
795
796 // Check for "", "ab", "ab,cd", etc.
797 for (char_u *s = p_hlg; *s != NUL; s += 3)
798 {
799 if (s[1] == NUL || ((s[2] != ',' || s[3] == NUL) && s[2] != NUL))
800 {
801 errmsg = e_invalid_argument;
802 break;
803 }
804 if (s[2] == NUL)
805 break;
806 }
807
808 return errmsg;
809 }
810 #endif
811
812 /*
813 * The 'highlight' option is changed.
814 */
815 static char *
816 did_set_highlight(void)
817 {
818 if (highlight_changed() == FAIL)
819 return e_invalid_argument; // invalid flags
820
821 return NULL;
822 }
823
824 /*
825 * An option that accepts a list of flags is changed.
826 * e.g. 'viewoptions', 'switchbuf', 'casemap', etc.
827 */
828 static char *
829 did_set_opt_flags(char_u *val, char **values, unsigned *flagp, int list)
830 {
831 if (opt_strings_flags(val, values, flagp, list) == FAIL)
832 return e_invalid_argument;
833
834 return NULL;
835 }
836
837 /*
838 * An option that accepts a list of string values is changed.
839 * e.g. 'nrformats', 'scrollopt', 'wildoptions', etc.
840 */
841 static char *
842 did_set_opt_strings(char_u *val, char **values, int list)
843 {
844 return did_set_opt_flags(val, values, NULL, list);
845 }
846
847 #ifdef FEAT_SESSION
848 /*
849 * The 'sessionoptions' option is changed.
850 */
851 static char *
852 did_set_sessionoptions(char_u *oldval)
853 {
854 if (opt_strings_flags(p_ssop, p_ssop_values, &ssop_flags, TRUE) != OK)
855 return e_invalid_argument;
856 if ((ssop_flags & SSOP_CURDIR) && (ssop_flags & SSOP_SESDIR))
857 {
858 // Don't allow both "sesdir" and "curdir".
859 (void)opt_strings_flags(oldval, p_ssop_values, &ssop_flags, TRUE);
860 return e_invalid_argument;
861 }
862
863 return NULL;
864 }
865 #endif
866
867 /*
868 * The 'ambiwidth' option is changed.
869 */
870 static char *
871 did_set_ambiwidth(void)
872 {
873 if (check_opt_strings(p_ambw, p_ambw_values, FALSE) != OK)
874 return e_invalid_argument;
875
876 return check_chars_options();
877 }
878
879 /*
880 * The 'background' option is changed.
881 */
882 static char *
883 did_set_background(void)
884 {
885 if (check_opt_strings(p_bg, p_bg_values, FALSE) == FAIL)
886 return e_invalid_argument;
887
888 #ifdef FEAT_EVAL
889 int dark = (*p_bg == 'd');
890 #endif
891
892 init_highlight(FALSE, FALSE);
893
894 #ifdef FEAT_EVAL
895 if (dark != (*p_bg == 'd')
896 && get_var_value((char_u *)"g:colors_name") != NULL)
897 {
898 // The color scheme must have set 'background' back to another
899 // value, that's not what we want here. Disable the color
900 // scheme and set the colors again.
901 do_unlet((char_u *)"g:colors_name", TRUE);
902 free_string_option(p_bg);
903 p_bg = vim_strsave((char_u *)(dark ? "dark" : "light"));
904 check_string_option(&p_bg);
905 init_highlight(FALSE, FALSE);
906 }
907 #endif
908 #ifdef FEAT_TERMINAL
909 term_update_colors_all();
910 #endif
911
912 return NULL;
913 }
914
915 /*
916 * The 'wildmode' option is changed.
917 */
918 static char *
919 did_set_wildmode(void)
920 {
921 if (check_opt_wim() == FAIL)
922 return e_invalid_argument;
923 return NULL;
924 }
925
926 #ifdef FEAT_WAK
927 /*
928 * The 'winaltkeys' option is changed.
929 */
930 static char *
931 did_set_winaltkeys(void)
932 {
933 char *errmsg = NULL;
934
935 if (*p_wak == NUL
936 || check_opt_strings(p_wak, p_wak_values, FALSE) != OK)
937 errmsg = e_invalid_argument;
938 # ifdef FEAT_MENU
939 # if defined(FEAT_GUI_MOTIF)
940 else if (gui.in_use)
941 gui_motif_set_mnemonics(p_wak[0] == 'y' || p_wak[0] == 'm');
942 # elif defined(FEAT_GUI_GTK)
943 else if (gui.in_use)
944 gui_gtk_set_mnemonics(p_wak[0] == 'y' || p_wak[0] == 'm');
945 # endif
946 # endif
947 return errmsg;
948 }
949 #endif
950
951 /*
952 * The 'eventignore' option is changed.
953 */
954 static char *
955 did_set_eventignore(void)
956 {
957 if (check_ei() == FAIL)
958 return e_invalid_argument;
959 return NULL;
960 }
961
962 /*
963 * One of the 'encoding', 'fileencoding', 'termencoding' or 'makeencoding'
964 * options is changed.
965 */
966 static char *
967 did_set_encoding(char_u **varp, char_u **gvarp, int opt_flags)
968 {
969 char *errmsg = NULL;
970 char_u *p;
971
972 if (gvarp == &p_fenc)
973 {
974 if (!curbuf->b_p_ma && opt_flags != OPT_GLOBAL)
975 errmsg = e_cannot_make_changes_modifiable_is_off;
976 else if (vim_strchr(*varp, ',') != NULL)
977 // No comma allowed in 'fileencoding'; catches confusing it
978 // with 'fileencodings'.
979 errmsg = e_invalid_argument;
980 else
981 {
982 // May show a "+" in the title now.
983 redraw_titles();
984 // Add 'fileencoding' to the swap file.
985 ml_setflags(curbuf);
986 }
987 }
988 if (errmsg == NULL)
989 {
990 // canonize the value, so that STRCMP() can be used on it
991 p = enc_canonize(*varp);
992 if (p != NULL)
993 {
994 vim_free(*varp);
995 *varp = p;
996 }
997 if (varp == &p_enc)
998 {
999 errmsg = mb_init();
1000 redraw_titles();
1001 }
1002 }
1003
1004 #if defined(FEAT_GUI_GTK)
1005 if (errmsg == NULL && varp == &p_tenc && gui.in_use)
1006 {
1007 // GTK uses only a single encoding, and that is UTF-8.
1008 if (STRCMP(p_tenc, "utf-8") != 0)
1009 errmsg = e_cannot_be_changed_in_gtk_GUI;
1010 }
1011 #endif
1012
1013 if (errmsg == NULL)
1014 {
1015 #ifdef FEAT_KEYMAP
1016 // When 'keymap' is used and 'encoding' changes, reload the keymap
1017 // (with another encoding).
1018 if (varp == &p_enc && *curbuf->b_p_keymap != NUL)
1019 (void)keymap_init();
1020 #endif
1021
1022 // When 'termencoding' is not empty and 'encoding' changes or when
1023 // 'termencoding' changes, need to setup for keyboard input and
1024 // display output conversion.
1025 if (((varp == &p_enc && *p_tenc != NUL) || varp == &p_tenc))
1026 {
1027 if (convert_setup(&input_conv, p_tenc, p_enc) == FAIL
1028 || convert_setup(&output_conv, p_enc, p_tenc) == FAIL)
1029 {
1030 semsg(_(e_cannot_convert_between_str_and_str),
1031 p_tenc, p_enc);
1032 errmsg = e_invalid_argument;
1033 }
1034 }
1035
1036 #if defined(MSWIN)
1037 // $HOME may have characters in active code page.
1038 if (varp == &p_enc)
1039 init_homedir();
1040 #endif
1041 }
1042
1043 return errmsg;
1044 }
1045
1046 #if defined(FEAT_POSTSCRIPT)
1047 /*
1048 * The 'printencoding' option is changed.
1049 */
1050 static void
1051 did_set_printencoding(void)
1052 {
1053 char_u *s, *p;
1054
1055 // Canonize printencoding if VIM standard one
1056 p = enc_canonize(p_penc);
1057 if (p != NULL)
1058 {
1059 vim_free(p_penc);
1060 p_penc = p;
1061 }
1062 else
1063 {
1064 // Ensure lower case and '-' for '_'
1065 for (s = p_penc; *s != NUL; s++)
1066 {
1067 if (*s == '_')
1068 *s = '-';
1069 else
1070 *s = TOLOWER_ASC(*s);
1071 }
1072 }
1073 }
1074 #endif
1075
1076 #if defined(FEAT_XIM) && defined(FEAT_GUI_GTK)
1077 /*
1078 * The 'imactivatekey' option is changed.
1079 */
1080 static char *
1081 did_set_imactivatekey(void)
1082 {
1083 if (!im_xim_isvalid_imactivate())
1084 return e_invalid_argument;
1085 return NULL;
1086 }
1087 #endif
1088
1089 #ifdef FEAT_KEYMAP
1090 /*
1091 * The 'keymap' option is changed.
1092 */
1093 static char *
1094 did_set_keymap(char_u **varp, int opt_flags, int *value_checked)
1095 {
1096 char *errmsg = NULL;
1097
1098 if (!valid_filetype(*varp))
1099 errmsg = e_invalid_argument;
1100 else
1101 {
1102 int secure_save = secure;
1103
1104 // Reset the secure flag, since the value of 'keymap' has
1105 // been checked to be safe.
1106 secure = 0;
1107
1108 // load or unload key mapping tables
1109 errmsg = keymap_init();
1110
1111 secure = secure_save;
1112
1113 // Since we check the value, there is no need to set P_INSECURE,
1114 // even when the value comes from a modeline.
1115 *value_checked = TRUE;
1116 }
1117
1118 if (errmsg == NULL)
1119 {
1120 if (*curbuf->b_p_keymap != NUL)
1121 {
1122 // Installed a new keymap, switch on using it.
1123 curbuf->b_p_iminsert = B_IMODE_LMAP;
1124 if (curbuf->b_p_imsearch != B_IMODE_USE_INSERT)
1125 curbuf->b_p_imsearch = B_IMODE_LMAP;
1126 }
1127 else
1128 {
1129 // Cleared the keymap, may reset 'iminsert' and 'imsearch'.
1130 if (curbuf->b_p_iminsert == B_IMODE_LMAP)
1131 curbuf->b_p_iminsert = B_IMODE_NONE;
1132 if (curbuf->b_p_imsearch == B_IMODE_LMAP)
1133 curbuf->b_p_imsearch = B_IMODE_USE_INSERT;
1134 }
1135 if ((opt_flags & OPT_LOCAL) == 0)
1136 {
1137 set_iminsert_global();
1138 set_imsearch_global();
1139 }
1140 status_redraw_curbuf();
1141 }
1142
1143 return errmsg;
1144 }
1145 #endif
1146
1147 /*
1148 * The 'fileformat' option is changed.
1149 */
1150 static char *
1151 did_set_fileformat(char_u **varp, char_u *oldval, int opt_flags)
1152 {
1153 if (!curbuf->b_p_ma && !(opt_flags & OPT_GLOBAL))
1154 return e_cannot_make_changes_modifiable_is_off;
1155 else if (check_opt_strings(*varp, p_ff_values, FALSE) != OK)
1156 return e_invalid_argument;
1157
1158 // may also change 'textmode'
1159 if (get_fileformat(curbuf) == EOL_DOS)
1160 curbuf->b_p_tx = TRUE;
1161 else
1162 curbuf->b_p_tx = FALSE;
1163 redraw_titles();
1164 // update flag in swap file
1165 ml_setflags(curbuf);
1166 // Redraw needed when switching to/from "mac": a CR in the text
1167 // will be displayed differently.
1168 if (get_fileformat(curbuf) == EOL_MAC || *oldval == 'm')
1169 redraw_curbuf_later(UPD_NOT_VALID);
1170
1171 return NULL;
1172 }
1173
1174 /*
1175 * The 'fileformats' option is changed.
1176 */
1177 static char *
1178 did_set_fileformats(void)
1179 {
1180 if (check_opt_strings(p_ffs, p_ff_values, TRUE) != OK)
1181 return e_invalid_argument;
1182
1183 // also change 'textauto'
1184 if (*p_ffs == NUL)
1185 p_ta = FALSE;
1186 else
1187 p_ta = TRUE;
1188
1189 return NULL;
1190 }
1191
1192 #if defined(FEAT_CRYPT)
1193 /*
1194 * The 'cryptkey' option is changed.
1195 */
1196 static void
1197 did_set_cryptkey(char_u *oldval)
1198 {
1199 // Make sure the ":set" command doesn't show the new value in the
1200 // history.
1201 remove_key_from_history();
1202
1203 if (STRCMP(curbuf->b_p_key, oldval) != 0)
1204 // Need to update the swapfile.
1205 {
1206 ml_set_crypt_key(curbuf, oldval,
1207 *curbuf->b_p_cm == NUL ? p_cm : curbuf->b_p_cm);
1208 changed_internal();
1209 }
1210 }
1211
1212 /*
1213 * The 'cryptmethod' option is changed.
1214 */
1215 static char *
1216 did_set_cryptmethod(char_u *oldval, int opt_flags)
1217 {
1218 char_u *p;
1219 char_u *s;
1220
1221 if (opt_flags & OPT_LOCAL)
1222 p = curbuf->b_p_cm;
1223 else
1224 p = p_cm;
1225 if (check_opt_strings(p, p_cm_values, TRUE) != OK)
1226 return e_invalid_argument;
1227 else if (crypt_self_test() == FAIL)
1228 return e_invalid_argument;
1229
1230 // When setting the global value to empty, make it "zip".
1231 if (*p_cm == NUL)
1232 {
1233 free_string_option(p_cm);
1234 p_cm = vim_strsave((char_u *)"zip");
1235 }
1236 // When using ":set cm=name" the local value is going to be empty.
1237 // Do that here, otherwise the crypt functions will still use the
1238 // local value.
1239 if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0)
1240 {
1241 free_string_option(curbuf->b_p_cm);
1242 curbuf->b_p_cm = empty_option;
1243 }
1244
1245 // Need to update the swapfile when the effective method changed.
1246 // Set "s" to the effective old value, "p" to the effective new
1247 // method and compare.
1248 if ((opt_flags & OPT_LOCAL) && *oldval == NUL)
1249 s = p_cm; // was previously using the global value
1250 else
1251 s = oldval;
1252 if (*curbuf->b_p_cm == NUL)
1253 p = p_cm; // is now using the global value
1254 else
1255 p = curbuf->b_p_cm;
1256 if (STRCMP(s, p) != 0)
1257 ml_set_crypt_key(curbuf, curbuf->b_p_key, s);
1258
1259 // If the global value changes need to update the swapfile for all
1260 // buffers using that value.
1261 if ((opt_flags & OPT_GLOBAL) && STRCMP(p_cm, oldval) != 0)
1262 {
1263 buf_T *buf;
1264
1265 FOR_ALL_BUFFERS(buf)
1266 if (buf != curbuf && *buf->b_p_cm == NUL)
1267 ml_set_crypt_key(buf, buf->b_p_key, oldval);
1268 }
1269 return NULL;
1270 }
1271 #endif
1272
1273 /*
1274 * The 'matchpairs' option is changed.
1275 */
1276 static char *
1277 did_set_matchpairs(char_u **varp)
1278 {
1279 char_u *p;
1280
1281 if (has_mbyte)
1282 {
1283 for (p = *varp; *p != NUL; ++p)
1284 {
1285 int x2 = -1;
1286 int x3 = -1;
1287
1288 p += mb_ptr2len(p);
1289 if (*p != NUL)
1290 x2 = *p++;
1291 if (*p != NUL)
1292 {
1293 x3 = mb_ptr2char(p);
1294 p += mb_ptr2len(p);
1295 }
1296 if (x2 != ':' || x3 == -1 || (*p != NUL && *p != ','))
1297 return e_invalid_argument;
1298 if (*p == NUL)
1299 break;
1300 }
1301 }
1302 else
1303 {
1304 // Check for "x:y,x:y"
1305 for (p = *varp; *p != NUL; p += 4)
1306 {
1307 if (p[1] != ':' || p[2] == NUL || (p[3] != NUL && p[3] != ','))
1308 return e_invalid_argument;
1309 if (p[3] == NUL)
1310 break;
1311 }
1312 }
1313
1314 return NULL;
1315 }
1316
1317 /*
1318 * The 'comments' option is changed.
1319 */
1320 static char *
1321 did_set_comments(char_u **varp, char *errbuf)
1322 {
1323 char_u *s;
1324 char *errmsg = NULL;
1325
1326 for (s = *varp; *s; )
1327 {
1328 while (*s && *s != ':')
1329 {
1330 if (vim_strchr((char_u *)COM_ALL, *s) == NULL
1331 && !VIM_ISDIGIT(*s) && *s != '-')
1332 {
1333 errmsg = illegal_char(errbuf, *s);
1334 break;
1335 }
1336 ++s;
1337 }
1338 if (*s++ == NUL)
1339 errmsg = e_missing_colon;
1340 else if (*s == ',' || *s == NUL)
1341 errmsg = e_zero_length_string;
1342 if (errmsg != NULL)
1343 break;
1344 while (*s && *s != ',')
1345 {
1346 if (*s == '\\' && s[1] != NUL)
1347 ++s;
1348 ++s;
1349 }
1350 s = skip_to_option_part(s);
1351 }
1352
1353 return errmsg;
1354 }
1355
1356 /*
1357 * The global 'listchars' or 'fillchars' option is changed.
1358 */
1359 static char *
1360 did_set_global_listfillchars(char_u **varp, int opt_flags)
1361 {
1362 char *errmsg = NULL;
1363 char_u **local_ptr = varp == &p_lcs
1364 ? &curwin->w_p_lcs : &curwin->w_p_fcs;
1365
1366 // only apply the global value to "curwin" when it does not have a
1367 // local value
1368 errmsg = set_chars_option(curwin, varp,
1369 **local_ptr == NUL || !(opt_flags & OPT_GLOBAL));
1370 if (errmsg != NULL)
1371 return errmsg;
1372
1373 tabpage_T *tp;
1374 win_T *wp;
1375
1376 // If the current window is set to use the global
1377 // 'listchars'/'fillchars' value, clear the window-local value.
1378 if (!(opt_flags & OPT_GLOBAL))
1379 clear_string_option(local_ptr);
1380 FOR_ALL_TAB_WINDOWS(tp, wp)
1381 {
1382 // If the current window has a local value need to apply it
1383 // again, it was changed when setting the global value.
1384 // If no error was returned above, we don't expect an error
1385 // here, so ignore the return value.
1386 local_ptr = varp == &p_lcs ? &wp->w_p_lcs : &wp->w_p_fcs;
1387 if (**local_ptr == NUL)
1388 (void)set_chars_option(wp, local_ptr, TRUE);
1389 }
1390
1391 redraw_all_later(UPD_NOT_VALID);
1392
1393 return NULL;
1394 }
1395
1396 /*
1397 * The 'verbosefile' option is changed.
1398 */
1399 static char *
1400 did_set_verbosefile(void)
1401 {
1402 verbose_stop();
1403 if (*p_vfile != NUL && verbose_open() == FAIL)
1404 return e_invalid_argument;
1405
1406 return NULL;
1407 }
1408
1409 #ifdef FEAT_VIMINFO
1410 /*
1411 * The 'viminfo' option is changed.
1412 */
1413 static char *
1414 did_set_viminfo(char *errbuf)
1415 {
1416 char_u *s;
1417 char *errmsg = NULL;
1418
1419 for (s = p_viminfo; *s;)
1420 {
1421 // Check it's a valid character
1422 if (vim_strchr((char_u *)"!\"%'/:<@cfhnrs", *s) == NULL)
1423 {
1424 errmsg = illegal_char(errbuf, *s);
1425 break;
1426 }
1427 if (*s == 'n') // name is always last one
1428 break;
1429 else if (*s == 'r') // skip until next ','
1430 {
1431 while (*++s && *s != ',')
1432 ;
1433 }
1434 else if (*s == '%')
1435 {
1436 // optional number
1437 while (vim_isdigit(*++s))
1438 ;
1439 }
1440 else if (*s == '!' || *s == 'h' || *s == 'c')
1441 ++s; // no extra chars
1442 else // must have a number
1443 {
1444 while (vim_isdigit(*++s))
1445 ;
1446
1447 if (!VIM_ISDIGIT(*(s - 1)))
1448 {
1449 if (errbuf != NULL)
1450 {
1451 sprintf(errbuf,
1452 _(e_missing_number_after_angle_str_angle),
1453 transchar_byte(*(s - 1)));
1454 errmsg = errbuf;
1455 }
1456 else
1457 errmsg = "";
1458 break;
1459 }
1460 }
1461 if (*s == ',')
1462 ++s;
1463 else if (*s)
1464 {
1465 if (errbuf != NULL)
1466 errmsg = e_missing_comma;
1467 else
1468 errmsg = "";
1469 break;
1470 }
1471 }
1472 if (*p_viminfo && errmsg == NULL && get_viminfo_parameter('\'') < 0)
1473 errmsg = e_must_specify_a_value;
1474
1475 return errmsg;
1476 }
1477 #endif
1478
1479 /*
1480 * Some terminal option (t_xxx) is changed
1481 */
1482 static void
1483 did_set_term_option(char_u **varp, int *did_swaptcap UNUSED)
1484 {
1485 // ":set t_Co=0" and ":set t_Co=1" do ":set t_Co="
1486 if (varp == &T_CCO)
1487 {
1488 int colors = atoi((char *)T_CCO);
1489
1490 // Only reinitialize colors if t_Co value has really changed to
1491 // avoid expensive reload of colorscheme if t_Co is set to the
1492 // same value multiple times.
1493 if (colors != t_colors)
1494 {
1495 t_colors = colors;
1496 if (t_colors <= 1)
1497 {
1498 vim_free(T_CCO);
1499 T_CCO = empty_option;
1500 }
1501 #if defined(FEAT_VTP) && defined(FEAT_TERMGUICOLORS)
1502 if (is_term_win32())
1503 {
1504 swap_tcap();
1505 *did_swaptcap = TRUE;
1506 }
1507 #endif
1508 // We now have a different color setup, initialize it again.
1509 init_highlight(TRUE, FALSE);
1510 }
1511 }
1512 ttest(FALSE);
1513 if (varp == &T_ME)
1514 {
1515 out_str(T_ME);
1516 redraw_later(UPD_CLEAR);
1517 #if defined(MSWIN) && (!defined(FEAT_GUI_MSWIN) || defined(VIMDLL))
1518 // Since t_me has been set, this probably means that the user
1519 // wants to use this as default colors. Need to reset default
1520 // background/foreground colors.
1521 # ifdef VIMDLL
1522 if (!gui.in_use && !gui.starting)
1523 # endif
1524 mch_set_normal_colors();
1525 #endif
1526 }
1527 if (varp == &T_BE && termcap_active)
1528 {
1529 MAY_WANT_TO_LOG_THIS;
1530
1531 if (*T_BE == NUL)
1532 // When clearing t_BE we assume the user no longer wants
1533 // bracketed paste, thus disable it by writing t_BD.
1534 out_str(T_BD);
1535 else
1536 out_str(T_BE);
1537 }
1538 }
1539
1540 #ifdef FEAT_LINEBREAK
1541 /*
1542 * The 'showbreak' option is changed.
1543 */
1544 static char *
1545 did_set_showbreak(char_u **varp)
1546 {
1547 char_u *s;
1548
1549 for (s = *varp; *s; )
1550 {
1551 if (ptr2cells(s) != 1)
1552 return e_showbreak_contains_unprintable_or_wide_character;
1553 MB_PTR_ADV(s);
1554 }
1555
1556 return NULL;
1557 }
1558 #endif
1559
1560 #ifdef FEAT_GUI
1561 /*
1562 * The 'guifont' option is changed.
1563 */
1564 static char *
1565 did_set_guifont(char_u *oldval, int *redraw_gui_only)
1566 {
1567 char_u *p;
1568 char *errmsg = NULL;
1569
1570 if (gui.in_use)
1571 {
1572 p = p_guifont;
1573 # if defined(FEAT_GUI_GTK)
1574 // Put up a font dialog and let the user select a new value.
1575 // If this is cancelled go back to the old value but don't
1576 // give an error message.
1577 if (STRCMP(p, "*") == 0)
1578 {
1579 p = gui_mch_font_dialog(oldval);
1580 free_string_option(p_guifont);
1581 p_guifont = (p != NULL) ? p : vim_strsave(oldval);
1582 }
1583 # endif
1584 if (p != NULL && gui_init_font(p_guifont, FALSE) != OK)
1585 {
1586 # if defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_PHOTON)
1587 if (STRCMP(p_guifont, "*") == 0)
1588 {
1589 // Dialog was cancelled: Keep the old value without giving
1590 // an error message.
1591 free_string_option(p_guifont);
1592 p_guifont = vim_strsave(oldval);
1593 }
1594 else
1595 # endif
1596 errmsg = e_invalid_fonts;
1597 }
1598 }
1599 *redraw_gui_only = TRUE;
1600
1601 return errmsg;
1602 }
1603
1604 # ifdef FEAT_XFONTSET
1605 /*
1606 * The 'guifontset' option is changed.
1607 */
1608 static char *
1609 did_set_guifontset(int *redraw_gui_only)
1610 {
1611 char *errmsg = NULL;
1612
1613 if (STRCMP(p_guifontset, "*") == 0)
1614 errmsg = e_cant_select_fontset;
1615 else if (gui.in_use && gui_init_font(p_guifontset, TRUE) != OK)
1616 errmsg = e_invalid_fontset;
1617 *redraw_gui_only = TRUE;
1618
1619 return errmsg;
1620 }
1621 # endif
1622
1623 /*
1624 * The 'guifontwide' option is changed.
1625 */
1626 static char *
1627 did_set_guifontwide(int *redraw_gui_only)
1628 {
1629 char *errmsg = NULL;
1630
1631 if (STRCMP(p_guifontwide, "*") == 0)
1632 errmsg = e_cant_select_wide_font;
1633 else if (gui_get_wide_font() == FAIL)
1634 errmsg = e_invalid_wide_font;
1635 *redraw_gui_only = TRUE;
1636
1637 return errmsg;
1638 }
1639 #endif
1640
1641 #if defined(FEAT_GUI_GTK)
1642 static void
1643 did_set_guiligatures(int *redraw_gui_only)
1644 {
1645 gui_set_ligatures();
1646 *redraw_gui_only = TRUE;
1647 }
1648 #endif
1649
1650 #ifdef FEAT_MOUSESHAPE
1651 static char *
1652 did_set_mouseshape(void)
1653 {
1654 char *errmsg = NULL;
1655
1656 errmsg = parse_shape_opt(SHAPE_MOUSE);
1657 update_mouseshape(-1);
1658
1659 return errmsg;
1660 }
1661 #endif
1662
1663 /*
1664 * The 'titlestring' or the 'iconstring' option is changed.
1665 */
1666 static void
1667 did_set_titleiconstring(char_u **varp UNUSED)
1668 {
1669 #ifdef FEAT_STL_OPT
1670 int flagval = (varp == &p_titlestring) ? STL_IN_TITLE : STL_IN_ICON;
1671
1672 // NULL => statusline syntax
1673 if (vim_strchr(*varp, '%') && check_stl_option(*varp) == NULL)
1674 stl_syntax |= flagval;
1675 else
1676 stl_syntax &= ~flagval;
1677 #endif
1678 did_set_title();
1679 }
1680
1681 #ifdef FEAT_GUI
1682 /*
1683 * The 'guioptions' option is changed.
1684 */
1685 static void
1686 did_set_guioptions(char_u *oldval, int *redraw_gui_only)
1687 {
1688 gui_init_which_components(oldval);
1689 *redraw_gui_only = TRUE;
1690 }
1691 #endif
1692
1693 #if defined(FEAT_GUI_TABLINE)
1694 static void
1695 did_set_guitablabel(int *redraw_gui_only)
1696 {
1697 redraw_tabline = TRUE;
1698 *redraw_gui_only = TRUE;
1699 }
1700 #endif
1701
1702 #if defined(UNIX) || defined(VMS)
1703 /*
1704 * The 'ttymouse' option is changed.
1705 */
1706 static char *
1707 did_set_ttymouse(void)
1708 {
1709 char *errmsg = NULL;
1710
1711 // Switch the mouse off before changing the escape sequences used for
1712 // that.
1713 mch_setmouse(FALSE);
1714 if (opt_strings_flags(p_ttym, p_ttym_values, &ttym_flags, FALSE) != OK)
1715 errmsg = e_invalid_argument;
1716 else
1717 check_mouse_termcode();
1718 if (termcap_active)
1719 setmouse(); // may switch it on again
1720
1721 return errmsg;
1722 }
1723 #endif
1724
1725 /*
1726 * The 'selection' option is changed.
1727 */
1728 static char *
1729 did_set_selection(void)
1730 {
1731 if (*p_sel == NUL
1732 || check_opt_strings(p_sel, p_sel_values, FALSE) != OK)
1733 return e_invalid_argument;
1734
1735 return NULL;
1736 }
1737
1738 #ifdef FEAT_BROWSE
1739 /*
1740 * The 'browsedir' option is changed.
1741 */
1742 static char *
1743 did_set_browsedir(void)
1744 {
1745 if (check_opt_strings(p_bsdir, p_bsdir_values, FALSE) != OK
1746 && !mch_isdir(p_bsdir))
1747 return e_invalid_argument;
1748
1749 return NULL;
1750 }
1751 #endif
1752
1753 /*
1754 * The 'keymodel' option is changed.
1755 */
1756 static char *
1757 did_set_keymodel(void)
1758 {
1759 if (check_opt_strings(p_km, p_km_values, TRUE) != OK)
1760 return e_invalid_argument;
1761
1762 km_stopsel = (vim_strchr(p_km, 'o') != NULL);
1763 km_startsel = (vim_strchr(p_km, 'a') != NULL);
1764 return NULL;
1765 }
1766
1767 /*
1768 * The 'keyprotocol' option is changed.
1769 */
1770 static char *
1771 did_set_keyprotocol(void)
1772 {
1773 if (match_keyprotocol(NULL) == KEYPROTOCOL_FAIL)
1774 return e_invalid_argument;
1775
1776 return NULL;
1777 }
1778
1779 /*
1780 * The 'mousemodel' option is changed.
1781 */
1782 static char *
1783 did_set_mousemodel(void)
1784 {
1785 if (check_opt_strings(p_mousem, p_mousem_values, FALSE) != OK)
1786 return e_invalid_argument;
1787 #if defined(FEAT_GUI_MOTIF) && defined(FEAT_MENU) && (XmVersion <= 1002)
1788 else if (*p_mousem != *oldval)
1789 // Changed from "extend" to "popup" or "popup_setpos" or vv: need
1790 // to create or delete the popup menus.
1791 gui_motif_update_mousemodel(root_menu);
1792 #endif
1793
1794 return NULL;
1795 }
1796
1797 /*
1798 * The 'display' option is changed.
1799 */
1800 static char *
1801 did_set_display(void)
1802 {
1803 if (opt_strings_flags(p_dy, p_dy_values, &dy_flags, TRUE) != OK)
1804 return e_invalid_argument;
1805
1806 (void)init_chartab();
1807 return NULL;
1808 }
1809
1810 #ifdef FEAT_SPELL
1811 /*
1812 * The 'spellfile' option is changed.
1813 */
1814 static char *
1815 did_set_spellfile(char_u **varp)
1816 {
1817 if (!valid_spellfile(*varp))
1818 return e_invalid_argument;
1819
1820 // If there is a window for this buffer in which 'spell' is set load the
1821 // wordlists.
1822 return did_set_spell_option(TRUE);
1823 }
1824
1825 /*
1826 * The 'spell' option is changed.
1827 */
1828 static char *
1829 did_set_spell(char_u **varp)
1830 {
1831 if (!valid_spelllang(*varp))
1832 return e_invalid_argument;
1833
1834 // If there is a window for this buffer in which 'spell' is set load the
1835 // wordlists.
1836 return did_set_spell_option(FALSE);
1837 }
1838
1839 /*
1840 * The 'spellcapcheck' option is changed.
1841 */
1842 static char *
1843 did_set_spellcapcheck(void)
1844 {
1845 // compile the regexp program.
1846 return compile_cap_prog(curwin->w_s);
1847 }
1848
1849 /*
1850 * The 'spelloptions' option is changed.
1851 */
1852 static char *
1853 did_set_spelloptions(char_u **varp)
1854 {
1855 if (**varp != NUL && STRCMP("camel", *varp) != 0)
1856 return e_invalid_argument;
1857
1858 return NULL;
1859 }
1860
1861 /*
1862 * The 'spellsuggest' option is changed.
1863 */
1864 static char *
1865 did_set_spellsuggest(void)
1866 {
1867 if (spell_check_sps() != OK)
1868 return e_invalid_argument;
1869
1870 return NULL;
1871 }
1872
1873 /*
1874 * The 'mkspellmem' option is changed.
1875 */
1876 static char *
1877 did_set_mkspellmem(void)
1878 {
1879 if (spell_check_msm() != OK)
1880 return e_invalid_argument;
1881
1882 return NULL;
1883 }
1884 #endif
1885
1886 /*
1887 * The 'buftype' option is changed.
1888 */
1889 static char *
1890 did_set_buftype(void)
1891 {
1892 if (check_opt_strings(curbuf->b_p_bt, p_buftype_values, FALSE) != OK)
1893 return e_invalid_argument;
1894
1895 if (curwin->w_status_height)
1896 {
1897 curwin->w_redr_status = TRUE;
1898 redraw_later(UPD_VALID);
1899 }
1900 curbuf->b_help = (curbuf->b_p_bt[0] == 'h');
1901 redraw_titles();
1902
1903 return NULL;
1904 }
1905
1906 #ifdef FEAT_STL_OPT
1907 /*
1908 * The 'statusline' or the 'tabline' or the 'rulerformat' option is changed.
1909 */
1910 static char *
1911 did_set_statusline(char_u **varp)
1912 {
1913 char_u *s;
1914 char *errmsg = NULL;
1915 int wid;
1916
1917 if (varp == &p_ruf) // reset ru_wid first
1918 ru_wid = 0;
1919 s = *varp;
1920 if (varp == &p_ruf && *s == '%')
1921 {
1922 // set ru_wid if 'ruf' starts with "%99("
1923 if (*++s == '-') // ignore a '-'
1924 s++;
1925 wid = getdigits(&s);
1926 if (wid && *s == '(' && (errmsg = check_stl_option(p_ruf)) == NULL)
1927 ru_wid = wid;
1928 else
1929 errmsg = check_stl_option(p_ruf);
1930 }
1931 // check 'statusline' or 'tabline' only if it doesn't start with "%!"
1932 else if (varp == &p_ruf || s[0] != '%' || s[1] != '!')
1933 errmsg = check_stl_option(s);
1934 if (varp == &p_ruf && errmsg == NULL)
1935 comp_col();
1936
1937 return errmsg;
1938 }
1939 #endif
1940
1941 /*
1942 * The 'complete' option is changed.
1943 */
1944 static char *
1945 did_set_complete(char_u **varp, char *errbuf)
1946 {
1947 char_u *s;
1948
1949 // check if it is a valid value for 'complete' -- Acevedo
1950 for (s = *varp; *s;)
1951 {
1952 while (*s == ',' || *s == ' ')
1953 s++;
1954 if (!*s)
1955 break;
1956 if (vim_strchr((char_u *)".wbuksid]tU", *s) == NULL)
1957 return illegal_char(errbuf, *s);
1958 if (*++s != NUL && *s != ',' && *s != ' ')
1959 {
1960 if (s[-1] == 'k' || s[-1] == 's')
1961 {
1962 // skip optional filename after 'k' and 's'
1963 while (*s && *s != ',' && *s != ' ')
1964 {
1965 if (*s == '\\' && s[1] != NUL)
1966 ++s;
1967 ++s;
1968 }
1969 }
1970 else
1971 {
1972 if (errbuf != NULL)
1973 {
1974 sprintf((char *)errbuf,
1975 _(e_illegal_character_after_chr), *--s);
1976 return errbuf;
1977 }
1978 return "";
1979 }
1980 }
1981 }
1982
1983 return NULL;
1984 }
1985
1986 /*
1987 * The 'completeopt' option is changed.
1988 */
1989 static char *
1990 did_set_completeopt(void)
1991 {
1992 if (check_opt_strings(p_cot, p_cot_values, TRUE) != OK)
1993 return e_invalid_argument;
1994
1995 completeopt_was_set();
1996 return NULL;
1997 }
1998
1999 #ifdef FEAT_SIGNS
2000 /*
2001 * The 'signcolumn' option is changed.
2002 */
2003 static char *
2004 did_set_signcolumn(char_u **varp, char_u *oldval)
2005 {
2006 if (check_opt_strings(*varp, p_scl_values, FALSE) != OK)
2007 return e_invalid_argument;
2008 // When changing the 'signcolumn' to or from 'number', recompute the
2009 // width of the number column if 'number' or 'relativenumber' is set.
2010 if (((*oldval == 'n' && *(oldval + 1) == 'u')
2011 || (*curwin->w_p_scl == 'n' && *(curwin->w_p_scl + 1) =='u'))
2012 && (curwin->w_p_nu || curwin->w_p_rnu))
2013 curwin->w_nrwidth_line_count = 0;
2014
2015 return NULL;
2016 }
2017 #endif
2018
2019 #if defined(FEAT_TOOLBAR) && !defined(FEAT_GUI_MSWIN)
2020 /*
2021 * The 'toolbar' option is changed.
2022 */
2023 static char *
2024 did_set_toolbar(void)
2025 {
2026 if (opt_strings_flags(p_toolbar, p_toolbar_values,
2027 &toolbar_flags, TRUE) != OK)
2028 return e_invalid_argument;
2029
2030 out_flush();
2031 gui_mch_show_toolbar((toolbar_flags &
2032 (TOOLBAR_TEXT | TOOLBAR_ICONS)) != 0);
2033 return NULL;
2034 }
2035 #endif
2036
2037 #if defined(FEAT_TOOLBAR) && defined(FEAT_GUI_GTK)
2038 /*
2039 * The 'toolbariconsize' option is changed. GTK+ 2 only.
2040 */
2041 static char *
2042 did_set_toolbariconsize(void)
2043 {
2044 if (opt_strings_flags(p_tbis, p_tbis_values, &tbis_flags, FALSE) != OK)
2045 return e_invalid_argument;
2046
2047 out_flush();
2048 gui_mch_show_toolbar((toolbar_flags &
2049 (TOOLBAR_TEXT | TOOLBAR_ICONS)) != 0);
2050 return NULL;
2051 }
2052 #endif
2053
2054 /*
2055 * The 'pastetoggle' option is changed.
2056 */
2057 static void
2058 did_set_pastetoggle(void)
2059 {
2060 char_u *p;
2061
2062 // translate key codes like in a mapping
2063 if (*p_pt)
2064 {
2065 (void)replace_termcodes(p_pt, &p,
2066 REPTERM_FROM_PART | REPTERM_DO_LT, NULL);
2067 if (p != NULL)
2068 {
2069 free_string_option(p_pt);
2070 p_pt = p;
2071 }
2072 }
2073 }
2074
2075 /*
2076 * The 'backspace' option is changed.
2077 */
2078 static char *
2079 did_set_backspace(void)
2080 {
2081 if (VIM_ISDIGIT(*p_bs))
2082 {
2083 if (*p_bs > '3' || p_bs[1] != NUL)
2084 return e_invalid_argument;
2085 }
2086 else if (check_opt_strings(p_bs, p_bs_values, TRUE) != OK)
2087 return e_invalid_argument;
2088
2089 return NULL;
2090 }
2091
2092 /*
2093 * The 'tagcase' option is changed.
2094 */
2095 static char *
2096 did_set_tagcase(int opt_flags)
2097 {
2098 unsigned int *flags;
2099 char_u *p;
2100
2101 if (opt_flags & OPT_LOCAL)
2102 {
2103 p = curbuf->b_p_tc;
2104 flags = &curbuf->b_tc_flags;
2105 }
2106 else
2107 {
2108 p = p_tc;
2109 flags = &tc_flags;
2110 }
2111
2112 if ((opt_flags & OPT_LOCAL) && *p == NUL)
2113 // make the local value empty: use the global value
2114 *flags = 0;
2115 else if (*p == NUL
2116 || opt_strings_flags(p, p_tc_values, flags, FALSE) != OK)
2117 return e_invalid_argument;
2118
2119 return NULL;
2120 }
2121
2122 #ifdef FEAT_DIFF
2123 /*
2124 * The 'diffopt' option is changed.
2125 */
2126 static char *
2127 did_set_diffopt(void)
2128 {
2129 if (diffopt_changed() == FAIL)
2130 return e_invalid_argument;
2131
2132 return NULL;
2133 }
2134 #endif
2135
2136 #ifdef FEAT_FOLDING
2137 /*
2138 * The 'foldmethod' option is changed.
2139 */
2140 static char *
2141 did_set_foldmethod(char_u **varp)
2142 {
2143 if (check_opt_strings(*varp, p_fdm_values, FALSE) != OK
2144 || *curwin->w_p_fdm == NUL)
2145 return e_invalid_argument;
2146
2147 foldUpdateAll(curwin);
2148 if (foldmethodIsDiff(curwin))
2149 newFoldLevel();
2150 return NULL;
2151 }
2152
2153 /*
2154 * The 'foldmarker' option is changed.
2155 */
2156 static char *
2157 did_set_foldmarker(char_u **varp)
2158 {
2159 char_u *p;
2160
2161 p = vim_strchr(*varp, ',');
2162 if (p == NULL)
2163 return e_comma_required;
2164 else if (p == *varp || p[1] == NUL)
2165 return e_invalid_argument;
2166 else if (foldmethodIsMarker(curwin))
2167 foldUpdateAll(curwin);
2168
2169 return NULL;
2170 }
2171
2172 /*
2173 * The 'commentstring' option is changed.
2174 */
2175 static char *
2176 did_set_commentstring(char_u **varp)
2177 {
2178 if (**varp != NUL && strstr((char *)*varp, "%s") == NULL)
2179 return e_commentstring_must_be_empty_or_contain_str;
2180
2181 return NULL;
2182 }
2183
2184 /*
2185 * The 'foldignore' option is changed.
2186 */
2187 static void
2188 did_set_foldignore(void)
2189 {
2190 if (foldmethodIsIndent(curwin))
2191 foldUpdateAll(curwin);
2192 }
2193 #endif
2194
2195 /*
2196 * The 'virtualedit' option is changed.
2197 */
2198 static char *
2199 did_set_virtualedit(char_u *oldval, int opt_flags)
2200 {
2201 char_u *ve = p_ve;
2202 unsigned int *flags = &ve_flags;
2203
2204 if (opt_flags & OPT_LOCAL)
2205 {
2206 ve = curwin->w_p_ve;
2207 flags = &curwin->w_ve_flags;
2208 }
2209
2210 if ((opt_flags & OPT_LOCAL) && *ve == NUL)
2211 // make the local value empty: use the global value
2212 *flags = 0;
2213 else
2214 {
2215 if (opt_strings_flags(ve, p_ve_values, flags, TRUE) != OK)
2216 return e_invalid_argument;
2217 else if (STRCMP(ve, oldval) != 0)
2218 {
2219 // Recompute cursor position in case the new 've' setting
2220 // changes something.
2221 validate_virtcol();
2222 coladvance(curwin->w_virtcol);
2223 }
2224 }
2225
2226 return NULL;
2227 }
2228
2229 #if defined(FEAT_CSCOPE) && defined(FEAT_QUICKFIX)
2230 /*
2231 * The 'cscopequickfix' option is changed.
2232 */
2233 static char *
2234 did_set_cscopequickfix(void)
2235 {
2236 char_u *p;
2237
2238 if (p_csqf == NULL)
2239 return NULL;
2240
2241 p = p_csqf;
2242 while (*p != NUL)
2243 {
2244 if (vim_strchr((char_u *)CSQF_CMDS, *p) == NULL
2245 || p[1] == NUL
2246 || vim_strchr((char_u *)CSQF_FLAGS, p[1]) == NULL
2247 || (p[2] != NUL && p[2] != ','))
2248 return e_invalid_argument;
2249 else if (p[2] == NUL)
2250 break;
2251 else
2252 p += 3;
2253 }
2254
2255 return NULL;
2256 }
2257 #endif
2258
2259 /*
2260 * The 'cinoptions' option is changed.
2261 */
2262 static void
2263 did_set_cinoptions(void)
2264 {
2265 // TODO: recognize errors
2266 parse_cino(curbuf);
2267 }
2268
2269 /*
2270 * The 'lispoptions' option is changed.
2271 */
2272 static char *
2273 did_set_lispoptions(char_u **varp)
2274 {
2275 if (**varp != NUL && STRCMP(*varp, "expr:0") != 0
2276 && STRCMP(*varp, "expr:1") != 0)
2277 return e_invalid_argument;
2278
2279 return NULL;
2280 }
2281
2282 #if defined(FEAT_RENDER_OPTIONS)
2283 /*
2284 * The 'renderoptions' option is changed.
2285 */
2286 static char *
2287 did_set_renderoptions(void)
2288 {
2289 if (!gui_mch_set_rendering_options(p_rop))
2290 return e_invalid_argument;
2291
2292 return NULL;
2293 }
2294 #endif
2295
2296 /*
2297 * The 'filetype' or the 'syntax' option is changed.
2298 */
2299 static char *
2300 did_set_filetype_or_syntax(
2301 char_u **varp,
2302 char_u *oldval,
2303 int *value_checked,
2304 int *value_changed)
2305 {
2306 if (!valid_filetype(*varp))
2307 return e_invalid_argument;
2308
2309 *value_changed = STRCMP(oldval, *varp) != 0;
2310
2311 // Since we check the value, there is no need to set P_INSECURE,
2312 // even when the value comes from a modeline.
2313 *value_checked = TRUE;
2314
2315 return NULL;
2316 }
2317
2318 #ifdef FEAT_TERMINAL
2319 /*
2320 * The 'termwinkey' option is changed.
2321 */
2322 static char *
2323 did_set_termwinkey(void)
2324 {
2325 if (*curwin->w_p_twk != NUL
2326 && string_to_key(curwin->w_p_twk, TRUE) == 0)
2327 return e_invalid_argument;
2328
2329 return NULL;
2330 }
2331
2332 /*
2333 * The 'termwinsize' option is changed.
2334 */
2335 static char *
2336 did_set_termwinsize(void)
2337 {
2338 char_u *p;
2339
2340 if (*curwin->w_p_tws == NUL)
2341 return NULL;
2342
2343 p = skipdigits(curwin->w_p_tws);
2344 if (p == curwin->w_p_tws
2345 || (*p != 'x' && *p != '*')
2346 || *skipdigits(p + 1) != NUL)
2347 return e_invalid_argument;
2348
2349 return NULL;
2350 }
2351 #endif
2352
2353 #ifdef FEAT_VARTABS
2354 /*
2355 * The 'varsofttabstop' option is changed.
2356 */
2357 static char *
2358 did_set_varsofttabstop(char_u **varp)
2359 {
2360 char_u *cp;
2361
2362 if (!(*varp)[0] || ((*varp)[0] == '0' && !(*varp)[1]))
2363 {
2364 if (curbuf->b_p_vsts_array)
2365 {
2366 vim_free(curbuf->b_p_vsts_array);
2367 curbuf->b_p_vsts_array = 0;
2368 }
2369 }
2370 else
2371 {
2372 for (cp = *varp; *cp; ++cp)
2373 {
2374 if (vim_isdigit(*cp))
2375 continue;
2376 if (*cp == ',' && cp > *varp && *(cp-1) != ',')
2377 continue;
2378 return e_invalid_argument;
2379 }
2380
2381 int *oldarray = curbuf->b_p_vsts_array;
2382 if (tabstop_set(*varp, &(curbuf->b_p_vsts_array)) == OK)
2383 {
2384 if (oldarray)
2385 vim_free(oldarray);
2386 }
2387 else
2388 return e_invalid_argument;
2389 }
2390
2391 return NULL;
2392 }
2393
2394 /*
2395 * The 'vartabstop' option is changed.
2396 */
2397 static char *
2398 did_set_vartabstop(char_u **varp)
2399 {
2400 char_u *cp;
2401
2402 if (!(*varp)[0] || ((*varp)[0] == '0' && !(*varp)[1]))
2403 {
2404 if (curbuf->b_p_vts_array)
2405 {
2406 vim_free(curbuf->b_p_vts_array);
2407 curbuf->b_p_vts_array = NULL;
2408 }
2409 }
2410 else
2411 {
2412 for (cp = *varp; *cp; ++cp)
2413 {
2414 if (vim_isdigit(*cp))
2415 continue;
2416 if (*cp == ',' && cp > *varp && *(cp-1) != ',')
2417 continue;
2418 return e_invalid_argument;
2419 }
2420
2421 int *oldarray = curbuf->b_p_vts_array;
2422
2423 if (tabstop_set(*varp, &(curbuf->b_p_vts_array)) == OK)
2424 {
2425 vim_free(oldarray);
2426 # ifdef FEAT_FOLDING
2427 if (foldmethodIsIndent(curwin))
2428 foldUpdateAll(curwin);
2429 # endif
2430 }
2431 else
2432 return e_invalid_argument;
2433 }
2434
2435 return NULL;
2436 }
2437 #endif
2438
2439 #ifdef FEAT_PROP_POPUP
2440 /*
2441 * The 'previewpopup' option is changed.
2442 */
2443 static char *
2444 did_set_previewpopup(void)
2445 {
2446 if (parse_previewpopup(NULL) == FAIL)
2447 return e_invalid_argument;
2448
2449 return NULL;
2450 }
2451
2452 # ifdef FEAT_QUICKFIX
2453 /*
2454 * The 'completepopup' option is changed.
2455 */
2456 static char *
2457 did_set_completepopup(void)
2458 {
2459 if (parse_completepopup(NULL) == FAIL)
2460 return e_invalid_argument;
2461
2462 popup_close_info();
2463 return NULL;
2464 }
2465 # endif
2466 #endif
2467
2468 #ifdef FEAT_EVAL
2469 /*
2470 * One of the '*expr' options is changed: 'balloonexpr', 'diffexpr',
2471 * 'foldexpr', 'foldtext', 'formatexpr', 'includeexpr', 'indentexpr',
2472 * 'patchexpr', 'printexpr' and 'charconvert'.
2473 *
2474 */
2475 static void
2476 did_set_optexpr(char_u **varp)
2477 {
2478 // If the option value starts with <SID> or s:, then replace that with
2479 // the script identifier.
2480 char_u *name = get_scriptlocal_funcname(*varp);
2481 if (name != NULL)
2482 {
2483 free_string_option(*varp);
2484 *varp = name;
2485 }
2486
2487 # ifdef FEAT_FOLDING
2488 if (varp == &curwin->w_p_fde && foldmethodIsExpr(curwin))
2489 foldUpdateAll(curwin);
2490 # endif
2491 }
2492 #endif
2493
2494 /*
643 * Handle string options that need some action to perform when changed. 2495 * Handle string options that need some action to perform when changed.
644 * The new value must be allocated. 2496 * The new value must be allocated.
645 * Returns NULL for success, or an unstranslated error message for an error. 2497 * Returns NULL for success, or an unstranslated error message for an error.
646 */ 2498 */
647 char * 2499 char *
662 #ifdef FEAT_GUI 2514 #ifdef FEAT_GUI
663 // set when changing an option that only requires a redraw in the GUI 2515 // set when changing an option that only requires a redraw in the GUI
664 int redraw_gui_only = FALSE; 2516 int redraw_gui_only = FALSE;
665 #endif 2517 #endif
666 int value_changed = FALSE; 2518 int value_changed = FALSE;
667 #if defined(FEAT_VTP) && defined(FEAT_TERMGUICOLORS)
668 int did_swaptcap = FALSE; 2519 int did_swaptcap = FALSE;
669 #endif
670 2520
671 // Get the global option to compare with, otherwise we would have to check 2521 // Get the global option to compare with, otherwise we would have to check
672 // two values for all local options. 2522 // two values for all local options.
673 gvarp = (char_u **)get_option_varp_scope(opt_idx, OPT_GLOBAL); 2523 gvarp = (char_u **)get_option_varp_scope(opt_idx, OPT_GLOBAL);
674 2524
690 && vim_strpbrk(*varp, (char_u *)"*?[|;&<>\r\n") != NULL)) 2540 && vim_strpbrk(*varp, (char_u *)"*?[|;&<>\r\n") != NULL))
691 errmsg = e_invalid_argument; 2541 errmsg = e_invalid_argument;
692 2542
693 // 'term' 2543 // 'term'
694 else if (varp == &T_NAME) 2544 else if (varp == &T_NAME)
695 { 2545 errmsg = did_set_term(&opt_idx, &free_oldval);
696 if (T_NAME[0] == NUL)
697 errmsg = e_cannot_set_term_to_empty_string;
698 #ifdef FEAT_GUI
699 else if (gui.in_use)
700 errmsg = e_cannot_change_term_in_GUI;
701 else if (term_is_gui(T_NAME))
702 errmsg = e_use_gui_to_start_GUI;
703 #endif
704 else if (set_termname(T_NAME) == FAIL)
705 errmsg = e_not_found_in_termcap;
706 else
707 {
708 // Screen colors may have changed.
709 redraw_later_clear();
710
711 // Both 'term' and 'ttytype' point to T_NAME, only set the
712 // P_ALLOCED flag on 'term'.
713 opt_idx = findoption((char_u *)"term");
714 free_oldval = (get_option_flags(opt_idx) & P_ALLOCED);
715 }
716 }
717 2546
718 // 'backupcopy' 2547 // 'backupcopy'
719 else if (gvarp == &p_bkc) 2548 else if (gvarp == &p_bkc)
720 { 2549 errmsg = did_set_backupcopy(oldval, opt_flags);
721 char_u *bkc = p_bkc;
722 unsigned int *flags = &bkc_flags;
723
724 if (opt_flags & OPT_LOCAL)
725 {
726 bkc = curbuf->b_p_bkc;
727 flags = &curbuf->b_bkc_flags;
728 }
729
730 if ((opt_flags & OPT_LOCAL) && *bkc == NUL)
731 // make the local value empty: use the global value
732 *flags = 0;
733 else
734 {
735 if (opt_strings_flags(bkc, p_bkc_values, flags, TRUE) != OK)
736 errmsg = e_invalid_argument;
737 if ((((int)*flags & BKC_AUTO) != 0)
738 + (((int)*flags & BKC_YES) != 0)
739 + (((int)*flags & BKC_NO) != 0) != 1)
740 {
741 // Must have exactly one of "auto", "yes" and "no".
742 (void)opt_strings_flags(oldval, p_bkc_values, flags, TRUE);
743 errmsg = e_invalid_argument;
744 }
745 }
746 }
747 2550
748 // 'backupext' and 'patchmode' 2551 // 'backupext' and 'patchmode'
749 else if (varp == &p_bex || varp == &p_pm) 2552 else if (varp == &p_bex || varp == &p_pm)
750 { 2553 errmsg = did_set_backupext_or_patchmode();
751 if (STRCMP(*p_bex == '.' ? p_bex + 1 : p_bex, 2554
752 *p_pm == '.' ? p_pm + 1 : p_pm) == 0)
753 errmsg = e_backupext_and_patchmode_are_equal;
754 }
755 #ifdef FEAT_LINEBREAK 2555 #ifdef FEAT_LINEBREAK
756 // 'breakindentopt' 2556 // 'breakindentopt'
757 else if (varp == &curwin->w_p_briopt) 2557 else if (varp == &curwin->w_p_briopt)
758 { 2558 errmsg = did_set_breakindentopt();
759 if (briopt_check(curwin) == FAIL)
760 errmsg = e_invalid_argument;
761 // list setting requires a redraw
762 if (curwin->w_briopt_list)
763 redraw_all_later(UPD_NOT_VALID);
764 }
765 #endif 2559 #endif
766 2560
767 // 'isident', 'iskeyword', 'isprint or 'isfname' option: refill g_chartab[] 2561 // 'isident', 'iskeyword', 'isprint or 'isfname' option: refill g_chartab[]
768 // If the new option is invalid, use old value. 'lisp' option: refill 2562 // If the new option is invalid, use old value. 'lisp' option: refill
769 // g_chartab[] for '-' char 2563 // g_chartab[] for '-' char
770 else if ( varp == &p_isi 2564 else if ( varp == &p_isi
771 || varp == &(curbuf->b_p_isk) 2565 || varp == &(curbuf->b_p_isk)
772 || varp == &p_isp 2566 || varp == &p_isp
773 || varp == &p_isf) 2567 || varp == &p_isf)
774 { 2568 errmsg = did_set_isopt(&did_chartab);
775 if (init_chartab() == FAIL)
776 {
777 did_chartab = TRUE; // need to restore it below
778 errmsg = e_invalid_argument; // error in value
779 }
780 }
781 2569
782 // 'helpfile' 2570 // 'helpfile'
783 else if (varp == &p_hf) 2571 else if (varp == &p_hf)
784 { 2572 did_set_helpfile();
785 // May compute new values for $VIM and $VIMRUNTIME
786 if (didset_vim)
787 vim_unsetenv_ext((char_u *)"VIM");
788 if (didset_vimruntime)
789 vim_unsetenv_ext((char_u *)"VIMRUNTIME");
790 }
791 2573
792 #ifdef FEAT_SYN_HL 2574 #ifdef FEAT_SYN_HL
793 // 'cursorlineopt' 2575 // 'cursorlineopt'
794 else if (varp == &curwin->w_p_culopt 2576 else if (varp == &curwin->w_p_culopt
795 || gvarp == &curwin->w_allbuf_opt.wo_culopt) 2577 || gvarp == &curwin->w_allbuf_opt.wo_culopt)
796 { 2578 errmsg = did_set_cursorlineopt(varp);
797 if (**varp == NUL || fill_culopt_flags(*varp, curwin) != OK)
798 errmsg = e_invalid_argument;
799 }
800 2579
801 // 'colorcolumn' 2580 // 'colorcolumn'
802 else if (varp == &curwin->w_p_cc) 2581 else if (varp == &curwin->w_p_cc)
803 errmsg = check_colorcolumn(curwin); 2582 errmsg = check_colorcolumn(curwin);
804 #endif 2583 #endif
805 2584
806 #ifdef FEAT_MULTI_LANG 2585 #ifdef FEAT_MULTI_LANG
807 // 'helplang' 2586 // 'helplang'
808 else if (varp == &p_hlg) 2587 else if (varp == &p_hlg)
809 { 2588 errmsg = did_set_helplang();
810 // Check for "", "ab", "ab,cd", etc.
811 for (s = p_hlg; *s != NUL; s += 3)
812 {
813 if (s[1] == NUL || ((s[2] != ',' || s[3] == NUL) && s[2] != NUL))
814 {
815 errmsg = e_invalid_argument;
816 break;
817 }
818 if (s[2] == NUL)
819 break;
820 }
821 }
822 #endif 2589 #endif
823 2590
824 // 'highlight' 2591 // 'highlight'
825 else if (varp == &p_hl) 2592 else if (varp == &p_hl)
826 { 2593 errmsg = did_set_highlight();
827 if (highlight_changed() == FAIL)
828 errmsg = e_invalid_argument; // invalid flags
829 }
830 2594
831 // 'nrformats' 2595 // 'nrformats'
832 else if (gvarp == &p_nf) 2596 else if (gvarp == &p_nf)
833 { 2597 errmsg = did_set_opt_strings(*varp, p_nf_values, TRUE);
834 if (check_opt_strings(*varp, p_nf_values, TRUE) != OK)
835 errmsg = e_invalid_argument;
836 }
837 2598
838 #ifdef FEAT_SESSION 2599 #ifdef FEAT_SESSION
839 // 'sessionoptions' 2600 // 'sessionoptions'
840 else if (varp == &p_ssop) 2601 else if (varp == &p_ssop)
841 { 2602 errmsg = did_set_sessionoptions(oldval);
842 if (opt_strings_flags(p_ssop, p_ssop_values, &ssop_flags, TRUE) != OK) 2603
843 errmsg = e_invalid_argument;
844 if ((ssop_flags & SSOP_CURDIR) && (ssop_flags & SSOP_SESDIR))
845 {
846 // Don't allow both "sesdir" and "curdir".
847 (void)opt_strings_flags(oldval, p_ssop_values, &ssop_flags, TRUE);
848 errmsg = e_invalid_argument;
849 }
850 }
851 // 'viewoptions' 2604 // 'viewoptions'
852 else if (varp == &p_vop) 2605 else if (varp == &p_vop)
853 { 2606 errmsg = did_set_opt_flags(p_vop, p_ssop_values, &vop_flags, TRUE);
854 if (opt_strings_flags(p_vop, p_ssop_values, &vop_flags, TRUE) != OK)
855 errmsg = e_invalid_argument;
856 }
857 #endif 2607 #endif
858 2608
859 // 'scrollopt' 2609 // 'scrollopt'
860 else if (varp == &p_sbo) 2610 else if (varp == &p_sbo)
861 { 2611 errmsg = did_set_opt_strings(p_sbo, p_scbopt_values, TRUE);
862 if (check_opt_strings(p_sbo, p_scbopt_values, TRUE) != OK)
863 errmsg = e_invalid_argument;
864 }
865 2612
866 // 'ambiwidth' 2613 // 'ambiwidth'
867 else if (varp == &p_ambw || varp == &p_emoji) 2614 else if (varp == &p_ambw || varp == &p_emoji)
868 { 2615 errmsg = did_set_ambiwidth();
869 if (check_opt_strings(p_ambw, p_ambw_values, FALSE) != OK)
870 errmsg = e_invalid_argument;
871 else
872 errmsg = check_chars_options();
873 }
874 2616
875 // 'background' 2617 // 'background'
876 else if (varp == &p_bg) 2618 else if (varp == &p_bg)
877 { 2619 errmsg = did_set_background();
878 if (check_opt_strings(p_bg, p_bg_values, FALSE) == OK)
879 {
880 #ifdef FEAT_EVAL
881 int dark = (*p_bg == 'd');
882 #endif
883
884 init_highlight(FALSE, FALSE);
885
886 #ifdef FEAT_EVAL
887 if (dark != (*p_bg == 'd')
888 && get_var_value((char_u *)"g:colors_name") != NULL)
889 {
890 // The color scheme must have set 'background' back to another
891 // value, that's not what we want here. Disable the color
892 // scheme and set the colors again.
893 do_unlet((char_u *)"g:colors_name", TRUE);
894 free_string_option(p_bg);
895 p_bg = vim_strsave((char_u *)(dark ? "dark" : "light"));
896 check_string_option(&p_bg);
897 init_highlight(FALSE, FALSE);
898 }
899 #endif
900 #ifdef FEAT_TERMINAL
901 term_update_colors_all();
902 #endif
903 }
904 else
905 errmsg = e_invalid_argument;
906 }
907 2620
908 // 'wildmode' 2621 // 'wildmode'
909 else if (varp == &p_wim) 2622 else if (varp == &p_wim)
910 { 2623 errmsg = did_set_wildmode();
911 if (check_opt_wim() == FAIL)
912 errmsg = e_invalid_argument;
913 }
914 2624
915 // 'wildoptions' 2625 // 'wildoptions'
916 else if (varp == &p_wop) 2626 else if (varp == &p_wop)
917 { 2627 errmsg = did_set_opt_strings(p_wop, p_wop_values, TRUE);
918 if (check_opt_strings(p_wop, p_wop_values, TRUE) != OK)
919 errmsg = e_invalid_argument;
920 }
921 2628
922 #ifdef FEAT_WAK 2629 #ifdef FEAT_WAK
923 // 'winaltkeys' 2630 // 'winaltkeys'
924 else if (varp == &p_wak) 2631 else if (varp == &p_wak)
925 { 2632 errmsg = did_set_winaltkeys();
926 if (*p_wak == NUL
927 || check_opt_strings(p_wak, p_wak_values, FALSE) != OK)
928 errmsg = e_invalid_argument;
929 # ifdef FEAT_MENU
930 # if defined(FEAT_GUI_MOTIF)
931 else if (gui.in_use)
932 gui_motif_set_mnemonics(p_wak[0] == 'y' || p_wak[0] == 'm');
933 # elif defined(FEAT_GUI_GTK)
934 else if (gui.in_use)
935 gui_gtk_set_mnemonics(p_wak[0] == 'y' || p_wak[0] == 'm');
936 # endif
937 # endif
938 }
939 #endif 2633 #endif
940 2634
941 // 'eventignore' 2635 // 'eventignore'
942 else if (varp == &p_ei) 2636 else if (varp == &p_ei)
943 { 2637 errmsg = did_set_eventignore();
944 if (check_ei() == FAIL)
945 errmsg = e_invalid_argument;
946 }
947 2638
948 // 'encoding', 'fileencoding', 'termencoding' and 'makeencoding' 2639 // 'encoding', 'fileencoding', 'termencoding' and 'makeencoding'
949 else if (varp == &p_enc || gvarp == &p_fenc || varp == &p_tenc 2640 else if (varp == &p_enc || gvarp == &p_fenc || varp == &p_tenc
950 || gvarp == &p_menc) 2641 || gvarp == &p_menc)
951 { 2642 errmsg = did_set_encoding(varp, gvarp, opt_flags);
952 if (gvarp == &p_fenc)
953 {
954 if (!curbuf->b_p_ma && opt_flags != OPT_GLOBAL)
955 errmsg = e_cannot_make_changes_modifiable_is_off;
956 else if (vim_strchr(*varp, ',') != NULL)
957 // No comma allowed in 'fileencoding'; catches confusing it
958 // with 'fileencodings'.
959 errmsg = e_invalid_argument;
960 else
961 {
962 // May show a "+" in the title now.
963 redraw_titles();
964 // Add 'fileencoding' to the swap file.
965 ml_setflags(curbuf);
966 }
967 }
968 if (errmsg == NULL)
969 {
970 // canonize the value, so that STRCMP() can be used on it
971 p = enc_canonize(*varp);
972 if (p != NULL)
973 {
974 vim_free(*varp);
975 *varp = p;
976 }
977 if (varp == &p_enc)
978 {
979 errmsg = mb_init();
980 redraw_titles();
981 }
982 }
983
984 #if defined(FEAT_GUI_GTK)
985 if (errmsg == NULL && varp == &p_tenc && gui.in_use)
986 {
987 // GTK uses only a single encoding, and that is UTF-8.
988 if (STRCMP(p_tenc, "utf-8") != 0)
989 errmsg = e_cannot_be_changed_in_gtk_GUI;
990 }
991 #endif
992
993 if (errmsg == NULL)
994 {
995 #ifdef FEAT_KEYMAP
996 // When 'keymap' is used and 'encoding' changes, reload the keymap
997 // (with another encoding).
998 if (varp == &p_enc && *curbuf->b_p_keymap != NUL)
999 (void)keymap_init();
1000 #endif
1001
1002 // When 'termencoding' is not empty and 'encoding' changes or when
1003 // 'termencoding' changes, need to setup for keyboard input and
1004 // display output conversion.
1005 if (((varp == &p_enc && *p_tenc != NUL) || varp == &p_tenc))
1006 {
1007 if (convert_setup(&input_conv, p_tenc, p_enc) == FAIL
1008 || convert_setup(&output_conv, p_enc, p_tenc) == FAIL)
1009 {
1010 semsg(_(e_cannot_convert_between_str_and_str),
1011 p_tenc, p_enc);
1012 errmsg = e_invalid_argument;
1013 }
1014 }
1015
1016 #if defined(MSWIN)
1017 // $HOME may have characters in active code page.
1018 if (varp == &p_enc)
1019 init_homedir();
1020 #endif
1021 }
1022 }
1023 2643
1024 #if defined(FEAT_POSTSCRIPT) 2644 #if defined(FEAT_POSTSCRIPT)
1025 else if (varp == &p_penc) 2645 else if (varp == &p_penc)
1026 { 2646 did_set_printencoding();
1027 // Canonize printencoding if VIM standard one
1028 p = enc_canonize(p_penc);
1029 if (p != NULL)
1030 {
1031 vim_free(p_penc);
1032 p_penc = p;
1033 }
1034 else
1035 {
1036 // Ensure lower case and '-' for '_'
1037 for (s = p_penc; *s != NUL; s++)
1038 {
1039 if (*s == '_')
1040 *s = '-';
1041 else
1042 *s = TOLOWER_ASC(*s);
1043 }
1044 }
1045 }
1046 #endif 2647 #endif
1047 2648
1048 #if defined(FEAT_XIM) && defined(FEAT_GUI_GTK) 2649 #if defined(FEAT_XIM) && defined(FEAT_GUI_GTK)
1049 else if (varp == &p_imak) 2650 else if (varp == &p_imak)
1050 { 2651 errmsg = did_set_imactivatekey();
1051 if (!im_xim_isvalid_imactivate())
1052 errmsg = e_invalid_argument;
1053 }
1054 #endif 2652 #endif
1055 2653
1056 #ifdef FEAT_KEYMAP 2654 #ifdef FEAT_KEYMAP
1057 else if (varp == &curbuf->b_p_keymap) 2655 else if (varp == &curbuf->b_p_keymap)
1058 { 2656 errmsg = did_set_keymap(varp, opt_flags, value_checked);
1059 if (!valid_filetype(*varp))
1060 errmsg = e_invalid_argument;
1061 else
1062 {
1063 int secure_save = secure;
1064
1065 // Reset the secure flag, since the value of 'keymap' has
1066 // been checked to be safe.
1067 secure = 0;
1068
1069 // load or unload key mapping tables
1070 errmsg = keymap_init();
1071
1072 secure = secure_save;
1073
1074 // Since we check the value, there is no need to set P_INSECURE,
1075 // even when the value comes from a modeline.
1076 *value_checked = TRUE;
1077 }
1078
1079 if (errmsg == NULL)
1080 {
1081 if (*curbuf->b_p_keymap != NUL)
1082 {
1083 // Installed a new keymap, switch on using it.
1084 curbuf->b_p_iminsert = B_IMODE_LMAP;
1085 if (curbuf->b_p_imsearch != B_IMODE_USE_INSERT)
1086 curbuf->b_p_imsearch = B_IMODE_LMAP;
1087 }
1088 else
1089 {
1090 // Cleared the keymap, may reset 'iminsert' and 'imsearch'.
1091 if (curbuf->b_p_iminsert == B_IMODE_LMAP)
1092 curbuf->b_p_iminsert = B_IMODE_NONE;
1093 if (curbuf->b_p_imsearch == B_IMODE_LMAP)
1094 curbuf->b_p_imsearch = B_IMODE_USE_INSERT;
1095 }
1096 if ((opt_flags & OPT_LOCAL) == 0)
1097 {
1098 set_iminsert_global();
1099 set_imsearch_global();
1100 }
1101 status_redraw_curbuf();
1102 }
1103 }
1104 #endif 2657 #endif
1105 2658
1106 // 'fileformat' 2659 // 'fileformat'
1107 else if (gvarp == &p_ff) 2660 else if (gvarp == &p_ff)
1108 { 2661 errmsg = did_set_fileformat(varp, oldval, opt_flags);
1109 if (!curbuf->b_p_ma && !(opt_flags & OPT_GLOBAL))
1110 errmsg = e_cannot_make_changes_modifiable_is_off;
1111 else if (check_opt_strings(*varp, p_ff_values, FALSE) != OK)
1112 errmsg = e_invalid_argument;
1113 else
1114 {
1115 // may also change 'textmode'
1116 if (get_fileformat(curbuf) == EOL_DOS)
1117 curbuf->b_p_tx = TRUE;
1118 else
1119 curbuf->b_p_tx = FALSE;
1120 redraw_titles();
1121 // update flag in swap file
1122 ml_setflags(curbuf);
1123 // Redraw needed when switching to/from "mac": a CR in the text
1124 // will be displayed differently.
1125 if (get_fileformat(curbuf) == EOL_MAC || *oldval == 'm')
1126 redraw_curbuf_later(UPD_NOT_VALID);
1127 }
1128 }
1129 2662
1130 // 'fileformats' 2663 // 'fileformats'
1131 else if (varp == &p_ffs) 2664 else if (varp == &p_ffs)
1132 { 2665 errmsg = did_set_fileformats();
1133 if (check_opt_strings(p_ffs, p_ff_values, TRUE) != OK)
1134 errmsg = e_invalid_argument;
1135 else
1136 {
1137 // also change 'textauto'
1138 if (*p_ffs == NUL)
1139 p_ta = FALSE;
1140 else
1141 p_ta = TRUE;
1142 }
1143 }
1144 2666
1145 #if defined(FEAT_CRYPT) 2667 #if defined(FEAT_CRYPT)
1146 // 'cryptkey' 2668 // 'cryptkey'
1147 else if (gvarp == &p_key) 2669 else if (gvarp == &p_key)
1148 { 2670 did_set_cryptkey(oldval);
1149 // Make sure the ":set" command doesn't show the new value in the 2671
1150 // history. 2672 // 'cryptmethod'
1151 remove_key_from_history();
1152
1153 if (STRCMP(curbuf->b_p_key, oldval) != 0)
1154 // Need to update the swapfile.
1155 {
1156 ml_set_crypt_key(curbuf, oldval,
1157 *curbuf->b_p_cm == NUL ? p_cm : curbuf->b_p_cm);
1158 changed_internal();
1159 }
1160 }
1161
1162 else if (gvarp == &p_cm) 2673 else if (gvarp == &p_cm)
1163 { 2674 errmsg = did_set_cryptmethod(oldval, opt_flags);
1164 if (opt_flags & OPT_LOCAL)
1165 p = curbuf->b_p_cm;
1166 else
1167 p = p_cm;
1168 if (check_opt_strings(p, p_cm_values, TRUE) != OK)
1169 errmsg = e_invalid_argument;
1170 else if (crypt_self_test() == FAIL)
1171 errmsg = e_invalid_argument;
1172 else
1173 {
1174 // When setting the global value to empty, make it "zip".
1175 if (*p_cm == NUL)
1176 {
1177 free_string_option(p_cm);
1178 p_cm = vim_strsave((char_u *)"zip");
1179 }
1180 // When using ":set cm=name" the local value is going to be empty.
1181 // Do that here, otherwise the crypt functions will still use the
1182 // local value.
1183 if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0)
1184 {
1185 free_string_option(curbuf->b_p_cm);
1186 curbuf->b_p_cm = empty_option;
1187 }
1188
1189 // Need to update the swapfile when the effective method changed.
1190 // Set "s" to the effective old value, "p" to the effective new
1191 // method and compare.
1192 if ((opt_flags & OPT_LOCAL) && *oldval == NUL)
1193 s = p_cm; // was previously using the global value
1194 else
1195 s = oldval;
1196 if (*curbuf->b_p_cm == NUL)
1197 p = p_cm; // is now using the global value
1198 else
1199 p = curbuf->b_p_cm;
1200 if (STRCMP(s, p) != 0)
1201 ml_set_crypt_key(curbuf, curbuf->b_p_key, s);
1202
1203 // If the global value changes need to update the swapfile for all
1204 // buffers using that value.
1205 if ((opt_flags & OPT_GLOBAL) && STRCMP(p_cm, oldval) != 0)
1206 {
1207 buf_T *buf;
1208
1209 FOR_ALL_BUFFERS(buf)
1210 if (buf != curbuf && *buf->b_p_cm == NUL)
1211 ml_set_crypt_key(buf, buf->b_p_key, oldval);
1212 }
1213 }
1214 }
1215 #endif 2675 #endif
1216 2676
1217 // 'matchpairs' 2677 // 'matchpairs'
1218 else if (gvarp == &p_mps) 2678 else if (gvarp == &p_mps)
1219 { 2679 errmsg = did_set_matchpairs(varp);
1220 if (has_mbyte)
1221 {
1222 for (p = *varp; *p != NUL; ++p)
1223 {
1224 int x2 = -1;
1225 int x3 = -1;
1226
1227 p += mb_ptr2len(p);
1228 if (*p != NUL)
1229 x2 = *p++;
1230 if (*p != NUL)
1231 {
1232 x3 = mb_ptr2char(p);
1233 p += mb_ptr2len(p);
1234 }
1235 if (x2 != ':' || x3 == -1 || (*p != NUL && *p != ','))
1236 {
1237 errmsg = e_invalid_argument;
1238 break;
1239 }
1240 if (*p == NUL)
1241 break;
1242 }
1243 }
1244 else
1245 {
1246 // Check for "x:y,x:y"
1247 for (p = *varp; *p != NUL; p += 4)
1248 {
1249 if (p[1] != ':' || p[2] == NUL || (p[3] != NUL && p[3] != ','))
1250 {
1251 errmsg = e_invalid_argument;
1252 break;
1253 }
1254 if (p[3] == NUL)
1255 break;
1256 }
1257 }
1258 }
1259 2680
1260 // 'comments' 2681 // 'comments'
1261 else if (gvarp == &p_com) 2682 else if (gvarp == &p_com)
1262 { 2683 errmsg = did_set_comments(varp, errbuf);
1263 for (s = *varp; *s; )
1264 {
1265 while (*s && *s != ':')
1266 {
1267 if (vim_strchr((char_u *)COM_ALL, *s) == NULL
1268 && !VIM_ISDIGIT(*s) && *s != '-')
1269 {
1270 errmsg = illegal_char(errbuf, *s);
1271 break;
1272 }
1273 ++s;
1274 }
1275 if (*s++ == NUL)
1276 errmsg = e_missing_colon;
1277 else if (*s == ',' || *s == NUL)
1278 errmsg = e_zero_length_string;
1279 if (errmsg != NULL)
1280 break;
1281 while (*s && *s != ',')
1282 {
1283 if (*s == '\\' && s[1] != NUL)
1284 ++s;
1285 ++s;
1286 }
1287 s = skip_to_option_part(s);
1288 }
1289 }
1290 2684
1291 // global 'listchars' or 'fillchars' 2685 // global 'listchars' or 'fillchars'
1292 else if (varp == &p_lcs || varp == &p_fcs) 2686 else if (varp == &p_lcs || varp == &p_fcs)
1293 { 2687 errmsg = did_set_global_listfillchars(varp, opt_flags);
1294 char_u **local_ptr = varp == &p_lcs 2688
1295 ? &curwin->w_p_lcs : &curwin->w_p_fcs;
1296
1297 // only apply the global value to "curwin" when it does not have a
1298 // local value
1299 errmsg = set_chars_option(curwin, varp,
1300 **local_ptr == NUL || !(opt_flags & OPT_GLOBAL));
1301 if (errmsg == NULL)
1302 {
1303 tabpage_T *tp;
1304 win_T *wp;
1305
1306 // If the current window is set to use the global
1307 // 'listchars'/'fillchars' value, clear the window-local value.
1308 if (!(opt_flags & OPT_GLOBAL))
1309 clear_string_option(local_ptr);
1310 FOR_ALL_TAB_WINDOWS(tp, wp)
1311 {
1312 // If the current window has a local value need to apply it
1313 // again, it was changed when setting the global value.
1314 // If no error was returned above, we don't expect an error
1315 // here, so ignore the return value.
1316 local_ptr = varp == &p_lcs ? &wp->w_p_lcs : &wp->w_p_fcs;
1317 if (**local_ptr == NUL)
1318 (void)set_chars_option(wp, local_ptr, TRUE);
1319 }
1320
1321 redraw_all_later(UPD_NOT_VALID);
1322 }
1323 }
1324 // local 'listchars' 2689 // local 'listchars'
1325 else if (varp == &curwin->w_p_lcs) 2690 else if (varp == &curwin->w_p_lcs)
1326 errmsg = set_chars_option(curwin, varp, TRUE); 2691 errmsg = set_chars_option(curwin, varp, TRUE);
1327 2692
1328 // local 'fillchars' 2693 // local 'fillchars'
1329 else if (varp == &curwin->w_p_fcs) 2694 else if (varp == &curwin->w_p_fcs)
1330 {
1331 errmsg = set_chars_option(curwin, varp, TRUE); 2695 errmsg = set_chars_option(curwin, varp, TRUE);
1332 }
1333 2696
1334 // 'cedit' 2697 // 'cedit'
1335 else if (varp == &p_cedit) 2698 else if (varp == &p_cedit)
1336 {
1337 errmsg = check_cedit(); 2699 errmsg = check_cedit();
1338 }
1339 2700
1340 // 'verbosefile' 2701 // 'verbosefile'
1341 else if (varp == &p_vfile) 2702 else if (varp == &p_vfile)
1342 { 2703 errmsg = did_set_verbosefile();
1343 verbose_stop();
1344 if (*p_vfile != NUL && verbose_open() == FAIL)
1345 errmsg = e_invalid_argument;
1346 }
1347 2704
1348 #ifdef FEAT_VIMINFO 2705 #ifdef FEAT_VIMINFO
1349 // 'viminfo' 2706 // 'viminfo'
1350 else if (varp == &p_viminfo) 2707 else if (varp == &p_viminfo)
1351 { 2708 errmsg = did_set_viminfo(errbuf);
1352 for (s = p_viminfo; *s;)
1353 {
1354 // Check it's a valid character
1355 if (vim_strchr((char_u *)"!\"%'/:<@cfhnrs", *s) == NULL)
1356 {
1357 errmsg = illegal_char(errbuf, *s);
1358 break;
1359 }
1360 if (*s == 'n') // name is always last one
1361 break;
1362 else if (*s == 'r') // skip until next ','
1363 {
1364 while (*++s && *s != ',')
1365 ;
1366 }
1367 else if (*s == '%')
1368 {
1369 // optional number
1370 while (vim_isdigit(*++s))
1371 ;
1372 }
1373 else if (*s == '!' || *s == 'h' || *s == 'c')
1374 ++s; // no extra chars
1375 else // must have a number
1376 {
1377 while (vim_isdigit(*++s))
1378 ;
1379
1380 if (!VIM_ISDIGIT(*(s - 1)))
1381 {
1382 if (errbuf != NULL)
1383 {
1384 sprintf(errbuf,
1385 _(e_missing_number_after_angle_str_angle),
1386 transchar_byte(*(s - 1)));
1387 errmsg = errbuf;
1388 }
1389 else
1390 errmsg = "";
1391 break;
1392 }
1393 }
1394 if (*s == ',')
1395 ++s;
1396 else if (*s)
1397 {
1398 if (errbuf != NULL)
1399 errmsg = e_missing_comma;
1400 else
1401 errmsg = "";
1402 break;
1403 }
1404 }
1405 if (*p_viminfo && errmsg == NULL && get_viminfo_parameter('\'') < 0)
1406 errmsg = e_must_specify_a_value;
1407 }
1408 #endif // FEAT_VIMINFO 2709 #endif // FEAT_VIMINFO
1409 2710
1410 // terminal options 2711 // terminal options
1411 else if (istermoption_idx(opt_idx) && full_screen) 2712 else if (istermoption_idx(opt_idx) && full_screen)
1412 { 2713 did_set_term_option(varp, &did_swaptcap);
1413 // ":set t_Co=0" and ":set t_Co=1" do ":set t_Co="
1414 if (varp == &T_CCO)
1415 {
1416 int colors = atoi((char *)T_CCO);
1417
1418 // Only reinitialize colors if t_Co value has really changed to
1419 // avoid expensive reload of colorscheme if t_Co is set to the
1420 // same value multiple times.
1421 if (colors != t_colors)
1422 {
1423 t_colors = colors;
1424 if (t_colors <= 1)
1425 {
1426 vim_free(T_CCO);
1427 T_CCO = empty_option;
1428 }
1429 #if defined(FEAT_VTP) && defined(FEAT_TERMGUICOLORS)
1430 if (is_term_win32())
1431 {
1432 swap_tcap();
1433 did_swaptcap = TRUE;
1434 }
1435 #endif
1436 // We now have a different color setup, initialize it again.
1437 init_highlight(TRUE, FALSE);
1438 }
1439 }
1440 ttest(FALSE);
1441 if (varp == &T_ME)
1442 {
1443 out_str(T_ME);
1444 redraw_later(UPD_CLEAR);
1445 #if defined(MSWIN) && (!defined(FEAT_GUI_MSWIN) || defined(VIMDLL))
1446 // Since t_me has been set, this probably means that the user
1447 // wants to use this as default colors. Need to reset default
1448 // background/foreground colors.
1449 # ifdef VIMDLL
1450 if (!gui.in_use && !gui.starting)
1451 # endif
1452 mch_set_normal_colors();
1453 #endif
1454 }
1455 if (varp == &T_BE && termcap_active)
1456 {
1457 MAY_WANT_TO_LOG_THIS;
1458
1459 if (*T_BE == NUL)
1460 // When clearing t_BE we assume the user no longer wants
1461 // bracketed paste, thus disable it by writing t_BD.
1462 out_str(T_BD);
1463 else
1464 out_str(T_BE);
1465 }
1466 }
1467 2714
1468 #ifdef FEAT_LINEBREAK 2715 #ifdef FEAT_LINEBREAK
1469 // 'showbreak' 2716 // 'showbreak'
1470 else if (gvarp == &p_sbr) 2717 else if (gvarp == &p_sbr)
1471 { 2718 errmsg = did_set_showbreak(varp);
1472 for (s = *varp; *s; )
1473 {
1474 if (ptr2cells(s) != 1)
1475 errmsg = e_showbreak_contains_unprintable_or_wide_character;
1476 MB_PTR_ADV(s);
1477 }
1478 }
1479 #endif 2719 #endif
1480 2720
1481 #ifdef FEAT_GUI 2721 #ifdef FEAT_GUI
1482 // 'guifont' 2722 // 'guifont'
1483 else if (varp == &p_guifont) 2723 else if (varp == &p_guifont)
1484 { 2724 errmsg = did_set_guifont(oldval, &redraw_gui_only);
1485 if (gui.in_use) 2725
1486 { 2726 # ifdef FEAT_XFONTSET
1487 p = p_guifont; 2727 // 'guifontset'
1488 # if defined(FEAT_GUI_GTK) 2728 else if (varp == &p_guifontset)
1489 // Put up a font dialog and let the user select a new value. 2729 errmsg = did_set_guifontset(&redraw_gui_only);
1490 // If this is cancelled go back to the old value but don't
1491 // give an error message.
1492 if (STRCMP(p, "*") == 0)
1493 {
1494 p = gui_mch_font_dialog(oldval);
1495 free_string_option(p_guifont);
1496 p_guifont = (p != NULL) ? p : vim_strsave(oldval);
1497 }
1498 # endif 2730 # endif
1499 if (p != NULL && gui_init_font(p_guifont, FALSE) != OK) 2731
1500 { 2732 // 'guifontwide'
1501 # if defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_PHOTON)
1502 if (STRCMP(p_guifont, "*") == 0)
1503 {
1504 // Dialog was cancelled: Keep the old value without giving
1505 // an error message.
1506 free_string_option(p_guifont);
1507 p_guifont = vim_strsave(oldval);
1508 }
1509 else
1510 # endif
1511 errmsg = e_invalid_fonts;
1512 }
1513 }
1514 redraw_gui_only = TRUE;
1515 }
1516 # ifdef FEAT_XFONTSET
1517 else if (varp == &p_guifontset)
1518 {
1519 if (STRCMP(p_guifontset, "*") == 0)
1520 errmsg = e_cant_select_fontset;
1521 else if (gui.in_use && gui_init_font(p_guifontset, TRUE) != OK)
1522 errmsg = e_invalid_fontset;
1523 redraw_gui_only = TRUE;
1524 }
1525 # endif
1526 else if (varp == &p_guifontwide) 2733 else if (varp == &p_guifontwide)
1527 { 2734 errmsg = did_set_guifontwide(&redraw_gui_only);
1528 if (STRCMP(p_guifontwide, "*") == 0) 2735 #endif
1529 errmsg = e_cant_select_wide_font; 2736 #if defined(FEAT_GUI_GTK)
1530 else if (gui_get_wide_font() == FAIL)
1531 errmsg = e_invalid_wide_font;
1532 redraw_gui_only = TRUE;
1533 }
1534 #endif
1535 # if defined(FEAT_GUI_GTK)
1536 else if (varp == &p_guiligatures) 2737 else if (varp == &p_guiligatures)
1537 { 2738 did_set_guiligatures(&redraw_gui_only);
1538 gui_set_ligatures(); 2739 #endif
1539 redraw_gui_only = TRUE;
1540 }
1541 # endif
1542 2740
1543 #ifdef CURSOR_SHAPE 2741 #ifdef CURSOR_SHAPE
1544 // 'guicursor' 2742 // 'guicursor'
1545 else if (varp == &p_guicursor) 2743 else if (varp == &p_guicursor)
1546 errmsg = parse_shape_opt(SHAPE_CURSOR); 2744 errmsg = parse_shape_opt(SHAPE_CURSOR);
1547 #endif 2745 #endif
1548 2746
1549 #ifdef FEAT_MOUSESHAPE 2747 #ifdef FEAT_MOUSESHAPE
1550 // 'mouseshape' 2748 // 'mouseshape'
1551 else if (varp == &p_mouseshape) 2749 else if (varp == &p_mouseshape)
1552 { 2750 errmsg = did_set_mouseshape();
1553 errmsg = parse_shape_opt(SHAPE_MOUSE);
1554 update_mouseshape(-1);
1555 }
1556 #endif 2751 #endif
1557 2752
1558 #ifdef FEAT_PRINTER 2753 #ifdef FEAT_PRINTER
1559 else if (varp == &p_popt) 2754 else if (varp == &p_popt)
1560 errmsg = parse_printoptions(); 2755 errmsg = parse_printoptions();
1576 fill_breakat_flags(); 2771 fill_breakat_flags();
1577 #endif 2772 #endif
1578 2773
1579 // 'titlestring' and 'iconstring' 2774 // 'titlestring' and 'iconstring'
1580 else if (varp == &p_titlestring || varp == &p_iconstring) 2775 else if (varp == &p_titlestring || varp == &p_iconstring)
1581 { 2776 did_set_titleiconstring(varp);
1582 #ifdef FEAT_STL_OPT
1583 int flagval = (varp == &p_titlestring) ? STL_IN_TITLE : STL_IN_ICON;
1584
1585 // NULL => statusline syntax
1586 if (vim_strchr(*varp, '%') && check_stl_option(*varp) == NULL)
1587 stl_syntax |= flagval;
1588 else
1589 stl_syntax &= ~flagval;
1590 #endif
1591 did_set_title();
1592 }
1593 2777
1594 #ifdef FEAT_GUI 2778 #ifdef FEAT_GUI
1595 // 'guioptions' 2779 // 'guioptions'
1596 else if (varp == &p_go) 2780 else if (varp == &p_go)
1597 { 2781 did_set_guioptions(oldval, &redraw_gui_only);
1598 gui_init_which_components(oldval);
1599 redraw_gui_only = TRUE;
1600 }
1601 #endif 2782 #endif
1602 2783
1603 #if defined(FEAT_GUI_TABLINE) 2784 #if defined(FEAT_GUI_TABLINE)
1604 // 'guitablabel' 2785 // 'guitablabel'
1605 else if (varp == &p_gtl) 2786 else if (varp == &p_gtl)
1606 { 2787 did_set_guitablabel(&redraw_gui_only);
1607 redraw_tabline = TRUE;
1608 redraw_gui_only = TRUE;
1609 }
1610 // 'guitabtooltip' 2788 // 'guitabtooltip'
1611 else if (varp == &p_gtt) 2789 else if (varp == &p_gtt)
1612 {
1613 redraw_gui_only = TRUE; 2790 redraw_gui_only = TRUE;
1614 }
1615 #endif 2791 #endif
1616 2792
1617 #if defined(UNIX) || defined(VMS) 2793 #if defined(UNIX) || defined(VMS)
1618 // 'ttymouse' 2794 // 'ttymouse'
1619 else if (varp == &p_ttym) 2795 else if (varp == &p_ttym)
1620 { 2796 errmsg = did_set_ttymouse();
1621 // Switch the mouse off before changing the escape sequences used for
1622 // that.
1623 mch_setmouse(FALSE);
1624 if (opt_strings_flags(p_ttym, p_ttym_values, &ttym_flags, FALSE) != OK)
1625 errmsg = e_invalid_argument;
1626 else
1627 check_mouse_termcode();
1628 if (termcap_active)
1629 setmouse(); // may switch it on again
1630 }
1631 #endif 2797 #endif
1632 2798
1633 // 'selection' 2799 // 'selection'
1634 else if (varp == &p_sel) 2800 else if (varp == &p_sel)
1635 { 2801 errmsg = did_set_selection();
1636 if (*p_sel == NUL
1637 || check_opt_strings(p_sel, p_sel_values, FALSE) != OK)
1638 errmsg = e_invalid_argument;
1639 }
1640 2802
1641 // 'selectmode' 2803 // 'selectmode'
1642 else if (varp == &p_slm) 2804 else if (varp == &p_slm)
1643 { 2805 errmsg = did_set_opt_strings(p_slm, p_slm_values, TRUE);
1644 if (check_opt_strings(p_slm, p_slm_values, TRUE) != OK)
1645 errmsg = e_invalid_argument;
1646 }
1647 2806
1648 #ifdef FEAT_BROWSE 2807 #ifdef FEAT_BROWSE
1649 // 'browsedir' 2808 // 'browsedir'
1650 else if (varp == &p_bsdir) 2809 else if (varp == &p_bsdir)
1651 { 2810 errmsg = did_set_browsedir();
1652 if (check_opt_strings(p_bsdir, p_bsdir_values, FALSE) != OK
1653 && !mch_isdir(p_bsdir))
1654 errmsg = e_invalid_argument;
1655 }
1656 #endif 2811 #endif
1657 2812
1658 // 'keymodel' 2813 // 'keymodel'
1659 else if (varp == &p_km) 2814 else if (varp == &p_km)
1660 { 2815 errmsg = did_set_keymodel();
1661 if (check_opt_strings(p_km, p_km_values, TRUE) != OK)
1662 errmsg = e_invalid_argument;
1663 else
1664 {
1665 km_stopsel = (vim_strchr(p_km, 'o') != NULL);
1666 km_startsel = (vim_strchr(p_km, 'a') != NULL);
1667 }
1668 }
1669 2816
1670 // 'keyprotocol' 2817 // 'keyprotocol'
1671 else if (varp == &p_kpc) 2818 else if (varp == &p_kpc)
1672 { 2819 errmsg = did_set_keyprotocol();
1673 if (match_keyprotocol(NULL) == KEYPROTOCOL_FAIL)
1674 errmsg = e_invalid_argument;
1675 }
1676 2820
1677 // 'mousemodel' 2821 // 'mousemodel'
1678 else if (varp == &p_mousem) 2822 else if (varp == &p_mousem)
1679 { 2823 errmsg = did_set_mousemodel();
1680 if (check_opt_strings(p_mousem, p_mousem_values, FALSE) != OK)
1681 errmsg = e_invalid_argument;
1682 #if defined(FEAT_GUI_MOTIF) && defined(FEAT_MENU) && (XmVersion <= 1002)
1683 else if (*p_mousem != *oldval)
1684 // Changed from "extend" to "popup" or "popup_setpos" or vv: need
1685 // to create or delete the popup menus.
1686 gui_motif_update_mousemodel(root_menu);
1687 #endif
1688 }
1689 2824
1690 // 'switchbuf' 2825 // 'switchbuf'
1691 else if (varp == &p_swb) 2826 else if (varp == &p_swb)
1692 { 2827 errmsg = did_set_opt_flags(p_swb, p_swb_values, &swb_flags, TRUE);
1693 if (opt_strings_flags(p_swb, p_swb_values, &swb_flags, TRUE) != OK)
1694 errmsg = e_invalid_argument;
1695 }
1696 2828
1697 // 'splitkeep' 2829 // 'splitkeep'
1698 else if (varp == &p_spk) 2830 else if (varp == &p_spk)
1699 { 2831 errmsg = did_set_opt_strings(p_spk, p_spk_values, FALSE);
1700 if (check_opt_strings(p_spk, p_spk_values, FALSE) != OK)
1701 errmsg = e_invalid_argument;
1702 }
1703 2832
1704 // 'debug' 2833 // 'debug'
1705 else if (varp == &p_debug) 2834 else if (varp == &p_debug)
1706 { 2835 errmsg = did_set_opt_strings(p_debug, p_debug_values, TRUE);
1707 if (check_opt_strings(p_debug, p_debug_values, TRUE) != OK)
1708 errmsg = e_invalid_argument;
1709 }
1710 2836
1711 // 'display' 2837 // 'display'
1712 else if (varp == &p_dy) 2838 else if (varp == &p_dy)
1713 { 2839 errmsg = did_set_display();
1714 if (opt_strings_flags(p_dy, p_dy_values, &dy_flags, TRUE) != OK)
1715 errmsg = e_invalid_argument;
1716 else
1717 (void)init_chartab();
1718
1719 }
1720 2840
1721 // 'eadirection' 2841 // 'eadirection'
1722 else if (varp == &p_ead) 2842 else if (varp == &p_ead)
1723 { 2843 errmsg = did_set_opt_strings(p_ead, p_ead_values, FALSE);
1724 if (check_opt_strings(p_ead, p_ead_values, FALSE) != OK)
1725 errmsg = e_invalid_argument;
1726 }
1727 2844
1728 #ifdef FEAT_CLIPBOARD 2845 #ifdef FEAT_CLIPBOARD
1729 // 'clipboard' 2846 // 'clipboard'
1730 else if (varp == &p_cb) 2847 else if (varp == &p_cb)
1731 errmsg = check_clipboard_option(); 2848 errmsg = check_clipboard_option();
1732 #endif 2849 #endif
1733 2850
1734 #ifdef FEAT_SPELL 2851 #ifdef FEAT_SPELL
1735 // When 'spelllang' or 'spellfile' is set and there is a window for this 2852 // 'spellfile'
1736 // buffer in which 'spell' is set load the wordlists. 2853 else if (varp == &(curwin->w_s->b_p_spf))
1737 else if (varp == &(curwin->w_s->b_p_spl) 2854 errmsg = did_set_spellfile(varp);
1738 || varp == &(curwin->w_s->b_p_spf)) 2855
1739 { 2856 // 'spell'
1740 int is_spellfile = varp == &(curwin->w_s->b_p_spf); 2857 else if (varp == &(curwin->w_s->b_p_spl))
1741 2858 errmsg = did_set_spell(varp);
1742 if ((is_spellfile && !valid_spellfile(*varp)) 2859
1743 || (!is_spellfile && !valid_spelllang(*varp))) 2860 // 'spellcapcheck'
1744 errmsg = e_invalid_argument;
1745 else
1746 errmsg = did_set_spell_option(is_spellfile);
1747 }
1748 // When 'spellcapcheck' is set compile the regexp program.
1749 else if (varp == &(curwin->w_s->b_p_spc)) 2861 else if (varp == &(curwin->w_s->b_p_spc))
1750 { 2862 errmsg = did_set_spellcapcheck();
1751 errmsg = compile_cap_prog(curwin->w_s); 2863
1752 }
1753 // 'spelloptions' 2864 // 'spelloptions'
1754 else if (varp == &(curwin->w_s->b_p_spo)) 2865 else if (varp == &(curwin->w_s->b_p_spo))
1755 { 2866 errmsg = did_set_spelloptions(varp);
1756 if (**varp != NUL && STRCMP("camel", *varp) != 0) 2867
1757 errmsg = e_invalid_argument;
1758 }
1759 // 'spellsuggest' 2868 // 'spellsuggest'
1760 else if (varp == &p_sps) 2869 else if (varp == &p_sps)
1761 { 2870 errmsg = did_set_spellsuggest();
1762 if (spell_check_sps() != OK) 2871
1763 errmsg = e_invalid_argument;
1764 }
1765 // 'mkspellmem' 2872 // 'mkspellmem'
1766 else if (varp == &p_msm) 2873 else if (varp == &p_msm)
1767 { 2874 errmsg = did_set_mkspellmem();
1768 if (spell_check_msm() != OK)
1769 errmsg = e_invalid_argument;
1770 }
1771 #endif 2875 #endif
1772 2876
1773 // When 'bufhidden' is set, check for valid value. 2877 // When 'bufhidden' is set, check for valid value.
1774 else if (gvarp == &p_bh) 2878 else if (gvarp == &p_bh)
1775 { 2879 errmsg = did_set_opt_strings(curbuf->b_p_bh, p_bufhidden_values,
1776 if (check_opt_strings(curbuf->b_p_bh, p_bufhidden_values, FALSE) != OK) 2880 FALSE);
1777 errmsg = e_invalid_argument;
1778 }
1779 2881
1780 // When 'buftype' is set, check for valid value. 2882 // When 'buftype' is set, check for valid value.
1781 else if (gvarp == &p_bt) 2883 else if (gvarp == &p_bt)
1782 { 2884 errmsg = did_set_buftype();
1783 if (check_opt_strings(curbuf->b_p_bt, p_buftype_values, FALSE) != OK)
1784 errmsg = e_invalid_argument;
1785 else
1786 {
1787 if (curwin->w_status_height)
1788 {
1789 curwin->w_redr_status = TRUE;
1790 redraw_later(UPD_VALID);
1791 }
1792 curbuf->b_help = (curbuf->b_p_bt[0] == 'h');
1793 redraw_titles();
1794 }
1795 }
1796 2885
1797 #ifdef FEAT_STL_OPT 2886 #ifdef FEAT_STL_OPT
1798 // 'statusline', 'tabline' or 'rulerformat' 2887 // 'statusline', 'tabline' or 'rulerformat'
1799 else if (gvarp == &p_stl || varp == &p_tal || varp == &p_ruf) 2888 else if (gvarp == &p_stl || varp == &p_tal || varp == &p_ruf)
1800 { 2889 errmsg = did_set_statusline(varp);
1801 int wid; 2890 #endif
1802 2891
1803 if (varp == &p_ruf) // reset ru_wid first 2892 // 'complete'
1804 ru_wid = 0;
1805 s = *varp;
1806 if (varp == &p_ruf && *s == '%')
1807 {
1808 // set ru_wid if 'ruf' starts with "%99("
1809 if (*++s == '-') // ignore a '-'
1810 s++;
1811 wid = getdigits(&s);
1812 if (wid && *s == '(' && (errmsg = check_stl_option(p_ruf)) == NULL)
1813 ru_wid = wid;
1814 else
1815 errmsg = check_stl_option(p_ruf);
1816 }
1817 // check 'statusline' or 'tabline' only if it doesn't start with "%!"
1818 else if (varp == &p_ruf || s[0] != '%' || s[1] != '!')
1819 errmsg = check_stl_option(s);
1820 if (varp == &p_ruf && errmsg == NULL)
1821 comp_col();
1822 }
1823 #endif
1824
1825 // check if it is a valid value for 'complete' -- Acevedo
1826 else if (gvarp == &p_cpt) 2893 else if (gvarp == &p_cpt)
1827 { 2894 errmsg = did_set_complete(varp, errbuf);
1828 for (s = *varp; *s;)
1829 {
1830 while (*s == ',' || *s == ' ')
1831 s++;
1832 if (!*s)
1833 break;
1834 if (vim_strchr((char_u *)".wbuksid]tU", *s) == NULL)
1835 {
1836 errmsg = illegal_char(errbuf, *s);
1837 break;
1838 }
1839 if (*++s != NUL && *s != ',' && *s != ' ')
1840 {
1841 if (s[-1] == 'k' || s[-1] == 's')
1842 {
1843 // skip optional filename after 'k' and 's'
1844 while (*s && *s != ',' && *s != ' ')
1845 {
1846 if (*s == '\\' && s[1] != NUL)
1847 ++s;
1848 ++s;
1849 }
1850 }
1851 else
1852 {
1853 if (errbuf != NULL)
1854 {
1855 sprintf((char *)errbuf,
1856 _(e_illegal_character_after_chr), *--s);
1857 errmsg = errbuf;
1858 }
1859 else
1860 errmsg = "";
1861 break;
1862 }
1863 }
1864 }
1865 }
1866 2895
1867 // 'completeopt' 2896 // 'completeopt'
1868 else if (varp == &p_cot) 2897 else if (varp == &p_cot)
1869 { 2898 errmsg = did_set_completeopt();
1870 if (check_opt_strings(p_cot, p_cot_values, TRUE) != OK)
1871 errmsg = e_invalid_argument;
1872 else
1873 completeopt_was_set();
1874 }
1875 2899
1876 #ifdef BACKSLASH_IN_FILENAME 2900 #ifdef BACKSLASH_IN_FILENAME
1877 // 'completeslash' 2901 // 'completeslash'
1878 else if (gvarp == &p_csl) 2902 else if (gvarp == &p_csl)
1879 { 2903 {
1884 #endif 2908 #endif
1885 2909
1886 #ifdef FEAT_SIGNS 2910 #ifdef FEAT_SIGNS
1887 // 'signcolumn' 2911 // 'signcolumn'
1888 else if (varp == &curwin->w_p_scl) 2912 else if (varp == &curwin->w_p_scl)
1889 { 2913 errmsg = did_set_signcolumn(varp, oldval);
1890 if (check_opt_strings(*varp, p_scl_values, FALSE) != OK)
1891 errmsg = e_invalid_argument;
1892 // When changing the 'signcolumn' to or from 'number', recompute the
1893 // width of the number column if 'number' or 'relativenumber' is set.
1894 if (((*oldval == 'n' && *(oldval + 1) == 'u')
1895 || (*curwin->w_p_scl == 'n' && *(curwin->w_p_scl + 1) =='u'))
1896 && (curwin->w_p_nu || curwin->w_p_rnu))
1897 curwin->w_nrwidth_line_count = 0;
1898 }
1899 #endif 2914 #endif
1900 2915
1901 // 'showcmdloc' 2916 // 'showcmdloc'
1902 else if (varp == &p_sloc) 2917 else if (varp == &p_sloc)
1903 { 2918 errmsg = did_set_opt_strings(p_sloc, p_sloc_values, FALSE);
1904 if (check_opt_strings(p_sloc, p_sloc_values, FALSE) != OK)
1905 errmsg = e_invalid_argument;
1906 }
1907 2919
1908 #if defined(FEAT_TOOLBAR) && !defined(FEAT_GUI_MSWIN) 2920 #if defined(FEAT_TOOLBAR) && !defined(FEAT_GUI_MSWIN)
1909 // 'toolbar' 2921 // 'toolbar'
1910 else if (varp == &p_toolbar) 2922 else if (varp == &p_toolbar)
1911 { 2923 errmsg = did_set_toolbar();
1912 if (opt_strings_flags(p_toolbar, p_toolbar_values,
1913 &toolbar_flags, TRUE) != OK)
1914 errmsg = e_invalid_argument;
1915 else
1916 {
1917 out_flush();
1918 gui_mch_show_toolbar((toolbar_flags &
1919 (TOOLBAR_TEXT | TOOLBAR_ICONS)) != 0);
1920 }
1921 }
1922 #endif 2924 #endif
1923 2925
1924 #if defined(FEAT_TOOLBAR) && defined(FEAT_GUI_GTK) 2926 #if defined(FEAT_TOOLBAR) && defined(FEAT_GUI_GTK)
1925 // 'toolbariconsize': GTK+ 2 only 2927 // 'toolbariconsize': GTK+ 2 only
1926 else if (varp == &p_tbis) 2928 else if (varp == &p_tbis)
1927 { 2929 errmsg = did_set_toolbariconsize();
1928 if (opt_strings_flags(p_tbis, p_tbis_values, &tbis_flags, FALSE) != OK) 2930 #endif
1929 errmsg = e_invalid_argument; 2931
1930 else 2932 // 'pastetoggle'
1931 {
1932 out_flush();
1933 gui_mch_show_toolbar((toolbar_flags &
1934 (TOOLBAR_TEXT | TOOLBAR_ICONS)) != 0);
1935 }
1936 }
1937 #endif
1938
1939 // 'pastetoggle': translate key codes like in a mapping
1940 else if (varp == &p_pt) 2933 else if (varp == &p_pt)
1941 { 2934 did_set_pastetoggle();
1942 if (*p_pt)
1943 {
1944 (void)replace_termcodes(p_pt, &p,
1945 REPTERM_FROM_PART | REPTERM_DO_LT, NULL);
1946 if (p != NULL)
1947 {
1948 free_string_option(p_pt);
1949 p_pt = p;
1950 }
1951 }
1952 }
1953 2935
1954 // 'backspace' 2936 // 'backspace'
1955 else if (varp == &p_bs) 2937 else if (varp == &p_bs)
1956 { 2938 errmsg = did_set_backspace();
1957 if (VIM_ISDIGIT(*p_bs)) 2939
1958 { 2940 // 'belloff'
1959 if (*p_bs > '3' || p_bs[1] != NUL)
1960 errmsg = e_invalid_argument;
1961 }
1962 else if (check_opt_strings(p_bs, p_bs_values, TRUE) != OK)
1963 errmsg = e_invalid_argument;
1964 }
1965 else if (varp == &p_bo) 2941 else if (varp == &p_bo)
1966 { 2942 errmsg = did_set_opt_flags(p_bo, p_bo_values, &bo_flags, TRUE);
1967 if (opt_strings_flags(p_bo, p_bo_values, &bo_flags, TRUE) != OK)
1968 errmsg = e_invalid_argument;
1969 }
1970 2943
1971 // 'tagcase' 2944 // 'tagcase'
1972 else if (gvarp == &p_tc) 2945 else if (gvarp == &p_tc)
1973 { 2946 errmsg = did_set_tagcase(opt_flags);
1974 unsigned int *flags;
1975
1976 if (opt_flags & OPT_LOCAL)
1977 {
1978 p = curbuf->b_p_tc;
1979 flags = &curbuf->b_tc_flags;
1980 }
1981 else
1982 {
1983 p = p_tc;
1984 flags = &tc_flags;
1985 }
1986
1987 if ((opt_flags & OPT_LOCAL) && *p == NUL)
1988 // make the local value empty: use the global value
1989 *flags = 0;
1990 else if (*p == NUL
1991 || opt_strings_flags(p, p_tc_values, flags, FALSE) != OK)
1992 errmsg = e_invalid_argument;
1993 }
1994 2947
1995 // 'casemap' 2948 // 'casemap'
1996 else if (varp == &p_cmp) 2949 else if (varp == &p_cmp)
1997 { 2950 errmsg = did_set_opt_flags(p_cmp, p_cmp_values, &cmp_flags, TRUE);
1998 if (opt_strings_flags(p_cmp, p_cmp_values, &cmp_flags, TRUE) != OK)
1999 errmsg = e_invalid_argument;
2000 }
2001 2951
2002 #ifdef FEAT_DIFF 2952 #ifdef FEAT_DIFF
2003 // 'diffopt' 2953 // 'diffopt'
2004 else if (varp == &p_dip) 2954 else if (varp == &p_dip)
2005 { 2955 errmsg = did_set_diffopt();
2006 if (diffopt_changed() == FAIL)
2007 errmsg = e_invalid_argument;
2008 }
2009 #endif 2956 #endif
2010 2957
2011 #ifdef FEAT_FOLDING 2958 #ifdef FEAT_FOLDING
2012 // 'foldmethod' 2959 // 'foldmethod'
2013 else if (gvarp == &curwin->w_allbuf_opt.wo_fdm) 2960 else if (gvarp == &curwin->w_allbuf_opt.wo_fdm)
2014 { 2961 errmsg = did_set_foldmethod(varp);
2015 if (check_opt_strings(*varp, p_fdm_values, FALSE) != OK 2962
2016 || *curwin->w_p_fdm == NUL)
2017 errmsg = e_invalid_argument;
2018 else
2019 {
2020 foldUpdateAll(curwin);
2021 if (foldmethodIsDiff(curwin))
2022 newFoldLevel();
2023 }
2024 }
2025 // 'foldmarker' 2963 // 'foldmarker'
2026 else if (gvarp == &curwin->w_allbuf_opt.wo_fmr) 2964 else if (gvarp == &curwin->w_allbuf_opt.wo_fmr)
2027 { 2965 errmsg = did_set_foldmarker(varp);
2028 p = vim_strchr(*varp, ','); 2966
2029 if (p == NULL)
2030 errmsg = e_comma_required;
2031 else if (p == *varp || p[1] == NUL)
2032 errmsg = e_invalid_argument;
2033 else if (foldmethodIsMarker(curwin))
2034 foldUpdateAll(curwin);
2035 }
2036 // 'commentstring' 2967 // 'commentstring'
2037 else if (gvarp == &p_cms) 2968 else if (gvarp == &p_cms)
2038 { 2969 errmsg = did_set_commentstring(varp);
2039 if (**varp != NUL && strstr((char *)*varp, "%s") == NULL) 2970
2040 errmsg = e_commentstring_must_be_empty_or_contain_str;
2041 }
2042 // 'foldopen' 2971 // 'foldopen'
2043 else if (varp == &p_fdo) 2972 else if (varp == &p_fdo)
2044 { 2973 errmsg = did_set_opt_flags(p_fdo, p_fdo_values, &fdo_flags, TRUE);
2045 if (opt_strings_flags(p_fdo, p_fdo_values, &fdo_flags, TRUE) != OK) 2974
2046 errmsg = e_invalid_argument;
2047 }
2048 // 'foldclose' 2975 // 'foldclose'
2049 else if (varp == &p_fcl) 2976 else if (varp == &p_fcl)
2050 { 2977 errmsg = did_set_opt_strings(p_fcl, p_fcl_values, TRUE);
2051 if (check_opt_strings(p_fcl, p_fcl_values, TRUE) != OK) 2978
2052 errmsg = e_invalid_argument;
2053 }
2054 // 'foldignore' 2979 // 'foldignore'
2055 else if (gvarp == &curwin->w_allbuf_opt.wo_fdi) 2980 else if (gvarp == &curwin->w_allbuf_opt.wo_fdi)
2056 { 2981 did_set_foldignore();
2057 if (foldmethodIsIndent(curwin))
2058 foldUpdateAll(curwin);
2059 }
2060 #endif 2982 #endif
2061 2983
2062 // 'virtualedit' 2984 // 'virtualedit'
2063 else if (gvarp == &p_ve) 2985 else if (gvarp == &p_ve)
2064 { 2986 errmsg = did_set_virtualedit(oldval, opt_flags);
2065 char_u *ve = p_ve;
2066 unsigned int *flags = &ve_flags;
2067
2068 if (opt_flags & OPT_LOCAL)
2069 {
2070 ve = curwin->w_p_ve;
2071 flags = &curwin->w_ve_flags;
2072 }
2073
2074 if ((opt_flags & OPT_LOCAL) && *ve == NUL)
2075 // make the local value empty: use the global value
2076 *flags = 0;
2077 else
2078 {
2079 if (opt_strings_flags(ve, p_ve_values, flags, TRUE) != OK)
2080 errmsg = e_invalid_argument;
2081 else if (STRCMP(ve, oldval) != 0)
2082 {
2083 // Recompute cursor position in case the new 've' setting
2084 // changes something.
2085 validate_virtcol();
2086 coladvance(curwin->w_virtcol);
2087 }
2088 }
2089 }
2090 2987
2091 #if defined(FEAT_CSCOPE) && defined(FEAT_QUICKFIX) 2988 #if defined(FEAT_CSCOPE) && defined(FEAT_QUICKFIX)
2989 // 'cscopequickfix'
2092 else if (varp == &p_csqf) 2990 else if (varp == &p_csqf)
2093 { 2991 errmsg = did_set_cscopequickfix();
2094 if (p_csqf != NULL)
2095 {
2096 p = p_csqf;
2097 while (*p != NUL)
2098 {
2099 if (vim_strchr((char_u *)CSQF_CMDS, *p) == NULL
2100 || p[1] == NUL
2101 || vim_strchr((char_u *)CSQF_FLAGS, p[1]) == NULL
2102 || (p[2] != NUL && p[2] != ','))
2103 {
2104 errmsg = e_invalid_argument;
2105 break;
2106 }
2107 else if (p[2] == NUL)
2108 break;
2109 else
2110 p += 3;
2111 }
2112 }
2113 }
2114 #endif 2992 #endif
2115 2993
2116 // 'cinoptions' 2994 // 'cinoptions'
2117 else if (gvarp == &p_cino) 2995 else if (gvarp == &p_cino)
2118 { 2996 did_set_cinoptions();
2119 // TODO: recognize errors
2120 parse_cino(curbuf);
2121 }
2122 2997
2123 // 'lispoptions' 2998 // 'lispoptions'
2124 else if (gvarp == &p_lop) 2999 else if (gvarp == &p_lop)
2125 { 3000 errmsg = did_set_lispoptions(varp);
2126 if (**varp != NUL && STRCMP(*varp, "expr:0") != 0
2127 && STRCMP(*varp, "expr:1") != 0)
2128 errmsg = e_invalid_argument;
2129 }
2130 3001
2131 #if defined(FEAT_RENDER_OPTIONS) 3002 #if defined(FEAT_RENDER_OPTIONS)
2132 // 'renderoptions' 3003 // 'renderoptions'
2133 else if (varp == &p_rop) 3004 else if (varp == &p_rop)
2134 { 3005 errmsg = did_set_renderoptions();
2135 if (!gui_mch_set_rendering_options(p_rop)) 3006 #endif
2136 errmsg = e_invalid_argument; 3007
2137 } 3008 // 'filetype'
2138 #endif
2139
2140 else if (gvarp == &p_ft) 3009 else if (gvarp == &p_ft)
2141 { 3010 errmsg = did_set_filetype_or_syntax(varp, oldval, value_checked,
2142 if (!valid_filetype(*varp)) 3011 &value_changed);
2143 errmsg = e_invalid_argument;
2144 else
2145 {
2146 value_changed = STRCMP(oldval, *varp) != 0;
2147
2148 // Since we check the value, there is no need to set P_INSECURE,
2149 // even when the value comes from a modeline.
2150 *value_checked = TRUE;
2151 }
2152 }
2153 3012
2154 #ifdef FEAT_SYN_HL 3013 #ifdef FEAT_SYN_HL
3014 // 'syntax'
2155 else if (gvarp == &p_syn) 3015 else if (gvarp == &p_syn)
2156 { 3016 errmsg = did_set_filetype_or_syntax(varp, oldval, value_checked,
2157 if (!valid_filetype(*varp)) 3017 &value_changed);
2158 errmsg = e_invalid_argument;
2159 else
2160 {
2161 value_changed = STRCMP(oldval, *varp) != 0;
2162
2163 // Since we check the value, there is no need to set P_INSECURE,
2164 // even when the value comes from a modeline.
2165 *value_checked = TRUE;
2166 }
2167 }
2168 #endif 3018 #endif
2169 3019
2170 #ifdef FEAT_TERMINAL 3020 #ifdef FEAT_TERMINAL
2171 // 'termwinkey' 3021 // 'termwinkey'
2172 else if (varp == &curwin->w_p_twk) 3022 else if (varp == &curwin->w_p_twk)
2173 { 3023 errmsg = did_set_termwinkey();
2174 if (*curwin->w_p_twk != NUL 3024
2175 && string_to_key(curwin->w_p_twk, TRUE) == 0)
2176 errmsg = e_invalid_argument;
2177 }
2178 // 'termwinsize' 3025 // 'termwinsize'
2179 else if (varp == &curwin->w_p_tws) 3026 else if (varp == &curwin->w_p_tws)
2180 { 3027 errmsg = did_set_termwinsize();
2181 if (*curwin->w_p_tws != NUL) 3028
2182 {
2183 p = skipdigits(curwin->w_p_tws);
2184 if (p == curwin->w_p_tws
2185 || (*p != 'x' && *p != '*')
2186 || *skipdigits(p + 1) != NUL)
2187 errmsg = e_invalid_argument;
2188 }
2189 }
2190 // 'wincolor' 3029 // 'wincolor'
2191 else if (varp == &curwin->w_p_wcr) 3030 else if (varp == &curwin->w_p_wcr)
2192 term_update_wincolor(curwin); 3031 term_update_wincolor(curwin);
2193 # if defined(MSWIN) 3032 # if defined(MSWIN)
2194 // 'termwintype' 3033 // 'termwintype'
2195 else if (varp == &p_twt) 3034 else if (varp == &p_twt)
2196 { 3035 errmsg = did_set_opt_strings(p_twt, p_twt_values, FALSE);
2197 if (check_opt_strings(*varp, p_twt_values, FALSE) != OK)
2198 errmsg = e_invalid_argument;
2199 }
2200 # endif 3036 # endif
2201 #endif 3037 #endif
2202 3038
2203 #ifdef FEAT_VARTABS 3039 #ifdef FEAT_VARTABS
2204 // 'varsofttabstop' 3040 // 'varsofttabstop'
2205 else if (varp == &(curbuf->b_p_vsts)) 3041 else if (varp == &(curbuf->b_p_vsts))
2206 { 3042 errmsg = did_set_varsofttabstop(varp);
2207 char_u *cp;
2208
2209 if (!(*varp)[0] || ((*varp)[0] == '0' && !(*varp)[1]))
2210 {
2211 if (curbuf->b_p_vsts_array)
2212 {
2213 vim_free(curbuf->b_p_vsts_array);
2214 curbuf->b_p_vsts_array = 0;
2215 }
2216 }
2217 else
2218 {
2219 for (cp = *varp; *cp; ++cp)
2220 {
2221 if (vim_isdigit(*cp))
2222 continue;
2223 if (*cp == ',' && cp > *varp && *(cp-1) != ',')
2224 continue;
2225 errmsg = e_invalid_argument;
2226 break;
2227 }
2228 if (errmsg == NULL)
2229 {
2230 int *oldarray = curbuf->b_p_vsts_array;
2231 if (tabstop_set(*varp, &(curbuf->b_p_vsts_array)) == OK)
2232 {
2233 if (oldarray)
2234 vim_free(oldarray);
2235 }
2236 else
2237 errmsg = e_invalid_argument;
2238 }
2239 }
2240 }
2241 3043
2242 // 'vartabstop' 3044 // 'vartabstop'
2243 else if (varp == &(curbuf->b_p_vts)) 3045 else if (varp == &(curbuf->b_p_vts))
2244 { 3046 errmsg = did_set_vartabstop(varp);
2245 char_u *cp;
2246
2247 if (!(*varp)[0] || ((*varp)[0] == '0' && !(*varp)[1]))
2248 {
2249 if (curbuf->b_p_vts_array)
2250 {
2251 vim_free(curbuf->b_p_vts_array);
2252 curbuf->b_p_vts_array = NULL;
2253 }
2254 }
2255 else
2256 {
2257 for (cp = *varp; *cp; ++cp)
2258 {
2259 if (vim_isdigit(*cp))
2260 continue;
2261 if (*cp == ',' && cp > *varp && *(cp-1) != ',')
2262 continue;
2263 errmsg = e_invalid_argument;
2264 break;
2265 }
2266 if (errmsg == NULL)
2267 {
2268 int *oldarray = curbuf->b_p_vts_array;
2269
2270 if (tabstop_set(*varp, &(curbuf->b_p_vts_array)) == OK)
2271 {
2272 vim_free(oldarray);
2273 #ifdef FEAT_FOLDING
2274 if (foldmethodIsIndent(curwin))
2275 foldUpdateAll(curwin);
2276 #endif
2277 }
2278 else
2279 errmsg = e_invalid_argument;
2280 }
2281 }
2282 }
2283 #endif 3047 #endif
2284 3048
2285 #ifdef FEAT_PROP_POPUP 3049 #ifdef FEAT_PROP_POPUP
2286 // 'previewpopup' 3050 // 'previewpopup'
2287 else if (varp == &p_pvp) 3051 else if (varp == &p_pvp)
2288 { 3052 errmsg = did_set_previewpopup();
2289 if (parse_previewpopup(NULL) == FAIL)
2290 errmsg = e_invalid_argument;
2291 }
2292 # ifdef FEAT_QUICKFIX 3053 # ifdef FEAT_QUICKFIX
2293 // 'completepopup' 3054 // 'completepopup'
2294 else if (varp == &p_cpp) 3055 else if (varp == &p_cpp)
2295 { 3056 errmsg = did_set_completepopup();
2296 if (parse_completepopup(NULL) == FAIL)
2297 errmsg = e_invalid_argument;
2298 else
2299 popup_close_info();
2300 }
2301 # endif 3057 # endif
2302 #endif 3058 #endif
2303 3059
2304 #ifdef FEAT_EVAL 3060 #ifdef FEAT_EVAL
2305 // '*expr' options 3061 // '*expr' options
2324 # endif 3080 # endif
2325 # ifdef FEAT_POSTSCRIPT 3081 # ifdef FEAT_POSTSCRIPT
2326 varp == &p_pexpr || 3082 varp == &p_pexpr ||
2327 # endif 3083 # endif
2328 varp == &p_ccv) 3084 varp == &p_ccv)
2329 { 3085 did_set_optexpr(varp);
2330 // If the option value starts with <SID> or s:, then replace that with
2331 // the script identifier.
2332 char_u *name = get_scriptlocal_funcname(*varp);
2333 if (name != NULL)
2334 {
2335 free_string_option(*varp);
2336 *varp = name;
2337 }
2338
2339 # ifdef FEAT_FOLDING
2340 if (varp == &curwin->w_p_fde && foldmethodIsExpr(curwin))
2341 foldUpdateAll(curwin);
2342 # endif
2343 }
2344 #endif 3086 #endif
2345 3087
2346 #ifdef FEAT_COMPL_FUNC 3088 #ifdef FEAT_COMPL_FUNC
2347 // 'completefunc' 3089 // 'completefunc'
2348 else if (gvarp == &p_cfu) 3090 else if (gvarp == &p_cfu)
2349 { 3091 errmsg = set_completefunc_option();
2350 if (set_completefunc_option() == FAIL)
2351 errmsg = e_invalid_argument;
2352 }
2353 3092
2354 // 'omnifunc' 3093 // 'omnifunc'
2355 else if (gvarp == &p_ofu) 3094 else if (gvarp == &p_ofu)
2356 { 3095 errmsg = set_omnifunc_option();
2357 if (set_omnifunc_option() == FAIL)
2358 errmsg = e_invalid_argument;
2359 }
2360 3096
2361 // 'thesaurusfunc' 3097 // 'thesaurusfunc'
2362 else if (gvarp == &p_tsrfu) 3098 else if (gvarp == &p_tsrfu)
2363 { 3099 errmsg = set_thesaurusfunc_option();
2364 if (set_thesaurusfunc_option() == FAIL)
2365 errmsg = e_invalid_argument;
2366 }
2367 #endif 3100 #endif
2368 3101
2369 #if defined(FEAT_EVAL) && \ 3102 #if defined(FEAT_EVAL) && \
2370 (defined(FEAT_XIM) || defined(IME_WITHOUT_XIM) || defined(VIMDLL)) 3103 (defined(FEAT_XIM) || defined(IME_WITHOUT_XIM) || defined(VIMDLL))
2371 // 'imactivatefunc' 3104 // 'imactivatefunc'
2372 else if (gvarp == &p_imaf) 3105 else if (gvarp == &p_imaf)
2373 { 3106 errmsg = set_imactivatefunc_option();
2374 if (set_imactivatefunc_option() == FAIL)
2375 errmsg = e_invalid_argument;
2376 }
2377 3107
2378 // 'imstatusfunc' 3108 // 'imstatusfunc'
2379 else if (gvarp == &p_imsf) 3109 else if (gvarp == &p_imsf)
2380 { 3110 errmsg = set_imstatusfunc_option();
2381 if (set_imstatusfunc_option() == FAIL)
2382 errmsg = e_invalid_argument;
2383 }
2384 #endif 3111 #endif
2385 3112
2386 // 'operatorfunc' 3113 // 'operatorfunc'
2387 else if (varp == &p_opfunc) 3114 else if (varp == &p_opfunc)
2388 { 3115 errmsg = set_operatorfunc_option();
2389 if (set_operatorfunc_option() == FAIL)
2390 errmsg = e_invalid_argument;
2391 }
2392 3116
2393 #ifdef FEAT_QUICKFIX 3117 #ifdef FEAT_QUICKFIX
2394 // 'quickfixtextfunc' 3118 // 'quickfixtextfunc'
2395 else if (varp == &p_qftf) 3119 else if (varp == &p_qftf)
2396 { 3120 errmsg = qf_process_qftf_option();
2397 if (qf_process_qftf_option() == FAIL)
2398 errmsg = e_invalid_argument;
2399 }
2400 #endif 3121 #endif
2401 3122
2402 #ifdef FEAT_EVAL 3123 #ifdef FEAT_EVAL
2403 // 'tagfunc' 3124 // 'tagfunc'
2404 else if (gvarp == &p_tfu) 3125 else if (gvarp == &p_tfu)
2405 { 3126 errmsg = set_tagfunc_option();
2406 if (set_tagfunc_option() == FAIL)
2407 errmsg = e_invalid_argument;
2408 }
2409 #endif 3127 #endif
2410 3128
2411 // Options that are a list of flags. 3129 // Options that are a list of flags.
2412 else 3130 else
2413 { 3131 {