Open arp242 opened 2 years ago
But ideally, "undefined variable: tabs_len" or the like would be best, but I'm guessing there may be a reason it doesn't do that already.
The difference between tabs_len
and xxx
, is that the former contains a prefix which matches a known Ex command, while the latter does not (:x
is invalid in Vim9).
As a result, there is an ambiguity in the semantics of tabs_len
. Is it a variable, or is it the :tabs
command to which you pass the _len
argument? Here, since Vim has never seen a declaration for a variable tabs_len
, it infers that you're trying to execute :tabs
, because that's the only remaining semantics.
However, I agree that the error is a bit confusing, because it suggests to add a space which wouldn't help here, since :tabs
doesn't accept any argument.
In this specific case, we might give an E121: Undefined variable
error. But not in the general case where the variable might contain a prefix matching a known Ex command which does accept an argument. For example, as documented at :help E1144
:
vim9script
exit_cb = 123
E1144: Command "exit" is not followed by white space: exit_cb = 123
Here, we can't give E121: Undefined variable
, because it might be that you wanted to execute :exit _cb
(notice the space).
Either way, the white space error is very confusing.
This started with patch 8.2.2138. Before that, it was even worse, because Vim didn't enforce a space between a command and its argument, which could lead to no error being given and an unexpected command being run. Now, we no longer have any unexpected command being run, and we do have an error. But we might need to make it easier to understand when possible (like here).
Steps to reproduce
% cat err vim9script tabs_len = 2
% vim -Nu NONE +source\ err Error detected while processing command line..script /home/martin/err: line 2: E1144: Command "tabs" is not followed by white space: tabs_len = 2 Press ENTER or type command to continue
I copy/pasted some code from somewhere else, and the
var tabs_len
got lost. Also happens with+=
,-=
, etc.If I change the variable name to
xxx
it's a little bit better:Error detected while processing command line..script /home/martin/err: line 2: E492: Not an editor command: xxx = 2 Press ENTER or type command to continue
But ideally, "undefined variable: tabs_len" or the like would be best, but I'm guessing there may be a reason it doesn't do that already. Either way, the white space error is very confusing.
As lacygoill mentioned: we do not know that you were using a variable name. Vim just see ":tabs" and something following.
We could make an exception for using "_", to give a different error message. But it's just one case. What if you used "tabs2 = 2"?
Another guess is that "=" follows. But it could also be "+=" or "->" or "(args)" (used for a function reference with a typo).
I think the error is clear enough, since it mentions it recognized "tabs" as a command. Just takes a bit of background knowledge to understand it.
-- E M A C S s e l o h c t t n i a a t f p r t e o l
/// Bram Moolenaar -- @.*** -- http://www.Moolenaar.net \\ /// \\ \\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\ help me help AIDS victims -- http://ICCF-Holland.org ///
Does Vim really need to check if it's the :tabs
command if spaces after it are mandatory? It's allowed in legacy VimScript and I've seen it on a few (rare) occasions, but even when migrating I'd consider tabs_len not defined
to be clearer, but also cases where you do want to pass an argument, like say:
vim9script
tabmove1
"undefined reference: tabmove1" seems clearer to me. People can figure out that they need to add a space, because that's how pretty much everything works. Although there are still other cases where this kind of "forgot to use var" error goes wrong, for example:
first = 1
Will try to run :first.
Not sure that can easily be improved on. But that's a different issue.
Just takes a bit of background knowledge to understand it.
Personally I'd say the thing with VimScript is that very few people have this knowledge. Very few people write VimScript for a living outside of the very occasional plugin to interface with $product, like GitHub Copilot, and there's a comparatively small community of plugin authors and Vim aficionados. Most "normal" people I've use VimScript once in a blue moon, at most.
How about we append (missing var?)
at the end of the message?
Before:
E1144: Command "tabs" is not followed by white space: tabs_len = 2
After:
E1144: Command "tabs" is not followed by white space: tabs_len = 2 (missing var?)
^------------^
diff --git a/src/errors.h b/src/errors.h
index 8aad956d9..cb7eb9df6 100644
--- a/src/errors.h
+++ b/src/errors.h
@@ -2925,7 +2925,7 @@ EXTERN char e_calling_test_garbagecollect_now_while_v_testing_is_not_set[]
EXTERN char e_empty_expression_str[]
INIT(= N_("E1143: Empty expression: \"%s\""));
EXTERN char e_command_str_not_followed_by_white_space_str[]
- INIT(= N_("E1144: Command \"%s\" is not followed by white space: %s"));
+ INIT(= N_("E1144: Command \"%s\" is not followed by white space: %s (missing var?)"));
EXTERN char e_missing_heredoc_end_marker_str[]
INIT(= N_("E1145: Missing heredoc end marker: %s"));
EXTERN char e_command_not_recognized_str[]
Would it help? Would it make sense in the general case?
That's what we do in E1100
:
https://github.com/vim/vim/blob/326c5d36e7cb8526330565109c17b4a13ff790ae/src/errors.h#L2836
The previous patch would make E1144
inconsistent with E1100
. New patch to make it consistent:
diff --git a/src/errors.h b/src/errors.h
index 8aad956d9..78ccda660 100644
--- a/src/errors.h
+++ b/src/errors.h
@@ -2925,7 +2925,7 @@ EXTERN char e_calling_test_garbagecollect_now_while_v_testing_is_not_set[]
EXTERN char e_empty_expression_str[]
INIT(= N_("E1143: Empty expression: \"%s\""));
EXTERN char e_command_str_not_followed_by_white_space_str[]
- INIT(= N_("E1144: Command \"%s\" is not followed by white space: %s"));
+ INIT(= N_("E1144: Command \"%s\" is not followed by white space (missing :var?): %s"));
EXTERN char e_missing_heredoc_end_marker_str[]
INIT(= N_("E1145: Missing heredoc end marker: %s"));
EXTERN char e_command_not_recognized_str[]
Maybe we should add the or
conjunction to make it clear that it's another possible cause for the error (and not further info about the previous cause):
diff --git a/src/errors.h b/src/errors.h
index 8aad956d9..d1e764260 100644
--- a/src/errors.h
+++ b/src/errors.h
@@ -2833,7 +2833,7 @@ EXTERN char e_string_list_or_blob_required[]
EXTERN char e_unknown_error_while_executing_str[]
INIT(= N_("E1099: Unknown error while executing %s"));
EXTERN char e_command_not_supported_in_vim9_script_missing_var_str[]
- INIT(= N_("E1100: Command not supported in Vim9 script (missing :var?): %s"));
+ INIT(= N_("E1100: Command not supported in Vim9 script (or missing :var?): %s"));
EXTERN char e_cannot_declare_script_variable_in_function_str[]
INIT(= N_("E1101: Cannot declare a script variable in a function: %s"));
EXTERN char e_lambda_function_not_found_str[]
@@ -2925,7 +2925,7 @@ EXTERN char e_calling_test_garbagecollect_now_while_v_testing_is_not_set[]
EXTERN char e_empty_expression_str[]
INIT(= N_("E1143: Empty expression: \"%s\""));
EXTERN char e_command_str_not_followed_by_white_space_str[]
- INIT(= N_("E1144: Command \"%s\" is not followed by white space: %s"));
+ INIT(= N_("E1144: Command \"%s\" is not followed by white space (or missing :var?): %s"));
EXTERN char e_missing_heredoc_end_marker_str[]
INIT(= N_("E1145: Missing heredoc end marker: %s"));
EXTERN char e_command_not_recognized_str[]
Maybe we should add the
or
conjunction to make it clear that it's another possible cause for the error (and not further info about the previous error):diff --git a/src/errors.h b/src/errors.h index 8aad956d9..d1e764260 100644 --- a/src/errors.h +++ b/src/errors.h @@ -2833,7 +2833,7 @@ EXTERN char e_string_list_or_blob_required[] EXTERN char e_unknown_error_while_executing_str[] INIT(= N_("E1099: Unknown error while executing %s")); EXTERN char e_command_not_supported_in_vim9_script_missing_var_str[] - INIT(= N_("E1100: Command not supported in Vim9 script (missing :var?): %s")); + INIT(= N_("E1100: Command not supported in Vim9 script (or missing :var?): %s")); EXTERN char e_cannot_declare_script_variable_in_function_str[] INIT(= N_("E1101: Cannot declare a script variable in a function: %s")); EXTERN char e_lambda_function_not_found_str[] @@ -2925,7 +2925,7 @@ EXTERN char e_calling_test_garbagecollect_now_while_v_testing_is_not_set[] EXTERN char e_empty_expression_str[] INIT(= N_("E1143: Empty expression: \"%s\"")); EXTERN char e_command_str_not_followed_by_white_space_str[] - INIT(= N_("E1144: Command \"%s\" is not followed by white space: %s")); + INIT(= N_("E1144: Command \"%s\" is not followed by white space (or missing :var?): %s")); EXTERN char e_missing_heredoc_end_marker_str[] INIT(= N_("E1145: Missing heredoc end marker: %s")); EXTERN char e_command_not_recognized_str[]
The "missing var?" should only be given if the non-white character can be used in a variable. "tabs_name" could be a variable, but "tabs/name" looks more like a command with an invalid argument. Mentioning "var" would then only add to the confusion.
-- I'd like to meet the man who invented sex and see what he's working on now.
/// Bram Moolenaar -- @.*** -- http://www.Moolenaar.net \\ /// \\ \\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\ help me help AIDS victims -- http://ICCF-Holland.org ///
I copy/pasted some code from somewhere else, and the
var tabs_len
got lost. Also happens with+=
,-=
, etc.If I change the variable name to
xxx
it's a little bit better:But ideally, "undefined variable: tabs_len" or the like would be best, but I'm guessing there may be a reason it doesn't do that already. Either way, the white space error is very confusing.
Vim 9.0.0192