@@ -3398,8 +3398,11 @@ find_ex_command(
33983398 int len ;
33993399 char_u * p ;
34003400 int i ;
3401+ #ifndef FEAT_EVAL
3402+ int vim9 = FALSE;
3403+ #else
3404+ int vim9 = in_vim9script ();
34013405
3402- #ifdef FEAT_EVAL
34033406 /*
34043407 * Recognize a Vim9 script function/method call and assignment:
34053408 * "lvar = value", "lvar(arg)", "[1, 2 3]->Func()"
@@ -3562,12 +3565,13 @@ find_ex_command(
35623565 * - the "d" command can directly be followed by 'l' or 'p' flag.
35633566 */
35643567 p = eap -> cmd ;
3565- if (* p == 'k' )
3568+ if (! vim9 && * p == 'k' )
35663569 {
35673570 eap -> cmdidx = CMD_k ;
35683571 ++ p ;
35693572 }
3570- else if (p [0 ] == 's'
3573+ else if (!vim9
3574+ && p [0 ] == 's'
35713575 && ((p [1 ] == 'c' && (p [2 ] == NUL || (p [2 ] != 's' && p [2 ] != 'r'
35723576 && (p [3 ] == NUL || (p [3 ] != 'i' && p [4 ] != 'p' )))))
35733577 || p [1 ] == 'g'
@@ -3600,7 +3604,7 @@ find_ex_command(
36003604 if (p == eap -> cmd && vim_strchr ((char_u * )"@*!=><&~#}" , * p ) != NULL )
36013605 ++ p ;
36023606 len = (int )(p - eap -> cmd );
3603- if (* eap -> cmd == 'd' && (p [-1 ] == 'l' || p [-1 ] == 'p' ))
3607+ if (! vim9 && * eap -> cmd == 'd' && (p [-1 ] == 'l' || p [-1 ] == 'p' ))
36043608 {
36053609 // Check for ":dl", ":dell", etc. to ":deletel": that's
36063610 // :delete with the 'l' flag. Same for 'p'.
@@ -3677,7 +3681,7 @@ find_ex_command(
36773681
36783682#ifdef FEAT_EVAL
36793683 if (eap -> cmdidx < CMD_SIZE
3680- && in_vim9script ()
3684+ && vim9
36813685 && !IS_WHITE_OR_NUL (* p ) && * p != '\n' && * p != '!'
36823686 && (eap -> cmdidx < 0 ||
36833687 (cmdnames [eap -> cmdidx ].cmd_argt & EX_NONWHITE_OK ) == 0 ))
@@ -3797,17 +3801,32 @@ f_fullcommand(typval_T *argvars, typval_T *rettv)
37973801 char_u * name = argvars [0 ].vval .v_string ;
37983802 char_u * p ;
37993803
3800- while (name [0 ] != NUL && name [0 ] == ':' )
3804+ rettv -> v_type = VAR_STRING ;
3805+ rettv -> vval .v_string = NULL ;
3806+ if (name == NULL )
3807+ return ;
3808+
3809+ while (* name != NUL && * name == ':' )
38013810 name ++ ;
38023811 name = skip_range (name , TRUE, NULL );
38033812
3804- rettv -> v_type = VAR_STRING ;
3805-
38063813 ea .cmd = (* name == '2' || * name == '3' ) ? name + 1 : name ;
38073814 ea .cmdidx = (cmdidx_T )0 ;
3815+ ea .addr_count = 0 ;
38083816 p = find_ex_command (& ea , NULL , NULL , NULL );
38093817 if (p == NULL || ea .cmdidx == CMD_SIZE )
38103818 return ;
3819+ if (in_vim9script ())
3820+ {
3821+ int res ;
3822+
3823+ ++ emsg_silent ;
3824+ res = not_in_vim9 (& ea );
3825+ -- emsg_silent ;
3826+
3827+ if (res == FAIL )
3828+ return ;
3829+ }
38113830
38123831 rettv -> vval .v_string = vim_strsave (IS_USER_CMDIDX (ea .cmdidx )
38133832 ? get_user_commands (NULL , ea .useridx )
@@ -5485,7 +5504,7 @@ not_exiting(void)
54855504 settmode (TMODE_RAW );
54865505}
54875506
5488- static int
5507+ int
54895508before_quit_autocmds (win_T * wp , int quit_all , int forceit )
54905509{
54915510 apply_autocmds (EVENT_QUITPRE , NULL , NULL , FALSE, wp -> w_buffer );
@@ -5559,7 +5578,7 @@ ex_quit(exarg_T *eap)
55595578#endif
55605579
55615580 /*
5562- * If there are more files or windows we won't exit.
5581+ * If there is only one relevant window we will exit.
55635582 */
55645583 if (check_more (FALSE, eap -> forceit ) == OK && only_one_window ())
55655584 exiting = TRUE;
@@ -6076,7 +6095,7 @@ ex_stop(exarg_T *eap)
60766095}
60776096
60786097/*
6079- * ":exit", ":xit" and ":wq": Write file and quite the current window.
6098+ * ":exit", ":xit" and ":wq": Write file and quit the current window.
60806099 */
60816100 static void
60826101ex_exit (exarg_T * eap )
@@ -6099,17 +6118,17 @@ ex_exit(exarg_T *eap)
60996118 return ;
61006119 }
61016120
6102- if (before_quit_autocmds (curwin , FALSE, eap -> forceit ))
6103- return ;
6104-
61056121 /*
6106- * if more files or windows we won't exit
6122+ * we plan to exit if there is only one relevant window
61076123 */
61086124 if (check_more (FALSE, eap -> forceit ) == OK && only_one_window ())
61096125 exiting = TRUE;
6110- if ( ((eap -> cmdidx == CMD_wq
6111- || curbufIsChanged ())
6112- && do_write (eap ) == FAIL )
6126+
6127+ // Write the buffer for ":wq" or when it was changed.
6128+ // Trigger QuitPre and ExitPre.
6129+ // Check if we can exit now, after autocommands have changed things.
6130+ if (((eap -> cmdidx == CMD_wq || curbufIsChanged ()) && do_write (eap ) == FAIL )
6131+ || before_quit_autocmds (curwin , FALSE, eap -> forceit )
61136132 || check_more (TRUE, eap -> forceit ) == FAIL
61146133 || (only_one_window () && check_changed_any (eap -> forceit , FALSE)))
61156134 {
0 commit comments